FastAPI is een snel en lichtgewicht webframework voor het bouwen van moderne applicatieprogrammeer-interfaces met Python 3.6 en hoger. In deze tutorial lopen we door de basis van het bouwen van een app met FastAPI, en krijg je een idee waarom het is genomineerd als een van de beste open-source frameworks van 2021.
Als je eenmaal klaar bent om je eigen FastAPI apps te ontwikkelen, hoef je niet ver te zoeken naar een plek om ze te hosten. Kinsta’s Applicatie Hosting en Database Hosting diensten bieden een Platform as a Service dat enorm goed werkt met Python.
Maar eerst is het tijd om de basics te leren.
Voordelen van FastAPI
Hieronder staan enkele van de voordelen die het FastAPI framework aan een project toevoegt.
- Snelheid: Zoals de naam al aangeeft, is FastAPI een zeer snel framework. Zijn snelheid is vergelijkbaar met die van Go en Node.js, die algemeen beschouwd worden als de snelste opties voor het bouwen van API’s.
- Gemakkelijk te leren en te coderen: FastAPI heeft bijna alles wat je nodig hebt om een productieklare API te maken al bedacht. Als developer die FastAPI gebruikt, hoef je niet alles vanaf nul te coderen. Met slechts een paar regels code kun je een RESTful API klaar hebben voor deployment.
- Uitgebreide documentatie: FastAPI maakt gebruik van de OpenAPI documentatiestandaarden, zodat documentatie dynamisch kan worden gegenereerd. Deze documentatie geeft gedetailleerde informatie over FastAPI’s endpoints, responses, parameters en returncodes.
- API’s met minder bugs: FastAPI ondersteunt aangepaste gegevensvalidatie, waardoor developers API’s kunnen bouwen met minder bugs. De developers van FastAPI scheppen op dat het framework resulteert in minder door mensen veroorzaakte bugs – wel 40% minder.
- Type hints: De types module werd geïntroduceerd in Python 3.5. Hiermee kun je de
type
van een variabele declaren. Wanneer het type van een variabele wordt gedeclared, kunnen IDE’s betere ondersteuning bieden en fouten nauwkeuriger voorspellen.
Zo begin je met FastAPI
Om deze tutorial te volgen en met FastAPI aan de slag te gaan, moet je eerst een paar dingen doen.
Zorg ervoor dat je een teksteditor/IDE voor programmeurs hebt, zoals Visual Studio Code. Andere opties zijn Sublime Text en Espresso.
Het is gebruikelijk om je Python apps en hun instanties in virtuele omgevingen te laten draaien. Virtuele omgevingen laten verschillende pakketsets en configuraties tegelijkertijd draaien, en voorkomen conflicten door incompatibele pakketversies.
Om een virtuele omgeving aan te maken, open je terminal en voer je dit commando uit:
$ python3 -m venv env
Ook moet je de virtuele omgeving activeren. Het commando om dat te doen varieert afhankelijk van het besturingssysteem en de shell die je gebruikt. Hier zijn enkele CLI activeringsvoorbeelden voor een aantal omgevingen:
# Op Unix of MacOS (bash shell):
/path/to/venv/bin/activate
# Op Unix of MacOS (csh shell):
/path/to/venv/bin/activate.csh
# Op Unix of MacOS (fish shell):
/path/to/venv/bin/activate.fish
# Op Windows (command prompt):
pathtovenvScriptsactivate.bat
# Op Windows (PowerShell):
pathtovenvScriptsActivate.ps1
(Sommige Python bewuste IDE’s kunnen ook geconfigureerd worden om de huidige virtuele omgeving te activeren.)
Installeer nu FastAPI:
$ pip3 install fastapi
FastAPI is een framework voor het bouwen van API’s, maar om je API’s te testen heb je een lokale webserver nodig. Uvicorn is een bliksemsnelle Asynchronous Server Gateway Interface (ASGI) webserver voor Python die geweldig is voor development. Om Uvicorn te installeren voer je dit commando uit:
$ pip3 install "uvicorn[standard]"
Na een succesvolle installatie maak je een bestand aan met de naam main.py in de werkdirectory van je project. Dit bestand wordt het beginpunt van je applicatie.
Een kort FastAPI voorbeeld
Je gaat je FastAPI installatie testen door snel een voorbeeld eindpunt op te zetten. Plak in je main.py bestand de volgende code en sla het bestand op:
# main.py
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"greeting":"Hello world"}
Bovenstaand codefragment maakt een basic FastAPI endpoint aan. Hieronder staat een samenvatting van wat elke regel doet:
from fastapi import FastAPI
: De functionaliteit voor je API wordt geleverd door de FastAPI Python class.app = FastAPI()
: Hiermee wordt een FastAPI instantie gecreëerd.@app.get("/")
: Dit is een python decorator die FastAPI specificeert dat de functie eronder verantwoordelijk is voor de verzoekafhandeling.@app.get("/")
: Dit is een decorator die de route specificeert. Dit creëert eenGET
methode op de route van de site. Het resultaat wordt dan teruggegeven door de ingepakte functie.- Andere mogelijke operaties die gebruikt worden om te communiceren zijn
@app.post()
,@app.put()
,@app.delete()
,@app.options()
,@app.head()
,@app.patch()
, en@app.trace()
.
Voer in de files map het volgende commando in je terminal uit om de API server te starten:
$ uvicorn main:app --reload
In dit commando is main
de naam van je module. Het app
object is een instantie van je applicatie, en wordt geïmporteerd in de ASGI server. De --reload
flag vertelt de server om automatisch te herladen als je wijzigingen aanbrengt.
Je zou zoiets als dit in je terminal moeten zien:
$ 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.
Navigeer in je browser naar http://localhost:8000
om te bevestigen dat je API werkt. Je zou “Hello”: “World” als JSON object op de pagina moeten zien. Dit illustreert hoe eenvoudig het is om een API te maken met FastAPI. Je hoefde alleen maar een route te definiëren en je Python dictionary terug te geven, zoals te zien is op regel zes van het fargment hierboven.
Type hints gebruiken
Als je Python gebruikt, ben je gewend om variabelen te annoteren met basisgegevenstypes als int
, str
, float
, en bool
. Vanaf Python versie 3.9 zijn echter geavanceerde gegevensstructuren geïntroduceerd. Hierdoor kun je werken met gegevensstructuren als dictionaries
, tuples
, en lists
. Met de typehints van FastAPI kun je het schema van je gegevens structureren met behulp van pydantische modellen en vervolgens de pydantische modellen gebruiken om typehints te maken en te profiteren van de geboden datavalidatie.
In het onderstaande voorbeeld wordt het gebruik van typehints in Python gedemonstreerd met een eenvoudige maaltijdprijscalculator, 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))
Merk op dat type hints niet veranderen hoe je code draait.
Interactieve API documentatie van FastAPI
FastAPI gebruikt Swagger UI om automatisch interactieve API documentatie te bieden. Om toegang te krijgen, navigeer je naar http://localhost:8000/docs
en je ziet een scherm met al je endpoints, methoden en schema’s.
Deze automatische, browser gebaseerde API documentatie wordt geleverd door FastAPI, en je hoeft verder niets te doen om ervan te profiteren.
Een alternatieve browser gebaseerde API documentatie, ook geleverd door FastAPI, is Redoc. Om Redoc te openen, navigeer je naar http://localhost:8000/redoc
, waar je een lijst krijgt van je endpoints, de methoden en hun respectievelijke antwoorden.
Routes instellen in FastAPI
Met de decorator @app
kun je de methode van de route specificeren, zoals @app.get
of @app.post
, en hij ondersteunt GET
, POST
, PUT
, en DELETE
, evenals de minder gebruikelijke opties, HEAD
, PATCH
, en TRACE
.
Je app bouwen met FastAPI
In deze tutorial wordt het bouwen van een CRUD applicatie met FastAPI behandeld. De applicatie zal in staat zijn om:
- Een gebruiker aan te maken
- Een databaserecord van een gebruiker te lezen
- Een bestaande gebruiker te bijwerken
- Een bepaalde gebruiker te verwijderen
Om deze CRUD operaties uit te voeren, zul je methoden creëren die de API endpoints blootstellen. Het resultaat zal een in-memory database zijn die een lijst van gebruikers kan opslaan.
Je zult de pydantic bibliotheek gebruiken om gegevensvalidatie en instellingenbeheer uit te voeren met behulp van Python type annotaties. Voor deze tutorial declare je de vorm van je gegevens als classes met attributen.
Deze tutorial gebruikt de in-memory database. Dit is om je snel op weg te helpen met het gebruik van FastAPI om je API’s te bouwen. Voor productie kun je echter elke database naar keuze gebruiken, zoals PostgreSQL, MySQL, SQLite of zelfs Oracle.
De app bouwen
Je begint met het maken van een gebruikersmodel. Het gebruikersmodel heeft de volgende attributen:
id
: Een Universal Unique Identifier (UUID)first_name
: De voornaam van de gebruikerlast_name
: De achternaam van de gebruikergender
: Het geslacht van de gebruikerroles
, wat een lijst is metadmin
enuser
rollen
Begin met het maken van een nieuw bestand met de naam models.py in je werkdirectory, en plak dan de volgende code in models.py om je model te maken:
# 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]
In de bovenstaande code:
- Je
User
class breidtBaseModel
uit, die dan geïmporteerd wordt uitpydantic
. - Je hebt de attributen van de gebruiker gedefinieerd, zoals hierboven besproken.
De volgende stap is het aanmaken van je database. Vervang de inhoud van je main.py bestand door de volgende 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:
- Je initialiseerde
db
met een typeList
, en gaf het modelUser
door - Je maakte een in-memory database met vier gebruikers, elk met de vereiste attributen zoals
first_name
,last_name
,gender
, enroles
. De gebruikerEunit
krijgt de rollen vanadmin
enuser
, terwijl de andere drie gebruikers alleen de rol vanuser
toegewezen krijgen.
Databaserecords lezen
Je hebt met succes je in-memory database opgezet en gevuld met gebruikers, dus de volgende stap is het opzetten van een eindpunt dat een lijst van alle gebruikers teruggeeft. Hier komt FastAPI om de hoek kijken.
Plak in je main.py bestand de volgende code net onder je Hello World
eindpunt:
# main.py
@app.get("/api/v1/users")
async def get_users():
return db
Deze code definieert het endpoint /api/v1/users
, en maakt een async functie, get_users
, die alle inhoud van de database retourneert, db
.
Sla je bestand op, en je kunt je gebruikersendpoint testen. Voer het volgende commando uit in je terminal om de API server te starten:
$ uvicorn main:app --reload
Navigeer in je browser naar http://localhost:8000/api/v1/users
. Dit zou een lijst van al je gebruikers moeten opleveren, zoals hieronder te zien is:
In dit stadium ziet je main.py bestand er als volgt uit:
# 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
Databaserecords aanmaken
De volgende stap is het maken van een endpoint om een nieuwe gebruiker in je database aan te maken. Plak het volgende fragment in je main.py bestand:
# main.py
@app.post("/api/v1/users")
async def create_user(user: User):
db.append(user)
return {"id": user.id}
In dit fragment heb je het endpoint gedefinieerd om een nieuwe gebruiker in te dienen en gebruik gemaakt van de @app.post
decorator om een POST
methode te maken.
Je maakte ook de functie create_user
, die user
van het User
model accepteert, en voegde de nieuw aangemaakte user
toe aan de database, db
. Tenslotte retourneert het eindpunt een JSON object van de nieuw aangemaakte gebruiker id
.
Je zult de automatische API documentatie van FastAPI moeten gebruiken om je endpoint te testen, zoals hierboven te zien is. Dit komt omdat je geen post verzoek kunt doen met de webbrowser. Navigeer naar http://localhost:8000/docs
om te testen met behulp van de door SwaggerUI geleverde documentatie.
Databasercords verwijderen
Omdat je een CRUD app bouwt, moet je applicatie de mogelijkheid hebben om een gespecificeerde resource te verwijderen. Voor deze tutorial maak je een endpoint om een gebruiker te verwijderen.
Plak de volgende code in je main.py bestand:
# 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 is een regel-voor-regel uitleg van hoe die code werkt:
@app.delete("/api/v1/users/{id}")
: Je hebt het delete endpoint gemaakt met de@app.delete()
decorator. Het pad is nog steeds/api/v1/users/{id}
, maar dan haalt hetid
op, wat een padvariabele is die overeenkomt met het id van de gebruiker.async def delete_user(id: UUID):
: Creëert dedelete_user
functie, die deid
ophaalt uit de URL.for user in db:
: Dit vertelt de app om door de gebruikers in de database te lopen, en te controleren of de doorgegevenid
overeenkomt met een gebruiker in de database.db.remove(user)
: Als deid
overeenkomt met een gebruiker, wordt de gebruiker verwijderd; anders wordt eenHTTPException
met een statuscode van 404 opgehaald.
Databaserecords bijwerken
Je gaat een endpoint maken om de gegevens van een gebruiker bij te werken. De details die kunnen worden bijgewerkt zijn de volgende parameters: first_name
, last_name
, en roles
.
Plak in je models.py bestand de volgende code onder je User
model, dat is na de User(BaseModel):
klasse:
# models.py
class UpdateUser(BaseModel):
first_name: Optional[str]
last_name: Optional[str]
roles: Optional[List[Role]]
In dit fragment is de class UpdateUser
een uitbreiding van BaseModel
. Je stelt dan de updatebare gebruikersparameters, zoals first_name
, last_name
, en roles
, in als optioneel.
Nu maak je een endpoint om de gegevens van een bepaalde gebruiker bij te werken. Plak in je main.py bestand de volgende code na @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}")
In bovenstaande code heb je het volgende gedaan:
@app.put("/api/v1/users/{id}")
aangemaakt, het update endpoint. Het heeft een variabele parameterid
die overeenkomt met het id van de gebruiker.- Een methode aangemaakt genaamd
update_user
, die de classUpdateUser
enid
aanneemt. - Een loop
for
gebruikt om te controleren of de gebruiker geassocieerd met de doorgegevenid
in de database zit. - Gecontroleerd of een van de parameters van de gebruiker
is not None
(niet null) is. Als een parameter, zoalsfirst_name
,last_name
, ofroles
, niet null is, dan wordt hij bijgewerkt. - Als de operatie succesvol is, wordt het gebruikers-id teruggegeven.
- Als de gebruiker niet werd gelokaliseerd, wordt een
HTTPException
uitzondering met een statuscode van 404 en een bericht vanCould not find user with id: {id}
opgeworpen.
Om dit endpoint te testen, zorg je ervoor dat je Uvicorn server draait. Als hij niet draait, voer dan dit commando in:
uvicorn main:app --reload
Hieronder staat een screenshot van de test.
Samenvatting
In deze tutorial heb je geleerd over het FastAPI framework voor Python en zelf gezien hoe snel je een door FastAPI aangedreven applicatie aan de praat kunt krijgen. Je hebt geleerd hoe je CRUD API endpoints kunt bouwen met het framework – databaserecords maken, lezen, bijwerken en verwijderen.
Als je nu je webappontwikkeling naar het volgende niveau wilt brengen, kijk dan eens naar Kinsta’s platform voor Applicatie Hosting en Database Hosting. Net als FastAPI zijn ze enorm krachtig en eenvoudig in gebruik.
Laat een reactie achter