FastAPI est devenu le standard pour deployer des APIs de scoring ML en Python. En entretien, on evalue la capacite a aller au-dela du prototype : validation, securite, tests, containerisation.
Pourquoi FastAPI plutot que Flask pour exposer un modele ML ?
from fastapi import FastAPI
from pydantic import BaseModel
import joblib
import numpy as np
app = FastAPI(title='Churn Prediction API', version='1.0')
model = joblib.load('models/churn_v3.pkl')
class PredictionRequest(BaseModel):
age: int
nb_purchases: int
days_since_last_purchase: int
average_basket: float
class PredictionResponse(BaseModel):
probability: float
prediction: str
model_version: str = 'v3'
@app.post('/predict', response_model=PredictionResponse)
def predict(request: PredictionRequest):
features = np.array([[request.age, request.nb_purchases,
request.days_since_last_purchase, request.average_basket]])
proba = model.predict_proba(features)[0][1]
return PredictionResponse(
probability=round(float(proba), 4),
prediction='churn' if proba > 0.5 else 'no_churn'
)Comment validez-vous que les inputs d un endpoint de scoring sont dans les plages attendues ?
from pydantic import BaseModel, Field, validator
class PredictionRequest(BaseModel):
age: int = Field(ge=18, le=120, description='Age de l utilisateur')
nb_purchases: int = Field(ge=0, le=10000)
average_basket: float = Field(gt=0, le=100000)
@validator('nb_purchases')
def purchases_coherence(cls, v, values):
if 'age' in values and v > values['age'] * 100:
raise ValueError('Nombre d achats incoherent avec l age')
return vQuand utilisez-vous async def vs def dans FastAPI ?
Comment securisez-vous un endpoint de scoring ML ?
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from fastapi import Depends, HTTPException
security = HTTPBearer()
def verify_token(credentials: HTTPAuthorizationCredentials = Depends(security)):
token = credentials.credentials
if token not in VALID_API_KEYS:
raise HTTPException(status_code=401, detail='Invalid API key')
return token
@app.post('/predict')
async def predict(request: PredictionRequest, token: str = Depends(verify_token)):
# endpoint securise
...Comment testez-vous une API FastAPI ?
from fastapi.testclient import TestClient
client = TestClient(app)
def test_predict_valid():
response = client.post('/predict', json={
'age': 35, 'nb_purchases': 12,
'days_since_last_purchase': 30, 'average_basket': 49.90
})
assert response.status_code == 200
data = response.json()
assert 0 <= data['probability'] <= 1
assert data['prediction'] in ['churn', 'no_churn']
def test_predict_invalid_age():
response = client.post('/predict', json={'age': -5, ...})
assert response.status_code == 422 # Pydantic validation errorComment containerisez-vous une API FastAPI pour la production ?
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt --no-cache-dir
COPY . .
# Gunicorn avec workers Uvicorn pour la production
CMD ['gunicorn', 'main:app', '--workers', '4', '-k', 'uvicorn.workers.UvicornWorker',
'--bind', '0.0.0.0:8000', '--timeout', '60']| Niveau | Maitrise | Signal GO | NO-GO |
|---|---|---|---|
| Confirme | Endpoints basiques, Pydantic, documentation auto | A deploye une API ML avec FastAPI, utilise Pydantic pour la validation | N a jamais deploye de modele via API |
| Senior | Async, securite JWT, tests, Docker production | A securise une API avec des tokens, a teste avec TestClient, utilise Gunicorn+Uvicorn | Ne sait pas la difference entre async et sync dans FastAPI |
Premier entretien gratuit. Rapport GO/NO-GO sous 48h.