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