Maîtriser les bases de FastAPI pour le développement d'API

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

Étiquettes: FastAPI Python pydantic rest-api Uvicorn

Publié le 3 juillet à 02h13