4.2 · API web avec Flask et FastAPI

Niveau 4 · Spécialisations (Web, Data, IA, Automatisation)

4.2API web avec Flask et FastAPI

Objectif : Créer une API REST légère avec Flask ou FastAPI (ressources JSON, validation Pydantic, documentation auto) — pour servir vos données à n'importe quel client au lieu de les enfermer dans des pages.
Temps estimé : 13 min · lecture autonome · Si vous n'avez que 5 min : lisez « L'essentiel en 30s » + le schéma.

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.

Erreur d'interprétation fréquente : « Renvoyer 200 pour tout, le corps de la réponse suffit ». Non. Le statut HTTP est la première information que lit le client : un 200 sur une création empêche de distinguer lu/créé, un 200 sur une erreur casse toute gestion d'erreur automatique. Les statuts qui disent vrai (201, 400, 404) sont le contrat ; le JSON n'est que le contenu.
Le circuit d'une requête API Route → validation → logique → JSON + statut Route URL + méthodevers la fonctionValidation (Pydantic) Entréeconforme ? sinon 400Logique Lire ou stockerla ressourceRéponse JSON + statut 200 lu,201 créé, 404 manquant
Route → validation → logique → JSON + statut
Version texte du schéma (SEO / lecteurs d'écran / traduction) : 1) Nabil déclare ses routes : URL + méthode HTTP vers une fonction. 2) Pydantic valide chaque entrée depuis les type hints (400 si invalide). 3) La fonction lit ou stocke la ressource. 4) L'API répond en JSON avec le bon statut. Leçon : contrat d'abord, validation auto, documentation vivante.

🔎 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

  1. Installez fastapi et uvicorn dans un venv, puis déclarez un modèle Pydantic (ex. Vente : ville str, montant float).
  2. Ajoutez GET /ventes (lire, 200) et POST /ventes (créer, status_code=201) sur une liste en mémoire.
  3. Lancez avec « uvicorn main:app --reload » et explorez la doc interactive sur /docs : testez depuis le navigateur.
  4. Écrivez 2 tests (pytest + TestClient) : POST valide → 201, POST invalide → 400 ; corrigez jusqu'au vert.
Vous servez une API REST validée, documentée et testée : vos données deviennent consommables par n'importe quel client.

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.

Prudence : Une API ouverte est une porte : validez toute entrée avec Pydantic et ne renvoyez que le nécessaire, jamais de données personnelles superflues. Contenu pédagogique, exemples avec données fictives.

✓ 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.

Checklist sortie de section
  • 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.
Auto-évaluation 1-5 : chaque route renvoie-t-elle le bon statut ?mes entrées sont-elles toutes validé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.

Vérifiez votre compréhension

Qu'expose une API REST à ses clients ?

Ressources supplémentaires (optionnel, pour aller plus loin)

Examen du niveau 4Questions inédites et durcies pour valider vos acquis