Intégration de Pydantic pour la validation des entrées dans un backend FastAPI
Mise en place de l’endpoint de prédiction
Dans cette leçon, nous allons analyser en détail le code du backend que nous avons construit lors de la leçon précédente:
Mise en route et déploiement d'un modèle IA via FastAPI et Uvicorn.
Pour commencer, rappelons le script:
from fastapi import FastAPI
from pydantic import BaseModel
import joblib
# Charger le modèle sauvegardé
model = joblib.load("iris_model.joblib")
# Définir un schéma de données avec Pydantic
class IrisData(BaseModel):
sepal_length: float
sepal_width: float
petal_length: float
petal_width: float
# Créer l'application FastAPI
app = FastAPI()
# Endpoint de prédiction
@app.post("/predict")
def predict(data: IrisData):
# Transformer les données reçues en liste
# compatible avec le modèle
sample = [[
data.sepal_length,
data.sepal_width,
data.petal_length,
data.petal_width
]]
prediction = model.predict(sample)
return {"prediction": int(prediction[0])}
Avant de plonger dans l’explication ligne par ligne du code, il est utile de poser le décor. Ce script illustre comment transformer un modèle de machine learning déjà entraîné en un service web interactif grâce à FastAPI. L’idée est simple: au lieu d’utiliser le modèle uniquement dans un notebook ou un script local, on le rend accessible via une API. Ainsi, n’importe quel utilisateur ou application peut envoyer des données (caractéristiques d’une fleur Iris dans notre cas) et recevoir en retour une prédiction.
Ce type de déploiement est une étape clé dans le cycle de vie d’un projet IA, car il permet de passer de la recherche ou du prototypage à une utilisation concrète intégrée dans des systèmes ou des produits.
Le code que nous allons analyser montre donc la rencontre entre trois briques essentielles: FastAPI pour créer l’API, Pydantic pour valider les données reçues, et joblib pour recharger le modèle sauvegardé.
Qu'est ce que Pydantic?
Le premier bloc de notre script sert à importer les modules indispensables au fonctionnement du backend:
from fastapi import FastAPI
from pydantic import BaseModel
import joblib
Nous avons déjà étudié en détail l’utilisation de
Joblib pour charger un modèle. Quant à
FastAPI, il s’agit du framework principal sur lequel repose la construction de notre backend. Ce qui mérite une attention particulière ici, c’est
Pydantic, dont nous importons la classe
BaseModel, essentielle pour définir et valider la structure des données que l’API recevra.
Pydantic est une bibliothèque Python conçue pour faciliter la définition, la validation et la sérialisation des données en utilisant les annotations de type. Elle permet de créer des modèles clairs et fiables qui garantissent que les données reçues par une application respectent la structure attendue.
Caractéristiques principales de Pydantic
Dans le contexte de FastAPI, Pydantic joue un rôle central qui consiste à valider automatiquement les entrées des requêtes HTTP et génère des schémas JSON utiles pour la documentation de l’API. En gros, on peut résumer les avantage de Pydantic dans les points suivants:
- Validation automatique des types: Pydantic vérifie que les données reçues correspondent bien aux types définis dans le modèle. Par exemple, si un champ est déclaré comme int, une valeur "42" (chaîne) sera convertie en entier, mais "abc" provoquera une erreur. Cela évite d’avoir à écrire du code de validation manuel.
- Définition de schémas via la classe BaseModel: Les modèles héritent de BaseModel et décrivent la structure attendue des données (champs, types, valeurs par défaut). Ces schémas servent de contrat entre l’API et le client, garantissant que les données échangées sont cohérentes et bien typées.
- Gestion des erreurs avec des messages explicites: En cas de données invalides, Pydantic génère une erreur détaillée qui précise quel champ est incorrect et pourquoi. Cela facilite le débogage et permet de fournir un retour clair à l’utilisateur ou au développeur.
- Conversion et parsing des données JSON en objets Python: Pydantic peut transformer directement des données JSON en objets Python. Cela simplifie l’intégration avec des APIs, car les données reçues (souvent en JSON) deviennent immédiatement utilisables dans le code.
- Personnalisation grâce aux validateurs: Au-delà de la validation automatique, il est possible de définir des règles personnalisées. Par exemple, vérifier qu’un âge est positif ou qu’une adresse email respecte un format particulier. Ces validateurs ajoutent une couche de logique métier directement dans le modèle.
- Génération de schémas JSON pour la documentation: FastAPI exploite les modèles Pydantic pour générer automatiquement la documentation OpenAPI/Swagger. Les schémas JSON produits décrivent les champs attendus, leurs types et contraintes, ce qui rend l’API auto-documentée et facile à explorer.
Utilisation de Pydantic dans FastAPI
Ce bloc de code (extrait du code précédent) définit une classe de données avec Pydantic:
class IrisData(BaseModel):
sepal_length: float
sepal_width: float
petal_length: float
petal_width: float
Avec
class IrisData(BaseModel), on crée une classe
IrisData qui hérite de
BaseModel (la classe de base de Pydantic). Cela signifie que IrisData devient un modèle de données capable de valider automatiquement les champs qu’on lui fournit.
Dans la classe IrisData, chaque attribut correspond à une caractéristique de la fleur Iris et est typé en float. Ainsi,
sepal_length et
sepal_width représentent respectivement la longueur et la largeur du sépale, tandis que
petal_length et
petal_width indiquent la longueur et la largeur du pétale.
Le fait de préciser le type float garantit que l’API attend des valeurs numériques décimales pour chacun de ces champs, ce qui permet à Pydantic de valider automatiquement les données reçues et d’assurer leur cohérence avant de les transmettre au modèle de prédiction.
Traitement des requêtes et réponses JSON via FastAPI
Après avoir défini notre modèle de données avec Pydantic, nous devons maintenant mettre en place le backend FastAPI qui va recevoir les requêtes, valider les données et transmettre ces informations au modèle de machine learning pour produire une prédiction. C’est précisément ce que fait cette partie du code:
# Créer l'application FastAPI
app = FastAPI()
# Endpoint de prédiction
@app.post("/predict")
def predict(data: IrisData):
# Transformer les données reçues en liste
# compatible avec le modèle
sample = [[
data.sepal_length,
data.sepal_width,
data.petal_length,
data.petal_width
]]
prediction = model.predict(sample)
return {"prediction": int(prediction[0])}
Expliquons le en détails:
- app = FastAPI(): Cette ligne crée une instance de l’application FastAPI. C’est le cœur du backend qui doit gérer les requêtes HTTP et les réponses.
- @app.post("/predict"): Ce décorateur définit un endpoint accessible via une requête POST à l’URL /predict. C’est ici que les utilisateurs enverront leurs données pour obtenir une prédiction.
- def predict(data: IrisData): La fonction predict est appelée lorsqu’une requête POST est reçue. Le paramètre data est automatiquement validé par Pydantic selon le schéma IrisData. Cela garantit que les données envoyées respectent la structure attendue (longueur et largeur des sépales et pétales).
- sample = [[...]]: Les valeurs reçues sont regroupées dans une liste imbriquée, car le modèle de machine learning attend une entrée sous forme de tableau 2D (même pour une seule observation).
- prediction = model.predict(sample): Le modèle chargé avec joblib est utilisé pour générer une prédiction à partir des données fournies.
- return {"prediction": int(prediction[0])}: La fonction renvoie la prédiction sous forme de dictionnaire JSON. Cela permet à l’API de répondre avec un format standard, facilement exploitable par un client ou une autre application.
Un décorateur en Python est une fonction spéciale qui permet d’ajouter ou modifier le comportement d’une autre fonction sans changer son code interne. On l’applique avec le symbole @ placé juste au‑dessus de la définition de la fonction.
FastAPI et Pydantic: un duo pour des APIs fiables
Retenons que nous avons appris à transformer un modèle de machine learning en un service web interactif grâce à FastAPI et Pydantic. FastAPI nous a permis de créer une API simple et performante, tandis que Pydantic a assuré la validation et la fiabilité des données reçues.
L’endpoint
/predict illustre parfaitement ce processus: il reçoit une requête JSON, valide les informations, les transmet au modèle, puis renvoie une prédiction claire au format JSON.
Ce schéma constitue la base d’un backend robuste et ouvre la voie à des extensions plus avancées, comme la gestion d’erreurs personnalisées, l’ajout de documentation automatique ou l’intégration de nouveaux modèles.