Contexto
En cada proyecto Python terminas con el mismo patron: leer .env con python-dotenv, castear strings a int/float manualmente, y validar que no falte nada. Si olvidas un int(), tu app truena en runtime con un error críptico.
Lo que aprendi
pydantic-settings hace todo eso en una clase:
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
gemini_api_key: str
anthropic_api_key: str
scene_threshold: float = 0.2
frame_batch_size: int = 8
frame_max_count: int = 20
output_dir: str = "output"
model_config = {"env_file": ".env"}
settings = Settings()
# Si GEMINI_API_KEY no esta en .env, truena ANTES de que la app arranque
# scene_threshold ya es float, no string
Ventajas sobre os.getenv() manual:
- Validacion al arrancar: si falta una variable requerida, falla inmediato con mensaje claro
- Tipos automaticos:
int,float,boolse castean solos - Defaults tipados:
frame_batch_size: int = 8es mas claro queint(os.getenv("FRAME_BATCH_SIZE", "8")) - Autocompletado: tu IDE sabe que
settings.scene_thresholdesfloat
Tip: nested settings
Para apps mas grandes, puedes anidar:
class DatabaseSettings(BaseSettings):
url: str = "postgresql://localhost/mydb"
pool_size: int = 5
model_config = {"env_prefix": "DB_"}
class Settings(BaseSettings):
db: DatabaseSettings = DatabaseSettings()
Asi DB_URL y DB_POOL_SIZE en .env se mapean automaticamente.
Por que importa
Es una dependencia pequena (pip install pydantic-settings) que elimina una clase entera de bugs. La uso en todos mis proyectos Python desde que la descubri.