Construa Pacotes Python: Guia do Desenvolvimento ao PyPI
Mestre no empacotamento do Python do código até a implantação no PyPI
Empacotamento Python evoluiu significativamente, com ferramentas e padrões modernos tornando mais fácil do que nunca distribuir seu código.
Este guia orienta você na criação de pacotes Python profissionais e na publicação deles no PyPI. Se você é novo em Python ou precisa de um guia rápido, consulte nossa Folha de Dicas Python para se familiarizar com os fundamentos do Python.

Por que empacotar seu código Python?
Empacotar seu projeto Python oferece vários benefícios:
- Reutilização: Compartilhe código entre múltiplos projetos sem copiar e colar
- Distribuição: Permita que outros instalem seu código com um simples
pip install - Gerenciamento de dependências: Especifique e gerencie dependências de forma clara
- Versionamento: Rastreie lançamentos e mantenha compatibilidade para trás
- Padrões profissionais: Siga as melhores práticas da comunidade Python
- Documentação: Estrutura que incentiva documentação e testes adequados
Estrutura Moderna de Pacote Python
Um pacote bem organizado segue esta estrutura:
my-package/
├── src/
│ └── mypackage/
│ ├── __init__.py
│ ├── core.py
│ └── utils.py
├── tests/
│ ├── __init__.py
│ └── test_core.py
├── docs/
│ └── index.md
├── .github/
│ └── workflows/
│ └── publish.yml
├── pyproject.toml
├── README.md
├── LICENSE
└── .gitignore
O src-layout agora é preferido sobre o layout plano porque:
- Impede importações acidentais de código não instalado durante o desenvolvimento
- Torna os testes mais confiáveis forçando a instalação
- Separa claramente o código fonte de outros arquivos do projeto
Ao organizar a estrutura interna do seu pacote, considere aplicar princípios de arquitetura limpa para tornar seu código mais mantinível e testável. Nosso guia sobre Padrões de Projeto Python para Arquitetura Limpa aborda princípios SOLID, injeção de dependência e padrões de arquitetura em camadas que funcionam excelente com pacotes Python.
O arquivo pyproject.toml: Configuração Moderna
pyproject.toml (PEP 518, 621) é o padrão moderno para configuração de projetos Python, substituindo o legado setup.py:
[build-system]
requires = ["setuptools>=68.0", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "mypackage"
version = "0.1.0"
description = "Um fantástico pacote Python"
readme = "README.md"
requires-python = ">=3.8"
license = {text = "MIT"}
authors = [
{name = "Seu Nome", email = "você@example.com"}
]
keywords = ["exemplo", "tutorial", "pacote"]
classifiers = [
"Estado de Desenvolvimento :: 4 - Beta",
"Público-Alvo :: Desenvolvedores",
"Licença :: Aprovada pela OSI :: Licença MIT",
"Linguagem de Programação :: Python :: 3",
"Linguagem de Programação :: Python :: 3.8",
"Linguagem de Programação :: Python :: 3.9",
"Linguagem de Programação :: Python :: 3.10",
"Linguagem de Programação :: Python :: 3.11",
"Linguagem de Programação :: Python :: 3.12",
]
dependencies = [
"requests>=2.28.0",
"click>=8.1.0",
]
[project.optional-dependencies]
dev = [
"pytest>=7.4.0",
"black>=23.0.0",
"flake8>=6.0.0",
"mypy>=1.5.0",
]
docs = [
"sphinx>=7.0.0",
"sphinx-rtd-theme>=1.3.0",
]
[project.urls]
Homepage = "https://github.com/seuusername/mypackage"
Documentação = "https://mypackage.readthedocs.io"
Repositório = "https://github.com/seuusername/mypackage"
Issues = "https://github.com/seuusername/mypackage/issues"
[project.scripts]
mypackage-cli = "mypackage.cli:main"
[tool.setuptools.packages.find]
where = ["src"]
Seções Principais de Configuração
- build-system: Especifica o backend de construção (setuptools, hatchling, poetry-core, flit-core)
- project: Metadados principais e dependências
- project.optional-dependencies: Dependências de recursos extras (dev, docs, testes)
- project.scripts: Pontos de entrada para linha de comando
- tool.*: Configuração específica de ferramentas (black, pytest, mypy, etc.)
Escolhendo um Backend de Construção
Setuptools (Escolha Padrão)
A opção mais amplamente usada e compatível:
[build-system]
requires = ["setuptools>=68.0", "wheel"]
build-backend = "setuptools.build_meta"
Vantagens: Compatibilidade universal, recursos extensos, ecossistema grande Desvantagens: Configuração mais verbosa, mais lento do que alternativas mais novas
Hatchling (Moderno e Rápido)
Backend moderno leve e performante:
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
Vantagens: Construção rápida, configuração simples, bons padrões Desvantagens: Menos plugins do que setuptools
Poetry (Completo)
Gerenciamento completo de dependências e ambientes:
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
[tool.poetry]
name = "mypackage"
version = "0.1.0"
description = "Um fantástico pacote Python"
authors = ["Seu Nome <você@example.com>"]
[tool.poetry.dependencies]
python = "^3.8"
requests = "^2.28.0"
Vantagens: Resolução de dependências, arquivos de bloqueio, fluxo de trabalho integrado Desvantagens: Fluxo de trabalho diferente, superfície maior de ferramentas
Flit (Minimalista)
Ferramenta simples para pacotes simples:
[build-system]
requires = ["flit_core >=3.2,<4"]
build-backend = "flit_core.buildapi"
Vantagens: Extremamente simples, configuração mínima Desvantagens: Recursos limitados para pacotes complexos
Construindo seu Pacote
Instale as Ferramentas de Construção
# Instale a ferramenta moderna de construção
pip install build
# Ou para Poetry
pip install poetry
# Ou para Hatchling
pip install hatch
Construa os Arquivos de Distribuição
Usando o pacote build (funciona com qualquer backend):
# Limpe builds anteriores
rm -rf dist/ build/ *.egg-info
# Construa a distribuição de fonte e a roda
python -m build
# Isso cria:
# dist/mypackage-0.1.0.tar.gz (distribuição de fonte)
# dist/mypackage-0.1.0-py3-none-any.whl (roda)
Usando Poetry:
poetry build
Usando Hatch:
hatch build
Entenda os Formatos de Distribuição
Distribuição de Fonte (sdist) - .tar.gz
- Contém o código fonte e as instruções de construção
- O pip dos usuários o constrói durante a instalação
- Inclui testes, documentação e outros arquivos de desenvolvimento
Roda - .whl
- Distribuição binária pré-construída
- Instalação rápida (sem etapa de construção)
- Plataforma específica ou puramente em Python
- Formato recomendado para distribuição
Publicando no PyPI
Método 1: Upload Manual com Twine (Tradicional)
# Instale twine
pip install twine
# Verifique o pacote antes de enviar
twine check dist/*
# Faça upload para o TestPyPI primeiro (recomendado)
twine upload --repository testpypi dist/*
# Teste a instalação do TestPyPI
pip install --index-url https://test.pypi.org/simple/ mypackage
# Faça upload para o PyPI de produção
twine upload dist/*
Configure credenciais em ~/.pypirc:
[distutils]
index-servers =
pypi
testpypi
[pypi]
username = __token__
password = pypi-AgEIcHlwaS5vcmc...
[testpypi]
repository = https://test.pypi.org/legacy/
username = __token__
password = pypi-AgENdGVzdC5weXBpLm9yZw...
Método 2: Publicação Confiável (Recomendado para CI/CD)
A Publicação Confiável usa OpenID Connect (OIDC) para autenticar a partir de plataformas de CI/CD sem armazenar tokens.
Configuração no PyPI:
- Vá para as configurações do seu projeto no PyPI
- Navegue até a seção “Publicação”
- Adicione um novo “publicador pendente”
- Configure:
- Proprietário: Seu nome de usuário/organização no GitHub
- Repositório: Nome do repositório
- Workflow:
publish.yml - Ambiente:
release(opcional, mas recomendado)
Workflow do GitHub Actions (.github/workflows/publish.yml):
name: Publicar no PyPI
on:
release:
types: [published]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configurar Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Instalar dependências de construção
run: |
python -m pip install --upgrade pip
pip install build
- name: Construir o pacote
run: python -m build
- name: Armazenar pacotes de distribuição
uses: actions/upload-artifact@v3
with:
name: python-package-distributions
path: dist/
publish:
needs: build
runs-on: ubuntu-latest
environment: release
permissions:
id-token: write
steps:
- name: Baixar distribuições
uses: actions/download-artifact@v3
with:
name: python-package-distributions
path: dist/
- name: Publicar no PyPI
uses: pypa/gh-action-pypi-publish@release/v1
Vantagens:
- Nenhuma necessidade de gerenciar ou proteger tokens de API
- Autenticação automática via OIDC
- Segurança reforçada por meio de regras de proteção de ambiente
- Rastreamento de auditoria de todas as publicações
Boas Práticas
1. Gerenciamento de Versões
Use o versionamento semântico (SemVer): MAIOR.MENOR.PATCH
# Instale a ferramenta de aumento de versão
pip install bump2version
# Aumente a versão
bump2version patch # 0.1.0 -> 0.1.1
bump2version minor # 0.1.1 -> 0.2.0
bump2version major # 0.2.0 -> 1.0.0
Configure em .bumpversion.cfg:
[bumpversion]
current_version = 0.1.0
commit = True
tag = True
[bumpversion:file:pyproject.toml]
search = version = "{current_version}"
replace = version = "{new_version}"
[bumpversion:file:src/mypackage/__init__.py]
search = __version__ = "{current_version}"
replace = __version__ = "{new_version}"
2. Inclua Arquivos Essenciais
README.md: Descrição clara do projeto, instalação, exemplos de uso LICENSE: Escolha a licença apropriada (MIT, Apache 2.0, GPL, etc.) CHANGELOG.md: Documente as mudanças entre versões .gitignore: Exclua artefatos de construção, caches, ambientes virtuais
3. Testes abrangentes
# Instale dependências de teste
pip install pytest pytest-cov
# Execute testes com cobertura
pytest --cov=mypackage tests/
# Gere relatório de cobertura
pytest --cov=mypackage --cov-report=html tests/
Configure em pyproject.toml:
[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
python_functions = ["test_*"]
addopts = "--strict-markers --cov=mypackage"
4. Ferramentas de Qualidade do Código
# Formatação
black src/ tests/
# Linting
flake8 src/ tests/
# Verificação de tipo
mypy src/
# Ordenação de importações
isort src/ tests/
Integre em hooks de pre-commit (.pre-commit-config.yaml):
repos:
- repo: https://github.com/psf/black
rev: 23.9.1
hooks:
- id: black
- repo: https://github.com/pycqa/flake8
rev: 6.1.0
hooks:
- id: flake8
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.5.1
hooks:
- id: mypy
5. Documentação
Use Sphinx para documentação:
# Instale Sphinx
pip install sphinx sphinx-rtd-theme
# Inicialize docs
cd docs
sphinx-quickstart
# Construa a documentação
make html
Ou use MkDocs para documentação baseada em Markdown mais simples:
pip install mkdocs mkdocs-material
mkdocs new .
mkdocs serve
6. Integração Contínua
Testar seus pacotes Python em diferentes plataformas e ambientes é crucial para confiabilidade. Para insights sobre o desempenho do Python em diferentes cenários de implantação, veja nossa comparação de Desempenho de AWS Lambda: JavaScript vs Python vs Golang, que explora como o Python se comporta em ambientes sem servidor.
Workflow completo de CI/CD (.github/workflows/ci.yml):
name: CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
steps:
- uses: actions/checkout@v4
- name: Configurar Python
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Instalar dependências
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"
- name: Executar testes
run: pytest --cov=mypackage --cov-report=xml
- name: Enviar cobertura
uses: codecov/codecov-action@v3
with:
file: ./coverage.xml
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configurar Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Instalar dependências
run: |
pip install black flake8 mypy
- name: Verificação de formatação com Black
run: black --check src/ tests/
- name: Flake8
run: flake8 src/ tests/
- name: MyPy
run: mypy src/
Problemas Comuns e Soluções
Problema 1: Erros de Importação Após a Instalação
Problema: O pacote foi instalado, mas as importações falham
Solução: Garanta a estrutura adequada do pacote com arquivos __init__.py e configuração correta do pyproject.toml:
[tool.setuptools.packages.find]
where = ["src"]
include = ["mypackage*"]
Problema 2: Dependências Faltando
Problema: O pacote é instalado, mas falha no tempo de execução devido a dependências faltando
Solução: Declare todas as dependências de tempo de execução no pyproject.toml:
[project]
dependencies = [
"requests>=2.28.0",
"click>=8.1.0",
]
Problema 3: Conflitos de Versão
Problema: O pacote funciona no desenvolvimento, mas falha em produção
Solução: Use ambientes virtuais e especifique versões mínimas:
# Crie um ambiente isolado
python -m venv .venv
source .venv/bin/activate # No Windows: .venv\Scripts\activate
# Instale no modo editável para desenvolvimento
pip install -e ".[dev]"
Problema 4: Tamanho do Pacote Grande
Problema: O pacote demora muito para baixar/instalar
Solução: Exclua arquivos desnecessários usando MANIFEST.in:
include README.md
include LICENSE
include pyproject.toml
recursive-include src *.py
recursive-exclude * __pycache__
recursive-exclude * *.py[co]
recursive-exclude tests *
recursive-exclude docs *
Problema 5: Problemas Específicos da Plataforma
Problema: O pacote funciona em um OS, mas falha em outro
Solução: Teste em múltiplas plataformas usando matrizes de construção CI/CD (veja o exemplo de CI acima)
Checklist de Publicação
Antes de publicar seu pacote no PyPI, verifique:
- Todos os testes passam em diferentes versões do Python
- O código está formatado e lintado
- O README.md está completo com exemplos
- O arquivo LICENSE está incluído
- O número da versão foi atualizado
- O CHANGELOG.md foi atualizado
- As dependências estão especificadas corretamente
- O pacote constrói sem erros (
python -m build) - O pacote foi testado no TestPyPI
- A documentação está atualizada
- O repositório Git está marcado com a versão
- Um lançamento no GitHub foi criado (para publicação confiável)
Tópicos Avançados
Pontos de Entrada e Ferramentas CLI
Crie interfaces de linha de comando:
[project.scripts]
mypackage = "mypackage.cli:main"
Implementação em src/mypackage/cli.py:
import click
@click.command()
@click.option('--name', default='Mundo', help='Nome para cumprimentar')
def main(name):
"""Exemplo de ferramenta CLI simples"""
click.echo(f'Olá, {name}!')
if __name__ == '__main__':
main()
Para um exemplo real de como criar pacotes Python que interagem com APIs externas, consulte nosso guia sobre Integrando Ollama com Python, que demonstra a criação de clientes Python com integrações tanto da API REST quanto da biblioteca oficial.
Sistemas de Plugin
Habilite a descoberta de plugins:
[project.entry-points."mypackage.plugins"]
plugin_a = "mypackage_plugin_a:PluginA"
Extensões C
Para código crítico de desempenho:
[tool.setuptools.ext-modules]
name = "mypackage._speedups"
sources = ["src/mypackage/_speedups.c"]
Pacotes de Namespace
Para pacotes distribuídos sob um namespace comum:
[tool.setuptools.packages.find]
where = ["src"]
include = ["empresa.*"]
[tool.setuptools.package-data]
"empresa.mypackage" = ["py.typed"]
Ferramentas e Recursos Úteis
Ferramentas de Desenvolvimento de Pacotes
- cookiecutter: Modelos de projeto para pacotes Python
- tox: Automação de testes em várias versões do Python
- nox: Automação de testes flexível (alternativa ao tox)
- pre-commit: Framework de hooks do Git para qualidade do código
- commitizen: Padronize mensagens de commit e versionamento
Plataformas de Documentação
- Read the Docs: Hospedagem gratuita de documentação
- GitHub Pages: Hospede MkDocs ou documentação Sphinx
- pdoc: Gerador simples de documentação de API
Registries de Pacotes
- PyPI: O índice oficial de pacotes Python (pypi.org)
- TestPyPI: Ambiente de teste (test.pypi.org)
- Anaconda.org: Distribuição de pacotes Conda
- GitHub Packages: Hospedagem de pacotes privados
Monitoramento e Análise
- PyPI Stats: Estatísticas de downloads de pacotes
- Libraries.io: Monitoramento de dependências e alertas
- Snyk: Varredura de vulnerabilidades de segurança
- Dependabot: Atualizações automatizadas de dependências
Conclusão
O empacotamento moderno de Python evoluiu para ser amigável ao desenvolvedor com padrões como pyproject.toml, backends poderosos de construção e publicação segura via Publicação Confiável. Seguindo este guia, você pode criar pacotes Python profissionais e mantiveis que atendam efetivamente aos seus usuários.
Principais lições aprendidas:
- Use pyproject.toml para todos os novos projetos
- Escolha o backend de construção certo para suas necessidades
- Implemente testes automatizados e CI/CD
- Use Publicação Confiável para implantação segura sem tokens
- Siga versionamento semântico e mantenha logs de mudanças
- Forneça documentação abrangente e exemplos
O ecossistema de empacotamento Python continua a melhorar com melhor ferramentas, padrões e recursos de segurança. Mantenha-se atualizado com Propostas de Melhoria do Python (PEPs) e melhores práticas da comunidade para manter seus pacotes modernos e mantiveis.
Links Úteis
- Guia do Usuário do Empacotamento Python
- PEP 518 - Especificando Requisitos do Sistema de Construção
- PEP 621 - Armazenando metadados do projeto em pyproject.toml
- Documentação da Publicação Confiável do PyPI
- Documentação do Setuptools
- Documentação do Poetry
- Documentação do Hatch
- TestPyPI
- Repositório GitHub da Python Packaging Authority
- Versionamento Semântico
- Escolha uma Licença