Estruturando um projeto
Esta aula ensina como estruturar um projeto Python profissional, abordando desde o layout de diretórios até a configuração com pyproject.toml, com foco no src layout e boas práticas de organização, testes e documentação.
Nesta aula, você aprenderá a organizar um projeto Python de forma profissional, seguindo padrões amplamente adotados pela comunidade. Uma boa estrutura de projeto é essencial para a manutenibilidade, escalabilidade e colaboração em equipe. Vamos explorar desde o layout básico de pastas até a configuração moderna com pyproject.toml, incluindo o src layout e boas práticas que facilitam o desenvolvimento, teste e distribuição do seu código.
Muitos projetos Python começam com scripts soltos, mas conforme o código cresce, a falta de organização gera problemas como dificuldade de importação, testes frágeis e dificuldade de empacotamento. Ao final desta aula, você terá um modelo claro para iniciar novos projetos ou reorganizar os existentes, alinhado às ferramentas atuais como pip, build e poetry.
Layout
O layout de um projeto Python define a estrutura de diretórios e arquivos que compõem o projeto. Um layout bem planejado separa claramente o código-fonte, os testes, a documentação e os arquivos de configuração. Isso torna o projeto mais fácil de navegar, entender e manter.
Um layout comum para projetos pequenos e médios é o flat layout, onde o pacote principal fica na raiz, ao lado de outros arquivos. No entanto, para projetos maiores ou que serão publicados como bibliotecas, o src layout (que veremos adiante) é mais recomendado. Vamos começar com um exemplo simples e evoluir para o src layout.
Exemplo de layout flat:
meu_projeto/
├── meu_pacote/
│ ├── __init__.py
│ ├── modulo1.py
│ └── modulo2.py
├── tests/
│ ├── test_modulo1.py
│ └── test_modulo2.py
├── README.md
├── pyproject.toml
└── .gitignore
Nesse layout, o pacote meu_pacote está na raiz, o que facilita importações simples, mas pode causar conflitos de nomes em projetos grandes ou ao instalar o pacote em modo desenvolvimento. Por isso, muitos projetos adotam o src layout.
pyproject.toml (visão geral)
O arquivo pyproject.toml é o formato padrão para configuração de projetos Python, definido na PEP 518 e estendido pela PEP 621. Ele substitui arquivos como setup.py e setup.cfg em muitos projetos, centralizando metadados, dependências e configurações de ferramentas em um único arquivo.
Um pyproject.toml típico contém seções para o sistema de build, metadados do projeto e configurações de ferramentas (como pytest, black, isort). Exemplo:
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
[project]
name = "meu-projeto"
version = "0.1.0"
description = "Um projeto exemplo"
requires-python = ">=3.9"
dependencies = [
"requests>=2.25",
]
[project.optional-dependencies]
dev = [
"pytest>=7.0",
"black",
]
[tool.pytest.ini_options]
testpaths = ["tests"]
Nesse exemplo, a seção [build-system] define o backend de build (setuptools). A seção [project] contém metadados como nome, versão e dependências. A seção [project.optional-dependencies] define dependências opcionais para desenvolvimento. Configurações de ferramentas são colocadas em seções como [tool.pytest.ini_options].
O pyproject.toml é usado por ferramentas como pip (para instalar o pacote), build (para gerar distribuições) e editores de código para configuração de linting e formatação. É importante conhecer sua estrutura para configurar corretamente seu projeto.
src layout
O src layout é uma estrutura de diretórios onde o código-fonte do pacote fica dentro de uma pasta src/. Por exemplo:
meu_projeto/
├── src/
│ └── meu_pacote/
│ ├── __init__.py
│ ├── modulo1.py
│ └── modulo2.py
├── tests/
│ ├── test_modulo1.py
│ └── test_modulo2.py
├── README.md
├── pyproject.toml
└── .gitignore
Esse layout oferece várias vantagens: evita conflitos de importação acidentais, garante que os testes testem a versão instalada do pacote (e não uma cópia local), e facilita o empacotamento. Com o src layout, o código é instalado em modo desenvolvimento (pip install -e .) e os testes importam o pacote instalado, não o código da árvore de origem.
Para configurar o src layout no pyproject.toml, é necessário indicar onde está o pacote. Com setuptools, você pode usar a opção package-dir ou simplesmente a configuração automática:
[tool.setuptools.packages.find]
where = ["src"]
Isso faz com que o setuptools descubra pacotes dentro de src/. Ao instalar o pacote com pip install -e ., o Python poderá importar o pacote de qualquer lugar, pois ele é instalado no ambiente.
O src layout é recomendado para projetos que serão distribuídos, pois reduz erros de importação e garante consistência entre o desenvolvimento e o uso real do pacote.
Boas práticas
Além da estrutura de pastas, boas práticas de organização incluem: usar nomes descritivos para módulos e pacotes, manter a separação entre código, testes e documentação, e configurar ferramentas de qualidade de código (linters, formatters).
Algumas boas práticas essenciais:
- Use um ambiente virtual para isolar dependências do projeto.
- Mantenha os testes separados em uma pasta
tests/, com nomes começando comtest_. - Documente o projeto com um README claro e, se possível, docstrings nos módulos.
- Configure ferramentas como black, isort e flake8 no
pyproject.tomlou em arquivos de configuração. - Use controle de versão (git) e inclua um
.gitignoreadequado. - Defina uma licença e um arquivo
CHANGELOG.mdpara registrar mudanças.
Exemplo de configuração para black no pyproject.toml:
[tool.black]
line-length = 88
target-version = ["py39"]
Seguir essas práticas torna o projeto mais profissional e fácil de manter, tanto para você quanto para outros colaboradores.
Referências
- Empacotando projetos Python - Documentação oficial
- PEP 518 – Especificação do pyproject.toml
- PEP 621 – Metadados do projeto
- Documentação do pytest
- Documentação do Black
- Descoberta de pacotes no setuptools
Exercícios
- Crie a estrutura de diretórios para um projeto chamado
meu_appusando o src layout, com um pacotemeu_pacotee uma pasta de testes. - Escreva um
pyproject.tomlmínimo para um pacote chamadomeu_pacote, versão 0.1.0, com dependência em requests e usando setuptools como backend. - Explique por que o src layout é preferível ao flat layout em projetos que serão publicados como bibliotecas.
- Adicione uma configuração no
pyproject.tomlpara que o pytest considere a pastatestscomo diretório de testes. - Liste três boas práticas para manter um projeto Python organizado e explique brevemente cada uma.
- Usar um ambiente virtual: isola as dependências do projeto, evitando conflitos com outros projetos.
- Manter testes separados: facilita a execução e manutenção dos testes.
- Configurar ferramentas de qualidade: como black e flake8, para manter o código consistente e legível.
meu_app/
├── src/
│ └── meu_pacote/
│ ├── __init__.py
│ └── modulo.py
├── tests/
│ └── test_modulo.py
├── README.md
├── pyproject.toml
└── .gitignore
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
[project]
name = "meu_pacote"
version = "0.1.0"
dependencies = [
"requests>=2.25",
]
[tool.pytest.ini_options]
testpaths = ["tests"]
Observações finais
Estruturar um projeto Python corretamente é um investimento que economiza tempo e dores de cabeça no futuro. Comece com uma estrutura simples e evolua conforme a complexidade aumentar. Lembre-se de que a consistência é mais importante do que seguir cegamente um padrão; adapte o layout às necessidades do seu projeto.
Explore ferramentas como poetry e hatch, que gerenciam ambientes e empacotamento de forma integrada. O conhecimento de pyproject.toml é essencial para interagir com essas ferramentas modernas.