4.2API web avec Flask et FastAPI
L'essentiel en 30 secondes
- API = contrat JSON : ressources (
GET /articles,POST /articles) et statuts qui disent vrai (200 lu, 201 créé, 400 invalide, 404 introuvable). - Flask = liberté minimaliste (petits services, apprendre) ; FastAPI = moderne : type hints → validation auto + doc interactive
/docs, async natif. - Réflexe de Nabil : concevoir ressources et statuts AVANT le code, valider toute entrée avec Pydantic, tester avec TestClient.
Mini-cas filé — Nabil sert ses ventes en JSON
Le back-office Django de Nabil (4.1) rend bien service, mais un collègue veut les chiffres des ventes dans un tableau de bord séparé : il lui faut du JSON, pas des pages HTML. Nabil construit une petite API FastAPI à Alger : GET /ventes pour lire, POST /ventes (201 si créé, 400 si invalide) pour ajouter, avec validation Pydantic et documentation interactive sur /docs. Le collègue explore l'API seul, sans appeler Nabil. Deuxième jalon du fil rouge : les mêmes données, servies à tous les clients.
Suite du cas 4.1 — Nabil découple ses données de leur affichage.
1. API REST : ressources, JSON et statuts
Une API REST expose des données en JSON via des URL et des méthodes HTTP : GET /ventes lit, POST /ventes crée, et le statut HTTP dit le résultat — 200 lu, 201 créé, 400 entrée invalide, 404 introuvable. Le JSON (clés/valeurs, listes) correspond exactement aux dict et list Python : c'est le format universel. Nabil conçoit d'abord ses ressources et ses statuts — le contrat — avant d'écrire la moindre ligne.
2. Flask minimaliste, FastAPI moderne
Flask est un micro-framework : une route = une URL vers une fonction, liberté totale, idéal pour apprendre et pour les petits services. FastAPI est son successeur moderne : les type hints (titre: str) alimentent Pydantic qui valide chaque entrée automatiquement, la documentation OpenAPI se génère seule (page interactive /docs), et l'async natif (async/await) traite les requêtes simultanées sans bloquer. Nabil choisit FastAPI pour son API des ventes : validation + doc vivante sans effort.
Et on fiabilise : tester chaque route avec pytest + TestClient (POST valide → 201, POST invalide → 400), et documenter via /docs plutôt qu'un document Word qui se périme. Une API testée et auto-documentée, c'est un contrat que les collègues utilisent sans vous déranger.
🔎 Exemple concret — 🔎 Exemple concret — L'API des ventes de Nabil
Les gestes de Nabil avec les API réelles de FastAPI :
class Vente(BaseModel): ville: str; montant: float # validé auto
@app.get("/ventes") → liste en JSON (200)
@app.post("/ventes", status_code=201) → crée (201) ou 400 si invalide
uvicorn main:app --reload + doc sur /docs
Lecture : modèle validé, deux routes, statuts explicites.
Leçon : les hints donnent validation + documentation.
Vocabulaire de la section
- API REST
- Données exposées en JSON via des URL et des méthodes HTTP (GET lire, POST créer), avec des statuts qui disent le résultat.
Exemple simple : L'API de Nabil : GET /ventes lit, POST /ventes crée (201).
Ce que ce n'est pas : des pages HTML réservées à un seul affichage.
Réflexe : concevoir ressources + statuts avant le code.
- Flask
- Micro-framework Python minimaliste : une route = une URL vers une fonction ; liberté totale, idéal pour apprendre et petits services.
Exemple simple : Nabil y maquette son premier prototype d'API en quelques lignes.
Ce que ce n'est pas : un framework complet imposant admin et ORM.
Réflexe : petit service sur-mesure ? Flask suffit.
- FastAPI + Pydantic
- Framework API moderne : les type hints alimentent Pydantic qui valide les entrées, génère la doc OpenAPI et supporte l'async.
Exemple simple : La Vente de Nabil est validée (montant nombre requis) sans code de contrôle.
Ce que ce n'est pas : des entrées acceptées sans vérification.
Réflexe : typer chaque modèle d'entrée, tester le 400.
- Statuts HTTP
- Codes de résultat : 200 lu, 201 créé, 400 entrée invalide, 404 introuvable — le contrat lu en premier par le client.
Exemple simple : Le POST de Nabil répond 201 si créé, 400 si le montant manque.
Ce que ce n'est pas : un 200 renvoyé pour tout, succès comme erreurs.
Réflexe : chaque route : quel statut pour quel cas ?
En pratique — En pratique — Servir une API FastAPI
- Installez fastapi et uvicorn dans un venv, puis déclarez un modèle Pydantic (ex. Vente : ville str, montant float).
- Ajoutez GET /ventes (lire, 200) et POST /ventes (créer, status_code=201) sur une liste en mémoire.
- Lancez avec « uvicorn main:app --reload » et explorez la doc interactive sur /docs : testez depuis le navigateur.
- Écrivez 2 tests (pytest + TestClient) : POST valide → 201, POST invalide → 400 ; corrigez jusqu'au vert.
Script prêt à dire — présenter son API (30 s)
« C'est Nabil : nos ventes sont servies en JSON — GET pour lire, POST en 201 pour créer, 400 si l'entrée est invalide. Pydantic valide tout, la doc sur /docs est à jour d'office, et les tests verrouillent le contrat. »
À dire en démo ; montrez /docs en direct.
Modèle copier-coller — API FastAPI (code testé)
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Vente(BaseModel):
ville: str
montant: float
VENTES: list[Vente] = []
@app.get("/ventes")
def lister():
return VENTES
@app.post("/ventes", status_code=201)
def creer(vente: Vente):
VENTES.append(vente)
return vente
# Lancer : uvicorn main:app --reload
# Doc interactive : /docs
# Test :
# from fastapi.testclient import TestClient
# client = TestClient(app)
# assert client.post("/ventes", json={"ville": "Alger", "montant": 1200.5}).status_code == 201
# assert client.post("/ventes", json={"ville": "Alger"}).status_code == 422
Prototype rapide
Flask en quelques lignes : une route, du JSON, et votre idée est démontrable ce soir.
API d'équipe
Comme Nabil : FastAPI + Pydantic partout, /docs comme documentation officielle, TestClient en routine.
Fort trafic
Passez les vues gourmandes en async (async def) : les attentes réseau n'empilent plus les requêtes.
Données Django
Gardez vos modèles Django (4.1) et exposez-les en JSON : mêmes données, nouveau contrat, zéro réécriture.
✓ Bonnes pratiques
- Concevoir le contrat (ressources + statuts) avant le code.
- Valider toute entrée avec Pydantic.
- Tester avec TestClient et documenter via /docs.
✗ Pièges fréquents
- Renvoyer 200 pour tout, succès comme erreurs.
- Accepter des entrées non validées.
- Maintenir une doc séparée qui se périme.
Points clés à retenir
- API REST = JSON via URL + MÉTHODES HTTP ; STATUTS qui disent vrai (200/201/400/404).
- FLASK minimaliste (liberté, petits services) ; FASTAPI moderne (validation auto, /docs, async).
- PYDANTIC valide depuis les type hints ; TESTCLIENT verrouille le contrat.
- Mêmes données, plusieurs clients : découpler l'exposition de l'affichage.
Défi 48h — appliquez demain
Exposez vos propres données : GET + POST avec modèle Pydantic, 201/400 corrects, /docs explorée et 2 tests verts.
- Je peux citer ressources, JSON, statuts 200/201/400/404.
- Je sais expliquer validation Pydantic et /docs.
- J'ai 1 API testée qui sert mes données.
Questions fréquentes
Pourquoi le JSON est-il partout dans les API ?
Parce que c'est un format texte léger en clés/valeurs et listes qui correspond exactement aux dict et list Python : lisible par l'humain, manipulable en une ligne de code, compris par tous les langages. Le client reçoit du JSON, le convertit en objets natifs, et travaille — sans pilote ni format propriétaire.
À quoi sert l'async (async/await) dans FastAPI ?
À traiter beaucoup de requêtes simultanées sans bloquer : pendant qu'une requête attend la base ou le réseau, le serveur traite les autres au lieu d'attendre. Pour une API qui lit des données ou appelle des services, l'async augmente nettement le débit avec le même serveur — sans changer la logique.
Qu'expose une API REST à ses clients ?