Python Lernhandbuch

Kapitel 10: REST-APIs nutzen

Musterlösung mit Erklärung

Vergleiche Schritt für Schritt mit deinem Programm in VS Code. Wenn alles passt, markiere die Übung als erledigt.
Aufgabe noch einmal lesen

Nutze die kostenlose Test-API https://jsonplaceholder.typicode.com:

  1. Hole alle Beiträge von Benutzer 1 (GET /posts?userId=1) und gib Anzahl und die ersten drei Titel aus.
  2. Lege per POST /posts einen neuen Beitrag an und gib Statuscode und die zurückgegebene id aus. Die API speichert nichts wirklich, antwortet aber wie eine echte.
  3. Ruf /posts/99999 auf. Das Programm soll nicht abstürzen, sondern "nicht gefunden" melden.
  4. Verpacke alles in Funktionen und nutze einen httpx.Client mit base_url und timeout.
python
import httpx

BASIS = 'https://jsonplaceholder.typicode.com'


def beitraege_von(client, user_id):
    r = client.get('/posts', params={'userId': user_id})
    r.raise_for_status()
    return r.json()


def beitrag_anlegen(client, titel, text, user_id):
    r = client.post('/posts', json={'title': titel, 'body': text, 'userId': user_id})
    r.raise_for_status()
    return r.status_code, r.json()


def beitrag_holen(client, beitrag_id):
    r = client.get(f'/posts/{beitrag_id}')
    if r.status_code == 404:
        return None
    r.raise_for_status()
    return r.json()


def main():
    with httpx.Client(base_url=BASIS, timeout=10.0) as client:
        posts = beitraege_von(client, 1)
        print(f'{len(posts)} Beiträge')
        for p in posts[:3]:
            print('-', p['title'])

        status, neu = beitrag_anlegen(client, 'Hallo', 'Testbeitrag', 1)
        print('Angelegt:', status, 'id =', neu['id'])

        if beitrag_holen(client, 99999) is None:
            print('Beitrag 99999 nicht gefunden')


if __name__ == '__main__':
    try:
        main()
    except httpx.RequestError as e:
        print('Netzwerkproblem:', e)
    except httpx.HTTPStatusError as e:
        print('Fehlercode vom Server:', e.response.status_code)

Was passiert:

  • Jede Funktion tut genau eine Sache und bekommt den client als Parameter. So nutzen alle dieselbe Verbindung und dieselben Einstellungen.
  • beitrag_holen behandelt 404 als erwarteten Fall und gibt None zurück. Alle anderen Fehlercodes lösen weiterhin einen Fehler aus. So unterscheidest du "gibt es nicht" von "Server kaputt".
  • Die Fehlerbehandlung steht nur einmal ganz oben. Die kleinen Funktionen müssen sich nicht damit befassen.
  • Mit f'/posts/{beitrag_id}' setzt du Werte in die URL ein. Wenn die Werte vom Benutzer kommen, kodiere sie vorher, damit keine Sonderzeichen den Pfad verändern.

Warum so: Wenn du eine API in eigene Funktionen kapselst, kann der restliche Code mit Python-Daten arbeiten, ohne dass er Details von HTTP kennen muss. Ändert die API ihre Adresse, passt du eine Stelle an.