FastApi
Das Framework FastApi zecihnet sich durch eine herrvorragende Performance und die Unterstützung der EndPoint-Entwicklung aus. FastAPI baut auf dem Starlette-Webserver auf und enthält Funktionen, die das Erstellen von Webanwendungen erleichtern, z. B. automatische Datenvalidierung, Fehlerbehandlung und interaktive API-Dokumente.
Zahlreiche Erweiterungen wie:
- Pydantic
- SqlAlchemy
- SqlModel
- MongoEngine, Beanie
- ...
sind verfügbar.
Installation
pip install fastapi
Zusätzlich sollte der ASGI-Server uvicorn
installiert werden:
pip install uvicorn
Entwicklung einer App
Erstes Beispiel
Der nachfolgende Code definiert die Funktion async def root():
, die mit dem Dekorator @app.get("/")
ausgezeichnet ist:
- Methode GET
- Endpoint-Pfad ROOT
first.py
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
Um das Skript auszuführen, muss es mit fastapi aufgerufen werden:
py -m fastapi dev first.py
Ausgabe
INFO Using path first.py
INFO Resolved absolute path p:\py\first.py
INFO Searching for package file structure from directories with __init__.py files
INFO Importing from p:\py
╭─ Python module file ─╮
│ │
│ 🐍 first.py │
│ │
╰──────────────────────╯
INFO Importing module first
INFO Found importable FastAPI app
╭─ Importable FastAPI app ─╮
│ │
│ from first import app │
│ │
╰──────────────────────────╯
INFO Using import string first:app
╭────────── FastAPI CLI - Development mode ───────────╮
│ │
│ Serving at: http://127.0.0.1:8000 │
│ │
│ API docs: http://127.0.0.1:8000/docs │
│ │
│ Running in development mode, for production use: │
│ │
│ fastapi run │
│ │
╰─────────────────────────────────────────────────────╯
INFO: Will watch for changes in these directories: ['P:\\docs\\_frameworks\\_fastapi\\py']
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [27872] using WatchFiles
INFO: Started server process [2020]
INFO: Waiting for application startup.
INFO: Application startup complete.
Die App kann aber auch explizit mit dem uvicorn-Werbserver gestartet werden:
uvicorn first:app --host 0.0.0.0 --port 80
Ausgabe
INFO: Started server process [30840]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:80 (Press CTRL+C to quit)
Dieser Aufruf lässt sich auch mit VS Code in einer launch.json` konfigurieren:
{
"name": "Python-Debugger: FastAPI",
"type": "debugpy",
"request": "launch",
"module": "uvicorn",
"args": [
"first:app",
"--reload"
],
"jinja": true
}
uvicorn
Damit das Skript beim Start automatisch den Webserver startet, muss es wie folgt erweitert werden:
first_uvi.py
from fastapi import FastAPI
import uvicorn
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
if __name__ == "__main__":
uvicorn.run(app, host="127.0.0.1", port=8001)
Ausgabe
INFO: Started server process [35812]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:8001 (Press CTRL+C to quit)
Browser-Client
Diese erste App stellt den GET-Endpoint \
zur Verfügung. Ein Aufruf im Browser stößt diesen Request an und die App liefert durch Aufruf der Funktion root()
den Response aus:
Request und Response im Webbrowser
docs
Die FastApi-App kann mit dem Endpoint /docs
die komplette API-Schnittstelle, die der Spezifikation von "openapi" genügt zeigen:
Docs-Seite der Api-Schnitstellen
Docs-Seite der Api-Schnittstellen - Ausgeführter Request
Jinja2-Engine
Wenn gerenderte Html-Seiten über den Endpoint ausgeliefert werden sollen, dann bietet sich der Einsatz der Jinja2-Engine an. Die Grundlagen sind in Kapitel beschrieben.
Das folgende Skript realsiert die gleiche Aufgabe wie das Skript mit dem Flask-Framework:
site_html_1.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
Formular-Handling
Für die POST-Methode wird - anders als in Flask einen separate Funktion definiert, die mit dem Decorator @app.post
ausgezeichnet wird. Hier wird analog zum Formular-Beispiel mit Flask gezeigt:
site_html_form.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
|
Hier wird in der POST-Methode jedes Formularelement zusätzlich mit "Annotated" (1) verbunden.
- Python-Annotationen (auch bekannt als Typ-Hinweise oder Type Hints) sind eine Möglichkeit, den Datentyp von Variablen und Funktionsparametern in Python anzugeben.
Formular-Handling mit Pydantic
Um die Übergabe der Daten zu zusätzlichen Testroutinen zu versehen und die eigentliche Daten-Rückgabe aus dem Formular zu vereinfachen, kann die Datenklasse pydantic.Basemodel
eingesetzt werden (siehe Pydantic)
In einem ersten Schritt wird das Datenmodel, das später im Formular bearbeitet werden soll, definiert:
class User(BaseModel):
username: str # (1)
password : str
- lässt sich mit
Field(meta={"key1":"val1","key2":"val2", ... })
beliebig erweitern (siehe TIP)
Die POST-Methode kann nun direkt das Datenobjekt User(Basemodel)
übernehmen:
@app.post("/login/")
async def login(data: Annotated[User, Form()]):
print(data.model_json_schema()) #(1)
return data
- An dieser Stelle kann das gesamte Modell-Schema als json-Objekt ausgegeben werden.
Das gesamte Skript:
site_html_formdata.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
|
Tip
In einem nächsten Schritt könnte mit Hilfe von Jinja2-Makros auf der Basis des json-Modells das Formular automatisch aus dem Template generiert werden!! Dazu erweitert man im pydantic-Modell jedes Element mit Hilfe von pydantic.Field().
pydantic-Modelle lassen sich auch dynamisch erzeugen!