Project Oxygen & Ideo-LabIDEO LAB Dashboard 2026

🚀 FastAPI – Installation, Syntaxe & DĂ©ploiement

Guide complet IDEO‑Lab pour le framework Python haute performance (Pydantic, ASGI, DI).

1.1

Vue d'ensemble

Framework Python moderne, performance, auto-docs.

Python 3.7+ ASGI Performant
1.2

Architecture

Basé sur Starlette (ASGI) & Pydantic (Typage).

Starlette Pydantic ASGI
1.3

Installation & Serveur

pip install fastapi, uvicorn.

pip uvicorn --reload
2.1

"Hello World"

FastAPI(), décorateur @app.get.

@app.get main:app
2.2

ParamĂštres (Path & Query)

ParamĂštres de chemin (URL) et de requĂȘte (query).

Path Params Query Params
2.3

Pydantic (BaseModel)

Validation des données via BaseModel.

Pydantic BaseModel Typage
3.1

Request Body (POST)

Recevoir du JSON (POST, PUT) avec Pydantic.

@app.post Request Body
3.2

Documentation Auto

Swagger UI (/docs) et ReDoc (/redoc).

/docs /redoc OpenAPI
3.3

Validation Avancée

Query, Path, Body, Field (gt, lt, regex).

Query Path Field
4.1

Gestion des Erreurs

HTTPException, gestion des erreurs 404.

HTTPException 404
4.2

Async (async def)

Opérations asynchrones (async, await).

async await I/O
4.3

Injection de Dépendances

Depends (DI), gestion de BDD.

Depends DI
5.1

Sécurité (OAuth2)

OAuth2PasswordBearer, dépendances de sécurité.

OAuth2 Bearer
5.2

Middleware (CORS)

app.add_middleware(CORSMiddleware).

Middleware CORS
5.3

Déploiement (Prod)

Uvicorn (serveur), Gunicorn (manager).

Uvicorn Gunicorn Prod
6.1

Cheat-sheet FastAPI

Décorateurs, commandes, Pydantic.

cheat @app
1.1 Vue d'ensemble FastAPI
Le framework Python haute performance

FastAPI est un framework web Python 3.7+ moderne et haute performance pour la création d'APIs.

Il est conçu pour ĂȘtre "Fast" (rapide) Ă  deux niveaux :

  • Rapide Ă  exĂ©cuter : Performances trĂšs Ă©levĂ©es, comparables Ă  Node.js et Go (grĂące Ă  Starlette et Pydantic).
  • Rapide Ă  coder : Augmente la vitesse de dĂ©veloppement de 200% Ă  300%.
Caractéristiques Clés
  • BasĂ© sur les standards : Utilise OpenAPI (ex-Swagger) et JSON Schema.
  • Docs Automatiques : GĂ©nĂšre une documentation API interactive (Swagger UI & ReDoc) sans effort.
  • Typage (Pydantic) : Utilise les "type hints" Python pour la validation, la sĂ©rialisation et la documentation. C'est sa plus grande force.
  • Asynchrone : Supporte async/await nativement (grĂące Ă  ASGI).
  • Injection de DĂ©pendances : Un systĂšme simple et puissant (Depends).
Philosophie
"FastAPI vous donne le meilleur de Flask (micro-framework, simple)
et de Django (validation, docs) avec les performances de Node.js."
FastAPI vs. Flask vs. Django
CritĂšreFastAPIFlaskDjango
TypeAPI-first (ASGI)Micro-framework (WSGI)Full-stack "batteries incluses" (WSGI)
PerformanceExtrĂȘme (Asynchrone)Moyenne (Synchrone)Moyenne (Synchrone)
ValidationNatif (Pydantic)Externe (ex: Marshmallow)Natif (Django Forms/Serializers)
Docs APIAutomatique (Swagger/ReDoc)Externe (ex: Flasgger)Externe (ex: DRF-Swagger)
Admin UINonNonOui (Auto-générée)
Cas d'usageAPIs REST, MicroservicesPetits projets, APIs simplesProjets Full-stack, Admin, ORM puissant
1.2 Architecture : Starlette, Pydantic, Uvicorn
FastAPI = Starlette + Pydantic

FastAPI n'a pas réinventé la roue. Il combine intelligemment deux librairies :

  1. Starlette (Le Moteur) : Un micro-framework ASGI (Asynchronous Server Gateway Interface) lĂ©ger et trĂšs rapide. Il gĂšre le routage, les middlewares, et les requĂȘtes/rĂ©ponses asynchrones.
  2. Pydantic (La Validation) : Une librairie qui utilise les "type hints" Python (ex: name: str) pour valider, sérialiser et parser les données (ex: JSON).
Uvicorn (Le Serveur)

Un serveur web ASGI (comme Gunicorn pour WSGI). C'est lui qui exécute l'application FastAPI.

Schéma de la Stack
[Image d'une architecture ASGI]

+--------------------------------------+
| Internet (RequĂȘte HTTP)              |
+--------------------------------------+
                   |
                   ▌
+--------------------------------------+
| Serveur ASGI (ex: Uvicorn, Gunicorn) |
| (GĂšre les connexions)                |
+--------------------------------------+
                   |
                   ▌
+--------------------------------------+
| Starlette (Routage, Async)           |  <-- (FastAPI)
+--------------------------------------+
                   |
                   ▌
+--------------------------------------+
| Pydantic (Validation des données)    |  <-- (FastAPI)
+--------------------------------------+
                   |
                   ▌
+--------------------------------------+
| Votre Code Applicatif                |
| (ex: main.py, @app.get(...))         |
+--------------------------------------+
1.3 Installation & Lancement du Serveur
1. Créer un Environnement Virtuel (Requis)
# (Linux / macOS)
python3 -m venv .venv
source .venv/bin/activate

# (Windows)
py -m venv .venv
.\.venv\Scripts\activate
2. Installer FastAPI et Uvicorn

Installez FastAPI et un serveur ASGI comme Uvicorn.

# Installe FastAPI (qui installe Starlette et Pydantic)
pip install fastapi

# Installe le serveur
pip install "uvicorn[standard]"
# ('standard' ajoute des dépendances pour de meilleures perfs)
3. Fichier requirements.txt
pip freeze > requirements.txt
# (Pour geler les dépendances)
Lancer le serveur de développement (Uvicorn)

Uvicorn est le serveur qui exécute votre application.

Créez un fichier main.py (voir 2.1).

# Lancer uvicorn
uvicorn main:app --reload
ArgumentDescription
mainLe fichier main.py (sans .py).
appL'objet FastAPI() créé dans main.py (app = FastAPI()).
--reload(Dev) Redémarre le serveur à chaque modification du code.
--host(Optionnel) --host 0.0.0.0 pour le rendre accessible sur le réseau.
--port(Optionnel) --port 8080 (défaut: 8000).

Une fois lancé, votre API est accessible sur http://127.0.0.1:8000.

Structure de Projet (Simple)
mon_projet/
├── .venv/                   (Environnement virtuel)
├── main.py                  (Fichier principal de l'app)
└── requirements.txt         (DĂ©pendances)
Structure de Projet (Scalable - Recommandée)
mon_projet/
├── .venv/
├── app/
│   ├── __init__.py
│   ├── main.py              (CrĂ©ation de l'app FastAPI)
│   ├── routers/             (Fichiers de routes, ex: items.py)
│   ├── models/              (Modùles SQLAlchemy)
│   ├── schemas/             (Modùles Pydantic)
│   └── dependencies.py      (Injection de dĂ©pendances)
├── tests/
└── requirements.txt
2.1 "Hello World" (main.py)
main.py
from fastapi import FastAPI

# 1. Créer l'instance de l'application
app = FastAPI()

# 2. Définir une "route" avec un "décorateur"
# @app.get -> Opération (GET)
# "/" -> Path (URL)
@app.get("/")
def read_root():
    # 3. Ce que retourne la fonction (dict, list, str, int)
    #    est automatiquement converti en JSON.
    return {"message": "Hello, IDEO-Lab!"}

@app.get("/test")
def read_test():
    return {"status": "ok"}
Lancement
uvicorn main:app --reload
Résultat (via curl ou navigateur)
$ curl http://127.0.0.1:8000/
{"message":"Hello, IDEO-Lab!"}

$ curl http://127.0.0.1:8000/test
{"status":"ok"}
2.2 ParamĂštres (Path & Query)
1. Path Parameters (ParamĂštres de Chemin)

Variables dans l'URL. Définies avec {}.

from fastapi import FastAPI
app = FastAPI()

@app.get("/items/{item_id}")
def read_item(item_id: int): # 1. Type hint (int)
    
    # FastAPI valide que item_id est un entier.
    # Si vous appelez /items/foo, vous recevez une erreur JSON 422.
    
    return {"item_id": item_id, "type": "entier"}

@app.get("/users/{username}")
def read_user(username: str):
    return {"username": username, "type": "string"}
Appel
$ curl http://127.0.0.1:8000/items/123
{"item_id":123,"type":"entier"}

$ curl http://127.0.0.1:8000/items/abc
{"detail":[{"loc":["path","item_id"],"msg":"Input should be a valid integer"...
2. Query Parameters (ParamĂštres de RequĂȘte)

ParamÚtres (clé/valeur) aprÚs le ? dans l'URL. Définis comme arguments de fonction (non présents dans le path).

from fastapi import FastAPI
from typing import Optional # Pour les champs optionnels
app = FastAPI()

# URL: /items/?skip=0&limit=10&q=test

@app.get("/items/")
def read_items(
    skip: int = 0,               # Valeur par défaut (0)
    limit: int = 10,             # Valeur par défaut (10)
    q: Optional[str] = None      # Optionnel (par défaut: None)
):
    results = {"skip": skip, "limit": limit}
    if q:
        results.update({"q": q})
    
    return results
Appel
$ curl http://127.0.0.1:8000/items/?skip=5&q=mon-test
{"skip":5,"limit":10,"q":"mon-test"}

$ curl http://127.0.0.1:8000/items/
{"skip":0,"limit":10}
2.3 Pydantic (BaseModel)
La validation par les types

Pydantic est la librairie de validation de donnĂ©es au cƓur de FastAPI. Vous dĂ©finissez la "forme" (shape) de vos donnĂ©es en crĂ©ant une classe qui hĂ©rite de BaseModel.

FastAPI utilise ces modĂšles pour :

  • Valider les requĂȘtes entrantes (Request Body).
  • SĂ©rialiser les rĂ©ponses sortantes (Response Model).
  • GĂ©nĂ©rer la documentation OpenAPI (Swagger/ReDoc).
Exemple : schemas.py
from pydantic import BaseModel
from typing import Optional, List
from datetime import datetime

class Tag(BaseModel):
    id: int
    name: str

class Article(BaseModel):
    # Champ requis
    titre: str
    
    # Champ requis (type complexe)
    auteur_id: int
    
    # Champ optionnel (défaut: None)
    description: Optional[str] = None
    
    # Champ avec valeur par défaut
    publie: bool = False
    
    # Champ avec type complexe (Liste)
    tags: List[str] = []
    
    # Champ avec type imbriqué
    # (Pydantic gÚre les modÚles imbriqués)
    tag_objets: List[Tag] = []
    
    # Exemple de config (ex: pour l'ORM)
    class Config:
        orm_mode = True
3.1 Request Body (POST, PUT, PATCH)
Recevoir du JSON (POST)

Pour recevoir un corps de requĂȘte (ex: JSON), dĂ©clarez-le comme argument de fonction avec un type hint Pydantic (item: Article).

from fastapi import FastAPI
from pydantic import BaseModel
from typing import Optional

app = FastAPI()

# 1. Définir le modÚle Pydantic (le "schema")
class Article(BaseModel):
    titre: str
    description: Optional[str] = None
    publie: bool = False

# 2. Utiliser le modÚle dans le décorateur 'post'
@app.post("/articles/")
async def create_article(article: Article):
    
    # Si le JSON reçu ne correspond pas au modÚle Article,
    # FastAPI retourne une erreur 422 (Unprocessable Entity)
    
    # Le 'article' ici est un objet Pydantic
    
    # (Logique pour sauver en BDD...)
    
    return {"message": "Article créé", "data": article}

# 'PUT' (mise Ă  jour) et 'PATCH' (partielle) fonctionnent pareil
@app.put("/articles/{article_id}")
async def update_article(article_id: int, article: Article):
    return {"id": article_id, "data": article}
response_model (ContrĂŽler la sortie)

Parfois, vous ne voulez pas retourner *tout* ce que votre fonction manipule (ex: un mot de passe hashé). response_model filtre la sortie selon un modÚle Pydantic.

class ArticleInput(BaseModel):
    titre: str
    
class ArticleDB(BaseModel):
    id: int
    titre: str
    date_creation: datetime
    
    class Config:
        orm_mode = True # Permet de lire depuis un objet ORM

# 'response_model' garantit que la sortie
# correspondra au modĂšle 'ArticleDB'
@app.post("/articles/", response_model=ArticleDB)
async def create_article(article_in: ArticleInput):
    
    # (Logique BDD...)
    # db_article = BDD.create(titre=article_in.titre)
    # db_article contient {id: 1, titre: '...', date_creation: ...}
    
    return db_article # FastAPI va filtrer la sortie
3.2 Documentation Automatique (Swagger & ReDoc)
Génération automatique

C'est la fonctionnalité "magique" de FastAPI. En se basant sur vos décorateurs (@app.get), vos "type hints" (item_id: int) et vos modÚles Pydantic (item: Article), FastAPI génÚre un schéma OpenAPI 3.

Il expose ensuite ce schéma via deux interfaces web :

1. Swagger UI (/docs)

URL : http://127.0.0.1:8000/docs

Une interface interactive. Vous pouvez voir tous vos endpoints, leurs paramĂštres, leurs rĂ©ponses, et mĂȘme les tester directement depuis le navigateur.

2. ReDoc (/redoc)

URL : http://127.0.0.1:8000/redoc

Une interface de documentation statique (non-interactive), plus propre pour la lecture seule.

Personnalisation
app = FastAPI(
    title="IDEO-Lab API",
    description="L'API officielle pour IDEO-Lab",
    version="1.0.0"
)

@app.post(
    "/articles/",
    response_model=ArticleDB,
    tags=["Articles"], // Regroupe dans Swagger
    summary="Crée un nouvel article"
)
async def create_article(article_in: ArticleInput):
    ...
3.3 Validation Avancée (Query, Path, Field)
Validation (Query, Path)

Permet d'ajouter des contraintes (longueur, min/max) aux paramĂštres.

from fastapi import FastAPI, Query, Path
from typing import Optional, List
app = FastAPI()

@app.get("/items/")
async def read_items(
    # Valide un paramĂštre Query
    q: Optional[str] = Query(
        None, # Valeur par défaut
        min_length=3,
        max_length=50,
        regex="^fixedquery$" // Accepte que "fixedquery"
    ),
    
    # Valide une liste
    tags: List[str] = Query([])
):
    ...

@app.get("/users/{user_id}")
async def read_user(
    # Valide un paramĂštre Path
    user_id: int = Path(
        ..., # '...' signifie Requis
        title="L'ID de l'utilisateur",
        gt=0,  # Greater than 0
        le=1000 // Less than or equal to 1000
    )
):
    ...
Validation Pydantic (Field)

Permet d'ajouter les mĂȘmes contraintes aux modĂšles Pydantic.

from pydantic import BaseModel, Field, EmailStr
from typing import Optional

class Article(BaseModel):
    titre: str = Field(
        ...,
        min_length=5,
        max_length=100,
        example="Mon Super Titre"
    )
    
    description: Optional[str] = Field(None)
    
    prix: float = Field(
        ...,
        gt=0,  // > 0
        le=999.99 // <= 999.99
    )
    
    auteur_email: EmailStr // Validation de format email

class Commande(BaseModel):
    article: Article
    quantite: int = Field(1, gt=0)
4.1 Gestion des Erreurs (HTTPException)
HTTPException

Pour retourner une réponse d'erreur HTTP (4xx, 5xx), le plus simple est de lever (raise) une HTTPException.

FastAPI l'interceptera et la convertira en une réponse JSON propre.

from fastapi import FastAPI, HTTPException

app = FastAPI()

items_db = {1: "Item A", 2: "Item B"}

@app.get("/items/{item_id}")
async def read_item(item_id: int):
    
    if item_id not in items_db:
        # Lever l'exception
        raise HTTPException(
            status_code=404,
            detail="Article non trouvé",
            headers={"X-Error": "ID Inconnu"}
        )
        
    return {"item": items_db[item_id]}
Appel
$ curl http://127.0.0.1:8000/items/99
{
  "detail": "Article non trouvé"
}
# (Le statut HTTP sera 404)
Gestionnaires d'exceptions (Avancé)

Vous pouvez intercepter des erreurs spécifiques (ex: erreur BDD) pour retourner une réponse 500 propre.

from fastapi.responses import JSONResponse
from fastapi import Request

class MaSuperErreur(Exception):
    pass

@app.exception_handler(MaSuperErreur)
async def mon_gestionnaire_erreur(req: Request, exc: MaSuperErreur):
    return JSONResponse(
        status_code=418,
        content={"message": "J'ai attrapé une erreur custom !"}
    )
4.2 Async (async / await)
async def

FastAPI est basé sur ASGI, il supporte donc nativement les fonctions "coroutines" (async def).

Quand l'utiliser ?
Utilisez async def si votre fonction contient une opération d'I/O (Entrée/Sortie) lente et asynchrone.
Ex: await (attendre) une requĂȘte BDD (async), await une API externe (async), await asyncio.sleep().

Quand ne PAS l'utiliser ?
Si votre fonction fait juste du calcul CPU (ex: crunching de nombres) ou utilise une librairie I/O *bloquante* (ex: requests standard), utilisez def normal.

Exemple
import asyncio
from fastapi import FastAPI
app = FastAPI()

# Fonction 'def' (Synchrone)
# (Bloque le worker pendant 5s)
@app.get("/sync")
def route_sync():
    time.sleep(5) # Bloquant !
    return {"message": "Sync terminé"}

# Fonction 'async def' (Asynchrone)
# (LibĂšre le worker pendant 5s)
@app.get("/async")
async def route_async():
    # 'await' cĂšde le contrĂŽle au serveur,
    # qui peut traiter d'autres requĂȘtes.
    await asyncio.sleep(5) # Non-bloquant !
    return {"message": "Async terminé"}
4.3 Injection de Dépendances (Depends)
Depends (DI)

L'injection de dépendances est un moyen de déclarer que votre route "dépend" d'autre chose (ex: une session BDD, l'utilisateur courant).

Vous utilisez Depends() comme valeur par défaut d'un paramÚtre de fonction.

FastAPI va :

  1. Exécuter la fonction dans Depends() (la "dépendance").
  2. Prendre la valeur retournée (return).
  3. Injecter cette valeur dans votre paramĂštre de route.

Exemple Simple (Dépendance partagée)
from fastapi import FastAPI, Depends
from typing import Optional
app = FastAPI()

# 1. La Dépendance (une fonction simple)
def get_common_params(
    q: Optional[str] = None,
    skip: int = 0,
    limit: int = 10
):
    # Retourne un dictionnaire
    return {"q": q, "skip": skip, "limit": limit}

# 2. Injection
@app.get("/items/")
async def read_items(commons: dict = Depends(get_common_params)):
    return {"message": "Items", "params": commons}

@app.get("/users/")
async def read_users(commons: dict = Depends(get_common_params)):
    return {"message": "Users", "params": commons}
Cas d'usage N°1 : Gestion de Session BDD

Le cas d'usage le plus courant est de gérer une session BDD (ex: SQLAlchemy).

# (En supposant que 'SessionLocal' est configuré)

# 1. La Dépendance (générateur 'yield')
#    (Ouvre la session, la 'yield', puis la ferme)
def get_db_session():
    db = SessionLocal()
    try:
        yield db # 3. Injecte la session
    finally:
        db.close() # 5. Ferme la session (mĂȘme en cas d'erreur)

# 2. L'Endpoint (la route)
@app.post("/users/")
async def create_user(
    user: UserSchema,
    # 2. FastAPI appelle get_db_session()
    db: Session = Depends(get_db_session)
):
    
    # 4. db est la session BDD
    db_user = models.User(nom=user.nom)
    db.add(db_user)
    db.commit()
    db.refresh(db_user)
    return db_user
5.1 Sécurité (OAuth2 & Bearer Token)

FastAPI intÚgre des outils (basés sur Depends) pour gérer l'authentification.

Exemple (Protection de route)
from fastapi import Depends, FastAPI, HTTPException, status
from fastapi.security import OAuth2PasswordBearer

app = FastAPI()

# 1. Définit le "schéma" de sécurité.
# Il dit Ă  FastAPI: "Va chercher un 'Authorization: Bearer [TOKEN]'
# dans le header de la requĂȘte sur l'URL '/token'".
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/token")


# 2. Une dépendance qui valide le token
# (C'est votre logique métier)
async def get_current_user(token: str = Depends(oauth2_scheme)):
    # (Ici, vous devriez décoder le token JWT,
    #  vérifier sa validité, et chercher l'utilisateur en BDD)
    
    if token != "fake-token": # Logique de validation bidon
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Token invalide"
        )
    return {"username": "admin", "id": 1}


# 3. La route protégée
@app.get("/users/me")
async def read_users_me(
    # Si le client n'a pas de token, ou si get_current_user
    # lĂšve une HTTPException, FastAPI gĂšre l'erreur 401.
    current_user: dict = Depends(get_current_user)
):
    # Si le code arrive ici, le token est valide.
    return current_user

La route /docs affichera un bouton "Authorize" pour tester.

5.2 Middleware (CORS)
Middleware

Un Middleware est une fonction qui s'exĂ©cute sur **chaque requĂȘte** *avant* qu'elle n'atteigne votre route (et sur chaque rĂ©ponse *aprĂšs*).

Utile pour : Logs, CORS, Gzip, gestion d'erreurs globales.

CORS (Cross-Origin Resource Sharing)

ProblÚme : Par défaut, un navigateur n'autorise pas un frontend (http://mon-site-react.com) à appeler une API (http://mon-api.com).

Solution : L'API doit envoyer des headers HTTP (ex: Access-Control-Allow-Origin) pour autoriser le frontend. FastAPI gĂšre cela avec CORSMiddleware.

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

# Liste des "origines" (frontends) autorisées
origins = [
    "http://localhost:3000", // React local
    "http://localhost:8080", // Vue local
    "https://mon-site-react.com",
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins, // Les sites autorisés
    allow_credentials=True,
    allow_methods=["*"], // (GET, POST, etc.)
    allow_headers=["*"],
)

@app.get("/")
def root():
    return {"message": "ok"}
5.3 Déploiement (Uvicorn & Gunicorn)
Serveur ASGI : Uvicorn

Uvicorn est un serveur ASGI. Il peut ĂȘtre utilisĂ© seul en production (contrairement au serveur de dev Flask/Django).

# Installer uvicorn
pip install "uvicorn[standard]"

# Lancer en production (sans --reload)
# Écoute sur 0.0.0.0:8000
uvicorn main:app --host 0.0.0.0
Process Manager : Gunicorn (Recommandé en Prod)

Uvicorn ne gùre qu'un seul processus. Pour exploiter plusieurs cƓurs de CPU (scaling vertical), on utilise Gunicorn (serveur WSGI mature) comme "Process Manager" qui lance et supervise des "Uvicorn Workers".

# 1. Installer Gunicorn
pip install gunicorn
2. Lancer Gunicorn + Uvicorn
# Syntaxe
gunicorn -w [WORKERS] -k [CLASSE_WORKER] [MODULE:APP]

# Exemple : 4 workers (pour 2-4 coeurs CPU)
gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app --bind 0.0.0.0:8000
ArgumentDescription
-w 4Nombre de "workers" (processus). Rùgle: (2 * Nb CƓurs) + 1.
-k uvicorn.workers.UvicornWorker(ClĂ©) Dit Ă  Gunicorn d'utiliser Uvicorn pour gĂ©rer les requĂȘtes (ASGI).
main:appModule Python et objet App.
--bind 0.0.0.0:8000L'interface et le port d'écoute.

On place Nginx en "reverse proxy" devant Gunicorn (comme pour Django).

6.1 Cheat-sheet FastAPI
Commandes
# Installation
pip install fastapi "uvicorn[standard]"

# Lancement (Dev)
uvicorn main:app --reload

# Lancement (Prod)
gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app
Décorateurs
from fastapi import FastAPI
app = FastAPI()

@app.get("/")
@app.post("/")
@app.put("/{item_id}")
@app.delete("/{item_id}")
@app.patch("/{item_id}")
ParamĂštres (from fastapi import ...)
# Path (ex: /items/{item_id})
def f(item_id: int): ...

# Query (ex: /items/?q=test)
def f(q: Optional[str] = None): ...

# Body (ex: POST /items)
from pydantic import BaseModel
class Item(BaseModel):
    name: str
def f(item: Item): ...

# Validation
from fastapi import Path, Query
def f(
    item_id: int = Path(..., gt=0),
    q: str = Query(None, max_length=10)
): ...

# Dépendances
from fastapi import Depends
def get_db(): ...
def f(db: Session = Depends(get_db)): ...

# Erreurs
from fastapi import HTTPException
raise HTTPException(status_code=404, detail="Not found")