pydantic-settings
pydantic-settings estende os modelos Pydantic para carregar configuração de variáveis de ambiente, arquivos .env e diretórios de segredos opcionais - com validação, coerção de tipo e mensagens de erro claras na inicialização.
Receita
from pydantic import Field
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
model_config = SettingsConfigDict(env_file=".env", extra="ignore")
database_url: str = Field(alias="DATABASE_URL")
debug: bool = False
api_key: str
settings = Settings() # levanta ValidationError se api_key estiver ausenteQuando usar isso:
- Aplicativos FastAPI/Django/Flask que leem
os.environ - Workers e CLIs que precisam de configuração tipada e documentada
- Substituindo casts manuais de
os.getenv("PORT", "8000") - Validando a configuração antes que os workers Gunicorn em fork iniciem
Exemplo de Trabalho
from __future__ import annotations
from functools import lru_cache
from pydantic import Field, PostgresDsn
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
model_config = SettingsConfigDict(
env_file=".env",
env_file_encoding="utf-8",
extra="ignore",
)
app_name: str = "billing-api"
database_url: PostgresDsn = Field(alias="DATABASE_URL")
redis_url: str = Field(default="redis://localhost:6379/0", alias="REDIS_URL")
log_level: str = "INFO"
@lru_cache
def get_settings() -> Settings:
return Settings()
def main() -> None:
s = get_settings()
print(s.app_name, s.database_url, s.log_level)
if __name__ == "__main__":
main()O que isso demonstra:
SettingsConfigDictcentraliza o arquivo env e a política de ignorar chaves desconhecidasField(alias=...)mapeia nomes env em letras maiúsculas para atributos snake_casePostgresDsnvalida a forma da string de conexão antecipadamente@lru_cachefornece configurações singleton estilo FastAPI sem globais
Mergulho Profundo
Como Funciona
- Prioridade da Fonte - Padrões < arquivo env < ambiente real (env vence o arquivo).
- Coerção de Tipo -
"true"se tornaTruepara campos bool; strings separadas por vírgula podem se tornar listas com parsers personalizados. - Configurações Aninhadas -
env_nested_delimiter="__"mapeiaDB__HOSTparadb.host. - Segredos -
secrets_dircarrega arquivos de segredo montados do Docker/Kubernetes como valores de campo.
Campos Comuns
| Tipo de Campo | Exemplo de Env | Notas |
|---|---|---|
str | API_KEY=abc | Obrigatório se não houver padrão |
bool | DEBUG=true | Aceita true/false/1/0 |
int | PORT=8000 | Valores inválidos levantam erro na inicialização |
list[str] | ORIGINS=a,b | Use NoDecode + validador personalizado para CSV |
SecretStr | TOKEN=... | Mascara o valor em repr/logs |
Notas Python
from pydantic import SecretStr
class Settings(BaseSettings):
token: SecretStr
# SecretStr esconde em logs
print(settings.token.get_secret_value()) # revelação explícitaArmadilhas
- Efeitos colaterais no momento da importação -
settings = Settings()no nível do módulo falha em testes. Correção: factory +lru_cacheou injeção de dependência. extra="allow"em produção - Erros de digitação em nomes de env criam atributos silenciosamente. Correção:extra="ignore"ou"forbid".- Commit de
.envcom segredos - O histórico do Git vaza credenciais. Correção: apenas.env.example; carregue valores reais dos segredos da plataforma. - Uma Configuração para monorepo - Acopla serviços não relacionados. Correção:
ApiSettings,WorkerSettingspor implantação. - Env ausente no Docker - String vazia pode ser coagida inesperadamente para inteiros opcionais. Correção: use
Optional[int] = Nonee valide. - Sensibilidade a maiúsculas/minúsculas - Chaves de env são sensíveis a maiúsculas/minúsculas no Linux. Correção: documente os nomes exatos em
.env.example.
Alternativas
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
os.environ + casts manuais | Scripts minúsculos com 2-3 variáveis | Mais do que um punhado de configurações |
python-decouple | Projetos Django legados já o utilizando | Pilhas Pydantic/FastAPI novas |
dynaconf | Camadas YAML/TOML multi-ambiente | Você quer tipos Pydantic de ponta a ponta |
django-environ | Configuração apenas para Django | FastAPI ou workers independentes |
FAQs
Como testar com diferentes valores de env?
Limpe o cache e passe o env via monkeypatch.setenv antes de chamar get_settings() - ou use substituições do construtor Settings(_env_file=None, api_key="test").
Posso carregar múltiplos arquivos env?
Passe env_file=(".env", ".env.local") - arquivos posteriores não substituem os anteriores, a menos que as variáveis de ambiente reais vençam.
Como funcionam as configurações aninhadas?
Defina um campo BaseModel aninhado e defina env_nested_delimiter="__" para que CACHE__TTL=300 seja mapeado corretamente.
Isso funciona com FastAPI Depends?
Sim - def settings_dep() -> Settings: return get_settings() e injete em rotas.
Como validar flags mutuamente exclusivas?
Use @model_validator(mode="after") para levantar um erro se USE_SQLITE e DATABASE_URL forem definidos.
E quanto à vinculação de PORT de 12 fatores?
port: int = Field(default=8000, alias="PORT") - Heroku/Fly/Railway injetam PORT automaticamente.
Posso usar TOML em vez de env?
pydantic-settings foca em env; para aplicativos pesados em TOML, combine com carregadores de seção pyproject.toml ou dynaconf.
Como documentar configurações para operadores?
Gere o esquema JSON a partir do modelo ou mantenha .env.example com cada chave e valor de exemplo.
SecretStr vs str simples?
Use SecretStr para tokens e senhas para que o log acidental não imprima segredos.
pydantic-settings funciona com Django?
Sim em scripts autônomos e workers ASGI; projetos Django frequentemente usam django-environ, mas configurações Pydantic funcionam para workers Celery que compartilham o mesmo env.
Relacionados
- Pydantic Basics - modelos e validação
- Configuration and Settings - padrões de arquitetura
- FastAPI Basics - injeção de dependência
- Secrets Management - tratamento de segredos em produção
Versões da Stack: Esta página foi escrita para Python 3.14.0 (stable 3.14, maintenance 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, e uv 0.6+.