Python's Requests Bibliothek (Anleitung)

Aus Micropython
Zur Navigation springen Zur Suche springen

Python's Requests Bibliothek (Anleitung)[Bearbeiten | Quelltext bearbeiten]

von Alex Ronquillo
Original: https://realpython.com/python-requests/
Übersetzt mit DeepL.com

Inhaltsübersicht

   Erste Schritte mit Pythons Requests-Bibliothek
   Eine GET-Anfrage stellen
   Prüfen der Antwort
       Mit Status Codes arbeiten
       Zugriff auf den Inhalt der Antwort
       Kopfzeilen der Antwort anzeigen
   Abfrage-String-Parameter hinzufügen
   Anforderungs-Header anpassen
   Andere HTTP-Methoden verwenden
   Anfragedaten senden
   Prüfen der vorbereiteten Anfrage
   Authentifizierung verwenden
   Sichere Kommunikation mit Servern
   Verbessern Sie die Leistung
       Anfrage-Timeouts festlegen
       Wiederverwendung von Verbindungen mit Sitzungsobjekten
       Fehlgeschlagene Anfragen wiederholen
   Schlussfolgerung
   Häufig gestellte Fragen

Die Bibliothek Requests ist das Standardpaket für die Erstellung von HTTP-Anfragen in Python. Sie abstrahiert die Komplexität von Anfragen hinter einer intuitiven API. Obwohl es nicht Teil der Standardbibliothek von Python ist, lohnt es sich, Requests in Betracht zu ziehen, um HTTP-Aktionen wie GET, POST und mehr durchzuführen.

Am Ende dieses Tutorials werden Sie das verstehen:[Bearbeiten | Quelltext bearbeiten]

  • Requests ist kein eingebautes Python-Modul - es ist eine Bibliothek eines Drittanbieters, die Sie separat installieren müssen.
  • Sie stellen eine GET-Anfrage in Python mit requests.get() mit der gewünschten URL.
  • Um Kopfzeilen zu Anfragen hinzuzufügen, übergeben Sie ein Wörterbuch von Kopfzeilen an den headers Parameter in Ihrer Anfrage.
  • Um POST-Daten zu senden, verwenden Sie den Parameter data für formcodierte Daten oder den Parameter json für JSON-Daten.
  • response.text gibt Ihnen eine String-Darstellung des Antwortinhalts, während response.content rohe Bytes liefert.

Dieses Tutorial führt Sie durch die Anpassung von Anfragen mit Kopfzeilen und Daten, die Behandlung von Antworten, die Authentifizierung und die Optimierung der Leistung mit Sitzungen und Wiederholungen.

Wenn Sie die Code-Beispiele, die Sie in diesem Tutorial sehen werden, erforschen möchten, können Sie sie hier herunterladen: https://realpython.com/bonus/python-requests-code/

Erste Schritte mit der Python Requests Bibliothek[Bearbeiten | Quelltext bearbeiten]

Obwohl die Requests-Bibliothek für viele Python-Entwickler eine Grundvoraussetzung ist, ist sie nicht in der Standardbibliothek von Python enthalten. Auf diese Weise kann die Bibliothek als eigenständiges Projekt freier weiterentwickelt werden.

Hinweis: Wenn Sie HTTP-Anfragen nur mit der Standardbibliothek von Python erstellen möchten, dann ist Pythons urllib.request eine gute Wahl für Sie.

Da Requests eine Bibliothek eines Drittanbieters ist, müssen Sie sie installieren, bevor Sie sie in Ihrem Code verwenden. Als gute Praxis sollten Sie externe Pakete in einer virtuellen Umgebung installieren, aber Sie können Requests in Ihrer globalen Umgebung installieren, wenn Sie es in mehreren Projekten verwenden wollen.

Egal, ob Sie in einer virtuellen Umgebung arbeiten oder nicht, Sie müssen Abfragen installieren:

$ python -m pip install requests

Sobald pip die Installation von requests beendet hat, kannst du es in deiner Anwendung verwenden. Der Import von requests sieht wie folgt aus:

import requests

Nachdem Sie nun alles eingerichtet haben, können Sie Ihre Reise mit Requests beginnen. Ihr erstes Ziel ist es, eine GET-Anfrage zu stellen.

Eine GET-Anfrage stellen[Bearbeiten | Quelltext bearbeiten]

HTTP-Methoden, wie GET und POST, geben die Aktion an, die Sie bei einer HTTP-Anfrage durchführen möchten. Neben GET und POST gibt es noch einige andere gebräuchliche Methoden, die Sie später in diesem Lernprogramm verwenden werden.

Eine der am häufigsten verwendeten HTTP-Methoden ist GET, die Daten von einer bestimmten Ressource abruft. Um eine GET-Anfrage mit Requests zu stellen, kann man requests.get() aufrufen.

Um dies auszuprobieren, können Sie eine GET-Anfrage an die REST-API von GitHub stellen, indem Sie get() mit der folgenden URL aufrufen:

>>> import requests
>>> requests.get("https://api.github.com")
<Response [200]>

Herzlichen Glückwunsch! Sie haben Ihre erste Anfrage gestellt. Jetzt werden Sie etwas tiefer in die Antwort auf diese Anfrage eintauchen.

Prüfen der Antwort[Bearbeiten | Quelltext bearbeiten]

Eine Response ist das Objekt, das die Ergebnisse Ihrer Anfrage enthält. Versuchen Sie, dieselbe Anfrage noch einmal zu stellen, aber speichern Sie diesmal den Rückgabewert in einer Variablen, damit Sie einen genaueren Blick auf ihre Attribute und Verhaltensweisen werfen können:

>>> import requests
>>> response = requests.get("https://api.github.com")

In diesem Beispiel haben Sie den Rückgabewert von requests.get() erfasst. Es handelt sich um eine Instanz von Response, und Sie haben sie in einer Variablen namens response gespeichert. Sie können nun Response verwenden, um eine Menge Informationen über die Ergebnisse Ihrer GET-Anfrage zu sehen.

Arbeiten mit Statuscodes[Bearbeiten | Quelltext bearbeiten]

Die erste Information, die Sie aus Response entnehmen können, ist der Statuscode. Ein Statuscode informiert Sie über den Status der Anfrage.

Zum Beispiel bedeutet ein 200 OK Status, dass Ihre Anfrage erfolgreich war, während ein 404 NOT FOUND Status bedeutet, dass die gesuchte Ressource nicht gefunden wurde. Es gibt noch viele andere mögliche Statuscodes, die Ihnen Aufschluss darüber geben, was mit Ihrer Anfrage passiert ist.

Wenn Sie auf .status_code zugreifen, können Sie den Statuscode sehen, den der Server zurückgegeben hat:

>>> response.status_code
200

.status_code gibt 200 zurück, was bedeutet, dass Ihre Anfrage erfolgreich war und der Server mit den angeforderten Daten geantwortet hat.

Manchmal möchten Sie diese Informationen verwenden, um Entscheidungen in Ihrem Code zu treffen:

if response.status_code == 200:
    print("Success!")
elif response.status_code == 404:
    print("Not Found.")

Mit dieser Logik, wenn der Server einen 200 Statuscode zurückgibt, dann wird Ihr Programm drucken Erfolg!. Wenn das Ergebnis ein 404 ist, dann wird Ihr Programm Nicht gefunden ausgeben.

Requests geht noch einen Schritt weiter und vereinfacht diesen Prozess für Sie. Wenn Sie eine Response-Instanz in einem Boolean-Kontext verwenden, z.B. in einer bedingten Anweisung, dann wird sie als True ausgewertet, wenn der Statuscode kleiner als 400 ist, und False andernfalls.

Das bedeutet, dass Sie das letzte Beispiel ändern können, indem Sie die if-Anweisung umschreiben:

if response:
    print("Success!")
else:
    raise Exception(f"Non-success status code: {response.status_code}")

Im obigen Codeschnipsel wird implizit geprüft, ob der .status_code von response zwischen 200 und 399 liegt. Wenn nicht, dann erzeugen Sie eine Ausnahme mit einer Fehlermeldung, die den Nicht-Erfolgs-Statuscode in einem f-string einschließt.

Hinweis: Dieser Wahrheitswerttest ist möglich, weil .__bool__() eine überladene Methode auf Response ist. Das bedeutet, dass das angepasste Standardverhalten von Response den Statuscode bei der Bestimmung des Wahrheitswertes des Objekts berücksichtigt.

Beachten Sie, dass diese Methode nicht prüft, ob der Statuscode gleich 200 ist. Das liegt daran, dass andere Statuscodes innerhalb des Bereichs 200 bis 399, wie 204 NO CONTENT und 304 NOT MODIFIED, ebenfalls als erfolgreich angesehen werden, da sie eine brauchbare Antwort liefern.

Der Statuscode 204 besagt zum Beispiel, dass die Antwort erfolgreich war, aber der Nachrichtentext keinen Inhalt enthält.

Verwenden Sie diese praktische Abkürzung also nur, wenn Sie wissen wollen, ob die Anfrage generell erfolgreich war. Dann müssen Sie, falls nötig, die Antwort auf der Grundlage des Statuscodes entsprechend behandeln.

Angenommen, Sie wollen den Statuscode der Antwort nicht in einer if-Anweisung überprüfen. Stattdessen möchte man die in Request eingebauten Kapazitäten nutzen, um eine Ausnahme auszulösen, wenn die Anfrage erfolglos war. Das kann man mit .raise_for_status() machen:

raise_error.py

import requests
from requests.exceptions import HTTPError

URLS = ["https://api.github.com", "https://api.github.com/invalid"]

for url in URLS:
    try:
        response = requests.get(url)
        response.raise_for_status()
    except HTTPError as http_err:
        print(f"HTTP error occurred: {http_err}")
    except Exception as err:
        print(f"Other error occurred: {err}")
    else:
        print("Success!")

Wenn Sie .raise_for_status() aufrufen, dann löst Requests einen HTTPError für Statuscodes zwischen 400 und 600 aus. Wenn der Statuscode eine erfolgreiche Anfrage anzeigt, fährt das Programm fort, ohne diese Ausnahme auszulösen.

Sie wissen jetzt viel darüber, wie man mit dem Statuscode der Antwort umgeht, die Sie vom Server zurückerhalten. Wenn Sie jedoch eine GET-Anfrage stellen, interessieren Sie sich selten nur für den Statuscode der Antwort. Normalerweise wollen Sie mehr sehen. Als Nächstes werden Sie lernen, wie Sie die tatsächlichen Daten, die der Server zurückgeschickt hat, im Textkörper der Antwort anzeigen können.

Zugriff auf den Inhalt der Antwort[Bearbeiten | Quelltext bearbeiten]

Die Antwort einer GET-Anfrage enthält oft einige wertvolle Informationen, die als Payload bekannt sind, im Nachrichtentext. Mit den Attributen und Methoden von Response können Sie die Nutzdaten in verschiedenen Formaten anzeigen.

Um den Inhalt der Antwort in Bytes zu sehen, verwendet man .content:

>>> import requests

>>> response = requests.get("https://api.github.com") >>> response.content b'{"current_user_url":"https://api.github.com/user", ...}'

>>> type(response.content) <class 'bytes'>

Während .content Ihnen Zugang zu den rohen Bytes der Antwort-Nutzlast gibt, werden Sie sie oft in eine Zeichenkette konvertieren wollen, indem Sie eine Zeichenkodierung wie UTF-8 verwenden. Response erledigt das für Sie, wenn Sie auf .text zugreifen:

>>> response.text '{"current_user_url":"https://api.github.com/user", ...}'

>>> type(response.text) <class 'str'>

Da die Dekodierung von Bytes zu einer Str ein Kodierungsschema erfordert, versucht Requests die Kodierung anhand der Kopfzeilen der Antwort zu erraten, wenn Sie keine angeben. Man kann eine explizite Kodierung angeben, indem man .encoding setzt, bevor man .text aufruft:

>>> response.encoding = "utf-8" # Optional: Requests infers this. >>> response.text '{"current_user_url":"https://api.github.com/user", ...}'

Wenn Sie einen Blick auf die Antwort werfen, werden Sie sehen, dass es sich tatsächlich um serialisierten JSON-Inhalt handelt. Um ein Wörterbuch zu erhalten, könnte man die str nehmen, die man von .text abgerufen hat und sie mit json.loads() deserialisieren. Der direkte Weg, diese Aufgabe zu erfüllen, ist jedoch die Verwendung von .json():

>>> response.json() {'current_user_url': 'https://api.github.com/user', ...}

>>> type(response.json()) <class 'dict'>

Der Typ des Rückgabewerts von .json() ist ein Wörterbuch, so dass man auf die Werte im Objekt über den Schlüssel zugreifen kann:

>>> response_dict = response.json() >>> response_dict["emojis_url"] 'https://api.github.com/emojis'

Mit Statuscodes und Nachrichtentexten kann man eine Menge anfangen. Aber wenn Sie mehr Informationen benötigen, wie Metadaten über die Antwort selbst, müssen Sie sich die Kopfzeilen der Antwort ansehen. Kopfzeilen der Antwort anzeigen

Die Antwort-Header können Ihnen nützliche Informationen liefern, wie z.B. den Inhaltstyp der Antwort-Payload und wie lange die Antwort zwischengespeichert werden soll. Um diese Header anzuzeigen, rufen Sie .headers auf:

>>> import requests

>>> response = requests.get("https://api.github.com") >>> response.headers {'Server': 'github.com', ... 'X-GitHub-Request-Id': 'AE83:3F40:2151C46:438A840:65C38178'}

Das .headers-Attribut gibt ein wörterbuchähnliches Objekt zurück, das den Zugriff auf Header-Werte nach Schlüssel ermöglicht. Um zum Beispiel den Inhaltstyp der Antwort zu sehen, kann man auf "Content-Type" zugreifen:

>>> response.headers["Content-Type"] 'application/json; charset=utf-8'

Dieses wörterbuchähnliche Header-Objekt hat etwas Besonderes an sich. Die HTTP-Spezifikation definiert Header als case-insensitive, was bedeutet, dass Sie auf sie zugreifen können, ohne sich Gedanken über ihre Großschreibung zu machen:

>>> response.headers["content-type"] 'application/json; charset=utf-8'

Ob Sie den Schlüssel "content-type" oder "Content-Type" verwenden, Sie erhalten denselben Wert.

Nachdem Sie nun die nützlichsten Attribute und Methoden von Response in Aktion gesehen haben, haben Sie bereits einen guten Überblick über die grundlegende Verwendung von Requests. Du kannst Inhalte aus dem Internet abrufen und mit der Antwort arbeiten, die du erhältst.

Aber das Internet besteht aus mehr als einfachen, simplen URLs. Im nächsten Abschnitt werden Sie einen Schritt zurückgehen und sehen, wie sich Ihre Antworten ändern, wenn Sie Ihre GET-Anfragen so anpassen, dass sie die Parameter der Abfragezeichenfolge berücksichtigen.

Hinzufügen von Abfrage-String-Parametern[Bearbeiten | Quelltext bearbeiten]

Eine gängige Möglichkeit, eine GET-Anfrage anzupassen, ist die Übergabe von Werten über Query String-Parameter in der URL. Um dies mit get() zu tun, übergeben Sie Daten an params. Sie können zum Beispiel die Repository-Suche API von GitHub verwenden, um nach beliebten Python-Repositories zu suchen: search_popular_repos.py

import requests

response = requests.get(

   "https://api.github.com/search/repositories",
   params={"q": "language:python", "sort": "stars", "order": "desc"},

)

json_response = response.json() popular_repositories = json_response["items"] for repo in popular_repositories[:3]:

   print(f"Name: {repo['name']}")
   print(f"Description: {repo['description']}")
   print(f"Stars: {repo['stargazers_count']}\n")

Durch die Übergabe eines Wörterbuchs an den Parameter params von get() können Sie die Ergebnisse, die von der Such-API zurückkommen, verändern.

Sie können params an get() entweder als Wörterbuch übergeben, wie Sie es gerade getan haben, oder als eine Liste von Tupeln:

>>> import requests

>>> requests.get( ... "https://api.github.com/search/repositories", ... [("q", "language:python"), ("sort", "stars"), ("order", "desc")], ... ) <Response [200]>

Sie können die Werte sogar als Bytes übergeben:

>>> requests.get( ... "https://api.github.com/search/repositories", ... params=b"q=language:python&sort=stars&order=desc", ... ) <Response [200]>

Abfragezeichenfolgen sind nützlich für die Parametrisierung von GET-Anfragen. Eine weitere Möglichkeit, Ihre Anfragen anzupassen, ist das Hinzufügen oder Ändern der Kopfzeilen, die Sie senden. Anpassen von Anfrage-Headern

Um Header anzupassen, übergeben Sie ein Wörterbuch von HTTP-Headern an get() mit dem Parameter headers. Sie können zum Beispiel Ihre vorherige Suchanfrage so ändern, dass übereinstimmende Suchbegriffe in den Ergebnissen hervorgehoben werden, indem Sie den Medientyp text-match im Accept-Header angeben: text_matches.py

import requests

response = requests.get(

   "https://api.github.com/search/repositories",
   params={"q": '"real python"'},
   headers={"Accept": "application/vnd.github.text-match+json"},

)

json_response = response.json() first_repository = json_response["items"][0] print(first_repository["text_matches"][0]["matches"])

Der Accept-Header teilt dem Server mit, welche Inhaltstypen Ihre Anwendung verarbeiten kann. In diesem Fall, da Sie erwarten, dass die übereinstimmenden Suchbegriffe hervorgehoben werden, verwenden Sie den Header-Wert application/vnd.github.text-match+json. Dies ist ein proprietärer Accept-Header von GitHub, dessen Inhalt ein spezielles JSON-Format ist.

Wenn Sie dieses Python-Skript ausführen, erhalten Sie ein ähnliches Ergebnis wie das unten gezeigte:

$ python text_matches.py [{'text': 'Real Python', 'indices': [23, 34]}]

Bevor Sie weitere Möglichkeiten zur Anpassung von Anfragen kennenlernen, werden Sie Ihren Horizont erweitern, indem Sie andere HTTP-Methoden erforschen. Andere HTTP-Methoden verwenden

Neben GET gibt es weitere beliebte HTTP-Methoden wie POST, PUT, DELETE, HEAD, PATCH und OPTIONS. Für jede dieser HTTP-Methoden bietet Requests eine Funktion mit einer ähnlichen Signatur wie get().

Hinweis: Um diese HTTP-Methoden auszuprobieren, werden Sie Anfragen an httpbin.org stellen. Der httpbin-Dienst ist eine großartige Ressource, die vom ursprünglichen Autor von Requests, Kenneth Reitz, geschaffen wurde. Der Dienst nimmt Testanfragen entgegen und antwortet mit Daten über die Anfragen.

Sie werden feststellen, dass Requests eine intuitive Schnittstelle für alle gängigen HTTP-Methoden bietet:

>>> import requests

>>> requests.get("https://httpbin.org/get") <Response [200]> >>> requests.post("https://httpbin.org/post", data={"key": "value"}) <Response [200]> >>> requests.put("https://httpbin.org/put", data={"key": "value"}) <Response [200]> >>> requests.delete("https://httpbin.org/delete") <Response [200]> >>> requests.head("https://httpbin.org/get") <Response [200]> >>> requests.patch("https://httpbin.org/patch", data={"key": "value"}) <Response [200]> >>> requests.options("https://httpbin.org/get") <Response [200]>

Im obigen Beispiel haben Sie jede Funktion aufgerufen, um eine Anforderung an den httpbin-Dienst mit der entsprechenden HTTP-Methode zu stellen.

Alle diese Funktionen sind High-Level-Verknüpfungen zu requests.request(), das den Methodennamen als erstes Argument nimmt:

>>> requests.request("GET", "https://httpbin.org/get") <Response [200]>

Sie könnten auch den entsprechenden Funktionsaufruf auf niedrigerer Ebene verwenden, aber die Stärke der Python-Request-Bibliothek liegt in ihrer menschenfreundlichen, hochentwickelten Schnittstelle. Sie können die Antworten genau wie zuvor untersuchen:

>>> response = requests.head("https://httpbin.org/get") >>> response.headers["Content-Type"] 'application/json'

>>> response = requests.delete("https://httpbin.org/delete") >>> json_response = response.json() >>> json_response["args"] {}

Unabhängig davon, welche Methode Sie verwenden, erhalten Sie ein Response-Objekt, das Zugriff auf Header, Antwortkörper, Statuscodes und mehr bietet.

Als Nächstes werden Sie sich die Methoden POST, PUT und PATCH genauer ansehen und erfahren, wie sie sich von den anderen Anfragearten unterscheiden. Anzeigen entfernen Senden Sie Daten anfordern

Gemäß der HTTP-Spezifikation übergeben POST, PUT und die weniger verbreiteten PATCH-Anfragen ihre Daten über den Nachrichtentext und nicht über Parameter im Query-String. Bei Requests übergeben Sie diese Nutzdaten an den Daten-Parameter der entsprechenden Funktion.

Der Parameter Daten kann ein Wörterbuch, eine Liste von Tupeln, Bytes oder ein dateiähnliches Objekt enthalten. Sie sollten die Daten, die Sie im Body Ihrer Anfrage senden, an die spezifischen Anforderungen des Dienstes, mit dem Sie interagieren, anpassen.

Wenn der Inhaltstyp Ihrer Anfrage zum Beispiel application/x-www-form-urlencoded ist, können Sie die Formulardaten als Wörterbuch senden:

>>> import requests

>>> requests.post("https://httpbin.org/post", data={"key": "value"}) <Response [200]>

Sie können die gleichen Daten auch als Liste von Tupeln senden:

>>> requests.post("https://httpbin.org/post", data=[("key", "value")]) <Response [200]>

Wenn Sie JSON Daten senden müssen, können Sie den json Parameter verwenden. Wenn Sie JSON-Daten über json übergeben, serialisiert Requests Ihre Daten und fügt den richtigen Content-Type-Header für Sie hinzu.

Wie Sie bereits gelernt haben, nimmt der httpbin-Dienst Testanfragen entgegen und antwortet mit Daten über die Anfragen. Sie können ihn zum Beispiel verwenden, um eine einfache POST-Anfrage zu untersuchen:

>>> response = requests.post("https://httpbin.org/post", json={"key": "value"}) >>> json_response = response.json() >>> json_response["data"] '{"key": "value"}' >>> json_response["headers"]["Content-Type"] 'application/json'

Aus der Antwort können Sie ersehen, dass der Server Ihre Anfragedaten und Kopfzeilen so erhalten hat, wie Sie sie gesendet haben. Requests stellt Ihnen diese Informationen auch in Form eines PreparedRequest zur Verfügung, den Sie im nächsten Abschnitt genauer betrachten werden. Prüfen der vorbereiteten Anfrage

Wenn Sie eine Anfrage stellen, bereitet die Requests-Bibliothek die Anfrage vor, bevor sie tatsächlich an den Zielserver gesendet wird. Die Vorbereitung der Anfrage umfasst Dinge wie die Validierung von Kopfzeilen und die Serialisierung von JSON-Inhalten.

Sie können das PreparedRequest Objekt durch Zugriff auf .request auf ein Response Objekt sehen:

>>> import requests

>>> response = requests.post("https://httpbin.org/post", json={"key":"value"})

>>> response.request <PreparedRequest [POST]>

>>> response.request.headers["Content-Type"] 'application/json'

>>> response.request.url 'https://httpbin.org/post'

>>> response.request.body b'{"key": "value"}'

Durch die Untersuchung von PreparedRequest erhalten Sie Zugriff auf alle möglichen Informationen über die gestellte Anfrage, wie z. B. Nutzdaten, URL, Header, Authentifizierung und mehr.

Bislang haben Sie viele verschiedene Arten von Anfragen gestellt, die jedoch alle eines gemeinsam hatten: Es waren unauthentifizierte Anfragen an öffentliche APIs. Viele Dienste, auf die Sie stoßen werden, verlangen, dass Sie sich auf irgendeine Weise authentifizieren. Authentifizierung verwenden

Authentifizierung hilft einem Dienst zu verstehen, wer Sie sind. Normalerweise geben Sie Ihre Anmeldedaten an einen Server weiter, indem Sie Daten über den Authorization-Header oder einen vom Dienst definierten Header übergeben. Alle Funktionen in Requests, die Sie bisher kennengelernt haben, bieten einen Parameter namens auth, mit dem Sie Ihre Anmeldedaten direkt übergeben können:

>>> import requests

>>> response = requests.get( ... "https://httpbin.org/basic-auth/user/passwd", ... auth=("user", "passwd") ... )

>>> response.status_code 200 >>> response.request.headers["Authorization"] 'Basic dXNlcjpwYXNzd2Q='

Die Anfrage ist erfolgreich, wenn die Anmeldeinformationen, die Sie in dem Tupel an auth übergeben, gültig sind.

Wenn Sie Ihre Anmeldedaten in einem Tupel an den Parameter auth übergeben, wendet Requests die Anmeldedaten unter Verwendung des HTTP-Schemas basic access authentication an.

Sie können die gleiche Anfrage stellen, indem Sie explizite Basis-Authentifizierungsdaten mit HTTPBasicAuth übergeben:

>>> from requests.auth import HTTPBasicAuth >>> requests.get( ... "https://httpbin.org/basic-auth/user/passwd", ... auth=HTTPBasicAuth("user", "passwd") ... ) <Response [200]>

Obwohl Sie sich nicht explizit für die Basisauthentifizierung entscheiden müssen, möchten Sie sich vielleicht mit einer anderen Methode authentifizieren. Requests bietet von Haus aus andere Methoden der Authentifizierung, wie HTTPDigestAuth und HTTPProxyAuth.

Ein praktisches Beispiel für eine API, die eine Authentifizierung erfordert, ist die API authentifizierter Benutzer von GitHub. Dieser Endpunkt liefert Informationen über das Profil des authentifizierten Benutzers.

Wenn Sie versuchen, eine Anfrage ohne Anmeldeinformationen zu stellen, werden Sie sehen, dass der Statuscode 401 Unauthorized lautet:

>>> requests.get("https://api.github.com/user") <Response [401]>

Wenn Sie beim Zugriff auf einen Dienst, der Authentifizierungsdaten erfordert, diese nicht angeben, erhalten Sie einen HTTP-Fehlercode als Antwort.

Um eine Anfrage an die GitHub-API für authentifizierte Benutzer zu stellen, müssen Sie zunächst ein persönliches Zugriffstoken mit dem read:user-Bereich generieren. Dann kann man dieses Token als zweites Element in einem Tupel an get() übergeben:

>>> import requests

>>> token = "<YOUR_GITHUB_PA_TOKEN>" >>> response = requests.get( ... "https://api.github.com/user", ... auth=("", token) ... ) >>> response.status_code 200

Wie Sie bereits gelernt haben, übergibt dieser Ansatz die Anmeldedaten an HTTPBasicAuth, das einen Benutzernamen und ein Passwort erwartet und die Anmeldedaten als Base64-kodierte Zeichenfolge mit dem Präfix "Basic" sendet:

>>> response.request.headers["Authorization"] 'Basic OmdocF92dkd...WpremM0SGRuUGY='

Diese Methode funktioniert, ist aber nicht der richtige Weg, um sich mit einem Bearer-Token zu authentifizieren, und die Verwendung einer leeren Zeichenkette für den überflüssigen Benutzernamen ist umständlich.

Mit Requests können Sie Ihren eigenen Authentifizierungsmechanismus bereitstellen, um dies zu beheben. Um dies auszuprobieren, erstellen Sie eine Unterklasse von AuthBase und implementieren .__call__(): custom_token_auth.py

from requests.auth import AuthBase

class TokenAuth(AuthBase):

   """Implements a token authentication scheme."""
   def __init__(self, token):
       self.token = token
   def __call__(self, request):
       """Attach an API token to the Authorization header."""
       request.headers["Authorization"] = f"Bearer {self.token}"
       return request

Hier empfängt Ihr benutzerdefinierter TokenAuth-Mechanismus ein Token und fügt dieses Token in den Authorization-Header Ihrer Anfrage ein, wobei auch das empfohlene "Bearer"-Präfix auf die Zeichenfolge gesetzt wird.

Sie können nun diese benutzerdefinierte Token-Authentifizierung verwenden, um Ihren Aufruf an die API für authentifizierte Benutzer von GitHub zu tätigen:

>>> import requests >>> from custom_token_auth import TokenAuth

>>> token = "<YOUR_GITHUB_PA_TOKEN>" >>> response = requests.get( ... "https://api.github.com/user", ... auth=TokenAuth(token) ... )

>>> response.status_code 200 >>> response.request.headers["Authorization"] 'Bearer ghp_b...Tx'

Ihre benutzerdefinierte TokenAuth erstellt einen gut formatierten String für den Authorization-Header. Dies gibt Ihnen eine intuitivere und wiederverwendbare Möglichkeit, mit Token-basierten Authentifizierungsschemata zu arbeiten, wie sie von Teilen der API von GitHub verlangt werden.

Hinweis: Während Sie den Authentifizierungsstring außerhalb einer benutzerdefinierten Authentifizierungsklasse konstruieren und ihn direkt mit headers übergeben könnten, wird von diesem Ansatz abgeraten, da er zu unerwartetem Verhalten führen kann.

Wenn Sie versuchen, Ihre Authentifizierungsdaten direkt mit Kopfzeilen zu setzen, kann Requests Ihre Eingabe intern überschreiben. Dies kann zum Beispiel passieren, wenn Sie eine .netrc-Datei haben, die Authentifizierungsdaten enthält. Anfragen werden versuchen, die Zugangsdaten aus der .netrc-Datei zu erhalten, wenn Sie keine Authentifizierungsmethode mit auth angeben.

Schlechte Authentifizierungsmechanismen können zu Sicherheitslücken führen. Sofern ein Dienst nicht aus irgendeinem Grund einen benutzerdefinierten Authentifizierungsmechanismus erfordert, ist es am besten, sich an eine bewährte Methode zu halten, wie die eingebaute Basisauthentifizierung oder OAuth, zum Beispiel über Requests-OAuthlib.

Wenn Sie schon über Sicherheit nachdenken, sollten Sie den Umgang mit TLS/SSL-Zertifikaten mit Requests in Betracht ziehen. Anzeigen entfernen Sichere Kommunikation mit Servern

Wenn die Daten, die Sie senden oder empfangen wollen, sensibel sind, ist Sicherheit ein Muss. Die Kommunikation mit sicheren Websites über HTTP erfolgt durch den Aufbau einer verschlüsselten Verbindung mit Transport Layer Security (TLS). TLS ist der Nachfolger von Secure Sockets Layer (SSL) und bietet verbesserte Sicherheit und Effizienz bei der sicheren Kommunikation. Dennoch ist es immer noch üblich, dass Programmierer den Begriff SSL anstelle von TLS verwenden.

Requests überprüft standardmäßig das digitale Zertifikat von Servern für Sie, und Sie müssen nur selten Anpassungen an diesem Verhalten vornehmen. Es gibt jedoch einige Fälle, in denen Sie den Verifizierungsprozess anpassen müssen.

Wenn Sie z. B. in einer Unternehmensumgebung mit benutzerdefinierten Zertifizierungsstellen arbeiten, müssen Sie möglicherweise Ihr eigenes Zertifikatspaket bereitstellen:

>>> import requests

>>> requests.get( ... "https://internal-api.company.com", ... verify="/path/to/company-ca.pem" ... ) <Response [200]>

Sie können auch ein Verzeichnis mit Zertifikatsdateien angeben, wenn Sie mehreren benutzerdefinierten Behörden vertrauen müssen.

Wenn Sie in der Entwicklung Probleme mit Zertifikaten debuggen, könnten Sie versucht sein, die Überprüfung komplett zu deaktivieren. Das funktioniert zwar, stellt aber ein erhebliches Sicherheitsrisiko dar, und Sie sollten diesen Ansatz niemals in der Produktion verwenden:

>>> requests.get("https://api.github.com", verify=False) InsecureRequestWarning: Unverified HTTPS request is being made to host ⮑ 'api.github.com'. Adding certificate verification is strongly advised. ⮑ See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings ⮑ warnings.warn( <Response [200]>

Requests warnt Sie vor dieser gefährlichen Praxis, da die Deaktivierung der Verifizierung Sie anfällig für Man-in-the-Middle-Angriffe macht.

Hinweis: Requests verwendet ein Paket namens certifi, um Zertifizierungsstellen bereitzustellen. Dies lässt Requests wissen, welchen Stellen es vertrauen kann. Um Ihre Verbindungen so sicher wie möglich zu halten, sollten Sie Zertifikate regelmäßig aktualisieren.

Da Sie nun wissen, wie Sie die Zertifikatsüberprüfung sicher handhaben, fragen Sie sich vielleicht, wie Sie Ihr Programm so schnell wie möglich zum Laufen bringen können. Verbessern Sie die Leistung

Bei der Verwendung von Requests, insbesondere in einer Produktionsanwendungsumgebung, ist es wichtig, die Auswirkungen auf die Leistung zu berücksichtigen. Funktionen wie Timeout-Kontrolle, Sitzungen und Wiederholungslimits können Ihnen helfen, dass Ihre Anwendung reibungslos läuft.

Hinweis: Requests unterstützt asynchrone HTTP-Anfragen nicht direkt. Wenn Sie async Unterstützung in Ihrem Programm benötigen, dann sollten Sie AIOHTTP oder HTTPX ausprobieren. Die letztgenannte Bibliothek ist weitgehend kompatibel mit der Syntax von Requests.

Selbst in synchronem Code gibt es mehrere wichtige Techniken, mit denen Sie Ihre HTTP-Anfragen optimieren und Leistungsengpässe vermeiden können. Zeitüberschreitungen für Anfragen festlegen

Wenn Sie eine Inline-Anfrage an einen externen Dienst stellen, muss Ihr System auf die Antwort warten, bevor es weitergeht. Wenn Ihre Anwendung zu lange auf diese Antwort wartet, können sich die Anfragen an Ihren Dienst stauen, die Benutzerfreundlichkeit kann darunter leiden, oder Hintergrundaufgaben können hängen bleiben.

Standardmäßig wartet Requests auf unbestimmte Zeit auf die Antwort, daher sollten Sie fast immer eine Timeout-Dauer angeben, um diese Probleme zu vermeiden. Um die Zeitüberschreitung der Anfrage zu setzen, verwenden Sie den Parameter timeout. timeout kann ein Integer oder Float sein, der die Anzahl der Sekunden angibt, die auf eine Antwort gewartet werden soll, bevor die Zeit abgelaufen ist:

>>> requests.get("https://api.github.com", timeout=1) <Response [200]>

>>> requests.get("https://api.github.com", timeout=0.01) Traceback (most recent call last):

 ...

requests.exceptions.ConnectTimeout: ⮑ HTTPSConnectionPool(host='api.github.com', port=443): ⮑ Max retries exceeded with url: / (Caused by ConnectTimeoutError(...))

Die erste Anfrage wurde erfolgreich abgeschlossen, da der Server innerhalb des Zeitlimits von einer Sekunde geantwortet hat. Die zweite Anfrage schlug dagegen fehl, da die Zeitüberschreitung auf extrem kurze zehn Millisekunden eingestellt war, die abliefen, bevor eine Verbindung hergestellt werden konnte.

Man kann auch ein Tupel an timeout mit den folgenden zwei Elementen übergeben:

   Connect timeout: Die Zeit, die der Client benötigt, um eine Verbindung zum Server herzustellen.
   Read timeout: Die Zeit, die auf eine Antwort gewartet wird, sobald der Client eine Verbindung hergestellt hat.

Diese beiden Elemente sollten Zahlen sein und können vom Typ int oder float sein:

>>> requests.get("https://api.github.com", timeout=(3.05, 5)) <Response [200]>

Wenn die Anfrage innerhalb von 3,05 Sekunden eine Verbindung aufbaut und innerhalb von 5 Sekunden nach dem Aufbau der Verbindung Daten empfängt, wird die Antwort wie zuvor zurückgegeben. Wenn die Anfrage eine Zeitüberschreitung aufweist, löst die Funktion entweder ConnectTimeout oder ReadTimeout aus, die Unterklassen der allgemeineren Timeout-Ausnahme sind: timeout_catcher.py

import requests from requests.exceptions import Timeout

try:

   response = requests.get("https://api.github.com", timeout=(3.05, 5))

except Timeout:

   print("The request timed out")

else:

   print("The request did not time out")

Ihr Programm kann die Timeout-Ausnahme abfangen und entsprechend reagieren. Anzeigen entfernen Wiederverwendung von Verbindungen mit Sitzungsobjekten

Bis jetzt haben Sie sich mit hochrangigen Abfragen-APIs wie get() und post() beschäftigt. Diese Funktionen sind Abstraktionen dessen, was vor sich geht, wenn Sie Ihre Anfragen stellen. Sie verbergen Implementierungsdetails, z. B. wie Verbindungen verwaltet werden, so dass Sie sich darüber keine Gedanken machen müssen.

Unterhalb dieser Abstraktionen befindet sich eine Klasse namens Session. Wenn Sie Ihre Kontrolle über die Art und Weise, wie Anfragen gestellt werden, verfeinern oder die Leistung Ihrer Anfragen verbessern wollen, müssen Sie möglicherweise eine Session-Instanz direkt verwenden.

Sessions werden verwendet, um Parameter über Abfragen hinweg beizubehalten. Wenn Sie zum Beispiel dieselbe Authentifizierung über mehrere Anfragen hinweg verwenden möchten, können Sie eine Sitzung verwenden: persist_info_with_session.py

import requests

from custom_token_auth import TokenAuth


TOKEN = "<YOUR_GITHUB_PA_TOKEN>"


with requests.Session() as session:

   session.auth = TokenAuth(TOKEN)


   first_response = session.get("https://api.github.com/user")
   second_response = session.get("https://api.github.com/user")


print(first_response.headers)

print(second_response.json())

In diesem Beispiel verwenden Sie einen Kontextmanager, um sicherzustellen, dass die Sitzung die Ressourcen freigibt, wenn sie sie nicht mehr benötigt.

In Zeile 7 fügen Sie die Anmeldeinformationen Ihres GitHub-Benutzers mit Ihrem benutzerdefinierten TokenAuth an das Sitzungsobjekt an. Sie müssen dies nur einmal pro Sitzung tun und können dann mehrere authentifizierte Anfragen stellen. Die Anfragen halten die Anmeldeinformationen so lange aufrecht, wie die Sitzung andauert.

In den Zeilen 9 und 10 stellen Sie dann zwei Anfragen an die API für authentifizierte Benutzer, indem Sie session.get() anstelle von requests.get() verwenden.

Die primäre Leistungsoptimierung von Sitzungen kommt in Form von dauerhaften Verbindungen. Wenn Ihre Anwendung eine Verbindung zu einem Server über eine Session herstellt, bleibt diese Verbindung in einem Verbindungspool erhalten. Wenn Ihre Anwendung sich wieder mit demselben Server verbinden möchte, wird sie eine Verbindung aus dem Pool wiederverwenden, anstatt eine neue aufzubauen. Fehlgeschlagene Anfragen wiederholen

Wenn eine Anfrage fehlschlägt, möchten Sie vielleicht, dass Ihre Anwendung dieselbe Anfrage erneut versucht. Requests wird dies jedoch nicht standardmäßig für Sie tun. Um diese Funktionalität anzuwenden, müssen Sie einen eigenen Transportadapter implementieren.

Mit Transportadaptern können Sie eine Reihe von Konfigurationen für jeden Dienst definieren, mit dem Sie interagieren. Nehmen wir an, Sie möchten, dass alle Anfragen an https://api.github.com zweimal wiederholt werden, bevor ein RetryError ausgelöst wird. In diesem Fall würde man einen Transportadapter erstellen, seinen max_retries Parameter setzen und ihn in eine bestehende Session einbinden: retry_twice.py

import requests from requests.adapters import HTTPAdapter from requests.exceptions import RetryError from urllib3.util.retry import Retry

retry_strategy = Retry(

   total=2,
   status_forcelist=[429, 500, 502, 503, 504]

) github_adapter = HTTPAdapter(max_retries=retry_strategy)

with requests.Session() as session:

   session.mount("https://api.github.com", github_adapter)
   try:
       response = session.get("https://api.github.com/")
   except RetryError as err:
       print(f"Error: {err}")

In diesem Beispiel haben Sie Ihre Sitzung so eingerichtet, dass sie maximal zweimal wiederholt wird, wenn Ihre Anfrage an die API von GitHub nicht wie erwartet funktioniert. Mit dem Retry-Objekt können Sie genau festlegen, welche Statuscodes Wiederholungsversuche auslösen sollen.

Das max_retries Argument nimmt entweder eine ganze Zahl oder ein Retry Objekt. Die Verwendung eines Retry-Objekts gibt Ihnen detaillierte Kontrolle darüber, welche Fehler erneut versucht werden. Während man für einfache Fälle immer noch eine einfache Ganzzahl übergeben kann, ist die Verwendung eines Retry-Objekts der moderne Ansatz.

Wenn man den HTTPAdapter in session einbindet, dann wird session seine Konfiguration für jede Anfrage an https://api.github.com einhalten.

Hinweis: Während die oben gezeigte Implementierung funktioniert, werden Sie keine Auswirkungen des Wiederholungsverhaltens sehen, es sei denn, es stimmt etwas mit Ihrer Netzwerkverbindung oder den Servern von GitHub nicht.

Wenn du mit dem Code herumspielen willst, der auf diesem Beispiel aufbaut und sehen willst, wann Wiederholungen stattfinden, dann hast du Glück. Du kannst die Materialien für dieses Tutorial herunterladen und einen Blick auf retry_thrice.py werfen:

Get Your Code: Klicken Sie hier, um den kostenlosen Beispielcode herunterzuladen, der Ihnen zeigt, wie Sie die Requests-Bibliothek von Python verwenden können.

Der Code in dieser Datei verbessert das oben gezeigte Beispiel, indem er Logging hinzufügt, um Debugging Ausgaben anzuzeigen. So können Sie überwachen, wann Python Wiederholungsversuche unternimmt.

Requests wird mit intuitiven Implementierungen für Timeouts, Transportadapter und Sessions geliefert, die Ihnen dabei helfen, Ihren Code effizient und Ihre Anwendung belastbar zu halten. Anzeigen entfernen Fazit

Gute Arbeit! Sie haben es bis zum Ende des Tutorials geschafft und Ihr Wissen über die leistungsstarke Requests-Bibliothek von Python erheblich erweitert.

In diesem Tutorial haben Sie gelernt, wie man:

   Anfragen mit einer Vielzahl von HTTP-Methoden wie GET, POST und PUT stellen
   Anpassen der Anfragen durch Ändern von Kopfzeilen, Authentifizierung, Abfragezeichenfolgen und Nachrichtentexten
   Prüfen Sie die Daten, die Sie an den Server senden, und die Daten, die der Server an Sie zurückschickt
   Arbeiten Sie mit TLS/SSL Zertifikatsüberprüfung
   Requests effektiv nutzen mit max_retries, timeout, Sessions und Transportadaptern

Da Sie gelernt haben, wie man Requests verwendet, sind Sie gerüstet, um die weite Welt der Webservices zu erkunden - und großartige Anwendungen mit den faszinierenden Daten zu erstellen, die sie bereitstellen.

Holen Sie sich Ihren Code: Klicken Sie hier, um den kostenlosen Beispielcode herunterzuladen, der Ihnen zeigt, wie Sie die Requests-Bibliothek von Python verwenden. Häufig gestellte Fragen

Nachdem Sie nun einige Erfahrung mit der Requests-Bibliothek von Python gesammelt haben, können Sie die folgenden Fragen und Antworten nutzen, um Ihr Verständnis zu überprüfen und das Gelernte zu wiederholen.

Diese FAQs beziehen sich auf die wichtigsten Konzepte, die Sie in diesem Lernprogramm behandelt haben. Klicken Sie auf das Zeigen/Verbergen neben jeder Frage, um die Antwort zu sehen.