Skip to content

Deine erste API mit Python

In diesem Tutorial baust du eine eigene API mit Python. Als Framework verwenden wir Flask – das ist eines der einfachsten Python-Frameworks für Web-APIs.

Am Ende hast du eine laufende API mit vier Endpunkten, die du mit Postman testen kannst.

Vorbereitung

Python installieren

Falls noch nicht installiert, lade Python von python.org herunter und installiere es.

Falls du Thonny installiert hast, funktioniert das auch bestens!

Überprüfe die Installation im Terminal:

bash
python --version

Flask installieren

Öffne ein Terminal und installiere Flask und das CORS-Paket mit pip:

bash
pip install flask flask-cors

Bei Thonny geht das über Werkzeuge > Pakete verwalten. Installiere dort sowohl flask als auch flask-cors.

Projektstruktur anlegen

Erstelle einen neuen Ordner für dein Projekt, z.B. meine-api, und darin eine Datei namens app.py.

meine-api/
└── app.py

Die Ausgangslage: unsere Daten

Da wir noch keine Datenbank verwenden, speichern wir die Daten einfach in einer Liste im Python-Script. Diese Daten gehen verloren, sobald du den Server neu startest – das ist okay für den Moment.

Füge diesen Code in app.py ein:

python
# Dinge, die unser Server braucht die wir nicht selber programmieren
from flask import Flask, request, jsonify
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

# Unsere "Datenbank" – eine einfache Liste im Arbeitsspeicher
aufgaben = [
    {"id": 1, "titel": "Mathe Hausaufgaben", "erledigt": False},
    {"id": 2, "titel": "Physik lernen", "erledigt": True},
]

# Hilfsfunktion: nächste freie ID bestimmen, kannst du für den Moment so ignorieren
def naechste_id():
    if len(aufgaben) == 0:
        return 1
    return max(a["id"] for a in aufgaben) + 1

Endpoint 1: GET – Alle Aufgaben abrufen

Dieser Endpoint gibt alle Aufgaben zurück.

python
@app.route("/aufgaben", methods=["GET"])
def get_aufgaben():
    return jsonify(aufgaben)

Was passiert hier?

  • from flask_cors import CORS und CORS(app) – das erlaubt es Webseiten, Anfragen an unsere API zu schicken. Ohne diese Zeilen würde der Browser die Anfragen blockieren (das nennt sich CORS-Policy). Mehr dazu später.
  • @app.route("/aufgaben", methods=["GET"]) – Flask soll auf Anfragen an /aufgaben reagieren, aber nur wenn es ein GET-Request ist.
  • jsonify(aufgaben) – wandelt die Python-Liste in JSON um und schickt sie zurück.

@app.route() nennt man einen "Dekorator". Es legt fest, dass Flask die Methode get_aufgaben ausführt, wenn jemand die API mit der Route /aufgaben aufruft. Diese routen gibt es auf jeder Seite. Du kannst als kleine Übung mal auf Scooltools kontrollieren, welche Routen du findest.

Endpoint 2: POST – Neue Aufgabe erstellen

Dieser Endpoint erstellt eine neue Aufgabe.

python
@app.route("/aufgaben", methods=["POST"])
def create_aufgabe():
    daten = request.get_json()

    if not daten or "titel" not in daten:
        return jsonify({"fehler": "Feld 'titel' fehlt"}), 400

    neue_aufgabe = {
        "id": naechste_id(),
        "titel": daten["titel"],
        "erledigt": False
    }
    aufgaben.append(neue_aufgabe)
    return jsonify(neue_aufgabe), 201

Was passiert hier?

  • request.get_json() – liest die JSON-Daten aus dem Request-Body.
  • Wir prüfen, ob das Feld titel vorhanden ist. Falls nicht, senden wir einen 400-Fehler zurück.
  • Die neue Aufgabe bekommt eine ID und wird der Liste hinzugefügt.
  • 201 ist der Statuscode für "erfolgreich erstellt".

Endpoint 3: PUT – Aufgabe aktualisieren

Dieser Endpoint aktualisiert eine bestehende Aufgabe anhand ihrer ID.

python
@app.route("/aufgaben/<int:aufgabe_id>", methods=["PUT"])
def update_aufgabe(aufgabe_id):
    daten = request.get_json()

    for aufgabe in aufgaben:
        if aufgabe["id"] == aufgabe_id:
            if "titel" in daten:
                aufgabe["titel"] = daten["titel"]
            if "erledigt" in daten:
                aufgabe["erledigt"] = daten["erledigt"]
            return jsonify(aufgabe)

    return jsonify({"fehler": "Aufgabe nicht gefunden"}), 404

Was passiert hier?

  • <int:aufgabe_id> – die ID in der URL wird als Integer an die Funktion übergeben.
  • Wir suchen die Aufgabe mit der passenden ID und aktualisieren die Felder.
  • Falls keine Aufgabe mit dieser ID existiert, geben wir 404 zurück.

Endpoint 4: DELETE – Aufgabe löschen

Dieser Endpoint löscht eine Aufgabe anhand ihrer ID.

python
@app.route("/aufgaben/<int:aufgabe_id>", methods=["DELETE"])
def delete_aufgabe(aufgabe_id):
    for i, aufgabe in enumerate(aufgaben):
        if aufgabe["id"] == aufgabe_id:
            aufgaben.pop(i)
            return jsonify({"nachricht": "Aufgabe gelöscht"})

    return jsonify({"fehler": "Aufgabe nicht gefunden"}), 404

Server starten

Füge am Ende der app.py noch diese Zeile hinzu:

python
if __name__ == "__main__":
    app.run(debug=True)

Der Parameter debug=True sorgt dafür, dass der Server bei Änderungen automatisch neu startet und Fehlermeldungen im Browser anzeigt. Wichtig: In einer echten Anwendung würde man debug=True nie verwenden.

Starte den Server:

bash
python app.py

Du solltest folgende Ausgabe sehen:

 * Running on http://127.0.0.1:5000

Deine API läuft jetzt lokal auf Port 5000.


Die komplette app.py

So sieht die fertige Datei aus:

python
from flask import Flask, request, jsonify
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

# Unsere "Datenbank" – eine einfache Liste im Arbeitsspeicher
aufgaben = [
    {"id": 1, "titel": "Mathe Hausaufgaben", "erledigt": False},
    {"id": 2, "titel": "Physik lernen", "erledigt": True},
]

def naechste_id():
    if len(aufgaben) == 0:
        return 1
    return max(a["id"] for a in aufgaben) + 1


@app.route("/aufgaben", methods=["GET"])
def get_aufgaben():
    return jsonify(aufgaben)


@app.route("/aufgaben", methods=["POST"])
def create_aufgabe():
    daten = request.get_json()
    if not daten or "titel" not in daten:
        return jsonify({"fehler": "Feld 'titel' fehlt"}), 400
    neue_aufgabe = {
        "id": naechste_id(),
        "titel": daten["titel"],
        "erledigt": False
    }
    aufgaben.append(neue_aufgabe)
    return jsonify(neue_aufgabe), 201


@app.route("/aufgaben/<int:aufgabe_id>", methods=["PUT"])
def update_aufgabe(aufgabe_id):
    daten = request.get_json()
    for aufgabe in aufgaben:
        if aufgabe["id"] == aufgabe_id:
            if "titel" in daten:
                aufgabe["titel"] = daten["titel"]
            if "erledigt" in daten:
                aufgabe["erledigt"] = daten["erledigt"]
            return jsonify(aufgabe)
    return jsonify({"fehler": "Aufgabe nicht gefunden"}), 404


@app.route("/aufgaben/<int:aufgabe_id>", methods=["DELETE"])
def delete_aufgabe(aufgabe_id):
    for i, aufgabe in enumerate(aufgaben):
        if aufgabe["id"] == aufgabe_id:
            aufgaben.pop(i)
            return jsonify({"nachricht": "Aufgabe gelöscht"})
    return jsonify({"fehler": "Aufgabe nicht gefunden"}), 404


if __name__ == "__main__":
    app.run(debug=True)

API testen mit Postman

Postman ist ein Tool, mit dem du HTTP-Requests an eine API schicken kannst – ohne ein Frontend bauen zu müssen. Genau das Richtige zum Testen.

Postman installieren

Lade Postman von postman.com herunter und installiere es. Du kannst auch die Browser-Version unter web.postman.co verwenden.

Request 1: Alle Aufgaben abrufen (GET)

  1. Klicke auf New → HTTP Request
  2. Wähle die Methode GET
  3. Gib die URL ein: http://127.0.0.1:5000/aufgaben
  4. Klicke auf Send

Du siehst die Liste mit den zwei Aufgaben als JSON-Antwort.

Request 2: Neue Aufgabe erstellen (POST)

  1. Methode: POST
  2. URL: http://127.0.0.1:5000/aufgaben
  3. Klicke auf den Tab Body
  4. Wähle raw und rechts davon JSON
  5. Füge folgenden Text ein:
    json
    {
      "titel": "Deutsch Aufsatz schreiben"
    }
  6. Klicke auf Send

Du bekommst die neu erstellte Aufgabe zurück (mit Statuscode 201).

Request 3: Aufgabe aktualisieren (PUT)

  1. Methode: PUT
  2. URL: http://127.0.0.1:5000/aufgaben/1
  3. Body → raw → JSON:
    json
    {
      "erledigt": true
    }
  4. Klicke auf Send

Die erste Aufgabe ist jetzt als erledigt markiert.

Request 4: Aufgabe löschen (DELETE)

  1. Methode: DELETE
  2. URL: http://127.0.0.1:5000/aufgaben/2
  3. Kein Body nötig
  4. Klicke auf Send

Die zweite Aufgabe wurde gelöscht. Überprüfe es mit einem GET-Request.


Was fehlt noch?

Unsere API funktioniert – aber sie hat ein grosses Problem: sobald du den Server neu startest, sind alle Daten weg. Das liegt daran, dass wir die Daten nur in einer Python-Liste im Arbeitsspeicher halten.

Im nächsten Teil lernst du, wie du die Daten dauerhaft in einer Datenbank speicherst.

Weiter zu: Daten speichern mit Supabase

Informatik & ICT Unterricht Neufeld