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.

De layout van een FastAPI project binnen een IDE.
Weergave van een basic FastAPI project binnen een IDE.

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 een GET 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.

Een FastAPI Hello World applicatie die wordt uitgevoerd in een webbrowser.
FastAPI Hello World applicatie in een webbrowser.

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.

Screenshot van de Swagger UI interface voor documentatie.
Swagger UI’s documentatie voor FastAPI.

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.

Screenshot van de Redoc interface voor documentatie.
Redoc’s documentatie voor FastAPI.

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.

Schema van databasetabelstructuur voor CRUD voorbeelden.
Databasetabelstructuur voor CRUD voorbeelden.

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 gebruiker
  • last_name: De achternaam van de gebruiker
  • gender: Het geslacht van de gebruiker
  • roles, wat een lijst is met admin en user 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 breidt BaseModel uit, die dan geïmporteerd wordt uit pydantic.
  • 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 type List, en gaf het model User door
  • Je maakte een in-memory database met vier gebruikers, elk met de vereiste attributen zoals first_name, last_name, gender, en roles. De gebruiker Eunit krijgt de rollen van admin en user, terwijl de andere drie gebruikers alleen de rol van user 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:

Screenshot van gebruikersgegevens geretourneerd door FastAPI GET verzoek.
Gebruikersgegevens opgehaald door FastAPI database read verzoek.

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.

Screenshot met parameters voor FastAPI POST verzoek.
Parameters voor een FastAPI POST verzoek.

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 het id op, wat een padvariabele is die overeenkomt met het id van de gebruiker.
  • async def delete_user(id: UUID):: Creëert de delete_user functie, die de id 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 doorgegeven id overeenkomt met een gebruiker in de database.
  • db.remove(user): Als de id overeenkomt met een gebruiker, wordt de gebruiker verwijderd; anders wordt een HTTPException met een statuscode van 404 opgehaald.
Screenshot met parameters voor FastAPI DELETE verzoek.
Parameters voor een FastAPI DELETE verzoek.

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 parameter id die overeenkomt met het id van de gebruiker.
  • Een methode aangemaakt genaamd update_user, die de classUpdateUser en id aanneemt.
  • Een loop for gebruikt om te controleren of de gebruiker geassocieerd met de doorgegeven id in de database zit.
  • Gecontroleerd of een van de parameters van de gebruiker is not None (niet null) is. Als een parameter, zoals first_name, last_name, of roles, 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 van Could 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.

Screenshot met parameters voor een UPDATE verzoek.
Parameters voor een FastAPI UPDATE verzoek.

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.

Emmanuel Uchenna

Emmanuel is een ervaren, gepassioneerde en enthousiaste software developer en technisch schrijver met aantoonbare jaren professionele ervaring. Hij richt zich op full-stack webontwikkeling. Hij spreekt vloeiend ReactJS, JavaScript, VueJS en NodeJS en is bekend met industriestandaard technologieën zoals Git, GitHub en TDD. Hij helpt particulieren, bedrijven en merken bij het bouwen van responsieve, toegankelijke, mooie en intuïtieve websites om hun online aanwezigheid te verbeteren. Hij is ook technisch schrijver voor verschillende websites en zijn eigen projecten.