FastAPI er en hurtig og letvægts webframework til opbygning af moderne programmeringsgrænseflader til applikationer ved hjælp af Python 3.6 og derover. I denne vejledning gennemgår vi det grundlæggende i at bygge en app med FastAPI, og du får en fornemmelse af, hvorfor det blev nomineret som en af de bedste open source-frameworks i 2021.
Når du er klar til at udvikle dine egne FastAPI-apps, skal du ikke lede længe for at finde et sted at hoste dem. Kinsta’s Applikation Hosting– og Database Hosting-tjenester giver en Platform as a Service, der er stærk på Python.
Lad os først lære det grundlæggende.
Fordele ved FastAPI
Nedenfor er nogle af de fordele, som FastAPI-framework bringer til et projekt.
- Hastighed: Som navnet antyder, er FastAPI en meget hurtig ramme. Dens hastighed kan sammenlignes med Go og Node.js, som generelt anses for at være blandt de hurtigste muligheder for at bygge API’er.
- Let at lære og kode: FastAPI har allerede regnet næsten alt det ud, du skal bruge for at lave en produktionsklar API. Som udvikler, der bruger FastAPI, behøver du ikke at kode alting fra bunden. Med kun få linjer kode kan du have et RESTful API klar til implementering.
- Omfattende dokumentation: FastAPI bruger OpenAPI-dokumentationsstandarderne, så dokumentation kan genereres dynamisk. Denne dokumentation indeholder detaljerede oplysninger om FastAPI’s endpoints, svar, parametre og returkoder.
- API’er med færre fejl: FastAPI understøtter brugerdefineret datavalidering, hvilket gør det muligt for udviklere at opbygge API’er med færre fejl. FastAPI’s udviklere praler af, at denne framework resulterer i færre menneskeskabte fejl – helt op til 40% færre.
- Typehints: Types-modulet blev indført i Python 3.5. Det giver dig mulighed for at deklarere
type
for en variabel. Når typen af en variabel er deklareret, kan IDE’er give bedre support og forudsige fejl mere præcist.
Sådan kommer du i gang med FastAPI
For at følge denne vejledning og komme i gang med FastAPI skal du først gøre et par ting.
Sørg for, at du har en teksteditor/IDE til programmører, f.eks. Visual Studio Code. Andre muligheder omfatter Sublime Text og Espresso.
Det er en almindelig praksis at have dine Python-apps og deres instanser kørende i virtuelle miljøer. Virtuelle miljøer gør det muligt at køre forskellige pakkesæt og konfigurationer samtidig og undgå konflikter på grund af inkompatible pakkeversioner.
For at oprette et virtuelt miljø skal du åbne din terminal og køre denne kommando:
$ python3 -m venv env
Du skal også aktivere det virtuelle miljø. Kommandoen til at gøre det vil variere afhængigt af det operativsystem og den shell, du bruger. Her er nogle eksempler på CLI-aktivering for en række miljøer:
# 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
(Nogle Python-aware IDE’er kan også konfigureres til at aktivere det aktuelle virtuelle miljø.)
Nu skal du installere FastAPI:
$ pip3 install fastapi
FastAPI er en ramme til opbygning af API’er, men for at teste dine API’er har du brug for en lokal webserver. Uvicorn er en lynhurtig Asynchronous Server Gateway Interface (ASGI) webserver til Python, som er fantastisk til udvikling. For at installere Uvicorn skal du køre denne kommando:
$ pip3 install "uvicorn[standard]"
Når installationen er lykkedes, skal du oprette en fil med navnet main.py i dit projekts arbejdskatalog. Denne fil vil være dit indgangspunkt for applikationen.
Et hurtigt FastAPI-eksempel
Du skal teste din FastAPI-installation ved hurtigt at opsætte et eksempel endpoint. Indsæt følgende kode i din main.py-fil, og gem derefter filen:
# main.py
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"greeting":"Hello world"}
Ovenstående uddrag skaber et grundlæggende FastAPI-endpoint. Nedenfor er en oversigt over, hvad hver linje gør:
from fastapi import FastAPI
: Funktionaliteten for din API leveres af FastAPI Python-klassen.app = FastAPI()
: Dette opretter en FastAPI-instans.@app.get("/")
: Dette er en python-dekorator, der angiver over for FastAPI, at funktionen under den er ansvarlig for håndteringen af anmodninger.@app.get("/")
: Dette er en dekorator, der angiver ruten. Dette opretter enGET
-metode på webstedets rute. Resultatet returneres derefter af den indpakkede funktion.- Andre mulige operationer, der bruges til at kommunikere, omfatter
@app.post()
,@app.put()
,@app.delete()
,@app.options()
,@app.head()
,@app.patch()
og@app.trace()
.
I filmappen skal du køre følgende kommando i din terminal for at starte API-serveren:
$ uvicorn main:app --reload
I denne kommando er main
navnet på dit modul. Objektet app
er en instans af dit program og importeres til ASGI-serveren. Flaget --reload
fortæller serveren, at den skal genindlæses automatisk, når du foretager ændringer.
Du bør se noget, der ligner dette i din terminal:
$ 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.
Naviger til http://localhost:8000
i din browser for at bekræfte, at din API fungerer. Du bør se “Hello”: “World” som et JSON-objekt på siden. Dette illustrerer, hvor nemt det er at oprette en API med FastAPI. Det eneste, du skulle gøre, var at definere en rute og returnere din Python-ordbog, som det ses på linje seks i ovenstående uddrag.
Brug af typehints
Hvis du bruger Python, er du vant til at anmærke variabler med grundlæggende datatyper som int
, str
, float
og bool
. Fra Python version 3.9 blev der imidlertid indført avancerede datastrukturer. Dette giver dig mulighed for at arbejde med datastrukturer som dictionaries
, tuples
og lists
. Med FastAPI’s typehints kan du strukturere skemaet for dine data ved hjælp af pydantiske modeller og derefter bruge de pydantiske modeller til at give typehints og drage fordel af den datavalidering, der er til rådighed.
I eksemplet nedenfor demonstreres brugen af typehints i Python med en simpel prisberegner til måltider, calculate_meal_fee
:
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))
Bemærk, at typehints ikke ændrer den måde, som din kode kører på.
FastAPI interaktiv API-dokumentation
FastAPI bruger Swagger UI til at levere automatisk interaktiv API-dokumentation. For at få adgang til den skal du navigere til http://localhost:8000/docs
, og du vil se en skærm med alle dine endpoints, metoder og skemaer.
Denne automatiske, browserbaserede API-dokumentation leveres af FastAPI, og du behøver ikke at gøre noget andet for at udnytte den.
En alternativ browserbaseret API-dokumentation, som også leveres af FastAPI, er Redoc. For at få adgang til Redoc skal du navigere til http://localhost:8000/redoc
, hvor du vil blive præsenteret for en liste over dine endpoints, metoderne og deres respektive svar.
Opsætning af ruter i FastAPI
Med dekoratoren @app
kan du angive rutens metode, f.eks. @app.get
eller @app.post
, og den understøtter GET
, POST
, PUT
og DELETE
, samt de mindre almindelige muligheder HEAD
, PATCH
og TRACE
.
Opbygning af din app med FastAPI
I denne vejledning vil du blive gennemgå opbygningen af en CRUD-applikation med FastAPI. Applikationen vil være i stand til at:
- Oprettelse af en bruger
- Læs en brugers databasepost
- Opdatering af en eksisterende bruger
- Sletning af en bestemt bruger
For at udføre disse CRUD-operationer vil du oprette metoder, der eksponerer API-slutpunkterne. Resultatet vil være en in-memory-database, der kan gemme en liste over brugere.
Du skal bruge pydantic-biblioteket til at udføre datavalidering og indstillinger ved hjælp af Python-typeannotationer. Med henblik på denne vejledning vil du erklære formen af dine data som klasser med attributter.
Denne tutorial vil bruge in-memory-databasen. Dette er for hurtigt at få dig i gang med at bruge FastAPI til at opbygge dine API’er. Til produktion kan du dog gøre brug af en hvilken som helst database efter eget valg, f.eks. PostgreSQL, MySQL, SQLite eller endda Oracle.
Opbygning af appen
Du begynder med at oprette din brugermodel. Brugermodellen vil have følgende attributter:
id
: En universel unik identifikator (UUID)first_name
: Brugerens fornavnlast_name
: Brugerens efternavngender
: Brugerens kønroles
, som er en liste medadmin
oguser
roller
Start med at oprette en ny fil ved navn models.py i din arbejdskatalog, og indsæt derefter følgende kode i models.py for at oprette din model:
# 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]
I ovenstående kode:
- Din
User
-klasse udviderBaseModel
, som derefter importeres frapydantic
. - Du har defineret brugerens attributter som beskrevet ovenfor.
Det næste skridt er at oprette din database. Udskift indholdet af din main.py-fil med følgende kode:
# 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],
),
]
I main.py:
- Du initialiserede
db
med en typeList
, og du indgavUser
-modellen - Du oprettede en in-memory-database med fire brugere, hver med de nødvendige attributter såsom
first_name
,last_name
,gender
ogroles
. BrugerenEunit
er tildelt rollerneadmin
oguser
, mens de tre andre brugere kun er tildelt rollenuser
.
Read Database Records
Du har oprettet din in-memory-database og udfyldt den med brugere, så det næste skridt er at oprette et slutpunkt, der returnerer en liste over alle brugere. Det er her, FastAPI kommer ind i billedet.
I din main.py-fil indsætter du følgende kode lige under dit Hello World
endpoint:
# main.py
@app.get("/api/v1/users")
async def get_users():
return db
Denne kode definerer endpointet /api/v1/users
og opretter en asynkron funktion, get_users
, som returnerer alt indhold i databasen, db
.
Gem din fil, og du kan teste dit brugerendpunkt. Kør følgende kommando i din terminal for at starte API-serveren:
$ uvicorn main:app --reload
Naviger til http://localhost:8000/api/v1/users
i din browser. Dette skulle give en liste over alle dine brugere, som vist nedenfor:
På dette tidspunkt vil din main.py-fil se således ud:
# 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
Opret Database Records
Det næste trin er at oprette et endpoint til at oprette en ny bruger i din database. Indsæt følgende uddrag i din main.py-fil:
# main.py
@app.post("/api/v1/users")
async def create_user(user: User):
db.append(user)
return {"id": user.id}
I dette uddrag har du defineret slutpunktet til at indsende en ny bruger og gjort brug af @app.post
decorator til at oprette en POST
-metode.
Du oprettede også funktionen create_user
, som accepterer user
i modellen User
, og du tilføjede (tilføjede) den nyligt oprettede user
til databasen, db
. Endelig returnerer endpoint et JSON-objekt med den nyoprettede brugers id
.
Du skal bruge den automatiske API-dokumentation fra FastAPI til at teste dit endpoint, som det fremgår ovenfor. Dette skyldes, at du ikke kan foretage en postanmodning ved hjælp af webbrowseren. Naviger til http://localhost:8000/docs
for at teste ved hjælp af den dokumentation, der leveres af SwaggerUI.
Sletning af databa records
Da du bygger en CRUD-app, skal din applikation have mulighed for at slette en bestemt ressource. I denne tutorial vil du oprette et endpoint til at slette en bruger.
Indsæt følgende kode i din main.py-fil:
# 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."
)
Her er en linje-for-linje opdeling af, hvordan denne kode fungerer:
@app.delete("/api/v1/users/{id}")
: Du har oprettet slette-endpoint ved hjælp af@app.delete()
-dekoratoren. Stien er stadig/api/v1/users/{id}
, men derefter hentesid
, som er en stivariabel, der svarer til brugerens id.async def delete_user(id: UUID):
: Opretter funktionendelete_user
, som henterid
fra URL’en.for user in db:
: Dette fortæller appen, at den skal gennemløbe brugerne i databasen og kontrollere, om den overførteid
passer til en bruger i databasen.db.remove(user)
: Hvisid
passer til en bruger, slettes brugeren, ellers sendes enHTTPException
med statuskode 404.
Opdatering af database records
Du skal oprette et endpoint til at opdatere en brugers oplysninger. De detaljer, der kan opdateres, omfatter følgende parametre: first_name
, , last_name
, og roles
.
I din models.py-fil indsætter du følgende kode under din User
-model, dvs. efter User(BaseModel):
-klassen:
# models.py
class UpdateUser(BaseModel):
first_name: Optional[str]
last_name: Optional[str]
roles: Optional[List[Role]]
I dette uddrag udvider klassen UpdateUser
BaseModel
. Derefter indstiller du de opdaterbare brugerparametre, f.eks. first_name
, last_name
og roles
, til at være valgfrie.
Nu opretter du et slutpunkt for at opdatere en bestemt brugers oplysninger. I din fil main.py indsætter du følgende kode efter @app.delete
decorator:
# 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}")
I ovenstående kode har du gjort følgende:
- Oprettede
@app.put("/api/v1/users/{id}")
, opdateringsslutpunktet. Det har en variabel parameterid
, der svarer til brugerens id. - Der blev oprettet en metode kaldet
update_user
, som indeholder klassenUpdateUser
ogid
. - Brugte et
for
loop til at kontrollere, om den bruger, der er knyttet til den overgivneid
, findes i databasen. - Kontrolleret, om nogen af brugerens parametre er
is not None
(ikke nul). Hvis en parameter, f.eks.first_name
,last_name
ellerroles
, ikke er nul, opdateres den. - Hvis operationen er vellykket, returneres bruger-id’et.
- Hvis brugeren ikke kunne findes, opstår der en
HTTPException
undtagelse med statuskode 404 og en meddelelseCould not find user with id: {id}
.
For at teste dette endpoint skal du sikre dig, at din Uvicorn-server kører. Hvis den ikke kører, skal du indtaste denne kommando:
uvicorn main:app --reload
Nedenfor er et skærmbillede af testen.
Opsummering
I denne tutorial har du lært om FastAPI-rammen til Python og har selv set, hvor hurtigt du kan få en FastAPI-drevet applikation op at køre. Du har lært at opbygge CRUD API endpoints ved hjælp af dette framework – oprettelse, læsning, opdatering og sletning af database records.
Hvis du nu ønsker at tage din webapp-udvikling til det næste niveau, skal du huske at tjekke Kinstas platform til applikationshosting og databasehosting. Ligesom FastAPI er den kraftfuldt enkel.
Skriv et svar