FastAPI-Tutorial in Visual Studio Code
FastAPI ist ein modernes, hochperformantes Webframework zum Erstellen von APIs mit Python. Es wurde entwickelt, um das schnelle und effiziente Erstellen von APIs zu vereinfachen und bietet Funktionen wie automatische Validierung, Serialisierung und Dokumentation Ihrer API, was es zu einer beliebten Wahl für die Erstellung von Webdiensten und Microservices macht.
In diesem FastAPI-Tutorial erstellen wir eine Einkaufslisten-App mit FastAPI. Am Ende des Tutorials verstehen Sie, wie Sie mit FastAPI im Visual Studio Code-Terminal, Editor und Debugger arbeiten. Dieses Tutorial ist keine tiefgehende Einführung in FastAPI. Dafür können Sie sich auf die offizielle FastAPI-Dokumentation beziehen.
Wenn Sie Python zum ersten Mal verwenden, empfehlen wir Ihnen, mit unserem Python-Tutorial zu beginnen, um sich mit der Sprache und der Python-Unterstützung von VS Code vertraut zu machen. Dieses Tutorial eignet sich eher für diejenigen, die bereits mit Python vertraut sind und lernen möchten, wie sie mit FastAPI in VS Code arbeiten.
Das abgeschlossene Code-Projekt aus diesem FastAPI-Tutorial finden Sie auf GitHub: python-sample-vscode-fastapi-tutorial.
Wenn Sie Probleme haben, können Sie auf den Diskussionen zur Python-Erweiterung (Fragen & Antworten) nach Antworten suchen oder eine Frage stellen.
Projekt einrichten
Es gibt verschiedene Möglichkeiten, Ihr Projekt für dieses Tutorial einzurichten. Wir behandeln, wie Sie es in GitHub Codespaces und in VS Code auf Ihrem lokalen Rechner einrichten können.
GitHub Codespaces
Sie können dieses Projekt so einrichten, dass Sie in GitHub Codespaces entwickeln können, wo Sie Ihre App remote in einem Codespace codieren, debuggen und ausführen können. Ein Codespace bietet eine vollständig konfigurierte Entwicklungsumgebung, die in der Cloud gehostet wird und den Bedarf an lokaler Einrichtung überflüssig macht. Diese Umgebung umfasst die Abhängigkeiten, Tools und Erweiterungen Ihres Projekts und gewährleistet eine konsistente und reproduzierbare Entwicklungserfahrung. Sie optimiert die Zusammenarbeit, indem sie Echtzeitbearbeitung, integrierte Versionskontrolle und einfachen Zugriff auf Debugging- und Testwerkzeuge bietet und gleichzeitig die Sicherheit und Zuverlässigkeit Ihres Projekts aufrechterhält.
Hinweis: Alle GitHub.com-Konten verfügen über eine monatliche Freikontingent für die Nutzung von GitHub Codespaces, die in den kostenlosen oder Pro-Plänen enthalten ist. Weitere Informationen finden Sie unter Informationen zur Abrechnung für GitHub Codespaces.
Um einen Codespace für dieses Tutorial einzurichten, navigieren Sie zum GitHub-Repository dieses Projekts. Dieser Codespace enthält alle notwendigen Konfigurationen und Abhängigkeiten, um schnell mit der FastAPI-Entwicklung zu beginnen.
Wählen Sie für dieses Tutorial den Branch dictionarybased

Wählen Sie dann Code > Codespaces > Codespace auf dem Branch <dictionarybased> erstellen, um einen Codespace für Ihr Projekt zu erstellen und zu öffnen.
Wenn Sie fertig sind, können Sie mit dem Abschnitt Die Datenbank ersetzen unten fortfahren.
Lokal in VS Code
Um dieses Tutorial in VS Code erfolgreich abzuschließen, müssen Sie zunächst Ihre Python-Entwicklungsumgebung einrichten. Insbesondere erfordert dieses Tutorial
- Python 3 (überprüfen Sie die Installationsanleitung, wenn Sie es noch nicht installiert haben)
- Python-Erweiterung für VS Code (Weitere Details zur Installation von Erweiterungen finden Sie im Extension Marketplace).
In diesem Abschnitt erstellen wir einen Ordner, den wir als Arbeitsbereich in VS Code öffnen, richten eine Python-virtuelle Umgebung ein und installieren die Abhängigkeiten des Projekts.
-
Erstellen Sie in Ihrem Dateisystem einen Projektordner für dieses Tutorial, z. B.
groceries-plugin. -
Öffnen Sie diesen neuen Ordner in VS Code (Datei > Ordner öffnen…).
-
Wenn die Aufforderung Workspace Trust angezeigt wird, wählen Sie Ja, ich vertraue den Autoren, um dem Workspace den Zugriff auf notwendige Ressourcen und Erweiterungen zu gestatten. Weitere Informationen zu Workspace Trust finden Sie in der Dokumentation.
Erstellen wir nun eine Datei requirements.txt, die die Abhängigkeiten auflistet, die wir für die Anwendung installieren möchten. Die Datei requirements.txt ist eine gängige Praxis in der Python-Entwicklung, um die Bibliotheken anzugeben, von denen Ihr Projekt abhängt, sowie deren Versionen. Diese Datei hilft sicherzustellen, dass jeder, der an dem Projekt arbeitet, eine ähnliche Entwicklungsumgebung erstellen kann, was sie zu einer praktischen Komponente für die Aufrechterhaltung der Konsistenz macht.
Wir installieren FastAPI zum Erstellen der App, uvicorn als Server und Redis sowie type-redis für die Datenhaltung und die Interaktion mit einer Redis-Datenbank.
-
Erstellen Sie eine neue Datei in VS Code (Datei > Neue Textdatei oder ⌘N (Windows, Linux Ctrl+N)).
-
Fügen Sie den folgenden Inhalt hinzu
fastapi redis types-redis uvicorn -
Speichern Sie die Datei (⌘S (Windows, Linux Ctrl+S)) und nennen Sie sie
requirements.txt. -
Erstellen Sie eine virtuelle Umgebung, indem Sie die Befehlspalette öffnen (⇧⌘P (Windows, Linux Ctrl+Shift+P)) und den Befehl Python: Environment erstellen ausführen.
Hinweis: Dieser Schritt kann einige Minuten dauern.
-
Wählen Sie bei der Aufforderung nach dem Umgebungstyp Venv

-
Wählen Sie dann die neueste Python-Version aus, die auf Ihrem Rechner verfügbar ist

-
Wählen Sie die Datei
requirements.txtaus der Dropdown-Liste aus, damit die Abhängigkeiten automatisch installiert werden, und wählen Sie dann OK
Die virtuelle Umgebung wird erstellt, die Abhängigkeiten werden automatisch installiert und die Umgebung wird für Ihren Arbeitsbereich ausgewählt, die von der Python-Erweiterung verwendet werden soll. Sie können dies bestätigen, indem Sie die rechte untere Ecke von VS Code überprüfen

Hinweis: Wenn Sie die neu erstellte Umgebungsinformation nicht in der Statusleiste finden, können Sie auf die Anzeige des Python-Interpreters klicken (oder den Befehl Python: Interpreter auswählen aus der Befehlspalette ausführen) und die virtuelle Umgebung manuell auswählen.
Mit dem Codieren beginnen
Lassen Sie uns die Anwendung erstellen!
-
Erstellen Sie eine neue Python-Datei mit Datei > Neue Datei… und wählen Sie dann Python-Datei.
-
Speichern Sie sie im Ordner
groceries-pluginalsmain.py(⇧⌘S (Windows, Linux Ctrl+Shift+S)). -
Fügen Sie den folgenden Code zu
main.pyhinzu und speichern Sie die Dateifrom fastapi import FastAPI app = FastAPI() @app.get("/") def root(): return {"message": "Hello World"} -
Führen Sie den Code aus, indem Sie den Debugger starten (F5).
-
Wählen Sie aus dem Dropdown-Menü die Konfigurationsoption FastAPI aus der Liste

Dies erstellt automatisch eine Debug-Konfiguration, die uvicorn aufruft, um den Anwendungsserver über den Debugger zu starten, und es Ihnen ermöglicht, den Quellcode schrittweise zu durchlaufen, um sein Verhalten zu untersuchen. Sie sollten etwas Ähnliches wie das Folgende im Terminal sehen

Tipp: Wenn Ihr Standardport bereits belegt ist, stoppen Sie den Debugger, öffnen Sie die Befehlspalette (⇧⌘P (Windows, Linux Ctrl+Shift+P)), suchen Sie nach Debug: Konfiguration hinzufügen, wählen Sie Python Debugger, und dann FastAPI. Dies erstellt eine benutzerdefinierte Konfigurationsdatei im Verzeichnis
.vscode/launch.json, die Sie bearbeiten können. Fügen Sie Folgendes zu"args":[]hinzu, um einen benutzerdefinierten Port festzulegen:"--port=5000". Speichern Sie die Datei und starten Sie den Debugger neu mit (F5). -
Ctrl+Klick auf die URL
http://127.0.0.1:8000/im Terminal, um Ihren Standardbrowser zu dieser Adresse zu öffnen
Herzlichen Glückwunsch! Ihre FastAPI-App läuft!
-
Stoppen Sie den Debugger mit der Schaltfläche Stoppen in der Debug-Symbolleiste oder über ⇧F5 (Windows, Linux Shift+F5).
Ein Modell für Einkaufslistenartikel erstellen
Nachdem die FastAPI-App nun funktioniert, können wir unsere Einkaufslistenartikel mit Pydantic definieren, einer Datenvalidierungs- und Parsing-Bibliothek, die sich nahtlos in FastAPI integriert. Pydantic ermöglicht es Ihnen, Datenmodelle mithilfe von Python-Klassen mit Type Hints zu definieren, um eingehende Daten (sogenannte "Payloads") in API-Anfragen automatisch zu validieren und zu parsen.
Erstellen wir ein Modell für unsere Einkaufslistenartikel. Wir verwenden das Modell ItemPayload, um die Datenstruktur der Artikel zu definieren, die zur Einkaufsliste hinzugefügt werden sollen. Dieses Modell hat drei Felder: item_id, item_name und quantity.
-
Erstellen Sie eine neue Python-Datei mit Datei > Neue Datei… und wählen Sie dann Python-Datei.
-
Fügen Sie die folgenden Zeilen in die Datei ein und speichern Sie sie dann im Ordner
groceries-pluginalsmodels.py(⇧⌘S (Windows, Linux Ctrl+Shift+S))from typing import Optional from pydantic import BaseModel class ItemPayload(BaseModel): item_id: Optional[int] item_name: str quantity: int
Pylance, der Standard-Sprachserver für Python in VS Code, unterstützt Type-Hinting-Funktionen, die beim Arbeiten mit Pydantic-Modellen und FastAPI hilfreich sein können. Dies liegt daran, dass Pylance auf Pyright basiert, einem statischen Typchecker für Python, der Typfehler in Ihrem Code erkennen kann, um Fehler zu vermeiden und die Codequalität zu verbessern.
Die folgenden drei Schritte sind optional, aber da FastAPI intensiv Type Hints verwendet, um die Lesbarkeit und Validierung des Codes zu verbessern, können wir die Type-Checking-Funktionen von Pylance nutzen, um Fehler frühzeitig zu erkennen.
-
Öffnen Sie den Einstellungen-Editor (⌘, (Windows, Linux Ctrl+,)).
-
Suchen Sie nach "python type checking mode" und stellen Sie ihn auf
basicfür grundlegendes Type Checking. Pylance zeigt nun Diagnosen und Warnungen an, um einfache typbezogene Fehler zu erkennen. Alternativ können Sie ihn aufstrictsetzen, um erweiterte Type-Checking-Regeln durchzusetzen.
-
Suchen Sie als Nächstes nach "Python inlay type hints" und aktivieren Sie Inline-Hinweise für Variablentypen und Funktionsrückgabetypen

Routen erstellen
Nun benötigen wir einen Ort, um die Einkaufslistenartikel zu speichern. Der Einfachheit halber beginnen wir mit einem leeren Dictionary.
-
Ersetzen Sie zuerst die erste Importzeile in der Datei
main.pydurch die folgenden Zeilen, um alle benötigten Pakete für das Beispiel zu importierenfrom fastapi import FastAPI, HTTPException from models import ItemPayload -
Fügen Sie nun die folgende Zeile direkt unter
app = FastAPI()hinzugrocery_list: dict[int, ItemPayload] = {}Dies erstellt ein neues leeres Dictionary, das Schlüssel vom Typ
int(als Artikel-IDs) und Werte vom TypItemPayloadempfängt.Wir definieren nun Routen in unserer FastAPI-Anwendung. Im Kontext von Webanwendungen sind Routen wie Pfade, die bestimmte URLs dem Code zuordnen, der sie verarbeitet. Diese Routen dienen als Einstiegspunkte für die verschiedenen Funktionalitäten innerhalb unserer Anwendung. Wenn ein Client, wie z. B. ein Webbrowser oder ein anderes Programm, eine Anfrage an unsere Anwendung mit einer bestimmten URL sendet, leitet FastAPI diese Anfrage basierend auf der URL an die entsprechende Funktion (auch bekannt als Routenhandler oder View-Funktion) weiter, und diese Funktion verarbeitet die Anfrage und generiert eine Antwort.
Lassen Sie uns mit der Definition von Routen zum Hinzufügen und Abrufen einzelner Artikel sowie zum Zurückgeben aller Artikel in der Einkaufsliste fortfahren.
-
Fügen Sie die folgende Route am Ende der Datei
main.pyhinzu# Route to add a item @app.post("/items/{item_name}/{quantity}") def add_item(item_name: str, quantity: int): if quantity <= 0: raise HTTPException(status_code=400, detail="Quantity must be greater than 0.") # if item already exists, we'll just add the quantity. # get all item names items_ids = {item.item_name: item.item_id if item.item_id is not None else 0 for item in grocery_list.values()} if item_name in items_ids.keys(): # get index of item_name in item_ids, which is the item_id item_id = items_ids[item_name] grocery_list[item_id].quantity += quantity # otherwise, create a new item else: # generate an ID for the item based on the highest ID in the grocery_list item_id = max(grocery_list.keys()) + 1 if grocery_list else 0 grocery_list[item_id] = ItemPayload( item_id=item_id, item_name=item_name, quantity=quantity ) return {"item": grocery_list[item_id]}Wenn Sie Type Hints im vorherigen Abschnitt aktiviert haben, stellen Sie fest, dass Pylance Inline-Hinweise mit dem Rückgabetyp der Funktion sowie den Typen für
item_idsunditem_idhinzufügt. Sie können optional auf jeden Vorschlag doppelklicken, um ihn in den Code einzufügen
Lassen Sie uns nun prüfen, ob diese Route wie erwartet funktioniert. Der schnellste Weg dazu ist die Nutzung sowohl des Debuggers von VS Code als auch des
/docs-Endpunkts von FastAPI, der Informationen über alle verfügbaren API-Routen liefert und es Ihnen ermöglicht, mit der API zu interagieren, um ihre Parameter und Antworten zu erkunden. Diese Dokumentation wird dynamisch basierend auf den Metadaten und Type Hints, die in der FastAPI-Anwendung definiert sind, generiert. -
Setzen Sie einen Haltepunkt neben der Anweisung
if quantity <= 0, indem Sie auf den linken Rand der Zeilennummer klicken (oder auf F9). Der Debugger stoppt vor der Ausführung dieser Zeile, sodass Sie den Code Zeile für Zeile untersuchen können.
-
Starten Sie den Debugger (F5) und navigieren Sie dann im Browser zu
http://127.0.0.1:8000/docs.Es sollte eine Swagger-Oberfläche mit den beiden verfügbaren Endpunkten in der App vorhanden sein:
/itemsund der Root (/).
-
Wählen Sie den Pfeil nach unten neben der Route
/itemsaus, um sie zu erweitern, und dann die Schaltfläche Try it out, die auf der rechten Seite erscheint.
-
Fügen Sie einen Einkaufslistenartikel hinzu, indem Sie einen String für das Feld
item_nameund eine Zahl fürquantityübergeben. Sie könnten zum Beispiel 'apple' alsitem_nameund 2 alsquantityangeben. -
Wählen Sie Execute.

-
Öffnen Sie VS Code erneut und stellen Sie fest, dass der Debugger am zuvor gesetzten Haltepunkt angehalten hat.

Auf der linken Seite werden alle lokalen und globalen Variablen, die zu diesem Zeitpunkt definiert sind, im Fenster Variablen unter der Ansicht Ausführen und Debuggen angezeigt. In unserem Beispiel ist
item_nameauf 'apple' undquantityauf 2 unter der lokalen Variablenansicht eingestellt, sowie ein leeresgrocery_list-Dictionary unter der globalen Variablenansicht.
Lassen Sie uns nun die Debug-Konsole von VS Code zur Erkundung nutzen.
-
Wählen Sie die Anweisung
quantity <= 0aus, klicken Sie mit der rechten Maustaste auf den Editor und wählen Sie Im Debug-Konsolen auswerten
Dies öffnet die Debug-Konsole und führt den ausgewählten Ausdruck aus. Wie in unserem Beispiel erwartet, wird der Ausdruck zu
Falseausgewertet.Die Debug-Konsole kann ein mächtiges Werkzeug sein, um schnell Ausdrücke zu testen und den Zustand Ihres Codes zum Zeitpunkt eines Haltepunkts besser zu verstehen. Sie können sie auch verwenden, um beliebigen Code auszuführen, z. B. Funktionen aufzurufen oder Variablen auszugeben. Weitere Informationen zum Debuggen von Python in VS Code finden Sie im Python-Tutorial.
Sie können die Ausführung des Codes jetzt fortsetzen, indem Sie auf Weiter in der Symbolleiste der Debug-Ansicht klicken oder F5 drücken.
Fügen wir abschließend die restlichen Routen für die Anwendung hinzu, damit wir alle Artikel oder bestimmte Artikel auflisten und sie aus unserer Einkaufsliste entfernen können. Sie können den Debugger weiterlaufen lassen, da die Anwendung automatisch neu geladen wird, wenn Sie die Änderungen im nächsten Schritt speichern.
-
Ersetzen Sie den Inhalt in
main.pydurch den folgenden Codefrom fastapi import FastAPI, HTTPException from models import ItemPayload app = FastAPI() grocery_list: dict[int, ItemPayload] = {} # Route to add an item @app.post("/items/{item_name}/{quantity}") def add_item(item_name: str, quantity: int) -> dict[str, ItemPayload]: if quantity <= 0: raise HTTPException(status_code=400, detail="Quantity must be greater than 0.") # if item already exists, we'll just add the quantity. # get all item names items_ids: dict[str, int] = { item.item_name: item.item_id if item.item_id is not None else 0 for item in grocery_list.values() } if item_name in items_ids.keys(): # get index of item_name in item_ids, which is the item_id item_id: int = items_ids[item_name] grocery_list[item_id].quantity += quantity # otherwise, create a new item else: # generate an ID for the item based on the highest ID in the grocery_list item_id: int = max(grocery_list.keys()) + 1 if grocery_list else 0 grocery_list[item_id] = ItemPayload( item_id=item_id, item_name=item_name, quantity=quantity ) return {"item": grocery_list[item_id]} # Route to list a specific item by ID @app.get("/items/{item_id}") def list_item(item_id: int) -> dict[str, ItemPayload]: if item_id not in grocery_list: raise HTTPException(status_code=404, detail="Item not found.") return {"item": grocery_list[item_id]} # Route to list all items @app.get("/items") def list_items() -> dict[str, dict[int, ItemPayload]]: return {"items": grocery_list} # Route to delete a specific item by ID @app.delete("/items/{item_id}") def delete_item(item_id: int) -> dict[str, str]: if item_id not in grocery_list: raise HTTPException(status_code=404, detail="Item not found.") del grocery_list[item_id] return {"result": "Item deleted."} # Route to remove some quantity of a specific item by ID @app.delete("/items/{item_id}/{quantity}") def remove_quantity(item_id: int, quantity: int) -> dict[str, str]: if item_id not in grocery_list: raise HTTPException(status_code=404, detail="Item not found.") # if quantity to be removed is higher or equal to item's quantity, delete the item if grocery_list[item_id].quantity <= quantity: del grocery_list[item_id] return {"result": "Item deleted."} else: grocery_list[item_id].quantity -= quantity return {"result": f"{quantity} items removed."} -
Speichern Sie die Datei (⌘S (Windows, Linux Ctrl+S)). Die Anwendung sollte automatisch neu geladen werden.
Sie können nun erneut die Seite /docs öffnen und die neuen Routen testen, indem Sie den Debugger und die Debug-Konsole verwenden, um die Codeausführung besser zu verstehen. Wenn Sie fertig sind, können Sie den Debugger stoppen (⇧F5 (Windows, Linux Shift+F5)). Sie können auch den Haltepunkt entfernen, den wir in Schritt 4 hinzugefügt haben, indem Sie darauf klicken.
Herzlichen Glückwunsch! Sie haben nun eine funktionierende FastAPI-Anwendung mit Routen zum Hinzufügen, Auflisten und Löschen von Artikeln aus einer Einkaufsliste.
Datenspeicherung einrichten
An diesem Punkt haben Sie bereits eine funktionierende Version der Anwendung mit der Grundfunktionalität. Dieser Abschnitt führt Sie durch die Einrichtung der Datenspeicherung für die Persistenz, aber Sie können ihn überspringen, wenn Sie mit dem bisher Gelernten zufrieden sind.
Bisher speichern wir die Daten in einem Dictionary, was nicht ideal ist, da alle Daten verloren gehen, wenn die Anwendung neu gestartet wird.
Um die Daten zu persistent zu machen, werden wir Redis verwenden, einen Open-Source-In-Memory-Datenspeicher. Aufgrund seiner Geschwindigkeit und Vielseitigkeit wird Redis häufig als Datenspeichersystem in einer Vielzahl von Anwendungen verwendet, darunter Webanwendungen, Echtzeit-Analyse-Systeme, Caching-Schichten, dieses Tutorial und mehr.
Wenn Sie bereits mit GitHub Codespaces mit unserer bestehenden Vorlage arbeiten, können Sie direkt zum Abschnitt Die Datenbank ersetzen springen.
Wenn Sie unter Windows arbeiten, können Sie mit Redis arbeiten, indem Sie entweder einen Docker-Container oder einen GitHub Codespace einrichten. In diesem Tutorial verwenden wir einen Docker-Container, aber Sie können sich auf den obigen Abschnitt für Anleitungen zur Einrichtung eines GitHub Codespace beziehen.
Wenn Sie sich auf einer Linux- oder macOS-Maschine befinden, können Sie Redis installieren, indem Sie die Anweisungen auf deren Website befolgen und dann zum Abschnitt Die Datenbank ersetzen springen.
Einrichtung eines Docker-Containers unter Windows
Die VS Code-Erweiterung Dev Containers bietet einen optimierten Ansatz, um Ihr Projekt, seine Abhängigkeiten und alle notwendigen Werkzeuge in einem einzigen Container zu konsolidieren und so eine voll funktionsfähige Entwicklungsumgebung zu schaffen. Die Erweiterung ermöglicht es Ihnen, Ihr Projekt innerhalb (oder in den Container gemountet) des Containers in VS Code zu öffnen, wo Sie dessen vollen Funktionsumfang nutzen können.
Stellen Sie für die folgenden Schritte sicher, dass Sie die folgenden Anforderungen auf Ihrem Rechner installiert haben
Voraussetzungen
- Docker für Windows
- Dev Containers-Erweiterung
Dev-Container-Konfiguration erstellen
-
Öffnen Sie die Befehlspalette und führen Sie Dev Containers: Dev Container-Konfigurationsdateien hinzufügen… aus.
-
Wählen Sie Python 3

-
Wählen Sie die Standardversion.
-
Wählen Sie Redis Server als zusätzliche zu installierende Funktion, drücken Sie OK und wählen Sie dann Standardwerte beibehalten.
Wir können optional Features installieren, die in den Container aufgenommen werden sollen. Für dieses Tutorial installieren wir Redis Server, ein von der Community beigesteuertes Feature, das die richtige Dev-Container-Einrichtung für Redis installiert und hinzufügt.

Dies erstellt einen Ordner
.devcontainerin Ihrem Arbeitsbereich mit einer Dateidevcontainer.json. Nehmen wir einige Änderungen an dieser Datei vor, damit die Container-Einrichtung Schritte wie die Installation der benötigten VS Code-Erweiterungen sowie der Projekt Abhängigkeiten umfasst. -
Öffnen Sie die Datei
devcontainer.json. -
Fügen Sie nach dem Eintrag
"features" : { ... }ein "," hinzu, damit wir weitere Einstellungen zur Datei hinzufügen können.Als Nächstes fügen wir die notwendigen Befehle zur Installation von Abhängigkeiten in die Eigenschaft
postCreateCommandin der Dateidevcontainer.jsonein, damit unsere Anwendung nach der Einrichtung des Containers bereit zur Ausführung ist. -
Suchen Sie den folgenden Inhalt und entfernen Sie den Kommentar (
//) von dieser Zeile, damit die Abhängigkeiten nach der Erstellung des Containers installiert werden können"postCreateCommand": "pip3 install --user -r requirements.txt",Sie können mehr über
postCreateCommandund weitere Lifecycle-Skripte in der Development Containers Specification erfahren.Nun verwenden wir die Eigenschaft
customizations, um die VS Code-Erweiterungen hinzuzufügen, die wir im Container installiert haben möchten. -
Fügen Sie die folgende Einstellung zu
devcontainer.jsonhinzu// Use 'postCreateCommand' to run commands after the container is created. "postCreateCommand": "pip3 install --user -r requirements.txt", // Configure tool-specific properties. "customizations": { "vscode": { "extensions": [ "ms-python.python", //Python extension ID "ms-python.vscode-pylance" //Pylance extension ID ] } } -
Speichern Sie die Datei.
-
Wählen Sie Im Container neu öffnen aus der Benachrichtigung, die in der rechten unteren Ecke angezeigt wird, oder führen Sie den Befehl Dev Containers: Im Container neu öffnen aus der Befehlspalette aus.
Hinweis: Es kann mehrere Minuten dauern, bis der Container erstellt ist, abhängig von der Internetgeschwindigkeit und der Leistung des Rechners.
Sie können mehr über die Dev-Container-Konfiguration in der Dev Containers-Dokumentation erfahren.
Sobald dies abgeschlossen ist, haben Sie einen voll konfigurierten Linux-basierten Arbeitsbereich mit Python 3 und Redis Server installiert.
Sobald der Container eingerichtet ist, sehen Sie eine Anzeige in der linken unteren Ecke von VS Code

Hinweis: Stellen Sie sicher, dass die Python- und Pylance-Erweiterungen im Container erfolgreich installiert wurden, indem Sie die Erweiterungsansicht öffnen (⇧⌘X (Windows, Linux Ctrl+Shift+X)) und danach suchen. Wenn nicht, können Sie sie installieren, indem Sie Im Dev-Container installieren ausführen.
Die ausgewählten Informationen zum Python-Interpreter sind in der Statusleiste unten rechts verfügbar und entsprechen der in der Datei devcontainer.json angegebenen Version.

Hinweis: Wenn Sie die Informationen zum Python-Interpreter nicht in der Statusleiste finden, können Sie auf die Anzeige des Python-Interpreters klicken (oder den Befehl Python: Interpreter auswählen aus der Befehlspalette ausführen) und den Python-Interpreter im Container manuell auswählen.
Wir sind nun bereit, zum nächsten Abschnitt überzugehen, in dem wir die Datenspeicherung ersetzen.
Die Datenbank ersetzen
Wir haben ein Dictionary, das die Einkaufslistenartikel speichert, aber wir möchten es durch eine Redis-Datenbank ersetzen. In diesem Tutorial verwenden wir Redis-Hashes, um unsere Daten zu speichern, eine Datenstruktur, die mehrere Schlüssel-Wert-Paare speichern kann.
Im Gegensatz zu einer herkömmlichen Datenbank, bei der Sie einen Artikel abrufen können, ohne seine ID zu kennen, müssen Sie den Redis-Hash-Schlüssel kennen, um einen Wert daraus abzurufen. In diesem Tutorial erstellen wir einen Hash namens item_name_to_id, um Artikel anhand ihres Namens abzurufen und sie ihren IDs zuzuordnen. Zusätzlich erstellen wir weitere Hashes, um Artikel anhand ihrer IDs abzurufen und sie ihren Namen und Mengen zuzuordnen. Jeder Artikel-Hash heißt item_id:{item_id} und hat zwei Felder: item_name und quantity.
Beginnen wir damit, das Dictionary durch ein Redis-Client-Objekt zu ersetzen, das sich mit einem Redis-Server verbindet.
-
Ersetzen Sie in der Datei
main.pydie Zeilegrocery_list: dict[int, ItemPayload] = {}am Anfang der Datei durch die folgenden Zeilenredis_client = redis.StrictRedis(host='0.0.0.0', port=6379, db=0, decode_responses=True)Pylance wird eine Fehlermeldung anzeigen, da Redis noch nicht importiert wurde.
-
Setzen Sie den Cursor auf "redis" im Editor und klicken Sie auf die angezeigte Glühbirne (oder auf ⌘. (Windows, Linux Ctrl+.)). Wählen Sie dann 'import redis' hinzufügen.

Tipp: Sie können Pylance so einrichten, dass Importe automatisch hinzugefügt werden, indem Sie in den Einstellungen nach der Einstellung Automatische Importvervollständigungen suchen (⌘, (Windows, Linux Ctrl+,)) und diese aktivieren.
Wir haben nun ein Redis-Client-Objekt, das sich mit einem Redis-Server verbindet, der auf dem lokalen Host läuft (
host="0.0.0.0") und auf Port 6379 (port=6379) lauscht. Der Parameterdbgibt die zu verwendende Redis-Datenbank an. Redis unterstützt mehrere Datenbanken, und in diesem Code verwenden wir die Datenbank 0, die Standarddatenbank. Wir übergeben auchdecode_responses=True, damit die Antworten als Strings (anstatt als Bytes) dekodiert werden.Nehmen wir einige weitere Ersetzungen in der ersten Route
add_itemvor. Anstatt alle Schlüssel aus dem Dictionary zu prüfen, um den Namen des Artikels zu finden, der übergeben wurde, können wir diese Informationen direkt aus einem Redis-Hash abrufen.Wir gehen davon aus, dass der Hash
item_name_to_idbereits existiert und Artikelnamen seinen IDs zuordnet (keine Sorge, diesen Code werden wir gleich hinzufügen!). Wir können dann die ID des Artikelnamens, den wir in der Anfrage erhalten, abrufen, indem wir die Methodehgetvon Redis aufrufen, die die Artikel-ID zurückgibt, wenn der angeforderte Name bereits im Hash vorhanden ist, oderNone, wenn er nicht vorhanden ist. -
Löschen Sie die Zeile mit dem folgenden Inhalt
items_ids = {item.item_name: item.item_id if item.item_id is not None else 0 for item in grocery_list.values()}Und ersetzen Sie sie durch
item_id = redis_client.hget("item_name_to_id", item_name)Beachten Sie, dass Pylance bei dieser Änderung ein Problem meldet. Dies liegt daran, dass die Methode
hgetentwederstroderNonezurückgibt (wenn der Artikel nicht existiert). Die Zeilen unter dem noch nicht ersetzten Code erwarten jedoch, dassitem_idvom Typintist. Lassen Sie uns diese Warnung beheben, indem wir das Symbolitem_idumbenennen. -
Benennen Sie
item_idinitem_id_strum. -
Wenn Sie Inline-Hinweise aktiviert haben, sollte Pylance einen Variablentyp-Hinweis neben
item_id_stranzeigen. Sie können optional doppelklicken, um ihn zu akzeptieren
-
Wenn der Artikel nicht existiert, ist
item_id_strNone. Jetzt können wir die Zeile mit dem folgenden Inhalt löschenif item_name in items_ids.keys():Und ersetzen Sie sie durch
if item_id_str is not None:Jetzt, da wir die Artikel-ID als String haben, müssen wir sie in einen
intkonvertieren und die Menge für den Artikel aktualisieren. Derzeit ordnet unser Redis-Hash nur Artikelnamen ihren IDs zu. Um auch Artikel-IDs ihren Namen und Mengen zuzuordnen, erstellen wir für jeden Artikel einen separaten Redis-Hash, wobei wir"item_id:{item_id}"als unseren Hash-Namen verwenden, um den Abruf nach ID zu erleichtern. Wir fügen auch die Felderitem_nameundquantityfür jeden dieser Hashes hinzu. -
Löschen Sie den Code innerhalb des
if-Blocksitem_id: int = items_ids[item_name] grocery_list[item_id].quantity += quantityUnd fügen Sie Folgendes hinzu, um die
item_idin einenintzu konvertieren und dann die Menge des Artikels zu erhöhen, indem Sie die Methodehincrbyvon Redis aufrufen. Diese Methode erhöht den Wert des Feldes"quantity"um den angegebenen Betrag in der Anfrage (quantity)item_id = int(item_id_str) redis_client.hincrby(f"item_id:{item_id}", "quantity", quantity)Wir müssen nun nur noch den Code für den Fall ersetzen, dass der Artikel nicht existiert, wenn
item_id_strNoneist. In diesem Fall generieren wir eine neueitem_id, erstellen einen neuen Redis-Hash für den Artikel und fügen dann den angegebenen Artikelnamen und die Menge hinzu.Um eine neue
item_idzu generieren, verwenden wir die Methodeincrvon Redis und übergeben einen neuen Hash namens"item_ids". Dieser Hash wird verwendet, um die zuletzt generierte ID zu speichern, sodass wir sie jedes Mal erhöhen können, wenn wir einen neuen Artikel erstellen, um sicherzustellen, dass alle eine eindeutige ID haben. -
Löschen Sie die Zeile mit dem folgenden Inhalt
item_id: int = max(grocery_list.keys()) + 1 if grocery_list else 0Und fügen Sie Folgendes hinzu
item_id: int = redis_client.incr("item_ids")Wenn dieser
incr-Aufruf zum ersten Mal mit dem Schlüsselitem_idsausgeführt wird, erstellt Redis den Schlüssel und ordnet ihn dem Wert1zu. Jedes Mal, wenn er danach ausgeführt wird, erhöht er den gespeicherten Wert um 1.Nun fügen wir den Artikel dem Redis-Hash hinzu, indem wir die Methode
hsetverwenden und eine Zuordnung für die Felder (item_id,item_nameundquantity) und die Werte (die neu erstellte ID des Artikels und sein angegebener Name und seine Menge) bereitstellen. -
Löschen Sie die Zeile mit dem folgenden Inhalt
grocery_list[item_id] = ItemPayload( item_id=item_id, item_name=item_name, quantity=quantity )Und ersetzen Sie sie durch Folgendes
redis_client.hset( f"item_id:{item_id}", mapping={ "item_id": item_id, "item_name": item_name, "quantity": quantity, })Nun müssen wir nur noch die neu erstellte ID dem Artikelnamen zuordnen, indem wir den Hash festlegen, auf den wir anfangs verwiesen haben,
item_name_to_id. -
Fügen Sie diese Zeile am Ende der Route, innerhalb des
else-Blocks, hinzuredis_client.hset("item_name_to_id", item_name, item_id) -
Löschen Sie die Zeile mit dem folgenden Inhalt
return {"item": grocery_list[item_id]}Und ersetzen Sie sie durch
return {"item": ItemPayload(item_id=item_id, item_name=item_name, quantity=quantity)} -
Wenn Sie möchten, können Sie versuchen, eine ähnliche Ersetzung für die anderen Routen vorzunehmen. Andernfalls können Sie einfach den gesamten Inhalt der Datei durch die folgenden Zeilen ersetzen
import redis from fastapi import FastAPI, HTTPException from models import ItemPayload app = FastAPI() redis_client = redis.StrictRedis(host="0.0.0.0", port=6379, db=0, decode_responses=True) # Route to add an item @app.post("/items/{item_name}/{quantity}") def add_item(item_name: str, quantity: int) -> dict[str, ItemPayload]: if quantity <= 0: raise HTTPException(status_code=400, detail="Quantity must be greater than 0.") # Check if item already exists item_id_str: str | None = redis_client.hget("item_name_to_id", item_name) if item_id_str is not None: item_id = int(item_id_str) redis_client.hincrby(f"item_id:{item_id}", "quantity", quantity) else: # Generate an ID for the item item_id: int = redis_client.incr("item_ids") redis_client.hset( f"item_id:{item_id}", mapping={ "item_id": item_id, "item_name": item_name, "quantity": quantity, }, ) # Create a set so we can search by name too redis_client.hset("item_name_to_id", item_name, item_id) return { "item": ItemPayload(item_id=item_id, item_name=item_name, quantity=quantity) } # Route to list a specific item by ID but using Redis @app.get("/items/{item_id}") def list_item(item_id: int) -> dict[str, dict[str, str]]: if not redis_client.hexists(f"item_id:{item_id}", "item_id"): raise HTTPException(status_code=404, detail="Item not found.") else: return {"item": redis_client.hgetall(f"item_id:{item_id}")} @app.get("/items") def list_items() -> dict[str, list[ItemPayload]]: items: list[ItemPayload] = [] stored_items: dict[str, str] = redis_client.hgetall("item_name_to_id") for name, id_str in stored_items.items(): item_id: int = int(id_str) item_name_str: str | None = redis_client.hget(f"item_id:{item_id}", "item_name") if item_name_str is not None: item_name: str = item_name_str else: continue # skip this item if it has no name item_quantity_str: str | None = redis_client.hget( f"item_id:{item_id}", "quantity" ) if item_quantity_str is not None: item_quantity: int = int(item_quantity_str) else: item_quantity = 0 items.append( ItemPayload(item_id=item_id, item_name=item_name, quantity=item_quantity) ) return {"items": items} # Route to delete a specific item by ID but using Redis @app.delete("/items/{item_id}") def delete_item(item_id: int) -> dict[str, str]: if not redis_client.hexists(f"item_id:{item_id}", "item_id"): raise HTTPException(status_code=404, detail="Item not found.") else: item_name: str | None = redis_client.hget(f"item_id:{item_id}", "item_name") redis_client.hdel("item_name_to_id", f"{item_name}") redis_client.delete(f"item_id:{item_id}") return {"result": "Item deleted."} # Route to remove some quantity of a specific item by ID but using Redis @app.delete("/items/{item_id}/{quantity}") def remove_quantity(item_id: int, quantity: int) -> dict[str, str]: if not redis_client.hexists(f"item_id:{item_id}", "item_id"): raise HTTPException(status_code=404, detail="Item not found.") item_quantity: str | None = redis_client.hget(f"item_id:{item_id}", "quantity") # if quantity to be removed is higher or equal to item's quantity, delete the item if item_quantity is None: existing_quantity: int = 0 else: existing_quantity: int = int(item_quantity) if existing_quantity <= quantity: item_name: str | None = redis_client.hget(f"item_id:{item_id}", "item_name") redis_client.hdel("item_name_to_id", f"{item_name}") redis_client.delete(f"item_id:{item_id}") return {"result": "Item deleted."} else: redis_client.hincrby(f"item_id:{item_id}", "quantity", -quantity) return {"result": f"{quantity} items removed."} -
Führen Sie den Debugger erneut aus, um diese Anwendung zu testen, indem Sie mit der Route
/docsinteragieren. Sie können den Debugger stoppen, sobald Sie fertig sind.
Glückwunsch! Sie haben nun eine funktionierende FastAPI-Anwendung mit Routen zum Hinzufügen, Auflisten und Löschen von Artikeln aus einer Einkaufsliste, und die Daten werden in einer Redis-Datenbank gespeichert.
Optional: Datenbanklöschung einrichten
Da die Daten nun von Redis persistent gemacht werden, möchten Sie möglicherweise ein Skript erstellen, um alle Testdaten zu löschen. Erstellen Sie dazu eine neue Datei namens flushdb.py mit dem folgenden Inhalt
import redis
redis_client = redis.StrictRedis(host='0.0.0.0', port=6379, db=0, decode_responses=True)
redis_client.flushdb()
Wenn Sie die Datenbank zurücksetzen möchten, können Sie die Datei flushdb.py in VS Code öffnen und die Schaltfläche Ausführen in der oberen rechten Ecke des Editors auswählen oder den Befehl Python: Python-Datei im Terminal ausführen aus der Befehlspalette ausführen.
Beachten Sie, dass dies mit Vorsicht geschehen sollte, da alle Schlüssel in der aktuellen Datenbank gelöscht werden, was bei der Ausführung in einer Produktionsumgebung zu Datenverlust führen kann.
Optional: Eine GPT-Aktion erstellen
Mit GitHub Codespaces können Sie Ihre Anwendung zu Testzwecken hosten, wenn Sie GPT Actions verwenden. GPT Actions sind Tools, die es ChatGPT ermöglichen, mit bestehenden APIs zu interagieren, um die Fähigkeiten von ChatGPT zu erweitern und es eine breite Palette von Aktionen ausführen zu lassen. Sie können dem Live-Stream-Mitschnitt unten folgen, um Ihr eigenes Einkaufslisten-Plugin für ChatGPT zu erstellen
Hinweis: Alle persönlichen GitHub.com-Konten haben ein monatliches Freikontingent für die Nutzung von GitHub Codespaces, das in den kostenlosen oder Pro-Plänen enthalten ist. Weitere Informationen finden Sie unter Informationen zur Abrechnung für GitHub Codespaces.
Nächste Schritte
Vielen Dank, dass Sie diesem Tutorial gefolgt sind! Wir hoffen, Sie haben etwas Neues über FastAPI und die Verwendung mit VS Code gelernt.
Das abgeschlossene Code-Projekt aus diesem Tutorial finden Sie auf GitHub: python-sample-vscode-fastapi-tutorial.
Erfahren Sie mehr über FastAPI in der offiziellen Dokumentation.
Um die App auf einer Produktionswebsite auszuprobieren, lesen Sie das Tutorial Python-Apps mit Docker-Containern auf Azure App Service bereitstellen.
Sie können auch diese anderen VS Code Python-Artikel lesen