FastAPI-Tutorial in Visual Studio Code
FastAPI ist ein modernes, leistungsstarkes Web-Framework zum Erstellen von APIs mit Python. Es wurde entwickelt, um die schnelle und effiziente Erstellung von APIs zu ermöglichen, und bietet gleichzeitig Funktionen wie automatische Validierung, Serialisierung und Dokumentation Ihrer API, was es zu einer beliebten Wahl für den Aufbau von Webdiensten und Microservices macht.
In diesem FastAPI-Tutorial erstellen wir eine Einkaufslisten-App mit FastAPI. Am Ende des Tutorials werden Sie verstehen, wie Sie mit FastAPI im Visual Studio Code-Terminal, im Editor und im Debugger arbeiten. Dieses Tutorial ist keine tiefgehende Auseinandersetzung mit 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 ist eher für diejenigen geeignet, die bereits mit Python vertraut sind und lernen möchten, wie man mit FastAPI in VS Code arbeitet.
Das vollständige Codeprojekt 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 Computer einrichten können.
GitHub Codespaces
Sie können dieses Projekt für die Entwicklung in GitHub Codespaces einrichten, wo Sie Ihre App remote in einem Codespace programmieren, debuggen und ausführen können. Ein Codespace bietet eine vollständig konfigurierte Entwicklungsumgebung, die in der Cloud gehostet wird, wodurch eine lokale Einrichtung entfällt. Diese Umgebung enthält die Abhängigkeiten, Tools und Erweiterungen Ihres Projekts und sorgt so für eine konsistente und reproduzierbare Entwicklungserfahrung. Sie optimiert die Zusammenarbeit durch Echtzeitbearbeitung, integrierte Versionskontrolle und einfachen Zugriff auf Debugging- und Test-Tools, während gleichzeitig die Sicherheit und Zuverlässigkeit Ihres Projekts gewahrt bleibt.
Hinweis: Alle GitHub.com-Konten haben ein monatliches Kontingent für die kostenlose Nutzung von GitHub Codespaces, das im Free- oder Pro-Plan 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 aus.

Wählen Sie dann Code > Codespaces > Create Codespace on <dictionarybased> branch, um einen Codespace für Ihr Projekt zu erstellen und zu öffnen.
Sobald Sie fertig sind, können Sie mit dem Abschnitt Datenbank austauschen weiter unten fortfahren.
Lokal in VS Code
Um dieses Tutorial erfolgreich in VS Code abzuschließen, müssen Sie zuerst Ihre Python-Entwicklungsumgebung einrichten. Insbesondere erfordert dieses Tutorial:
- Python 3 (prüfen Sie die Installationsanleitung, falls Sie es 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 Workspace in VS Code öffnen, richten eine virtuelle Python-Umgebung ein und installieren die Abhängigkeiten des Projekts.
-
Erstellen Sie in Ihrem Dateisystem einen Projektordner für dieses Tutorial, zum Beispiel
groceries-plugin. -
Öffnen Sie diesen neuen Ordner in VS Code (Datei > Ordner öffnen...).
-
Wenn die Aufforderung zum Workspace-Vertrauen (Workspace Trust) erscheint, wählen Sie Ja, ich vertraue den Autoren, damit der Workspace auf die erforderlichen Ressourcen und Erweiterungen zugreifen kann. Sie können mehr über Workspace-Vertrauen in der Dokumentation erfahren.
Erstellen wir nun eine requirements.txt-Datei, die die Abhängigkeiten auflistet, die wir für die Anwendung installieren möchten. Die requirements.txt-Datei ist eine gängige Praxis in der Python-Entwicklung, um die Bibliotheken anzugeben, auf die Ihr Projekt angewiesen ist, sowie deren Versionen. Diese Datei stellt sicher, dass jeder, der an dem Projekt arbeitet, eine ähnliche Entwicklungsumgebung nachbilden kann, was sie zu einer bequemen Komponente zur Aufrechterhaltung der Konsistenz macht.
Wir installieren FastAPI für die Erstellung der App, uvicorn als Server sowie Redis und type-redis für die Handhabung der Datenspeicherung 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: Umgebung erstellen ausführen.
Hinweis: Dieser Schritt kann einige Minuten in Anspruch nehmen.
-
Wenn Sie nach dem Umgebungstyp gefragt werden, wählen Sie Venv

-
Wählen Sie dann die neueste auf Ihrem Computer verfügbare Version von Python aus.

-
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 für Ihren Workspace zur Verwendung durch die Python-Erweiterung ausgewählt. Sie können überprüfen, ob sie ausgewählt wurde, indem Sie in die untere rechte Ecke von VS Code schauen.

Hinweis: Wenn Sie die Informationen zur neu erstellten Umgebung nicht in der Statusleiste finden, können Sie auf die Python-Interpreter-Anzeige klicken (oder den Befehl Python: Interpreter auswählen aus der Befehlspalette ausführen) und die virtuelle Umgebung manuell auswählen.
Programmierung starten
Lassen Sie uns die Anwendung erstellen!
-
Erstellen Sie eine neue Python-Datei über Datei > Neue Datei... und wählen Sie dann Python-Datei.
-
Speichern Sie sie als
main.py(⇧⌘S (Windows, Linux Ctrl+Shift+S)) imgroceries-pluginOrdner. -
Fügen Sie den folgenden Code in
main.pyein und speichern Sie die Datei.from 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 FastAPI-Konfigurationsoption aus der Liste.

Dadurch wird automatisch eine Debug-Konfiguration erstellt, 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 im Terminal in etwa Folgendes sehen:

Tipp: Falls Ihr Standardport bereits verwendet wird, stoppen Sie den Debugger und ö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 in
.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 (F5). -
Strg+Klick auf die URL
http://127.0.0.1:8000/im Terminal, um Ihren Standardbrowser unter dieser Adresse zu öffnen.
Herzlichen Glückwunsch! Ihre FastAPI-App ist startklar!
-
Stoppen Sie den Debugger mit der Stopp-Schaltfläche in der Debug-Symbolleiste oder über ⇧F5 (Windows, Linux Shift+F5).
Erstellen eines Modells für Einkaufslistenelemente
Nachdem unsere FastAPI-App nun läuft, können wir unsere Einkaufslistenelemente mithilfe von Pydantic definieren, einer Bibliothek zur Datenvalidierung und -analyse, die sich nahtlos in FastAPI integriert. Pydantic ermöglicht es Ihnen, Datenmodelle mithilfe von Python-Klassen mit Typ-Hinweisen für die automatische Validierung und Analyse eingehender Daten (als "Payloads" bezeichnet) in API-Anfragen zu definieren.
Erstellen wir ein Modell für unsere Einkaufslistenelemente. Wir verwenden das Modell ItemPayload, um die Datenstruktur der Elemente zu definieren, die der Einkaufsliste hinzugefügt werden sollen. Dieses Modell hat drei Felder: item_id, item_name und quantity.
-
Erstellen Sie eine neue Python-Datei über Datei > Neue Datei... und wählen Sie dann Python-Datei.
-
Fügen Sie die folgenden Zeilen zur Datei hinzu und speichern Sie sie 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 Funktionen für Typ-Hinweise, die bei der Arbeit mit Pydantic-Modellen und FastAPI hilfreich sein können. Dies liegt daran, dass Pylance auf Pyright aufbaut, einem statischen Typ-Prüfer 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 Typ-Hinweise ausgiebig nutzt, um die Lesbarkeit des Codes und die Validierung zu verbessern, können wir die Typ-Prüfungsfunktionen von Pylance nutzen, um Fehler frühzeitig zu erkennen.
-
Öffnen Sie den Einstellungseditor (⌘, (Windows, Linux Ctrl+,)).
-
Suchen Sie nach "python type checking mode" und setzen Sie ihn auf
basicfür eine grundlegende Typ-Prüfung. Pylance zeigt nun Diagnosen und Warnungen an, um einfache typbezogene Fehler zu finden. Alternativ können Sie ihn aufstrictsetzen, um fortgeschrittenere Typ-Prüfungsregeln durchzusetzen.
-
Suchen Sie als Nächstes nach "Python inlay type hints" und aktivieren Sie Inlay-Hinweise für Variablentypen und Funktionsrückgabetypen.

Routen erstellen
Nun benötigen wir einen Ort zum Speichern der Einkaufslistenelemente. Der Einfachheit halber beginnen wir mit einem leeren Dictionary.
-
Importieren wir zuerst alle Pakete, die wir für das Beispiel benötigen. Öffnen Sie die Datei
main.pyund ersetzen Sie die erste Import-Zeile durch die folgenden.from fastapi import FastAPI, HTTPException from models import ItemPayload -
Fügen Sie nun direkt unter
app = FastAPI()die folgende Zeile hinzu.grocery_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 Funktionen innerhalb unserer Anwendung. Wenn ein Client, wie ein Webbrowser oder ein anderes Programm, eine Anfrage mit einer bestimmten URL an unsere Anwendung sendet, leitet FastAPI diese Anfrage basierend auf der URL an die entsprechende Funktion (auch Routen-Handler oder View-Funktion genannt) weiter, und diese Funktion verarbeitet die Anfrage und generiert eine Antwort.
Lassen Sie uns mit der Definition von Routen fortfahren, um einzelne Elemente hinzuzufügen und abzurufen sowie alle Elemente in der Einkaufsliste zurückzugeben.
-
Fügen Sie am Ende der Datei
main.pydie folgende Route hinzu.# Route to add an 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 im vorherigen Abschnitt Typ-Hinweise aktiviert haben, werden Sie möglicherweise feststellen, dass Pylance Inlay-Hinweise mit dem Funktionsrückgabetyp sowie den Typen für
item_idsunditem_idhinzufügt. Sie können optional auf jeden Vorschlag doppelklicken, um ihn in den Code einzufügen.
Überprüfen wir nun, ob diese Route wie erwartet funktioniert. Der schnellste Weg dazu ist die Verwendung des Debuggers von VS Code sowie 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 untersuchen. Diese Dokumentation wird dynamisch basierend auf den Metadaten und Typ-Hinweisen in der FastAPI-Anwendung generiert. -
Setzen Sie einen Haltepunkt neben die Anweisung
if quantity <= 0, indem Sie auf den linken Rand der Zeilennummer klicken (oder F9 drücken). 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 zwei in der App verfügbaren Endpunkten geben:
/itemsund Root (/).
-
Wählen Sie den Abwärtspfeil neben der Route
/items, um sie zu erweitern, und dann die Schaltfläche Try it out, die auf der rechten Seite erscheint.
-
Fügen Sie ein Einkaufslistenelement hinzu, indem Sie einen String in das Feld
item_nameund eine Zahl inquantityeingeben. Sie könnten zum Beispiel "apple" alsitem_nameund 2 alsquantityeingeben. -
Wählen Sie Execute.

-
Öffnen Sie VS Code erneut und bemerken Sie, dass der Debugger an dem zuvor gesetzten Haltepunkt gestoppt hat.

Auf der linken Seite werden alle zu diesem Zeitpunkt definierten lokalen und globalen Variablen im Variablenfenster unter der Ansicht Ausführen und Debuggen angezeigt. In unserem Beispiel ist
item_nameauf 'apple' undquantityauf 2 in der Variablenansicht für Lokale Variablen gesetzt, sowie ein leeresgrocery_list-Dictionary in der Ansicht für Globale Variablen.
Lassen Sie uns nun die Debug-Konsole von VS Code nutzen, um etwas zu experimentieren.
-
Wählen Sie die Anweisung
quantity <= 0aus, führen Sie einen Rechtsklick im Editor aus und wählen Sie In Debug-Konsole auswerten.
Dies öffnet die Debug-Konsole und führt den ausgewählten Ausdruck aus. Wie in unserem Beispiel erwartet, wird der Ausdruck als
Falseausgewertet.Die Debug-Konsole kann ein leistungsstarkes Werkzeug sein, um Ausdrücke schnell 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. Mehr über das Python-Debugging in VS Code erfahren Sie im Python-Tutorial.
Sie können nun die Ausführung des Codes fortsetzen, indem Sie in der Symbolleiste der Debug-Ansicht auf Weiter klicken oder F5 drücken.
Fügen wir abschließend die verbleibenden Routen für die Anwendung hinzu, damit wir alle Elemente oder bestimmte Elemente auflisten sowie aus unserer Einkaufsliste entfernen können. Sie können den Debugger laufen lassen, da er die Anwendung automatisch neu lädt, wenn Sie die Änderungen im nächsten Schritt speichern.
-
Ersetzen Sie den Inhalt in
main.pydurch den untenstehenden Code.from 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 laden.
Sie können nun die /docs-Seite erneut ö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, den wir in Schritt 4 hinzugefügt haben, durch Anklicken entfernen.
Herzlichen Glückwunsch! Sie haben jetzt eine funktionierende FastAPI-Anwendung mit Routen zum Hinzufügen, Auflisten und Löschen von Elementen aus einer Einkaufsliste.
Datenspeicherung einrichten
An diesem Punkt haben Sie bereits eine funktionierende Version der Anwendung mit der grundlegenden Funktionalität. Dieser Abschnitt führt Sie durch das Einrichten der Datenspeicherung für die Persistenz, aber Sie können ihn überspringen, wenn Sie mit dem bereits 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 persistent zu speichern, verwenden wir Redis, einen Open-Source-Speicher für In-Memory-Datenstrukturen. Aufgrund seiner Geschwindigkeit und Vielseitigkeit wird Redis häufig als Datenspeichersystem in einer Vielzahl von Anwendungen eingesetzt, einschließlich Webanwendungen, Echtzeit-Analysesystemen, Caching-Ebenen, diesem Tutorial und mehr.
Wenn Sie bereits in GitHub Codespaces mit unserer bestehenden Vorlage arbeiten, können Sie direkt zum Abschnitt Datenbank austauschen 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 für Anweisungen zur Einrichtung eines GitHub Codespaces auf den obigen Abschnitt beziehen.
Ansonsten, wenn Sie auf einem Linux- oder macOS-Computer arbeiten, können Sie Redis installieren, indem Sie den Anweisungen auf ihrer Website folgen, und dann zum Abschnitt Datenbank austauschen springen.
Einrichten 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 ordentlichen Container zusammenzufassen und so eine voll ausgestattete Entwicklungsumgebung zu schaffen. Die Erweiterung ermöglicht es Ihnen, Ihr Projekt in (oder eingebunden in) den Container in VS Code zu öffnen, wo Ihnen der volle Funktionsumfang zur Verfügung steht.
Stellen Sie für die folgenden Schritte sicher, dass die folgenden Anforderungen auf Ihrem Computer installiert sind:
Voraussetzungen
- Docker for Windows
- Dev Containers-Erweiterung
Dev Container-Konfiguration erstellen
-
Öffnen Sie die Befehlspalette und führen Sie Dev Containers: Add Dev Container Configuration Files… 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 Keep Defaults.
Wir können optional Features installieren, die in den Container aufgenommen werden sollen. Für dieses Tutorial installieren wir Redis Server, eine von der Community beigesteuerte Funktion, die Redis installiert und das richtige Dev-Container-Setup hinzufügt.

Dies erstellt einen
.devcontainer-Ordner in Ihrem Workspace mit einerdevcontainer.json-Datei. Lassen Sie uns einige Änderungen an dieser Datei vornehmen, damit das Container-Setup Schritte wie die Installation der von uns benötigten VS Code-Erweiterungen sowie der Projekt-Abhängigkeiten beinhaltet. -
Öffnen Sie die Datei
devcontainer.json. -
Fügen Sie ein "," nach dem Eintrag
"features" : { ... }hinzu, damit wir weitere Einstellungen zur Datei hinzufügen können.Als Nächstes fügen wir die notwendigen Befehle zur Installation der Abhängigkeiten zur Eigenschaft
postCreateCommandin derdevcontainer.json-Datei hinzu, damit unsere Anwendung bereit ist, sobald der Container eingerichtet ist. -
Suchen Sie den untenstehenden Inhalt und entfernen Sie den Kommentar (
//) aus 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 In Container erneut öffnen aus der Benachrichtigung, die in der unteren rechten Ecke angezeigt wird, oder führen Sie den Befehl Dev Containers: Reopen in Container aus der Befehlspalette aus.
Hinweis: Es kann je nach Internetgeschwindigkeit und Maschinenleistung mehrere Minuten dauern, den Container zu erstellen.
Sie können mehr über die Dev-Container-Konfiguration in der Dev Containers-Dokumentation erfahren.
Sobald dies erledigt ist, verfügen Sie über einen vollständig konfigurierten Linux-basierten Workspace mit installiertem Python 3 und Redis Server.
Sobald der Container eingerichtet ist, werden Sie eine Anzeige in der unteren linken Ecke von VS Code bemerken.

Hinweis: Überprüfen Sie, ob die Python- und Pylance-Erweiterungen erfolgreich im Container installiert wurden, indem Sie die Erweiterungsansicht (⇧⌘X (Windows, Linux Ctrl+Shift+X)) öffnen und danach suchen. Falls nicht, können Sie sie durch Ausführen von Install in Dev Container installieren.
Die Informationen zum ausgewählten Python-Interpreter sind in der Statusleiste unten rechts verfügbar und stimmen mit der in der devcontainer.json-Datei angegebenen Version überein.

Hinweis: Wenn Sie die Informationen zum Python-Interpreter nicht in der Statusleiste finden, können Sie auf die Python-Interpreter-Anzeige 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, mit dem nächsten Abschnitt fortzufahren, in dem wir die Datenspeicherung austauschen werden.
Datenbank austauschen
Wir haben ein Dictionary, das die Einkaufslistenelemente 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, in der Sie ein Element abrufen können, ohne dessen 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 Elemente anhand ihres Namens abzurufen und sie ihren IDs zuzuordnen. Zusätzlich erstellen wir weitere Hashes, um Elemente anhand ihrer ID abzurufen und sie ihren Namen und Mengen zuzuordnen. Jeder Element-Hash wird item_id:{item_id} genannt und hat zwei Felder: item_name und quantity.
Beginnen wir zunächst damit, das Dictionary durch ein Redis-Client-Objekt zu ersetzen, das eine Verbindung zu einem Redis-Server herstellt.
-
Ersetzen Sie in der Datei
main.pydasgrocery_list: dict[int, ItemPayload] = {}am Anfang der Datei durch die folgenden Zeilen.redis_client = redis.StrictRedis(host='0.0.0.0', port=6379, db=0, decode_responses=True)Pylance zeigt eine Fehlermeldung an, da Redis noch nicht importiert wurde.
-
Platzieren Sie den Cursor im Editor auf "redis" und klicken Sie auf die angezeigte Glühbirne (oder ⌘. (Windows, Linux Ctrl+.)). Wählen Sie dann Add 'import redis' aus.

Tipp: Sie können Pylance so einrichten, dass Importe automatisch hinzugefügt werden, indem Sie in den Einstellungen des Einstellungseditors (⌘, (Windows, Linux Ctrl+,)) nach der Einstellung Auto Import Completions suchen und diese aktivieren.
Wir haben nun ein Redis-Client-Objekt, das eine Verbindung zu einem Redis-Server auf dem lokalen Host (
host="0.0.0.0") herstellt und an Port 6379 (port=6379) lauscht. Der Parameterdbgibt die zu verwendende Redis-Datenbank an. Redis unterstützt mehrere Datenbanken, und in diesem Code verwenden wir Datenbank 0, die Standarddatenbank. Wir übergeben außerdemdecode_responses=True, damit die Antworten als Strings (anstatt als Bytes) dekodiert werden.Lassen Sie uns einige weitere Ersetzungen in der ersten Route
add_itemvornehmen. Anstatt alle Schlüssel aus dem Dictionary zu durchsuchen, um den bereitgestellten Elementnamen zu finden, können wir diese Information direkt aus einem Redis-Hash abrufen.Wir gehen davon aus, dass der Hash
item_name_to_idbereits existiert und Elementnamen ihren IDs zuordnet (keine Sorge, wir fügen diesen Code in Kürze hinzu!). Wir können dann die ID des Elementnamens, den wir in der Anfrage erhalten, abrufen, indem wir die Methodehgetvon Redis aufrufen, die die Element-ID zurückgibt, wenn der angeforderte Name bereits im Hash existiert, oderNone, wenn dies nicht der Fall 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 aufwirft. Dies liegt daran, dass die
hget-Methode entweder einenstroderNone(wenn das Element nicht existiert) zurückgibt. Die Zeilen unterhalb des Codes, die wir noch nicht ersetzt haben, erwarten jedoch, dassitem_idvom Typintist. Beheben wir diese Warnung, indem wir das Symbolitem_idumbenennen. -
Benennen Sie
item_idinitem_id_strum. -
Wenn Inlay-Hinweise aktiviert sind, sollte Pylance neben
item_id_streinen Variablentyp-Hinweis anzeigen. Sie können optional doppelklicken, um ihn zu akzeptieren.
-
Wenn das Element nicht existiert, ist
item_id_strNone. Wir können also jetzt die Zeile mit folgendem Inhalt löschen:if item_name in items_ids.keys():Und ersetzen Sie sie durch:
if item_id_str is not None:Nachdem wir die Element-ID nun als String haben, müssen wir sie in einen
intkonvertieren und die Menge für das Element aktualisieren. Derzeit ordnet unser Redis-Hash Elementnamen nur ihren IDs zu. Um auch Element-IDs ihren Namen und Mengen zuzuordnen, erstellen wir einen separaten Redis-Hash für jedes Element, wobei wir"item_id:{item_id}"als Hash-Namen verwenden, um das Abrufen nach ID zu erleichtern. Wir fügen auchitem_nameundquantityFelder für jeden dieser Hashes hinzu. -
Löschen Sie den Code innerhalb des
if-Blocks:item_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 Elements durch Aufrufen derhincrby-Methode von Redis zu erhöhen. Diese Methode erhöht den Wert des Feldes"quantity"um den in der Anfrage angegebenen Betrag (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 das Element nicht existiert, also wenn
item_id_strden WertNonehat. In diesem Fall generieren wir eine neueitem_id, erstellen einen neuen Redis-Hash für das Element und fügen dann den bereitgestellten Elementnamen und die Menge hinzu.Um eine neue
item_idzu generieren, verwenden wir dieincr-Methode von 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 ein neues Element erstellen, um sicherzustellen, dass sie alle eine eindeutige ID haben. -
Löschen Sie die Zeile mit folgendem 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 demitem_ids-Schlüssel ausgeführt wird, erstellt Redis den Schlüssel und ordnet ihn dem Wert1zu. Bei jedem anschließenden Aufruf wird der gespeicherte Wert um 1 erhöht.Nun fügen wir das Element zum Redis-Hash hinzu, indem wir die
hset-Methode verwenden und ein Mapping für die Felder (item_id,item_nameundquantity) sowie die Werte (die neu erstellte ID des Elements sowie dessen bereitgestellter Name und Menge) bereitstellen. -
Löschen Sie die Zeile mit folgendem Inhalt:
grocery_list[item_id] = ItemPayload( item_id=item_id, item_name=item_name, quantity=quantity )Und ersetzen Sie es 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 Elementnamen zuordnen, indem wir den Hash einstellen, auf den wir am Anfang verwiesen haben,
item_name_to_id. -
Fügen Sie diese Zeile am Ende der Route innerhalb des
else-Blocks hinzu:redis_client.hset("item_name_to_id", item_name, item_id) -
Löschen Sie die Zeile mit folgendem 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 durchzuführen. Andernfalls können Sie einfach den gesamten Inhalt der Datei durch die untenstehenden 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."} -
Starten Sie den Debugger erneut, um diese Anwendung zu testen, indem Sie mit der
/docs-Route interagieren. Sie können den Debugger stoppen, sobald Sie fertig sind.
Glückwunsch! Sie haben jetzt eine funktionierende FastAPI-Anwendung mit Routen zum Hinzufügen, Auflisten und Löschen von Elementen aus einer Einkaufsliste, und die Daten werden in einer Redis-Datenbank persistent gespeichert.
Optional: Datenbanklöschung einrichten
Nachdem die Daten nun von Redis persistent gespeichert werden, möchten Sie vielleicht ein Skript erstellen, um alle Testdaten zu löschen. Erstellen Sie dazu eine neue Datei namens flushdb.py mit folgendem 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 Run-Schaltfläche 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 erfolgen sollte, da dadurch alle Schlüssel in der aktuellen Datenbank gelöscht werden, was bei einer Durchführung in der Produktion zu Datenverlust führen könnte.
Optional: Eine GPT-Aktion erstellen
Mit GitHub Codespaces können Sie Ihre Anwendung für Testzwecke hosten, wenn Sie GPT Actions verwenden. GPT Actions sind Werkzeuge, die es ChatGPT ermöglichen, mit bestehenden APIs zu interagieren, um die Fähigkeiten von ChatGPT zu verbessern und es ihm zu ermöglichen, eine breite Palette von Aktionen auszuführen. Sie können der untenstehenden Live-Stream-Aufzeichnung folgen, um Ihr eigenes Einkaufslisten-Plugin für ChatGPT zu erstellen.
Hinweis: Alle persönlichen GitHub.com-Konten haben ein monatliches Kontingent für die kostenlose Nutzung von GitHub Codespaces, das im Free- oder Pro-Plan enthalten ist. Weitere Informationen finden Sie unter Informationen zur Abrechnung für GitHub Codespaces.
Nächste Schritte
Vielen Dank, dass Sie dieses Tutorial durchgearbeitet haben! Wir hoffen, Sie haben etwas Neues über FastAPI und die Verwendung mit VS Code gelernt.
Das vollständige Codeprojekt 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 Bereitstellen von Python-Apps in Azure App Service mit Docker-Containern.
Sie können auch diese anderen VS Code Python-Artikel durchsehen: