from fastapi import FastAPIapp = FastAPI() # instance principale de l'application@app.get("/") # associe cette fonction a une requete GET sur /def home(): return {"message": "Hello"} # FastAPI convertit automatiquement en JSON# Lancer le serveur :# uvicorn main:app --reload # --reload = redemarre automatiquement a chaque modif# Documentation auto : http://localhost:8000/docsfrom fastapi import FastAPIapp = FastAPI()@app.get("/utilisateur/{id}")def get_utilisateur(id: int, actif: bool = True): # id : parametre de chemin, obligatoire -> /utilisateur/5 # actif : parametre de requete, optionnel -> /utilisateur/5?actif=false return {"id": id, "actif": actif}from fastapi import FastAPIfrom pydantic import BaseModelapp = FastAPI()class Utilisateur(BaseModel): nom: str # champ obligatoire, doit etre une chaine age: int # champ obligatoire, doit etre un entier@app.post("/utilisateur")def creer_utilisateur(utilisateur: Utilisateur): # 'utilisateur' est deja valide a ce stade : plus besoin de le verifier return {"message": f"{utilisateur.nom} cree", "age": utilisateur.age}from fastapi import FastAPI, HTTPExceptionapp = FastAPI()@app.get("/produit/{id}")def get_produit(id: int): if id != 1: # arrete immediatement la fonction et renvoie une erreur 404 raise HTTPException(status_code=404, detail="Produit introuvable") return {"id": 1, "nom": "Clavier"}200 OK # succes standard (GET reussi)201 Created # ressource creee avec succes (POST reussi)204 No Content # succes, mais rien a renvoyer (DELETE reussi)400 Bad Request # requete mal formee (donnees invalides)401 Unauthorized # authentification manquante ou invalide403 Forbidden # authentifie, mais pas les droits suffisants404 Not Found # ressource demandee introuvable422 Unprocessable Entity # erreur de validation Pydantic (type/champ incorrect)500 Internal Server Error # erreur imprevue cote serveurfrom fastapi import FastAPIfrom fastapi.middleware.cors import CORSMiddlewareapp = FastAPI()app.add_middleware( CORSMiddleware, allow_origins=["*"], # "*" = autorise tous les domaines (a restreindre en prod) allow_credentials=True, # autorise l'envoi de cookies/identifiants allow_methods=["*"], # autorise GET, POST, PUT, DELETE... allow_headers=["*"], # autorise tous les en-tetes HTTP personnalises)app/ ├── main.py # point d'entree : cree l'app et inclut les routers ├── database.py # connexion a la base de donnees (engine, session) ├── models/ # modeles SQLAlchemy (structure des tables en BDD) │ └── utilisateur.py ├── schemas/ # modeles Pydantic (structure des donnees de l'API) │ └── utilisateur.py ├── routers/ # routes regroupees par ressource (utilisateur, produit...) │ └── utilisateur.py └── utils/ # fonctions transverses (securite, envoi d'email...)# routers/utilisateur.pyfrom fastapi import APIRouterrouter = APIRouter(prefix="/utilisateur", tags=["Utilisateur"])@router.get("/{id}") # devient GET /utilisateur/{id} grace au prefixdef get_user(id: int): return {"id": id}from fastapi import FastAPIfrom routers.utilisateur import router as utilisateur_routerapp = FastAPI()app.include_router(utilisateur_router) # toutes les routes de ce router sont activeesfrom sqlalchemy import create_enginefrom sqlalchemy.orm import sessionmaker, DeclarativeBaseDATABASE_URL = "sqlite:///./test.db" # base SQLite locale (fichier test.db)engine = create_engine(DATABASE_URL, connect_args={"check_same_thread": False})SessionLocal = sessionmaker(bind=engine, autoflush=False, autocommit=False)class Base(DeclarativeBase): # classe de base dont heriteront tous les modeles (tables) de l'application passfrom sqlalchemy import Column, Integer, Stringfrom database import Baseclass Utilisateur(Base): __tablename__ = "utilisateurs" # nom de la table en base id = Column(Integer, primary_key=True, index=True) # cle primaire, indexee nom = Column(String, index=True) # colonne texte, indexee age = Column(Integer) # colonne numeriquefrom pydantic import BaseModelclass UtilisateurSchema(BaseModel): nom: str age: int class Config: from_attributes = True # permet UtilisateurSchema.from_orm(objet_sqlalchemy)from fastapi import Depends, APIRouterfrom sqlalchemy.orm import Sessionfrom database import SessionLocalfrom models.utilisateur import Utilisateurfrom schemas.utilisateur import UtilisateurSchemarouter = APIRouter(prefix="/utilisateur", tags=["Utilisateur"])def get_db(): db = SessionLocal() try: yield db # fournit la session a la route le temps de la requete finally: db.close() # fermee systematiquement, meme si une erreur survient@router.post("/")def creer_utilisateur(data: UtilisateurSchema, db: Session = Depends(get_db)): user = Utilisateur(nom=data.nom, age=data.age) # cree l'objet SQLAlchemy db.add(user) # prepare l'insertion db.commit() # ecrit reellement en base de donnees db.refresh(user) # recupere l'id genere automatiquement par la BDD return user