Checklist de Decisões de Arquitetura de Projeto
Use este checklist ao iniciar ou reestruturar um serviço Python para que as decisões de layout, limites e ferramentas sejam tomadas deliberadamente antes que o código se solidifique em torno de acidentes.
Como Usar Este Checklist
- Percorra os níveis em ordem - as escolhas posteriores dependem das anteriores.
- Registre cada decisão em um breve ADR (Architecture Decision Record) ou seção do README para que a equipe não precise rediscutir os padrões.
- Revise após o primeiro deploy em produção; suposições de "greenfield" raramente sobrevivem ao contato com os usuários.
- Trate itens não marcados como dívida técnica com um proprietário e data alvo, não como lacunas silenciosas.
Decisões Fundamentais
- Versão do Runtime: Python 3.14.0 (ou o piso suportado pela sua organização) travado em
pyproject.toml, CI e imagens Docker.- 3.14+: serviços greenfield, recursos mais recentes de tipagem e stdlib.
- 3.13 manutenção: bibliotecas que precisam suportar alvos de deploy mais antigos.
- Gerenciador de Pacotes:
uv 0.6+para lockfiles e instalações rápidas vspipsimples +requirements.txt.- uv: equipes que desejam ambientes reproduzíveis e monorepos de workspace.
- pip: scripts mínimos sem necessidade de lockfile.
- Layout: layout
src/vs pacote plano na raiz do repositório.- layout src: bibliotecas e serviços testados como pacotes instalados.
- plano: apenas utilitários de um único arquivo.
- Modelo de Distribuição: pacote instalável vs aplicativo implantável (ou ambos).
- Pacote: biblioteca compartilhada consumida por múltiplos serviços.
- App: implantação única com um ponto de entrada
main.
- Monorepo vs Polyrepo: um repositório com múltiplos pacotes vs um serviço por repositório.
- Monorepo: modelos de domínio compartilhados e lançamentos coordenados.
- Polyrepo: equipes e cadências de lançamento independentes.
Decisões de Limites
- Camada de Domínio: módulo(s) Python puro(s) sem importações de framework.
- Sim: regras de negócio de longa duração sobrevivem a FastAPI/Django/Flask.
- Não: scripts e notebooks descartáveis.
- Framework HTTP: FastAPI 0.115+, Django 5.2, ou Flask 3.1.
- FastAPI: APIs assíncronas, OpenAPI-first, modelos Pydantic 2.
- Django: admin, ORM, aplicativos web "batteries-included".
- Flask: aplicativos WSGI mínimos e crescimento gradual.
- Limite de Persistência: camada de repositório/DAO vs chamadas de ORM espalhadas nos handlers.
- Repositório: domínio testável sem um banco de dados.
- ORM Direto: protótipos e ferramentas internas.
- Fonte de Configuração: variáveis de ambiente +
pydantic-settingsvs arquivos de configuração no git.- Env + pydantic-settings: deploys 12-factor em dev/stage/prod.
- Arquivos: ferramentas de desenvolvimento apenas locais sem segredos.
- Manuseio de Segredos: armazenamento de segredos da plataforma vs
.envexcluído do git.- Armazenamento: credenciais de produção nunca no disco na imagem.
.env: apenas em máquinas de desenvolvedor locais.
Qualidade e Ferramentas
- Linter/Formatador:
ruff 0.9+como a ferramenta "tudo em um" padrão. - Verificação de Tipos: mypy ou pyright em CI com uma estratégia de "ratchet" (código novo estrito, legado gradual).
- Executor de Testes:
pytestcom fixtures colocalizadas emtests/. - Portão de Cobertura: limite mínimo em linhas alteradas, não uma meta de 100% de vaidade.
- Hooks de Pré-commit: formata, lint e verifica tipos antes do push.
- Matriz de CI: testa na versão Python fixada mais uma versão de manutenção (ex: 3.13).
Dados e Integração
- Stack de Dados Tabulares: pandas 2.2+ vs Polars 1.x.
- pandas: o ecossistema mais amplo e familiaridade com notebooks.
- Polars: ETL crítico para performance e pipelines lazy.
- Limite de Inferência de ML: PyTorch 2.6+ carregado em um adaptador, não dentro de entidades de domínio.
- Clientes HTTP Externos: módulo cliente dedicado com timeouts, retentativas e respostas tipadas.
- Mensagens/Trabalho Assíncrono: tarefas em segundo plano in-process vs worker de fila (Celery, ARQ, Dramatiq).
Operações
- Logging: logs JSON estruturados com IDs de correlação, não
printem código de biblioteca. - Endpoints de Saúde: liveness vs readiness separados para orquestradores.
- Ponto de Entrada do Contêiner:
python -m packageexplícito ou comando uvicorn/gunicorn documentado. - Estratégia de Migração: migrações Alembic/Django executadas como um passo de deploy, não SQL manual.
- Observabilidade: métricas e traces no limite do middleware do framework, não dentro de funções de domínio.
Aplicando o Checklist em Ordem
- Fundação (1-5): mais difícil de reverter - decida antes do primeiro merge.
- Limites (6-10): define a testabilidade e o custo de troca de framework.
- Qualidade (11-16): barato de adicionar cedo, caro de adaptar depois.
- Dados/Ops (17-25): alinhe com as habilidades da equipe e a plataforma de produção.
FAQs
Um novo projeto de API deve ter como padrão FastAPI ou Django?
Escolha FastAPI quando a superfície principal for uma API JSON/HTTP com documentação OpenAPI e I/O assíncrono. Escolha Django quando precisar do ecossistema de admin, autenticação e ORM como uma stack coesa. Ambos podem crescer - mas mudar depois é custoso.
O layout src vale a pena para um serviço pequeno?
Sim, para qualquer coisa instalada em CI ou Docker. O layout src força os testes a importar o pacote da maneira que a produção faz, pegando bugs do tipo "funciona localmente por causa de um hack no PYTHONPATH" cedo.
Quando posso pular uma camada de domínio dedicada?
Pule para scripts com cerca de 300 linhas ou menos, sem expectativa de vida além de um trimestre. Assim que múltiplos endpoints compartilharem regras, extraia a lógica de domínio antes que a duplicação vença.
Preciso de pandas e Polars?
Geralmente não. Escolha um motor tabular principal por serviço. Use o outro apenas nos limites de integração se um pipeline parceiro o exigir.
Onde os modelos Pydantic devem ficar?
Nos limites: DTOs de requisição/resposta HTTP, configurações e formas de API externa. Mantenha os tipos de domínio principais como dataclasses ou classes simples, a menos que a validação seja inerentemente focada no limite.
Quão rigorosa deve ser a verificação de tipos desde o primeiro dia?
Habilite a verificação em CI imediatamente, mas permita substituições em módulos legados. Ratchet: novos arquivos devem passar por regras estritas; aperte as configurações globais a cada sprint.
Os segredos devem viver em pydantic-settings?
As classes de configurações devem ler segredos do ambiente ou de um backend de segredos. Nunca cometa valores de segredo; documente os nomes das variáveis necessárias em .env.example.
Monorepo ou polyrepo para dois serviços relacionados?
Monorepo quando eles compartilham modelos e lançam juntos. Polyrepo quando equipes, SLAs e permissões de deploy são independentes.
Qual é a matriz mínima de CI para Python 3.14?
Execute testes em 3.14.0 mais 3.13 se você distribui bibliotecas. Repositórios apenas de aplicativos podem fixar uma única versão para corresponder às imagens de produção.
Quando devo escrever um ADR para um item do checklist?
Escreva um breve ADR quando a decisão afetar múltiplas equipes, for difícil de reverter ou surpreender alguém durante a revisão. Uma nota de uma linha no README é suficiente para padrões óbvios como "usamos ruff".
Como registro itens não marcados?
Adicione um issue rastreado para cada lacuna: proprietário, nível de risco e se bloqueia a produção. Revise no planejamento de sprint em vez de deixar caixas em branco silenciosas.
Este checklist se aplica a notebooks e experimentos de ML?
Use os níveis de Fundação e Qualidade. Os níveis de Limite e Ops se aplicam quando um experimento é promovido a um job agendado ou API.
Relacionados
- Layout src e Estrutura de Pacotes - higiene de importação após a escolha do layout
- Configuração e Configurações - padrões de configuração baseados em env
- Arquitetura Limpa / Hexagonal - detalhes de portas e adaptadores
- Decisões de Refatoração - quando a escolha inicial errada precisa de correção
- Melhores Práticas de Arquitetura - hábitos de design contínuos
Versões da Stack: Esta página foi escrita para Python 3.14.0 (estável 3.14, manutenção 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+.