Requests: Lever une exception si le code d'état n'est pas égal à 200

Créé le 27 juil. 2014  ·  3Commentaires  ·  Source: psf/requests

Bonjour,
Je m'attends souvent à ce que la demande ait le code d'état 200 et si ce n'est pas le cas, je ne peux pas faire grand-chose (sérieusement, lorsque le serveur revient avec l'erreur 500, je ne pourrai rien faire). J'ai donc besoin d'écrire un code comme celui-ci :

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

Je pense qu'un kwarg appelé allow_status_codes serait très pratique. Il pourrait être implémenté comme ceci :
Par défaut, c'est None . None , et une liste ou un tuple vide signifie autoriser tous les codes d'état. Il peut s'agir d'un entier, d'une liste, d'un tuple ou d'une énumération. S'il s'agit d'un nombre entier, n'autorisez que ce code d'état spécifique. S'il s'agit d'une liste ou d'un tuple, seuls les codes d'état qui se trouvent à l'intérieur de la liste/du tuple sont autorisés. La liste peut contenir des entiers et/ou des énumérations. Les énumérations devraient être un peu plus flexibles.
Par exemple, si je voulais autoriser toutes les demandes « réussies » (2xx), je pourrais écrire : allow_status_codes=requests.ALLOW_SUCCESS, qui lèvera une exception à moins que le code d'état ne soit 2xx. Si je voulais seulement interdire les erreurs de serveur (et donc gérer les erreurs non authentifiées), je pourrais simplement écrire allow_status_codes=requests.DISALLOW_SERVER_ERROR, ce qui déclenchera une exception si le code du serveur est 5xx.
Bien sûr, il devrait y avoir beaucoup d'énumérations qui couvrent des cas spécifiques. Et on devrait aussi pouvoir l'utiliser combiné au sein d'une liste (par exemple (200, ALLOW_REDIRECTIONS) ).
Si le code de statut n'est pas autorisé, un StatusCodeError(RequestException) sera généré.


Même si j'ai mentionné les énumérations, je ne parle pas des valeurs énumérées de Python 3.4. Je parlais plutôt de constantes. Les énumérations (constantes) pourraient être implémentées comme ceci :

#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

Commentaire le plus utile

De plus, chaque Response n'a-t-il pas une méthode raise_for_status qui lèvera une exception si le code d'état n'est pas 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

Tous les 3 commentaires

Merci pour cette idée !

On ne sait pas pourquoi cela appartient aux demandes elles-mêmes. Le code requis n'est pas complexe et je ne pense pas que nous ajouterions beaucoup de valeur en ayant ce code dans la bibliothèque. Cependant, nous _serions_ ajouter un autre argument de mot-clé à l'API, ce que nous ne sommes pas enclins à faire la plupart du temps.

De plus, chaque Response n'a-t-il pas une méthode raise_for_status qui lèvera une exception si le code d'état n'est pas 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 Parce que c'est très pratique, peut économiser beaucoup de code (disons simplement qu'un projet utilise une requête. Ce projet utilise environ 100 fois une requête. Donc, il _pourrait_ économiser 200 lignes de code et éviter les fautes de frappe parce que je devrais écrire l'exception 100 fois (au cas où je n'utiliserais pas de méthode pour lever une exception), et cela unifie les exceptions/erreurs (une autre API peut utiliser des requêtes et générer une erreur personnalisée en cas de code de statut invalide. Je l'aime mieux si il lève la même exception que les requêtes).

@sigmavirus24 Désolé, je ne savais pas que cette méthode
Vous pouvez également envisager d'implémenter certaines de mes idées dans mon raise_for_status afin qu'il puisse également autoriser d'autres codes de statut.

Cette page vous a été utile?
0 / 5 - 0 notes