Tu apprends Python et tu veux construire des applications web modernes ? L’un des frameworks les plus puissants et les plus agrĂ©ables Ă  utiliser est FastAPI. Contrairement Ă  Flask (minimaliste) ou Django (monolithique), FastAPI se positionne comme le choix idĂ©al pour les APIs REST, les microservices et les applications temps rĂ©el — le tout avec des performances dignes de Node.js ou Go.

Dans ce tutoriel pas-à-pas, tu vas construire une API REST complÚte de gestion de tùches (Todo API) avec FastAPI, en découvrant les concepts clés : validation automatique, documentation interactive, base de données SQLite et déploiement.

Pourquoi FastAPI plutĂŽt que Flask ou Django ?

Avant de coder, voici pourquoi FastAPI a conquis la communauté Python :

  • Performances : BasĂ© sur Starlette (asynchrone natif), FastAPI rivalise avec Go et Node.js en termes de dĂ©bit.
  • Validation automatique : Avec Pydantic, tu dĂ©clares tes modĂšles de donnĂ©es et FastAPI valide, sĂ©rialise et documente tout automatiquement.
  • Documentation interactive : Swagger UI et ReDoc sont gĂ©nĂ©rĂ©s automatiquement Ă  partir de ton code — plus besoin de maintenir une doc sĂ©parĂ©e.
  • Async natif : async/await est supportĂ© nativement, idĂ©al pour les appels API externes, les bases de donnĂ©es et le temps rĂ©el.
  • Type hints : FastAPI exploite les type hints Python — ton IDE te suggĂšre le code, et la validation est garantie Ă  l’exĂ©cution.

1. Installation et configuration

Crée un environnement virtuel et installe FastAPI avec un serveur ASGI :

python -m venv venv
source venv/bin/activate  # ou venv\Scripts\activate sur Windows
pip install fastapi uvicorn

C’est tout ce dont tu as besoin pour commencer. Uvicorn est le serveur ASGI haute performance qui exĂ©cutera ton application.

2. Ta premiĂšre API en 10 lignes

Crée un fichier main.py :

from fastapi import FastAPI

app = FastAPI(title="Todo API", version="1.0.0")

@app.get("/")
def read_root():
    return {"message": "Bienvenue sur la Todo API !"}

@app.get("/items/{item_id}")
def read_item(item_id: int, q: str | None = None):
    return {"item_id": item_id, "query": q}

Lance le serveur :

uvicorn main:app --reload

Ouvre http://127.0.0.1:8000 dans ton navigateur. Tu vois {"message": "Bienvenue sur la Todo API !"}. Maintenant, visite http://127.0.0.1:8000/docs — tu as dĂ©jĂ  une documentation Swagger interactive, gĂ©nĂ©rĂ©e automatiquement Ă  partir de ton code !

Remarque la magie des type hints : FastAPI sait que item_id est un entier (il valide et convertit automatiquement) et que q est une chaßne optionnelle. Pas de boilerplate de validation à écrire !

3. Les modùles Pydantic — Le cƓur de FastAPI

Les modÚles Pydantic définissent la structure de tes données et assurent la validation automatique. Ajoute ceci dans main.py :

from pydantic import BaseModel
from datetime import datetime
from typing import Optional

class TodoCreate(BaseModel):
    title: str
    description: Optional[str] = None
    completed: bool = False

class Todo(TodoCreate):
    id: int
    created_at: datetime

Maintenant, utilisons-les dans une route POST :

todos: list[Todo] = []
next_id = 1

@app.post("/todos/", response_model=Todo)
def create_todo(todo: TodoCreate):
    global next_id
    new_todo = Todo(
        id=next_id,
        title=todo.title,
        description=todo.description,
        completed=todo.completed,
        created_at=datetime.now()
    )
    todos.append(new_todo)
    next_id += 1
    return new_todo

Teste avec la doc Swagger : envoie un JSON {"title": "Apprendre FastAPI"} et reçois une tĂąche créée avec un ID et une date automatiques. Envoie un {"title": ""} — FastAPI le rejette automatiquement avec un message d’erreur clair (car une chaĂźne vide n’est pas un titre valide par dĂ©faut).

4. Route complĂšte CRUD

Ajoutons la récupération de toutes les tùches et la suppression :

@app.get("/todos/", response_model=list[Todo])
def list_todos(skip: int = 0, limit: int = 10):
    return todos[skip : skip + limit]

@app.get("/todos/{todo_id}", response_model=Todo)
def get_todo(todo_id: int):
    for todo in todos:
        if todo.id == todo_id:
            return todo
    from fastapi import HTTPException
    raise HTTPException(status_code=404, detail="TĂąche introuvable")

@app.delete("/todos/{todo_id}")
def delete_todo(todo_id: int):
    for i, todo in enumerate(todos):
        if todo.id == todo_id:
            todos.pop(i)
            return {"message": "Tùche supprimée"}
    raise HTTPException(status_code=404, detail="TĂąche introuvable")

Observe comme les paramĂštres de requĂȘte (skip, limit) sont automatiquement parsĂ©s depuis l’URL. FastAPI distingue tout seul les paramĂštres de path, de query et de body — pas besoin de dĂ©corateurs supplĂ©mentaires.

5. Persistance avec SQLite et SQLAlchemy

Pour l’instant, nos donnĂ©es sont en mĂ©moire et disparaissent au redĂ©marrage. Ajoutons une vraie base de donnĂ©es :

pip install sqlalchemy aiosqlite

Crée un fichier database.py :

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, DeclarativeBase

SQLALCHEMY_DATABASE_URL = "sqlite:///./todos.db"
engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False})
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

class Base(DeclarativeBase):
    pass

Et un modĂšle SQLAlchemy dans models.py :

from sqlalchemy import Column, Integer, String, Boolean, DateTime
from database import Base
from datetime import datetime

class TodoDB(Base):
    __tablename__ = "todos"
    id = Column(Integer, primary_key=True, index=True)
    title = Column(String, nullable=False)
    description = Column(String, nullable=True)
    completed = Column(Boolean, default=False)
    created_at = Column(DateTime, default=datetime.now)

Pour utiliser la base de données dans FastAPI, on ajoute une dépendance :

# Dans main.py
from database import SessionLocal, engine
from models import TodoDB
import models

models.Base.metadata.create_all(bind=engine)

def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

@app.post("/todos/", response_model=Todo)
def create_todo(todo: TodoCreate, db: Session = Depends(get_db)):
    db_todo = TodoDB(title=todo.title, description=todo.description)
    db.add(db_todo)
    db.commit()
    db.refresh(db_todo)
    return Todo(id=db_todo.id, title=db_todo.title,
                description=db_todo.description,
                completed=db_todo.completed,
                created_at=db_todo.created_at)

6. Tests automatiques

FastAPI s’intĂšgre parfaitement avec Pytest. Le client de test TestClient te permet de tester ton API sans serveur HTTP :

pip install pytest httpx
# test_main.py
from fastapi.testclient import TestClient
from main import app

client = TestClient(app)

def test_read_root():
    response = client.get("/")
    assert response.status_code == 200
    assert response.json() == {"message": "Bienvenue sur la Todo API !"}

def test_create_todo():
    response = client.post("/todos/", json={"title": "Tester FastAPI"})
    assert response.status_code == 200
    data = response.json()
    assert data["title"] == "Tester FastAPI"
    assert "id" in data
    assert data["completed"] is False

ExĂ©cute pytest — les tests passent en une fraction de seconde. Ce pattern de test intĂ©grĂ© est l’un des grands avantages de FastAPI pour le dĂ©veloppement professionnel.

Ce que tu as appris

  • ✅ Installer et configurer FastAPI avec Uvicorn
  • ✅ CrĂ©er des routes REST avec paramĂštres validĂ©s automatiquement
  • ✅ DĂ©finir des modĂšles Pydantic pour la validation des donnĂ©es
  • ✅ Construire une API CRUD complĂšte
  • ✅ Connecter SQLite via SQLAlchemy pour la persistance
  • ✅ Tester ton API avec Pytest et TestClient

FastAPI n’est pas seulement rapide — il rend le dĂ©veloppement d’APIs plus sĂ»r et plus agrĂ©able. La validation automatique avec Pydantic, la documentation gĂ©nĂ©rĂ©e et le typage strict rĂ©duisent les bugs et accĂ©lĂšrent le dĂ©veloppement.

Envie d’aller plus loin ? Tu peux ajouter l’authentification JWT, la pagination avancĂ©e, ou dĂ©ployer ton API avec Docker sur un VPS. Chacun de ces sujets mĂ©rite un article dĂ©diĂ© !

🚀 Tu dĂ©butes en Python et tu veux maĂźtriser les fondamentaux avant de te lancer dans les APIs ? Le cours Python — Les Fondamentaux t’enseigne tout ce qu’il faut savoir : variables, fonctions, listes, dictionnaires, classes et modules — les bases solides dont tu as besoin pour construire des projets comme cette API REST.

Photo de Stanislav Kondratiev sur Pexels.