Machine Learning Academy · Lezione

Servire previsioni con un endpoint FastAPI

Imparerete a racchiudere un modello joblib in una route POST di FastAPI che accetta un payload JSON e restituisce una previsione, quindi a testarla con una richiesta curl.

Lezione 3 di 413 passaggi

Servire previsioni con un endpoint FastAPI è una lezione Machine Learning Academy gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Machine Learning Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Machine Learning Academy include 4 lezioni in totale.

Dal notebook all'API di produzione

Un notebook Jupyter è un ottimo ambiente di sviluppo, ma un sistema di serving pessimo per la produzione. Il percorso standard dal notebook alla produzione è: addestrare e salvare un modello con joblib, integrarlo in una REST API e distribuire quell'API come servizio containerizzato. L'API accetta i valori grezzi delle feature in formato JSON, li preelabora tramite la pipeline addestrata e restituisce le previsioni in pochi millisecondi.

Perché usare FastAPI per il serving ML?

FastAPI è un moderno framework web Python basato su Pydantic e Starlette. Genera automaticamente documentazione interattiva (Swagger UI), convalida i corpi delle richieste tramite type hint e gestisce in modo efficiente l'I/O asincrono. Per il serving ML, FastAPI è diffuso perché richiede pochissimo codice ripetitivo, supporta richieste concorrenti tramite worker asincroni e si integra naturalmente con i tipi di dati Python usati in sklearn e pandas.

Installazione di FastAPI e Uvicorn

Per funzionare, FastAPI richiede uvicorn come server ASGI. Installi entrambi con un unico comando. uvicorn è un server asincrono ad alte prestazioni che gestisce le connessioni HTTP e inoltra le richieste all'applicazione FastAPI. In produzione, in genere si esegue uvicorn dietro un reverse proxy nginx con più processi worker.

# pip install fastapi uvicorn[standard]

# Verify installation
from fastapi import FastAPI
from pydantic import BaseModel
import uvicorn

print('FastAPI ready')

Definizione dello schema della richiesta con Pydantic

Le classi Pydantic BaseModel definiscono la struttura delle richieste in ingresso. FastAPI usa questi modelli per convalidare automaticamente i corpi JSON: se manca un campo obbligatorio o il tipo è errato, FastAPI restituisce un errore 422 chiaro prima ancora che venga eseguito il codice. Ogni campo del modello Pydantic corrisponde a una feature di input del modello.

from pydantic import BaseModel
from typing import Optional

class IrisFeatures(BaseModel):
    sepal_length: float
    sepal_width: float
    petal_length: float
    petal_width: float

class PredictionResponse(BaseModel):
    predicted_class: int
    class_name: str
    confidence: float

# Example input (FastAPI will validate this automatically)
input_data = IrisFeatures(sepal_length=5.1, sepal_width=3.5,
                           petal_length=1.4, petal_width=0.2)
print('Input:', input_data)

Caricamento del modello all'avvio

Carichi il modello una sola volta all'avvio, non a ogni richiesta. Caricare un file joblib per ogni previsione aggiungerebbe centinaia di millisecondi di latenza a ogni richiesta. Utilizzi una variabile a livello di modulo oppure un gestore di eventi FastAPI lifespan per caricare il modello all'avvio del server e mantenerlo in memoria per tutte le richieste successive.

import joblib
from contextlib import asynccontextmanager
from fastapi import FastAPI

ml_models = {}

@asynccontextmanager
async def lifespan(app: FastAPI):
    # Startup: load model once
    ml_models['iris'] = joblib.load('/tmp/iris_pipeline.joblib')
    print('Model loaded at startup')
    yield
    # Shutdown: cleanup if needed
    ml_models.clear()

app = FastAPI(title='Iris Predictor API', lifespan=lifespan)

Creazione dell'endpoint di predizione

Definisca una route POST che accetti il modello di input Pydantic, lo converta in un array NumPy, chiami pipeline.predict e predict_proba e restituisca la previsione come risposta JSON strutturata. FastAPI serializza automaticamente i modelli di risposta Pydantic.

import numpy as np
from fastapi import FastAPI
from pydantic import BaseModel
import joblib

app = FastAPI()
model = None

@app.on_event('startup')
def load_model():
    global model
    model = joblib.load('/tmp/iris_pipeline.joblib')

CLASS_NAMES = ['setosa', 'versicolor', 'virginica']

@app.post('/predict')
def predict(features: IrisFeatures):
    X = np.array([[features.sepal_length, features.sepal_width,
                   features.petal_length, features.petal_width]])
    pred = int(model.predict(X)[0])
    proba = float(model.predict_proba(X)[0].max())
    return {
        'predicted_class': pred,
        'class_name': CLASS_NAMES[pred],
        'confidence': round(proba, 4)
    }

Aggiunta di un endpoint per il controllo dello stato

Un endpoint /health o /ping è essenziale per i servizi di produzione. I bilanciatori del carico e i sistemi di orchestrazione (Kubernetes, ECS) chiamano periodicamente questo endpoint per verificare che il servizio sia attivo. Una risposta positiva indica che il server è in esecuzione E che il modello è stato caricato. Restituisca 503 se il caricamento del modello non è riuscito.

from fastapi import FastAPI
from fastapi.responses import JSONResponse

app = FastAPI()

@app.get('/health')
def health():
    if model is None:
        return JSONResponse(status_code=503,
                            content={'status': 'unhealthy', 'reason': 'model not loaded'})
    return {'status': 'ok', 'model': 'iris_pipeline', 'version': '1.0.0'}

@app.get('/')
def root():
    return {'message': 'Iris Predictor API — POST /predict to get a classification'}

Esecuzione locale del server

Salvi l'app FastAPI in main.py e la avvii con uvicorn main:app --reload. Il flag --reload riavvia automaticamente il server quando cambiano i file (solo in sviluppo). Apra http://localhost:8000/docs per visualizzare l'interfaccia Swagger UI generata automaticamente, dove può testare interattivamente le previsioni.

# Save to main.py then run:
# uvicorn main:app --host 0.0.0.0 --port 8000 --reload

# Test with curl:
# curl -X POST http://localhost:8000/predict \
#   -H 'Content-Type: application/json' \
#   -d '{"sepal_length": 5.1, "sepal_width": 3.5, "petal_length": 1.4, "petal_width": 0.2}'
#
# Expected response:
# {"predicted_class": 0, "class_name": "setosa", "confidence": 0.9981}

print('Command to start: uvicorn main:app --reload --port 8000')

Test dell'endpoint con la libreria requests

In uno script di test o in un notebook, utilizzi requests.post per chiamare l'API in esecuzione. È anche il modo in cui le applicazioni client (app mobili, dashboard e altri microservizi) utilizzano l'API di predizione. Lo stesso formato di richiesta funziona con qualsiasi linguaggio: curl, JavaScript fetch e http.Client di Go.

import requests

url = 'http://localhost:8000/predict'
payload = {
    'sepal_length': 6.3,
    'sepal_width': 3.3,
    'petal_length': 6.0,
    'petal_width': 2.5
}

response = requests.post(url, json=payload)
if response.status_code == 200:
    result = response.json()
    print('Predicted class:', result['class_name'])
    print('Confidence:', result['confidence'])
else:
    print('Error:', response.status_code, response.text)

Convalida degli input e gestione degli errori

La convalida Pydantic di FastAPI rileva automaticamente gli errori di tipo, ma dovrebbe gestire anche gli errori a livello di modello (ad esempio valori NaN imprevisti o input fuori intervallo). Utilizzi try/except all'interno della funzione della route e restituisca un errore 400 o 500 con un messaggio significativo. In produzione, eviti di esporre ai chiamanti dell'API i dettagli degli errori interni, come i traceback.

from fastapi import FastAPI, HTTPException
import numpy as np

app = FastAPI()

@app.post('/predict')
def predict(features: IrisFeatures):
    try:
        X = np.array([[features.sepal_length, features.sepal_width,
                       features.petal_length, features.petal_width]])
        if np.any(np.isnan(X)) or np.any(X < 0):
            raise HTTPException(status_code=400,
                                detail='Input contains invalid values (NaN or negative)')
        pred = int(model.predict(X)[0])
        proba = float(model.predict_proba(X)[0].max())
        return {'predicted_class': pred, 'confidence': round(proba, 4)}
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail='Internal prediction error')

Endpoint per la predizione batch

Per i casi d'uso ad alto throughput, aggiunga un endpoint batch che accetti un elenco di set di feature e restituisca un elenco di previsioni in un'unica chiamata API. L'elaborazione batch riduce l'overhead di rete e consente al modello di vettorializzare le previsioni in modo efficiente (predict di sklearn gestisce le matrici).

from typing import List
from pydantic import BaseModel
import numpy as np

class BatchRequest(BaseModel):
    instances: List[IrisFeatures]

@app.post('/predict/batch')
def predict_batch(batch: BatchRequest):
    X = np.array([[f.sepal_length, f.sepal_width, f.petal_length, f.petal_width]
                  for f in batch.instances])
    preds = model.predict(X).tolist()
    probas = model.predict_proba(X).max(axis=1).tolist()
    return {'predictions': [{'class': p, 'confidence': round(c, 4)}
                            for p, c in zip(preds, probas)]}

Verifica rapida

Verifichi la comprensione del serving delle previsioni ML con FastAPI trattato in questa lezione.

Riepilogo della lezione

In questa lezione ha imparato che: FastAPI integra una pipeline caricata con joblib in un endpoint REST tipizzato, con convalida automatica del JSON e documentazione Swagger; è importante caricare il modello una sola volta all’avvio per evitare la latenza dell’I/O su disco a ogni richiesta; e bisogna includere sempre un endpoint /health, così che i bilanciatori del carico e gli orchestratori possano verificare che il servizio sia attivo. Ora aggiungeremo la registrazione delle predizioni all’API e parleremo del data drift e dei criteri per riaddestrare il modello.

Gratis per iniziare

Impara Python con un tutor IA — gratis

Scrivi ed esegui vero codice nel tuo browser, ricevi aiuto istantaneo da un tutor IA disponibile 24/7, e riprendi da dove hai lasciato sul web o nell'app.

Corsi
30
Lezioni
120

Domande Frequenti

La lezione «Servire previsioni con un endpoint FastAPI» è gratuita?

Sì — il testo completo di «Servire previsioni con un endpoint FastAPI» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Machine Learning Academy, passa a CoddyKit PRO. Il corso Machine Learning Academy include 4 lezioni in totale.

Cosa imparerò in «Servire previsioni con un endpoint FastAPI»?

Imparerete a racchiudere un modello joblib in una route POST di FastAPI che accetta un payload JSON e restituisce una previsione, quindi a testarla con una richiesta curl. Eserciti Machine Learning Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Machine Learning Academy?

Non è richiesta alcuna esperienza precedente. Machine Learning Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.

Quanto tempo richiede la lezione «Servire previsioni con un endpoint FastAPI»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Machine Learning Academy?

Sì. Ogni lezione Machine Learning Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Salvare i modelli con joblib e pickle
  2. Versionare i modelli: perché nomi dei file e metadati sono importanti
  3. Servire previsioni con un endpoint FastAPI
  4. Monitorare le previsioni: registrare input e output
← Torna a Machine Learning Academy