Concepto clave
La validación en APIs de Machine Learning es como el control de calidad en una fábrica: asegura que los datos de entrada cumplan con los estándares necesarios antes de que el modelo los procese. En producción, esto previene errores costosos y mantiene la confiabilidad del sistema.
FastAPI utiliza Pydantic para validación declarativa, lo que significa que defines las reglas en modelos de datos y el framework se encarga del resto. Para modelos de regresión, esto incluye validar rangos numéricos, tipos de datos y relaciones entre características. Sin validación, un valor atípico o tipo incorrecto podría causar predicciones erróneas o caídas del servicio.
Cómo funciona en la práctica
Imagina que tienes un modelo de regresión para predecir precios de viviendas basado en área, habitaciones y ubicación. La validación asegura que el área sea positiva, las habitaciones sean enteros y la ubicación esté en una lista permitida. FastAPI valida automáticamente cuando recibe una solicitud HTTP.
Paso a paso: primero, defines un modelo Pydantic con restricciones. Luego, lo usas en el endpoint de FastAPI. Si los datos no cumplen, FastAPI devuelve un error 422 con detalles. Esto es crucial en producción para evitar que datos malformados lleguen al modelo.
Codigo en accion
Antes: sin validación explícita, el código es vulnerable a errores.
from fastapi import FastAPI
import numpy as np
app = FastAPI()
# Modelo simulado
def predict_price(area: float, rooms: int, location: str):
# Sin validación, esto podría fallar con datos incorrectos
return 100000 + 200 * area + 50000 * rooms
@app.post("/predict")
async def predict(area: float, rooms: int, location: str):
price = predict_price(area, rooms, location)
return {"predicted_price": price}Después: con validación usando Pydantic, el sistema es robusto.
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field, validator
from typing import List
import numpy as np
app = FastAPI()
# Modelo Pydantic para validación
class HouseFeatures(BaseModel):
area: float = Field(..., gt=0, description="Área en metros cuadrados, debe ser positiva")
rooms: int = Field(..., ge=1, le=10, description="Número de habitaciones, entre 1 y 10")
location: str = Field(..., min_length=2, max_length=50)
@validator('location')
def validate_location(cls, v):
allowed_locations = ["centro", "suburbio", "rural"]
if v.lower() not in allowed_locations:
raise ValueError(f"Ubicación debe ser una de: {allowed_locations}")
return v.lower()
# Modelo ML simulado
def predict_price(features: HouseFeatures):
# Lógica de predicción con datos validados
base_price = 100000
area_coef = 200
rooms_coef = 50000
location_bonus = {"centro": 30000, "suburbio": 10000, "rural": 0}
price = base_price + area_coef * features.area + rooms_coef * features.rooms + location_bonus[features.location]
return price
@app.post("/predict")
async def predict(features: HouseFeatures):
try:
price = predict_price(features)
return {"predicted_price": price, "status": "success"}
except Exception as e:
raise HTTPException(status_code=500, detail=f"Error en predicción: {str(e)}")Errores comunes
- No validar rangos numéricos: permitir valores negativos para área puede distorsionar predicciones. Solución: usar Field con gt=0 o ge=0.
- Ignorar validación de categorías: aceptar ubicaciones no soportadas causa errores en el modelo. Solución: usar validator con lista permitida.
- Falta de manejo de errores personalizado: devolver errores genéricos confunde a los clientes. Solución: usar HTTPException con mensajes claros.
- Validación solo en frontend: confiar en validación del cliente deja la API vulnerable. Solución: validar siempre en el backend con Pydantic.
- No probar casos límite: no verificar bordes como valores máximos lleva a fallos en producción. Solución: incluir pruebas con valores extremos.
Checklist de dominio
- ¿Definiste un modelo Pydantic con Field para restricciones básicas?
- ¿Usaste validators personalizados para reglas complejas?
- ¿Incluiste manejo de errores HTTP específicos (e.g., 422, 500)?
- ¿Probaste la API con datos válidos e inválidos?
- ¿Documentaste las reglas de validación en los docstrings?
- ¿Consideraste el impacto en rendimiento (validación vs. velocidad)?
- ¿Integraste la validación con el pipeline de ML existente?
Implementar validación para un modelo de predicción de salarios
En este ejercicio, crearás un endpoint FastAPI para un modelo de regresión que predice salarios basado en experiencia, educación y sector. Sigue estos pasos:
- Crea un nuevo proyecto FastAPI o modifica uno existente.
- Define un modelo Pydantic llamado
SalaryFeaturescon:experience_years: float, debe ser entre 0 y 50 (usa Field).education_level: string, solo permite "bachiller", "licenciatura", "maestria", "doctorado" (usa validator).sector: string, solo permite "tech", "finanzas", "salud", "otros" (usa validator).
- Implementa una función
predict_salaryque simule un modelo ML (e.g., salario = 30000 + 1000 * experiencia + bonus por educación y sector). - Crea un endpoint POST
/predict-salaryque use el modelo Pydantic y devuelva la predicción. - Agrega manejo de errores: devuelve 422 para validación fallida y 500 para errores internos.
- Prueba con curl o Postman usando datos válidos e inválidos.
- Usa Field de Pydantic con parámetros como ge y le para rangos numéricos.
- En el validator, convierte strings a minúsculas para hacer comparaciones insensibles a mayúsculas.
- Considera usar un diccionario para mapear educación y sector a bonos en la función de predicción.
Evalua tu comprension
Completa el quiz interactivo de arriba para ganar XP.