FastAPI est en 2026 le framework Python de référence pour la création d’APIs REST performantes. Son positionnement est simple : la productivité de Django REST Framework combinée aux performances d’un framework Go, grâce à l’asynchronisme Python natif (asyncio/await). Sa documentation automatique Swagger, sa validation de données intégrée via Pydantic, et sa compatibilité avec les outils modernes (Docker, Kubernetes, OpenTelemetry) en font le choix naturel pour les nouveaux projets API. Ce guide vous amène de l’installation à un déploiement Docker en production.
Pourquoi FastAPI en 2026 : avantages et cas d’usage
FastAPI se distingue de Flask et Django REST Framework sur trois points. Primo, les performances : basé sur Starlette (framework ASGI), il gère les requêtes de manière asynchrone, permettant de traiter plusieurs milliers de requêtes simultanées sans bloquer. Benchmarks 2025 : FastAPI traite 40 000+ requêtes/seconde sur une machine standard, contre 8 000 pour Flask synchrone. Secundo, la validation automatique : les types Python (int, str, list, Pydantic BaseModel) sont automatiquement convertis en JSON Schema, validés à chaque requête et documentés dans Swagger.
Tertio, la documentation auto-générée : FastAPI génère automatiquement une interface Swagger UI (`/docs`) et ReDoc (`/redoc`) depuis vos annotations Python. Toute l’API est documentée en temps réel — les développeurs clients n’ont plus besoin d’attendre une documentation séparée. C’est un gain de productivité énorme dans les équipes qui développent en parallèle frontend et backend.
Les cas d’usage où FastAPI excelle : microservices haute performance, APIs publiques avec fort trafic, services ML/IA (inférence de modèles, RAG, embeddings), prototypes qui doivent aller vite en production, et backends pour applications mobiles ou SPAs React/Vue. Il est moins adapté que Django pour les applications monolithiques avec beaucoup de logique métier côté serveur, rendu HTML, ou admin panel complexe.
Installation et premier endpoint en 5 minutes
Installez FastAPI et uvicorn (le serveur ASGI) dans un environnement virtuel Python : `pip install fastapi uvicorn[standard] pydantic`. Créez un fichier `main.py` :
« `python
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI(title=’Mon API’, version=’1.0′)
class Article(BaseModel):
titre: str
contenu: str
publie: bool = False
articles_db = []
@app.get(‘/articles’, response_model=list[Article])
async def lister_articles():
return articles_db
@app.post(‘/articles’, response_model=Article, status_code=201)
async def creer_article(article: Article):
articles_db.append(article)
return article
« `
Lancez avec `uvicorn main:app –reload`. Visitez `http://localhost:8000/docs` — vous avez une API CRUD fonctionnelle avec documentation Swagger interactive.
Quelques points importants dans cet exemple : `response_model=list[Article]` indique à FastAPI le type de la réponse — il valide que votre code retourne bien ce type et génère la documentation correspondante. `status_code=201` est le code HTTP approprié pour une création réussie (201 Created). Le paramètre `article: Article` dans la signature de la fonction indique que FastAPI doit lire et valider un corps JSON de type Article dans la requête — si la validation échoue, FastAPI retourne automatiquement un 422 Unprocessable Entity avec le détail des erreurs.
Le `–reload` d’uvicorn redémarre automatiquement le serveur à chaque modification de code — indispensable en développement. En production, utilisez `uvicorn main:app –host 0.0.0.0 –port 8000 –workers 4` (4 workers pour exploiter les 4 cores d’un serveur typique). Pour les applications avec beaucoup de code async, `–workers 1 –loop uvloop` est souvent plus performant qu’un multi-worker synchrone.
Validation avancée avec Pydantic V2
Pydantic V2 (publié en 2023, standard en 2026) offre des performances 5 à 50× supérieures à V1 grâce à un cœur Rust. Sa syntaxe a légèrement changé. Les validators se définissent avec `@field_validator` et `@model_validator`. Exemple d’un modèle avec validation personnalisée :
« `python
from pydantic import BaseModel, field_validator, EmailStr
from typing import Optional
class Utilisateur(BaseModel):
email: EmailStr # Valide le format email automatiquement
age: int
nom: str
bio: Optional[str] = None
@field_validator(‘age’)
@classmethod
def age_valide(cls, v):
if v 150:
raise ValueError(‘Age doit être entre 0 et 150’)
return v
@field_validator(‘nom’)
@classmethod
def nom_capitalise(cls, v):
return v.strip().title()
« `
FastAPI intègre Pydantic de manière transparente. Les erreurs de validation Pydantic sont automatiquement converties en réponses HTTP 422 avec un corps JSON détaillant chaque champ invalide et la raison. Vos clients API reçoivent des messages d’erreur clairs sans code de gestion d’erreur supplémentaire de votre part. C’est l’un des avantages les plus appréciés de FastAPI par les équipes qui consomment les APIs.
Pour les paramètres de requête (query parameters) et de chemin (path parameters), FastAPI offre la même validation via `Query()` et `Path()` : `@app.get(‘/articles/{id}’)` avec `async def get_article(id: int = Path(gt=0, description=’ID de l article’))` — l’ID est automatiquement converti en int, et une erreur est retournée si id <= 0. `async def lister_articles(page: int = Query(1, ge=1), taille: int = Query(10, le=100))` pagine vos résultats avec des paramètres validés.
Authentification JWT : sécuriser vos endpoints
L’authentification par JSON Web Token (JWT) est la méthode standard pour les APIs REST stateless. Le principe : l’utilisateur s’authentifie avec email/mot de passe, le serveur génère un JWT signé contenant l’identifiant utilisateur, le client inclut ce token dans le header `Authorization: Bearer ` de chaque requête protégée. Le serveur vérifie la signature du JWT sans interroger la base de données — c’est le caractère stateless de JWT.
« `python
from fastapi import Depends, HTTPException, status
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
import jwt
from datetime import datetime, timedelta
SECRET = ‘votre_secret_tres_long_et_aleatoire’
bearer = HTTPBearer()
def creer_token(user_id: int) -> str:
payload = {‘sub’: str(user_id), ‘exp’: datetime.utcnow() + timedelta(hours=24)}
return jwt.encode(payload, SECRET, algorithm=’HS256′)
def verifier_token(creds: HTTPAuthorizationCredentials = Depends(bearer)):
try:
payload = jwt.decode(creds.credentials, SECRET, algorithms=[‘HS256’])
return int(payload[‘sub’])
except jwt.ExpiredSignatureError:
raise HTTPException(status_code=401, detail=’Token expiré’)
except jwt.JWTError:
raise HTTPException(status_code=401, detail=’Token invalide’)
@app.get(‘/profil’)
async def mon_profil(user_id: int = Depends(verifier_token)):
return {‘user_id’: user_id}
« `
En production, stockez les tokens invalidés (logout) dans Redis avec un TTL correspondant à l’expiration du token. Sans cette liste noire, un token compromis reste valide jusqu’à son expiration naturelle. Utilisez des access tokens de courte durée (15-60 minutes) et des refresh tokens de longue durée (7-30 jours) pour équilibrer sécurité et expérience utilisateur — le client renouvelle silencieusement son access token via le refresh token sans interrompre l’utilisateur.
Connecter une base de données avec SQLModel
SQLModel est une bibliothèque créée par le développeur de FastAPI qui combine Pydantic et SQLAlchemy dans une syntaxe unifiée. Vos modèles Pydantic deviennent vos tables SQL, sans duplication de code. Installez avec `pip install sqlmodel`. Exemple avec SQLite (remplacez par PostgreSQL en production) :
« `python
from sqlmodel import SQLModel, Field, Session, create_engine, select
from typing import Optional
engine = create_engine(‘sqlite:///db.sqlite3’)
class Article(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
titre: str = Field(index=True)
contenu: str
publie: bool = False
SQLModel.metadata.create_all(engine)
@app.get(‘/articles’)
def lister_articles():
with Session(engine) as session:
return session.exec(select(Article)).all()
@app.post(‘/articles’, status_code=201)
def creer_article(article: Article):
with Session(engine) as session:
session.add(article)
session.commit()
session.refresh(article)
return article
« `
Pour les applications à fort trafic, utilisez `asyncpg` (driver PostgreSQL async) avec `create_async_engine` de SQLAlchemy pour des I/O non bloquantes. La gestion des connexions de base de données dans FastAPI se fait via les dépendances : un `AsyncGenerator` qui yield une session et la ferme automatiquement après la requête, même en cas d’exception. Cette approche garantit qu’aucune connexion n’est jamais laissée ouverte.
Migrations de base de données : utilisez Alembic (compatible SQLAlchemy/SQLModel) pour gérer les changements de schéma en production. `alembic init alembic`, puis `alembic revision –autogenerate -m ‘Add articles table’` génère automatiquement le script de migration en comparant vos modèles SQLModel avec l’état actuel de la base. `alembic upgrade head` applique la migration. Ce workflow évite les modifications manuelles de schéma en production — source principale d’incidents de base de données.
Déployer avec Docker : de localhost à la production
Dockeriser votre FastAPI simplifie le déploiement et garantit la cohérence entre environnements. Créez un `Dockerfile` :
« `dockerfile
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install –no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD [« uvicorn », « main:app », « –host », « 0.0.0.0 », « –port », « 8000 », « –workers », « 4 »]
« `
Et un `docker-compose.yml` avec votre API + PostgreSQL :
« `yaml
services:
api:
build: .
ports:
– ‘8000:8000’
environment:
– DATABASE_URL=postgresql://user:pass@db:5432/mydb
depends_on:
– db
db:
image: postgres:16
environment:
– POSTGRES_USER=user
– POSTGRES_PASSWORD=pass
– POSTGRES_DB=mydb
« `
En production, ne vous exposez jamais directement sur le port 8000. Placez Nginx comme reverse proxy devant uvicorn : Nginx gère le TLS, la compression Gzip, le rate limiting, et les connexions longue durée (timeouts clients), pendant qu’uvicorn se concentre sur le traitement Python. La configuration Nginx pour FastAPI est simple : `proxy_pass http://127.0.0.1:8000;` avec `proxy_set_header` pour les headers X-Forwarded-For (IP client réelle derrière le proxy).
Ajoutez des health checks à votre API : un endpoint `GET /health` qui retourne `{‘status’: ‘ok’}` et vérifie la connexion à la base de données. Docker Compose et Kubernetes utilisent ce endpoint pour détecter les instances en bonne santé. Ajoutez dans votre `Dockerfile` : `HEALTHCHECK –interval=30s –timeout=10s CMD curl -f http://localhost:8000/health || exit 1`. Sans health check, le load balancer envoie du trafic vers des instances en erreur sans s’en rendre compte.
Tests automatisés : pytest et TestClient pour une API robuste
Une API sans tests est une API qui échouera en production de manière imprévisible. FastAPI s’intègre nativement avec pytest via `TestClient` (basé sur httpx) : vous testez vos endpoints comme de vraies requêtes HTTP sans démarrer un vrai serveur. Installez `pip install pytest httpx`.
« `python
from fastapi.testclient import TestClient
from main import app
client = TestClient(app)
def test_creer_article():
response = client.post(‘/articles’, json={‘titre’: ‘Test’, ‘contenu’: ‘Contenu test’})
assert response.status_code == 201
assert response.json()[‘titre’] == ‘Test’
def test_article_titre_vide():
response = client.post(‘/articles’, json={‘titre’: », ‘contenu’: ‘Contenu’})
assert response.status_code == 422 # Validation error
« `
Lancez avec `pytest -v`. Ajoutez les tests dans votre pipeline CI/CD GitHub Actions pour valider chaque PR.
Structurez vos tests en trois catégories : tests unitaires (fonctions Python pures sans I/O), tests d’intégration (endpoints avec base de données de test), et tests E2E (flux complets simulant un client réel). Pour les tests d’intégration, utilisez une base SQLite en mémoire via une fixture pytest qui recrée le schéma pour chaque test — les tests sont ainsi isolés et idempotents. `@pytest.fixture(autouse=True)` pour nettoyer la base entre les tests.
Mesurez votre couverture de tests avec `pytest –cov=main –cov-report=html`. Ciblez 80 % de couverture sur le code métier et 100 % sur les endpoints publics. Une couverture à 100 % n’est pas un objectif en soi — tester les cas limites pertinents (données invalides, erreurs réseau, authentification échouée) a plus de valeur que tester des getters triviaux. Les tests sont de la documentation exécutable : un développeur qui rejoint le projet comprend les comportements attendus en lisant les tests.
OpenAPI et documentation interactive : exploiter le potentiel de FastAPI
La génération automatique de documentation OpenAPI (anciennement Swagger) est l’une des killer features de FastAPI. Tout ce que vous définissez via les types Pydantic et les annotations Python se retrouve automatiquement dans votre spec OpenAPI accessible en JSON sur `/openapi.json`. Swagger UI (`/docs`) offre une interface graphique pour tester tous vos endpoints directement depuis le navigateur — idéal pour le développement et les démos.
Enrichissez votre documentation avec des descriptions, exemples et tags. Dans vos routes : `@app.post(‘/articles’, tags=[‘Articles’], summary=’Créer un article’, response_description=’L article créé’)`. Dans vos modèles Pydantic : `class Article(BaseModel): titre: str = Field(description=’Titre de l article’, example=’Mon premier article’)`. Ces annotations apparaissent dans Swagger UI et rendent l’API auto-documentée pour les développeurs consommateurs.
Générez un SDK client automatiquement depuis votre spec OpenAPI avec `openapi-generator-cli` : il produit des clients Python, JavaScript, TypeScript, Java, Go et plus en une commande depuis votre fichier `/openapi.json`. Vos clients internes n’ont plus à écrire du code HTTP manuellement — ils importent un SDK typé qui reflète exactement votre API. Publiez ce SDK dans votre registre npm ou PyPI privé et versionnez-le en parallèle de votre API.
Commentaires (0)
Laisser un commentaire
Les commentaires sont modérés. Questions WordPress, cybersécurité ou dev web bienvenues.