Requests: Gerar exceção se o código de status não for igual a 200

Criado em 27 jul. 2014  ·  3Comentários  ·  Fonte: psf/requests

Olá,
Muitas vezes espero que a solicitação tenha o código de status 200 e, se não tiver, não há muito que possa fazer a respeito (sério, quando o servidor retorna com o erro 500, não poderei fazer nada). Portanto, preciso escrever um código como este:

    r = requests.get(self.url(False))
    if r.status_code != 200:
        raise requests.ConnectionError("Expected status code 200, but got {}".format(page.status_code))

Acho que um kwarg chamado allowed_status_codes seria muito conveniente. Pode ser implementado assim:
Por padrão, é None . None , e uma lista vazia ou tupla significa permitir todos os códigos de status. Pode ser um número inteiro, lista, tupla ou enum. Se for um número inteiro, permita apenas este código de status específico. No caso de ser uma lista ou tupla, apenas os códigos de status que estão dentro da lista / tupla são permitidos. A lista pode conter inteiros e / ou enums. Enums devem ser um pouco mais flexíveis.
Por exemplo, se eu quisesse permitir todas as solicitações "bem-sucedidas" (2xx), poderia escrever: allowed_status_codes = requests.ALLOW_SUCCESS, que lançará uma exceção, a menos que o código de status seja 2xx. Se eu quisesse apenas proibir erros de servidor (e, portanto, lidar com erros não autenticados), poderia simplesmente escrever allowed_status_codes = requests.DISALLOW_SERVER_ERROR, o que gerará uma exceção se o código do servidor for 5xx.
É claro que deve haver muitos enums que cubram casos específicos. E também deve ser possível usá-lo combinado em uma lista (por exemplo, (200, ALLOW_REDIRECTIONS) ).
Se o código de status não for permitido, um StatusCodeError(RequestException) será gerado.


Embora eu tenha mencionado enums, não estou falando sobre os valores enumerados do Python 3.4. Eu estava falando bastante sobre constantes. Enums (constantes) podem ser implementados assim:

#request model.

ALLOW_SUCCESS = AllowSuccessEnum()
# other enums

class RequestEnum(object):
     def is_status_code_allowed(status_code):
         raise NotImplementedError

class AllowSuccessEnum(RequestEnum):
    def is_status_code_allowed(status_code):
        # return false unless status code is 2xx

Comentários muito úteis

Além disso, cada Response tem um método raise_for_status que gerará uma exceção se o código de status não for 200?

Python 2.7.7 (default, Jun  2 2014, 18:55:26)
[GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import requests
>>> r = requests.get('http://httpbin.org/404')
>>> r
<Response [404]>
>>> r.raise_for_status()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/site-packages/requests/models.py", line 795, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 404 Client Error: NOT FOUND

Todos 3 comentários

Obrigado por esta ideia!

Não está claro por que isso pertence às próprias solicitações. O código necessário não é complexo e não acredito que agregaríamos muito valor tendo esse código na biblioteca. Nós _seria_, entretanto, adicionar outro argumento de palavra-chave à API, que é algo que não estamos inclinados a fazer na maioria das vezes.

Além disso, cada Response tem um método raise_for_status que gerará uma exceção se o código de status não for 200?

Python 2.7.7 (default, Jun  2 2014, 18:55:26)
[GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import requests
>>> r = requests.get('http://httpbin.org/404')
>>> r
<Response [404]>
>>> r.raise_for_status()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/site-packages/requests/models.py", line 795, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 404 Client Error: NOT FOUND

@Lukasa Por ser muito conveniente, pode salvar muitos códigos (digamos que um projeto usa solicitação. Este projeto usa cerca de 100 vezes uma solicitação. Portanto, _pode_ salvar 200 linhas de código e evitar erros de digitação porque eu teria que escrever a exceção 100 vezes (caso eu não use um método para gerar uma exceção) e unifica exceções / erros (outra API pode usar solicitações e gerar um erro personalizado no caso de um código de status inválido. Gosto mais se ele lança a mesma exceção que as solicitações fazem).

@ sigmavirus24 Desculpe, não sabia que esse método existia. Você deve mencionar que um HTTPError pode ser gerado por raise_for_status na seção Erro e Exceções nos documentos. Um HTTPError atualmente afirma ser gerado apenas "No caso raro de uma resposta HTTP inválida".
Você também pode considerar a implementação de algumas de minhas ideias em meu raise_for_status para que ele possa permitir outros códigos de status também.

Esta página foi útil?
0 / 5 - 0 avaliações