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:
python --versionFlask installieren
Öffne ein Terminal und installiere Flask und das CORS-Paket mit pip:
pip install flask flask-corsBei Thonny geht das über
Werkzeuge > Pakete verwalten. Installiere dort sowohlflaskals auchflask-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.pyDie 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:
# 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) + 1Endpoint 1: GET – Alle Aufgaben abrufen
Dieser Endpoint gibt alle Aufgaben zurück.
@app.route("/aufgaben", methods=["GET"])
def get_aufgaben():
return jsonify(aufgaben)Was passiert hier?
from flask_cors import CORSundCORS(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/aufgabenreagieren, 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 Methodeget_aufgabenausführt, wenn jemand die API mit der Route/aufgabenaufruft. 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.
@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), 201Was passiert hier?
request.get_json()– liest die JSON-Daten aus dem Request-Body.- Wir prüfen, ob das Feld
titelvorhanden ist. Falls nicht, senden wir einen400-Fehler zurück. - Die neue Aufgabe bekommt eine ID und wird der Liste hinzugefügt.
201ist der Statuscode für "erfolgreich erstellt".
Endpoint 3: PUT – Aufgabe aktualisieren
Dieser Endpoint aktualisiert eine bestehende Aufgabe anhand ihrer ID.
@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"}), 404Was 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
404zurück.
Endpoint 4: DELETE – Aufgabe löschen
Dieser Endpoint löscht eine Aufgabe anhand ihrer ID.
@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"}), 404Server starten
Füge am Ende der app.py noch diese Zeile hinzu:
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:
python app.pyDu solltest folgende Ausgabe sehen:
* Running on http://127.0.0.1:5000Deine API läuft jetzt lokal auf Port 5000.
Die komplette app.py
So sieht die fertige Datei aus:
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)
- Klicke auf New → HTTP Request
- Wähle die Methode GET
- Gib die URL ein:
http://127.0.0.1:5000/aufgaben - Klicke auf Send
Du siehst die Liste mit den zwei Aufgaben als JSON-Antwort.
Request 2: Neue Aufgabe erstellen (POST)
- Methode: POST
- URL:
http://127.0.0.1:5000/aufgaben - Klicke auf den Tab Body
- Wähle raw und rechts davon JSON
- Füge folgenden Text ein:json
{ "titel": "Deutsch Aufsatz schreiben" } - Klicke auf Send
Du bekommst die neu erstellte Aufgabe zurück (mit Statuscode 201).
Request 3: Aufgabe aktualisieren (PUT)
- Methode: PUT
- URL:
http://127.0.0.1:5000/aufgaben/1 - Body → raw → JSON:json
{ "erledigt": true } - Klicke auf Send
Die erste Aufgabe ist jetzt als erledigt markiert.
Request 4: Aufgabe löschen (DELETE)
- Methode: DELETE
- URL:
http://127.0.0.1:5000/aufgaben/2 - Kein Body nötig
- 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.