Chapitre 3.3 : Modèles de données avec Pydantic
Temps d'étude : 50 minutes
1. Pydantic : Le "plan numérique" d'un vaisseau spatial
Imaginez que vous construisez un vaisseau spatial. Vous ne pouvez pas simplement souder des morceaux de métal au hasard. Vous avez besoin d'un plan détaillé qui définit :
- Nom du vaisseau (type :
chaîne
, longueur max : 50 caractères) - Année de lancement (type :
entier
) - Présence d'un hyperpropulseur (type :
oui/non
)
Pydantic est une bibliothèque qui permet de créer de tels "plans numériques" pour vos données en Python. Dans FastAPI, elle remplit trois fonctions clés :
- Déclaration de structure : Décrit clairement de quels champs vos données sont composées.
- Validation des données : Vérifie automatiquement si les données entrantes correspondent au plan.
- Documentation : FastAPI utilise ces plans pour générer une documentation détaillée et interactive.
💡 Analogie spatiale : Un modèle Pydantic est le passeport technique d'un objet. Toute "cargaison" (données) arrivant à la station doit correspondre aux spécifications du passeport. Sinon, l'ordinateur de bord (Pydantic) la rejettera.
2. Création du premier plan : Le modèle Spaceship
Créons un modèle qui décrira notre engin spatial.
Étape 1 : Importation de BaseModel
depuis Pydantic
Pydantic est déjà installé avec fastapi[all]
. Nous avons seulement besoin d'importer la classe de base pour nos modèles.
Ajoutez ceci en haut de main.py
, à côté des autres importations :
Étape 2 : Description du modèle Spaceship
Créez une classe qui hérite de BaseModel
. À l'intérieur de la classe, définissez les champs et leurs types en utilisant les annotations de type Python standard.
Ajoutez ce code dans main.py
(peut être après les importations) :
class Spaceship(BaseModel):
"""
Passeport technique (modèle) d'un vaisseau spatial.
"""
name: str
type: str
launch_year: int
status: str
Spaceship
doit avoir quatre champs avec les types spécifiés.
3. Application du modèle : Amélioration de nos points d'API
Utilisons maintenant notre nouveau modèle pour rendre l'API "plus intelligente".
A. Modèle en tant que réponse (Response Model)
Nous pouvons indiquer à FastAPI que notre point d'API doit retourner des données correspondant au modèle Spaceship
. Cela garantit que la réponse aura toujours la bonne structure.
Modifiez le point d'API /spaceships/{ship_id}
comme suit :
# main.py
# ... code avec db_spaceships et le modèle Spaceship ...
# Utilisation de `response_model` pour spécifier le "plan" de la réponse
@app.get("/spaceships/{ship_id}", response_model=Spaceship)
def get_spaceship(ship_id: int):
"""
Retourne les données du vaisseau, correspondant au modèle Spaceship.
"""
ship = db_spaceships.get(ship_id)
return ship
response_model=Spaceship
: Nous disons à FastAPI : "La réponse de cette fonction doit correspondre à la structure Spaceship
. Filtre tous les champs superflus et assure-toi que les types sont corrects."
Qu'est-ce que cela apporte ?
- Filtrage des données : Si
db_spaceships
contenait des champs superflus (par exemple,"secret_code"
), ils ne seraient pas inclus dans le JSON final. - Garantie de structure : Le client de l'API peut être sûr de toujours recevoir une réponse dans le format attendu.
- Documentation : Dans
/docs
, un exemple précis de réponse (Example Value) sera désormais affiché.
B. Modèles pour les collections
Et qu'en est-il du point d'API /spaceships
qui retourne une liste de vaisseaux ? Pour cela, il faut utiliser list
du module typing
.
Modifiez les importations et le point d'API /spaceships
:
# main.py en haut
from fastapi import FastAPI
from pydantic import BaseModel
from typing import List # <-- Importation de List
# ... code ...
# Indique que la réponse est une liste (List) d'objets de type Spaceship
@app.get("/spaceships", response_model=List[Spaceship])
def get_spaceships():
"""
Retourne une liste de vaisseaux. Chaque élément de la liste
est validé selon le modèle Spaceship.
"""
# Pydantic ne peut pas fonctionner avec un dictionnaire dont les clés sont des ID.
# Convertissons notre dictionnaire en une simple liste.
return list(db_spaceships.values())
response_model=List[Spaceship]
: Nous indiquons que la réponse sera une liste, où chaque élément est un objet correspondant au modèleSpaceship
.return list(db_spaceships.values())
: Changement important ! Pydantic s'attend à un objet itérable (une liste), et non à un dictionnaire où les clés sont des ID. Nous convertissons les valeurs de notre "simulateur de base de données" en une liste.
4. Vérification de l'API améliorée
Assurez-vous que le serveur uvicorn
est lancé avec --reload
.
- Vérifiez
http://127.0.0.1:8000/spaceships
: La réponse est maintenant un tableau JSON, et non un objet. C'est une structure plus correcte et standard pour les collections. - Vérifiez
http://127.0.0.1:8000/spaceships/1
: La réponse n'a pas changé, mais elle est maintenant garantie de correspondre au modèle. - Consultez
/docs
: Dans la section "Schemas" en bas de page, votre modèleSpaceship
est apparu. Et dans les exemples de réponses pour les points d'API, un beau schéma de données structuré est maintenant affiché.
5. Validation avancée : L'"ordinateur de bord" en action
Pydantic peut faire bien plus que simplement vérifier les types.
Ajoutons la validation à notre modèle Spaceship
:
from pydantic import BaseModel, Field
class Spaceship(BaseModel):
name: str = Field(..., min_length=3, max_length=50, description="Nom du vaisseau")
type: str
launch_year: int = Field(..., gt=1950, description="L'année de lancement doit être après 1950")
status: str
Field(...)
: Utilisé pour ajouter des règles de validation supplémentaires....
(Ellipsis) : Indique que le champ est obligatoire.min_length
,max_length
: Contraintes pour la chaîne de caractères.gt
: "Greater Than" (plus grand que).
Bien que nous ne créions pas encore de nouveaux vaisseaux (ce sera dans le prochain chapitre), ces règles seront déjà reflétées dans la documentation et s'appliqueront lorsque nous implémenterons les requêtes POST
.
Quiz pour la consolidation
🚀 Résumé du chapitre :
Vous avez conçu des "plans numériques" pour les données de votre API. Maintenant, elle ne fonctionne pas seulement, elle fonctionne de manière prévisible et fiable.
- 📝 Le modèle
Spaceship
a été créé à l'aide de Pydantic. - 🛡️ L'API valide et filtre désormais les données sortantes à l'aide de
response_model
. - 📊 La documentation est devenue beaucoup plus informative, affichant des schémas de données précis.
Les plans sont prêts et approuvés ! Dans le prochain chapitre, nous passerons de la lecture des données à leur création — nous implémenterons des opérations CRUD complètes pour notre flotte.
📌 Vérification :
- Assurez-vous que le schéma du modèle
Spaceship
est apparu dans/docs
.- Vérifiez que le point d'API
/spaceships
retourne désormais un tableau JSON ([...]
), et non un objet ({...}
).- Assurez-vous qu'il n'y a pas d'erreurs de syntaxe dans le code après l'ajout des modèles.
⚠️ En cas d'erreurs : -
NameError: name 'BaseModel' is not defined
: Vérifiez que vous avez importéBaseModel
depuispydantic
. -NameError: name 'List' is not defined
: Vérifiez que vous avez importéList
depuistyping
. - La réponse à/spaceships
est vide ([]
) : Assurez-vous d'avoir changéreturn db_spaceships
enreturn list(db_spaceships.values())
.