Requests: Ausnahme auslösen, wenn Statuscode ungleich 200 . ist

Erstellt am 27. Juli 2014  ·  3Kommentare  ·  Quelle: psf/requests

Hallo,
Ich erwarte oft, dass die Anfrage den Statuscode 200 hat, und wenn dies nicht der Fall ist, kann ich nicht viel tun (im Ernst, wenn der Server mit Fehler 500 zurückkehrt, kann ich nichts tun). Also muss ich Code wie diesen schreiben:

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

Ich denke, ein Kwarg namens allow_status_codes wäre sehr praktisch. Es könnte so umgesetzt werden:
Standardmäßig ist es None . None , und eine leere Liste oder ein leeres Tupel bedeutet, dass alle Statuscodes zugelassen werden. Es kann eine ganze Zahl, eine Liste, ein Tupel oder eine Aufzählung sein. Wenn es sich um eine ganze Zahl handelt, lassen Sie nur diesen bestimmten Statuscode zu. Falls es sich um eine Liste oder ein Tupel handelt, sind nur Statuscodes zulässig, die sich innerhalb der Liste/des Tupels befinden. Die Liste kann ganze Zahlen und/oder Aufzählungen enthalten. Aufzählungen sollten etwas flexibler sein.
Wenn ich zum Beispiel alle "erfolgreichen" (2xx) Anfragen zulassen möchte, könnte ich schreiben: allow_status_codes=requests.ALLOW_SUCCESS, was eine Ausnahme auslöst, es sei denn, der Statuscode ist 2xx. Wenn ich nur Serverfehler verbieten wollte (und somit nicht authentifizierte Fehler behandeln wollte), könnte ich einfach allow_status_codes=requests.DISALLOW_SERVER_ERROR schreiben, was eine Ausnahme auslöst, wenn der Servercode 5xx ist.
Natürlich sollte es viele Aufzählungen geben, die bestimmte Fälle abdecken. Und man sollte es auch kombiniert innerhalb einer Liste verwenden können (zB (200, ALLOW_REDIRECTIONS) ).
Wenn der Statuscode nicht zulässig ist, wird ein StatusCodeError(RequestException) ausgegeben.


Obwohl ich Aufzählungen erwähnt habe, spreche ich nicht über die Aufzählungswerte von Python 3.4. Ich habe eher von Konstanten gesprochen. Aufzählungen (Konstanten) könnten wie folgt implementiert werden:

#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

Hilfreichster Kommentar

Hat nicht jedes Response eine raise_for_status Methode, die eine Ausnahme auslöst, wenn der Statuscode nicht 200 ist?

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

Alle 3 Kommentare

Danke für diese Idee!

Es ist nicht klar, warum dies in die Anfragen selbst gehört. Der erforderliche Code ist nicht komplex, und ich glaube nicht, dass wir viel Wert hinzufügen würden, wenn dieser Code in der Bibliothek vorhanden wäre. Wir _würden_ jedoch der API ein weiteres Schlüsselwortargument hinzufügen, was wir meistens nicht tun möchten.

Hat nicht jedes Response eine raise_for_status Methode, die eine Ausnahme auslöst, wenn der Statuscode nicht 200 ist?

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 Weil es sehr praktisch ist, kann man viel Code sparen (sagen wir einfach, ein Projekt verwendet eine Anfrage. Dieses Projekt verwendet etwa 100 Mal eine Anfrage. Es _könnte_ also 200 Zeilen Code sparen und Tippfehler verhindern, weil ich schreiben müsste die Ausnahme 100 Mal (falls ich keine Methode zum Auslösen einer Ausnahme verwende) und sie vereinheitlicht Ausnahmen/Fehler (eine andere API verwendet möglicherweise Anfragen und löst einen benutzerdefinierten Fehler im Falle eines ungültigen Statuscodes aus. Mir gefällt es besser, wenn es wirft die gleiche Ausnahme wie Anfragen).

@sigmavirus24 Entschuldigung, ich wusste nicht, dass diese Methode existiert. Sie sollten erwähnen, dass ein HTTPError von raise_for_status im Abschnitt Error and Exceptions in der Dokumentation ausgelöst werden kann. Ein HTTPError behauptet derzeit, nur "im seltenen Fall einer ungültigen HTTP-Antwort" ausgelöst zu werden.
Sie könnten auch erwägen, einige meiner Ideen in mein raise_for_status zu implementieren, damit es auch andere Statuscodes zulassen kann.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

avinassh picture avinassh  ·  4Kommentare

ReimarBauer picture ReimarBauer  ·  4Kommentare

mitar picture mitar  ·  4Kommentare

everping picture everping  ·  4Kommentare

NoahCardoza picture NoahCardoza  ·  4Kommentare