FastAPI est un framework web moderne et performant conçu pour bâtir des API avec Python 3.6+ en s'appuyant sur les annotations de type stanadrds. Ses principaux atouts résident dans sa rapidité d'exécution (comparable à Go ou Node.js), une réduction significative des erreurs de développement grâce à Pydantic et une génération automatique de documentation interactive.
Installation de l'environnement
Pour commencer, vous devez installer le framework ainsi qu'un serveur ASGI comme Uvicorn pour l'exécution.
pip install fastapi
pip install "uvicorn[standard]"
Démarrage rapide : Hello World
Créez un fichier nommé main.py pour définir votre première application.
from fastapi import FastAPI
# Initialisation de l'instance
api_app = FastAPI()
@api_app.get("/statut")
async def verifier_statut():
return {"etat": "operationnel", "version": "1.0.0"}
Lancement du serveur
Exécutez la commande suivante dans votre terminal pour démarrer le service avec le rechargement automatique :
uvicorn main:api_app --reload
Une fois lancé, l'API est accessible sur http://127.0.0.1:8000/statut. FastAPI génère nativement deux types de documentation :
- Swagger UI :
/docs(interactif) - ReDoc :
/redoc(statique)
Gestion des paramètres de chemin (Path Parameters)
Les paramètres de chemin permettent de capturer des variables directement dans l'URL.
@api_app.get("/utilisateurs/{user_id}")
async def lire_utilisateur(user_id: int):
return {"id_recherche": user_id}
L'utilisation des types Python (comme int) permet à FastAPI de valider automatiquement les données entrantes.
Utilisation des énumérations
Pour restreindre les valeurs possibles d'un paramètre, utilisez la classe Enum.
from enum import Enum
class ModeleVehicule(str, Enum):
berline = "berline"
suv = "suv"
utilitaire = "utilitaire"
@api_app.get("/vehicules/{type_modele}")
async def obtenir_vehicule(type_modele: ModeleVehicule):
if type_modele == ModeleVehicule.berline:
return {"description": "Voiture confortable pour la route"}
return {"description": f"Type sélectionné : {type_modele.value}"}
Paramètres de requête (Query Parameters)
Les paramètres qui ne font pas partie du chemin de l'URL sont interprétés comme des paramètres de requête (ex: ?offset=0&limit=10).
from typing import Optional
@api_app.get("/articles/")
async def lister_articles(debut: int = 0, quantite: Optional[int] = 20):
return {"index_depart": debut, "taille_page": quantite}
Corps de requête avec Pydantic
Pour recevoir des données complexes en JSON, on définit des modèles via Pydantic.
from pydantic import BaseModel
class Produit(BaseModel):
nom: str
description: Optional[str] = None
prix: float
remise: Optional[float] = 0.0
@api_app.post("/creer-produit/")
async def enregistrer_produit(item: Produit):
total = item.prix - item.remise
return {"produit": item.nom, "prix_final": total}
Combinaison de paramètres
Il est possible de mélanger paramètres de chemin, de requête et corps de texte dans une seule fonction.
@api_app.put("/maj-stock/{code_id}")
async def modifier_stock(code_id: int, produit: Produit, urgence: bool = False):
return {"id": code_id, "donnees": produit, "prioritaire": urgence}
Validations avancées
FastAPI propose les classes Query, Path et Body pour ajouter des contraintes de validation.
Validation des requêtes (Query)
from fastapi import Query
@api_app.get("/recherche/")
async def rechercher(terme: str = Query(..., min_length=3, max_length=15)):
return {"resultats": f"Recherche pour {terme}"}
Validation des chemins (Path)
from fastapi import Path
@api_app.get("/archive/{annee}")
async def consulter_archive(annee: int = Path(..., ge=1900, le=2024)):
return {"annee_archive": annee}
Validation au niveau du modèle (Field)
La fonction Field de Pydantic permet de valider les attributs à l'intérieur d'une classe BaseModel.
from pydantic import Field
class Compte(BaseModel):
pseudo: str = Field(..., example="admin123")
score: int = Field(0, ge=0, description="Le score ne peut pas être négatif")
En-têtes et Cookies
L'extraction des métadonnées comme les Cookies ou les Headers se fait de manière déclarative.
from fastapi import Cookie, Header
@api_app.get("/session/")
async def lire_session(session_id: Optional[str] = Cookie(None), user_agent: Optional[str] = Header(None)):
return {"cookie": session_id, "navigateur": user_agent}
Modélisation des réponses
Le paramètre response_model permet de filtrer et de valider les données sortantes, assurant que les informations sensibles (comme les mots de passe) ne soient pas exposées.
from typing import List
class UserSchema(BaseModel):
email: str
actif: bool
class UserDB(UserSchema):
mot_de_passe: str # Ne doit pas être retourné
@api_app.post("/inscription/", response_model=UserSchema)
async def inscription(user: UserDB):
# Le mot de passe sera automatiquement filtré de la réponse
return user
Gestion des listes dans les réponses
Pour retourner une collection d'objets, utilisez List de la bibliothèque typing.
@api_app.get("/utilisateurs/", response_model=List[UserSchema])
async def recuperer_tous():
data = [
{"email": "test@example.com", "actif": True},
{"email": "dev@example.com", "actif": False}
]
return data