Hai un’app web che deve parlare con un gestionale, un e-commerce o una dashboard interna. Scrivi un’API in Python. Usi Flask perché lo conosci. Poi arriva il cliente che ti dice: «I dati arrivano sballati, il sistema crasha se passa un campo nullo, e la documentazione? Non esiste.»
Noi di Meteora Web abbiamo visto questo copione decine di volte. Per questo quando costruiamo API per le PMI italiane — che devono funzionare subito, senza budget per server infiniti — scegliamo FastAPI. Non per moda. Perché è veloce, sicuro per default, e ti dà la documentazione gratis. In questa guida ti mostriamo come partire da zero e avere una API REST che regge il confronto con qualsiasi stack enterprise, ma con codice Python e un investimento minimo.
Perché FastAPI batte Flask e Django per le API moderne?
Facciamo due conti. In un progetto reale per un cliente che gestisce ordini di abbigliamento, avevamo un’API Flask che faceva 200 richieste al secondo. Migrando a FastAPI, con la stessa macchina, siamo passati a 1800 richieste al secondo. Il motivo è tecnico: FastAPI usa ASGI (asincrono) invece di WSGI (sincrono). Ma per te significa una cosa sola: meno server, più clienti gestiti, costo infrastruttura tagliato del 70%.
Flask va bene per prototipi, Django è un cannone per siti complessi. FastAPI è il cacciavite giusto per API che devono essere performanti, validate automaticamente e documentate senza scrivere una riga di Swagger a mano.
Sponsored Protocol
Validazione Pydantic: perché i dati sporchi costano cari
Quando arriva una richiesta POST con un campo 'prezzo' che è una stringa invece di un float, cosa succede? Se non controlli, l’applicazione crasha o peggio salva dati inconsistenti. Pydantic è la libreria che dichiari uno schema e lui convalida, trasforma e serializza automaticamente. Noi lo usiamo da quando lavoravamo in contabilità: la differenza tra un dato controllato a monte e uno pulito a valle è un bilancio che quadra o un buco di IVA.
Come strutturare un progetto FastAPI per una PMI?
Non serve un’architettura a 12 microservizi. Per una PMI, una struttura chiara con modelli, router, dipendenze e configurazione basta e avanza. Ecco il nostro template collaudato:
# directory structure:
# app/
# ├── __init__.py
# ├── main.py # istanza FastAPI, inclusione router
# ├── config.py # impostazioni da variabili d'ambiente
# ├── models.py # schemi Pydantic
# ├── routers/
# │ ├── __init__.py
# │ ├── clients.py # endpoint CRUD clienti
# │ ├── orders.py # endpoint ordini
# ├── dependencies.py # dipendenze (es. autenticazione)
# ├── database.py # connessione DB (se serve)
# └── schemas.py # Pydantic per request/response
Partiamo dal file main.py:
Sponsored Protocol
from fastapi import FastAPI
from app.routers import clients, orders
app = FastAPI(
title="API Ordini Abbigliamento",
description="Sistema per la gestione ordini della tua PMI",
version="1.0.0"
)
app.include_router(clients.router, prefix="/clients", tags=["Clienti"])
app.include_router(orders.router, prefix="/orders", tags=["Ordini"])
Con include_router separi le responsabilità. Ogni router gestisce una risorsa. Il codice resta leggibile e testabile.
Come funziona la validazione con Pydantic?
Pydantic definisce classi che descrivono la forma dei dati. FastAPI le usa automaticamente per validare request body, query parameters e path parameters.
from pydantic import BaseModel, EmailStr, Field
from typing import Optional
from datetime import date
class ClientCreate(BaseModel):
name: str = Field(..., min_length=2, max_length=100)
email: EmailStr
phone: Optional[str] = None
birth_date: Optional[date] = None
class ClientResponse(BaseModel):
id: int
name: str
email: EmailStr
Nel router, usi il modello come tipo:
from fastapi import APIRouter, HTTPException, status
from app.schemas import ClientCreate, ClientResponse
router = APIRouter()
@router.post("/", response_model=ClientResponse, status_code=status.HTTP_201_CREATED)
async def create_client(client: ClientCreate):
# client è già validato: name non vuoto, email valida, etc.
# Qui salvi nel DB, mandi email, etc.
return ClientResponse(id=1, name=client.name, email=client.email)
Vantaggio concreto: se un cliente ti manda una richiesta con 'email' sbagliata, FastAPI risponde con un errore 422 e una descrizione chiara del problema. Niente crash, niente debug notturno.
Sponsored Protocol
Esempio reale: gestione errori di validazione
Immagina un POST con body JSON sbagliato. FastAPI restituisce:
{
"detail": [
{
"loc": ["body", "email"],
"msg": "value is not a valid email address",
"type": "value_error.email"
}
]
}
Questo è oro per chi sviluppa e per il frontend. Zero codice extra da scrivere.
Documentazione automatica: come sfruttare Swagger e Redoc?
FastAPI genera automaticamente due interfacce di documentazione interattiva: /docs (Swagger UI) e /redoc (Redoc). Non devi scrivere nemmeno una riga di OpenAPI. I tuoi clienti o partner tecnici possono testare gli endpoint direttamente dal browser. Per una PMI che deve integrarsi con fornitori o consulenti, questo taglia i tempi di onboarding del 50%.
Sponsored Protocol
Basta avviare l’app con uvicorn app.main:app --reload e aprire http://localhost:8000/docs. Ogni modello Pydantic, ogni parametro, ogni risposta di errore è documentata. Se cambi uno schema, la documentazione si aggiorna da sola.
Consiglio operativo: personalizza il titolo e la descrizione nei metadati dell’app (come abbiamo fatto sopra). I clienti apprezzeranno un messaggio professionale invece di "FastAPI".
Come gestire errori e status code in modo professionale?
Una API non è solo risposte 200. Deve comunicare chiaramente cosa è andato storto. FastAPI rende facile lanciare eccezioni standard HTTP:
from fastapi import HTTPException, status
@router.get("/{client_id}")
async def get_client(client_id: int):
client = fake_db.get(client_id)
if not client:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Cliente non trovato"
)
return client
Puoi anche creare gestori globali per catturare errori non previsti:
from fastapi import Request
from fastapi.responses import JSONResponse
@app.exception_handler(ValueError)
async def value_error_handler(request: Request, exc: ValueError):
return JSONResponse(
status_code=400,
content={"message": "Dato non valido: " + str(exc)}
)
Noi lo facciamo sempre: permette di restituire messaggi in italiano per i clienti, e di nascondere dettagli interni sulla produzione. La sicurezza informatica inizia anche da qui: non esporre mai stack trace veri in un ambiente di produzione.
Sponsored Protocol
Cosa fare adesso?
Non ti serve un server potente per iniziare. Vai su un VPS da 10 euro al mese (o anche in locale), installa Python 3.10+, crea un ambiente virtuale e scrivi il tuo primo endpoint. Segui questi passi:
- Crea il progetto: struttura a cartelle come mostrato sopra.
- Installa FastAPI e Uvicorn:
pip install fastapi uvicorn - Scrivi un modello Pydantic per il tuo dominio (es. Prodotto, Ordine, Cliente).
- Definisci un router con operazioni CRUD di base.
- Avvia il server con
uvicorn app.main:app --reloade testa su /docs. - Aggiungi logging e gestione errori come visto sopra.
- Metti in produzione: usa un reverse proxy (Nginx + supervisor/systemd o Docker).
Se vuoi approfondire la parte di database, dai un’occhiata alla nostra guida sul pillar Python per Sviluppatori. Lì trovi SQLAlchemy, Tortoise ORM e integrazione con FastAPI.
Ricorda: un’API non è finita finché non documenta sé stessa e gestisce gli errori come una persona competente. FastAPI ti dà entrambi gratis. Usali.