
app.py com 800 linhas: como a estrutura do projeto me ensinou a dividir responsabilidade
Meu primeiro projeto profissional em Python era um arquivo. Oitocentas linhas, tudo misturado. Aqui está o que foi forçando a separação — e por que estrutura importa antes de framework.
Tinha um app.py com 800 linhas.
Routes, models, lógica de negócio, helpers de email, configuração — tudo num arquivo só. Quando precisava de algo, dava um Ctrl+F e rezava para encontrar.
Funcionava. O problema apareceu quando um colega começou a trabalhar no mesmo projeto.
Dois commits no mesmo arquivo quase todo dia. Merge conflict em coisa que não tinha relação nenhuma. Eu editava a route de leads, ele editava o modelo de usuário, os dois no mesmo arquivo, Git confuso.
O que forçou a mudança
Não foi arquitetura. Foi dor prática.
Primeiro split: models.py. Tirei tudo relacionado a banco para um arquivo separado. Merge conflict caiu à metade.
Segundo split: utils.py. Tudo que não sabia onde colocar foi para lá. Não é solução boa — utils.py vira lixo com o tempo — mas era melhor que app.py de 1.200 linhas.
O problema do utils.py apareceu quando precisava de algo e tinha que procurar: "isso é utils? é models? ta no app?"
O que funcionou: separar por domínio, não por tipo
Ao invés de "todos os models juntos, todas as routes juntas", separei por recurso:
projeto/
app.py # só inicialização e registro de blueprints
config.py # variáveis de ambiente
leads/
routes.py # HTTP: parse request → chama service → retorna JSON
service.py # lógica de negócio
model.py # estrutura de dados e queries
usuarios/
routes.py
service.py
model.py
tests/
test_leads.py
test_usuarios.py
A separação que importa não é onde o arquivo fica. É que routes.py nunca tem lógica de negócio.
Route: recebe request, valida formato, chama service, retorna response. Não sabe de banco.
Service: contém as regras. Não sabe de HTTP.
Quando isso está separado, você consegue testar o service sem montar request HTTP. Consegue trocar o framework web sem reescrever lógica de negócio.
O teste que mostra se a separação está certa
Se precisar trocar Flask por FastAPI, quantas linhas você reescreve?
Se a resposta é "só as routes", tá bom. Se a resposta é "preciso mexer em todo lugar", o framework vazou para dentro da lógica.
Não é questão de framework. É questão de o quê pode mudar independentemente do quê.
Essa semana: abre o projeto que você mais trabalha. Tem algum arquivo com mais de 300 linhas? Provavelmente tem mais de uma responsabilidade ali. Não precisa refatorar tudo — só identificar onde está misturado. O split acontece naturalmente quando você sabe onde está o problema.