FastAPI ist ein schnelles und leichtgewichtiges Web-Framework für die Erstellung moderner Anwendungsprogrammierschnittstellen mit Python 3.6 und höher. In diesem Lernprogramm gehen wir die Grundlagen der Erstellung einer App mit FastAPI durch und du bekommst eine Ahnung davon, warum es zu einem der besten Open-Source-Frameworks des Jahres 2021 gekürt wurde.
Wenn du bereit bist, deine eigenen FastAPI-Apps zu entwickeln, musst du nicht lange suchen, um einen Ort zu finden, an dem du sie hosten kannst. Das Anwendungs- und Datenbank-Hosting von Kinsta bietet eine Plattform als Service, die stark auf Python basiert.
Lass uns zuerst die Grundlagen lernen.
Vorteile von FastAPI
Im Folgenden sind einige der Vorteile aufgeführt, die das FastAPI-Framework für ein Projekt mit sich bringt.
- Geschwindigkeit: Wie der Name schon sagt, ist FastAPI ein sehr schnelles Framework. Seine Geschwindigkeit ist vergleichbar mit der von Go und Node.js, die allgemein als eine der schnellsten Optionen für die Erstellung von APIs gelten.
- Einfach zu lernen und zu programmieren: FastAPI hat fast alles, was du für eine produktionsreife API brauchst, bereits bedacht. Als Entwickler, der FastAPI nutzt, musst du nicht alles von Grund auf neu programmieren. Mit nur wenigen Zeilen Code ist eine RESTful-API zum Einsatz bereit.
- Umfassende Dokumentation: FastAPI nutzt die OpenAPI-Dokumentationsstandards, so dass die Dokumentation dynamisch erstellt werden kann. Diese Dokumentation enthält detaillierte Informationen über die Endpunkte, Antworten, Parameter und Rückgabecodes von FastAPI.
- APIs mit weniger Fehlern: FastAPI unterstützt eine benutzerdefinierte Datenvalidierung, die es Entwicklern ermöglicht, APIs mit weniger Fehlern zu erstellen. Die Entwickler von FastAPI rühmen sich, dass das Framework zu weniger von Menschen verursachten Fehlern führt – bis zu 40 % weniger.
- Typ-Hinweise: Das Modul types wurde in Python 3.5 eingeführt. Es ermöglicht dir, die
type
einer Variablen zu deklarieren. Wenn der Typ einer Variablen deklariert ist, können IDEs bessere Unterstützung bieten und Fehler genauer vorhersagen.
Wie man mit FastAPI anfängt
Um diesem Tutorial zu folgen und mit FastAPI loszulegen, musst du zunächst ein paar Dinge tun.
Vergewissere dich, dass du einen Texteditor/IDE für Programmierer hast, wie z. B. Visual Studio Code. Andere Möglichkeiten sind Sublime Text und Espresso.
Es ist eine gängige Praxis, deine Python-Anwendungen und ihre Instanzen in virtuellen Umgebungen laufen zu lassen. Virtuelle Umgebungen ermöglichen es, verschiedene Paketsätze und Konfigurationen gleichzeitig auszuführen und Konflikte aufgrund von inkompatiblen Paketversionen zu vermeiden.
Um eine virtuelle Umgebung zu erstellen, öffne dein Terminal und führe diesen Befehl aus:
$ python3 -m venv env
Außerdem musst du die virtuelle Umgebung aktivieren. Der entsprechende Befehl hängt von deinem Betriebssystem und der verwendeten Shell ab. Hier sind einige Beispiele für die CLI-Aktivierung für verschiedene Umgebungen:
# On Unix or MacOS (bash shell):
/path/to/venv/bin/activate
# On Unix or MacOS (csh shell):
/path/to/venv/bin/activate.csh
# On Unix or MacOS (fish shell):
/path/to/venv/bin/activate.fish
# On Windows (command prompt):
pathtovenvScriptsactivate.bat
# On Windows (PowerShell):
pathtovenvScriptsActivate.ps1
(Einige Python-fähige IDEs können auch so konfiguriert werden, dass sie die aktuelle virtuelle Umgebung aktivieren.)
Installiere nun FastAPI:
$ pip3 install fastapi
FastAPI ist ein Framework zum Erstellen von APIs, aber um deine APIs zu testen, brauchst du einen lokalen Webserver. Uvicorn ist ein blitzschneller Asynchronous Server Gateway Interface (ASGI) Webserver für Python, der sich hervorragend für die Entwicklung eignet. Um Uvicorn zu installieren, führe diesen Befehl aus:
$ pip3 install "uvicorn[standard]"
Nach erfolgreicher Installation erstellst du eine Datei namens main.py im Arbeitsverzeichnis deines Projekts. Diese Datei wird der Einstiegspunkt für deine Anwendung sein.
Ein schnelles FastAPI-Beispiel
Du kannst deine FastAPI-Installation testen, indem du schnell einen Beispiel-Endpunkt einrichtest. Füge in deine Datei main.py den folgenden Code ein und speichere die Datei:
# main.py
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"greeting":"Hello world"}
Das obige Snippet erstellt einen einfachen FastAPI-Endpunkt. Nachfolgend findest du eine Zusammenfassung der Funktionen der einzelnen Zeilen:
from fastapi import FastAPI
: Die Funktionalität für deine API wird von der Python-Klasse FastAPI bereitgestellt.app = FastAPI()
: Damit wird eine FastAPI-Instanz erstellt.@app.get("/")
: Dies ist ein Python-Dekorator, der der FastAPI mitteilt, dass die darunter liegende Funktion für die Bearbeitung der Anfragen zuständig ist.@app.get("/")
: Dies ist ein Dekorator, der die Route angibt. Damit wird eineGET
Methode auf der Route der Website erstellt. Das Ergebnis wird dann von der gewickelten Funktion zurückgegeben.- Andere mögliche Operationen, die zur Kommunikation verwendet werden, sind
@app.post()
,@app.put()
,@app.delete()
,@app.options()
,@app.head()
,@app.patch()
und@app.trace()
.
Im Dateiverzeichnis führst du den folgenden Befehl in deinem Terminal aus, um den API-Server zu starten:
$ uvicorn main:app --reload
In diesem Befehl ist main
der Name deines Moduls. Das Objekt app
ist eine Instanz deiner Anwendung und wird in den ASGI-Server importiert. Mit dem Flag --reload
wird der Server angewiesen, automatisch neu zu laden, wenn du Änderungen vornimmst.
In deinem Terminal solltest du etwa folgendes sehen:
$ uvicorn main:app --reload
INFO: Will watch for changes in these directories: ['D:\WEB DEV\Eunit\Tests\fast-api']
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [26888] using WatchFiles
INFO: Started server process [14956]
INFO: Waiting for application startup.
INFO: Application startup complete.
Navigiere in deinem Browser zu http://localhost:8000
, um zu überprüfen, ob deine API funktioniert. Du solltest „Hallo“: „World“ als JSON-Objekt auf der Seite sehen. Dies zeigt, wie einfach es ist, mit FastAPI eine API zu erstellen. Du musstest nur eine Route definieren und dein Python-Wörterbuch zurückgeben, wie in Zeile sechs des obigen Schnipsels zu sehen ist.
Typ-Hinweise verwenden
Wenn du Python verwendest, bist du es gewohnt, Variablen mit grundlegenden Datentypen wie int
, str
, float
und bool
zu kennzeichnen. Ab Python Version 3.9 wurden jedoch erweiterte Datenstrukturen eingeführt. Damit kannst du mit Datenstrukturen wie dictionaries
, tuples
und lists
arbeiten. Mit den Typ-Hinweisen der FastAPI kannst du das Schema deiner Daten mithilfe von pydantischen Modellen strukturieren und dann die pydantischen Modelle für die Typ-Hinweise verwenden und von der Datenvalidierung profitieren, die bereitgestellt wird.
Im folgenden Beispiel wird die Verwendung von Type Hints in Python anhand eines einfachen Essenspreisrechners ( calculate_meal_fee
) demonstriert:
def calculate_meal_fee(beef_price: int, meal_price: int) -> int:
total_price: int = beef_price + meal_price
return total_price
print("Calculated meal fee", calculate_meal_fee(75, 19))
Beachte, dass Type Hints die Ausführung deines Codes nicht verändern.
Interaktive FastAPI-API-Dokumentation
FastAPI verwendet Swagger UI, um eine automatische interaktive API-Dokumentation bereitzustellen. Um darauf zuzugreifen, navigiere zu http://localhost:8000/docs
und du wirst einen Bildschirm mit all deinen Endpunkten, Methoden und Schemas sehen.
Diese automatische, browserbasierte API-Dokumentation wird von FastAPI bereitgestellt, und du musst nichts weiter tun, um sie zu nutzen.
Eine alternative browserbasierte API-Dokumentation, die ebenfalls von FastAPI bereitgestellt wird, ist Redoc. Um auf Redoc zuzugreifen, navigiere zu http://localhost:8000/redoc
. Dort wird dir eine Liste deiner Endpunkte, der Methoden und der jeweiligen Antworten angezeigt.
Einrichten von Routes in FastAPI
Mit dem Dekorator @app
kannst du die Methode der Route angeben, z. B. @app.get
oder @app.post
, und unterstützt werden GET
, POST
, PUT
und DELETE
, sowie die weniger verbreiteten Optionen HEAD
, PATCH
und TRACE
.
Deine App mit FastAPI erstellen
In diesem Tutorium lernst du, wie du eine CRUD-Anwendung mit FastAPI erstellst. Die Anwendung wird in der Lage sein:
- Einen Benutzer zu erstellen
- Den Datenbankeintrag eines Benutzers zu lesen
- Einen bestehenden Benutzer zu aktualisieren
- Einen bestimmten Benutzer zu löschen
Um diese CRUD-Operationen auszuführen, erstellst du Methoden, die die API-Endpunkte offenlegen. Das Ergebnis wird eine In-Memory-Datenbank sein, die eine Liste von Benutzern speichern kann.
Du verwendest die pydantic-Bibliothek, um Datenvalidierung und Einstellungsmanagement mit Python-Typ-Annotationen durchzuführen. Für diesen Lehrgang deklarierst du die Form deiner Daten als Klassen mit Attributen.
In diesem Tutorium wird die In-Memory-Datenbank verwendet. Dies dient dazu, dir einen schnellen Einstieg in die Nutzung von FastAPI für die Erstellung deiner APIs zu ermöglichen. Für die Produktion kannst du jedoch jede beliebige Datenbank verwenden, z. B. PostgreSQL, MySQL, SQLite oder sogar Oracle.
Erstellen der App
Du beginnst mit der Erstellung deines Benutzermodells. Das Benutzermodell wird die folgenden Attribute haben:
id
: Ein Universal Unique Identifier (UUID)first_name
: Der erste Name des Benutzerslast_name
: Der Nachname des Nutzersgender
: Das Geschlecht des Benutzersroles
das ist eine Liste mit den Rollenadmin
unduser
Erstelle zunächst eine neue Datei namens models.py in deinem Arbeitsverzeichnis und füge dann den folgenden Code in models.py ein, um dein Modell zu erstellen:
# models.py
from typing import List, Optional
from uuid import UUID, uuid4
from pydantic import BaseModel
from enum import Enum
from pydantic import BaseModel
class Gender(str, Enum):
male = "male"
female = "female"
class Role(str, Enum):
admin = "admin"
user = "user"
class User(BaseModel):
id: Optional[UUID] = uuid4()
first_name: str
last_name: str
gender: Gender
roles: List[Role]
Im obigen Code:
- Deine Klasse
User
erweitertBaseModel
, die dann vonpydantic
importiert wird. - Du hast die Attribute des Benutzers definiert, wie oben beschrieben.
Der nächste Schritt ist die Erstellung deiner Datenbank. Ersetze den Inhalt deiner Datei main.py durch den folgenden Code:
# main.py
from typing import List
from uuid import uuid4
from fastapi import FastAPI
from models import Gender, Role, User
app = FastAPI()
db: List[User] = [
User(
id=uuid4(),
first_name="John",
last_name="Doe",
gender=Gender.male,
roles=[Role.user],
),
User(
id=uuid4(),
first_name="Jane",
last_name="Doe",
gender=Gender.female,
roles=[Role.user],
),
User(
id=uuid4(),
first_name="James",
last_name="Gabriel",
gender=Gender.male,
roles=[Role.user],
),
User(
id=uuid4(),
first_name="Eunit",
last_name="Eunit",
gender=Gender.male,
roles=[Role.admin, Role.user],
),
]
In main.py:
- Du hast
db
mit einem Typ vonList
initialisiert und das ModellUser
übergeben - Du hast eine In-Memory-Datenbank mit vier Benutzern erstellt, jeder mit den erforderlichen Attributen wie
first_name
,last_name
,gender
undroles
. Dem BenutzerEunit
werden die Rollenadmin
unduser
zugewiesen, während den anderen drei Benutzern nur die Rolleuser
zugewiesen wird.
Datenbankeinträge lesen
Nachdem du deine In-Memory-Datenbank erfolgreich eingerichtet und mit Benutzern gefüllt hast, musst du nun einen Endpunkt einrichten, der eine Liste aller Benutzer zurückgibt. Hier kommt die FastAPI ins Spiel.
Füge in deiner Datei main.py den folgenden Code direkt unter deinem Endpunkt Hello World
ein:
# main.py
@app.get("/api/v1/users")
async def get_users():
return db
Dieser Code definiert den Endpunkt /api/v1/users
und erstellt eine asynchrone Funktion, get_users
, die den gesamten Inhalt der Datenbank, db
, zurückgibt.
Speichere deine Datei und du kannst deinen Benutzerendpunkt testen. Führe den folgenden Befehl in deinem Terminal aus, um den API-Server zu starten:
$ uvicorn main:app --reload
Navigiere in deinem Browser zu http://localhost:8000/api/v1/users
. Du solltest eine Liste aller deiner Nutzer/innen erhalten, wie unten zu sehen:
In diesem Stadium wird deine Datei main.py wie folgt aussehen:
# main.py
from typing import List
from uuid import uuid4
from fastapi import FastAPI
from models import Gender, Role, User
app = FastAPI()
db: List[User] = [
User(
id=uuid4(),
first_name="John",
last_name="Doe",
gender=Gender.male,
roles=[Role.user],
),
User(
id=uuid4(),
first_name="Jane",
last_name="Doe",
gender=Gender.female,
roles=[Role.user],
),
User(
id=uuid4(),
first_name="James",
last_name="Gabriel",
gender=Gender.male,
roles=[Role.user],
),
User(
id=uuid4(),
first_name="Eunit",
last_name="Eunit",
gender=Gender.male,
roles=[Role.admin, Role.user],
),
]
@app.get("/")
async def root():
return {"Hello": "World",}
@app.get("/api/v1/users")
async def get_users():
return db
Datenbankeinträge erstellen
Im nächsten Schritt musst du einen Endpunkt erstellen, um einen neuen Benutzer in deiner Datenbank anzulegen. Füge den folgenden Ausschnitt in deine main.py-Datei ein:
# main.py
@app.post("/api/v1/users")
async def create_user(user: User):
db.append(user)
return {"id": user.id}
In diesem Schnipsel hast du den Endpunkt für die Anmeldung eines neuen Benutzers definiert und den @app.post
Dekorator verwendet, um eine POST
Methode zu erstellen.
Außerdem hast du die Funktion create_user
erstellt, die user
des Modells User
akzeptiert, und das neu erstellte user
an die Datenbank db
angehängt (hinzugefügt). Zum Schluss gibt der Endpunkt ein JSON-Objekt mit den Daten des neu angelegten Benutzers id
zurück.
Du musst die automatische API-Dokumentation von FastAPI verwenden, um deinen Endpunkt zu testen, wie oben gezeigt. Das liegt daran, dass du mit dem Webbrowser keine Post-Anfrage stellen kannst. Navigiere zu http://localhost:8000/docs
, um mit der von SwaggerUI bereitgestellten Dokumentation zu testen.
Datenbankeinträge löschen
Da du eine CRUD-Anwendung entwickelst, muss deine Anwendung die Möglichkeit haben, eine bestimmte Ressource zu löschen. In diesem Tutorial wirst du einen Endpunkt zum Löschen eines Benutzers erstellen.
Füge den folgenden Code in deine Datei main.py ein:
# main.py
from uuid import UUID
from fastapi HTTPException
@app.delete("/api/v1/users/{id}")
async def delete_user(id: UUID):
for user in db:
if user.id == id:
db.remove(user)
return
raise HTTPException(
status_code=404, detail=f"Delete user failed, id {id} not found."
)
Hier siehst du Zeile für Zeile, wie der Code funktioniert:
@app.delete("/api/v1/users/{id}")
: Du hast den Delete-Endpunkt mit dem@app.delete()
Dekorator erstellt. Der Pfad ist immer noch/api/v1/users/{id}
, aber dann ruft er dieid
ab, die eine Pfadvariable ist, die der ID des Benutzers entspricht.async def delete_user(id: UUID):
: Erstellt die Funktiondelete_user
, die dieid
aus der URL abruft.for user in db:
: Damit wird die App angewiesen, eine Schleife durch die Benutzer in der Datenbank zu ziehen und zu prüfen, ob die übergebeneid
mit einem Benutzer in der Datenbank übereinstimmt.db.remove(user)
: Wenn dieid
mit einem Benutzer übereinstimmt, wird dieser gelöscht; andernfalls wird eineHTTPException
mit dem Statuscode 404 ausgegeben.
Datenbankeinträge aktualisieren
Du wirst einen Endpunkt erstellen, um die Daten eines Benutzers zu aktualisieren. Zu den Details, die aktualisiert werden können, gehören die folgenden Parameter: first_name
, last_name
, und roles
.
Füge in deiner Datei models.py den folgenden Code unter deinem Modell User
ein, also nach der Klasse User(BaseModel):
:
# models.py
class UpdateUser(BaseModel):
first_name: Optional[str]
last_name: Optional[str]
roles: Optional[List[Role]]
In diesem Schnipsel erweitert die Klasse UpdateUser
BaseModel
. Dann legst du fest, dass die aktualisierbaren Benutzerparameter, wie first_name
, last_name
und roles
, optional sind.
Jetzt erstellst du einen Endpunkt, um die Daten eines bestimmten Benutzers zu aktualisieren. Füge in deiner Datei main.py den folgenden Code nach dem Dekorator @app.delete
ein:
# main.py
@app.put("/api/v1/users/{id}")
async def update_user(user_update: UpdateUser, id: UUID):
for user in db:
if user.id == id:
if user_update.first_name is not None:
user.first_name = user_update.first_name
if user_update.last_name is not None:
user.last_name = user_update.last_name
if user_update.roles is not None:
user.roles = user_update.roles
return user.id
raise HTTPException(status_code=404, detail=f"Could not find user with id: {id}")
Im obigen Code hast du Folgendes getan:
- Erstellt
@app.put("/api/v1/users/{id}")
, den Aktualisierungsendpunkt. Er hat einen variablen Parameterid
, der der ID des Benutzers entspricht. - Erstelle eine Methode namens
update_user
, die die KlasseUpdateUser
undid
aufnimmt. - Überprüfe in einer
for
-Schleife, ob der Benutzer, der mit dem übergebenenid
verbunden ist, in der Datenbank vorhanden ist. - Überprüft, ob einer der Parameter des Benutzers
is not None
(nicht null) ist. Wenn ein Parameter, wiefirst_name
,last_name
oderroles
, nicht null ist, wird er aktualisiert. - Wenn der Vorgang erfolgreich war, wird die Benutzer-ID zurückgegeben.
- Wenn der Benutzer nicht gefunden wurde, wird eine
HTTPException
Ausnahme mit dem Statuscode 404 und der MeldungCould not find user with id: {id}
ausgelöst.
Um diesen Endpunkt zu testen, stelle sicher, dass dein Uvicorn-Server läuft. Wenn er nicht läuft, gib diesen Befehl ein:
uvicorn main:app --reload
Unten siehst du einen Screenshot des Tests.
Zusammenfassung
In diesem Tutorial hast du das FastAPI-Framework für Python kennengelernt und selbst gesehen, wie schnell du eine FastAPI-gestützte Anwendung zum Laufen bringen kannst. Du hast gelernt, wie du mit dem Framework CRUD-API-Endpunkte erstellst – also das Erstellen, Lesen, Aktualisieren und Löschen von Datenbankeinträgen.
Wenn du die Entwicklung deiner Webanwendung auf die nächste Stufe heben willst, solltest du dir die Plattform von Kinsta für Application Hosting und Database Hosting ansehen. Wie FastAPI ist auch sie einfach und leistungsstark.
Schreibe einen Kommentar