Construindo Pacotes Python: Guia do Desenvolvimento ao PyPI
Domine o empacotamento em Python, do código ao deployment no PyPI.
A 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 construção de pacotes Python profissionais e na publicação deles no PyPI. Se você é novo em Python ou precisa de uma referência rápida, consulte nossa Lista de Referência de Python para se atualizar com os fundamentos do Python.

Por que Empacotar seu Código Python?
Empacotar seu projeto Python oferece múltiplos benefícios:
- Reutilização: Compartilhe código entre vários 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 claramente
- Versionamento: Rastreie lançamentos e mantenha compatibilidade retroativa
- Padrões Profissionais: Siga as melhores práticas da comunidade Python
- Documentação: A estrutura incentiva documentação e testes adequados
Estrutura Moderna de Pacotes 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 layout src é agora preferível ao layout plano porque:
- Previne importações acidentais de código não instalado durante o desenvolvimento
- Torna os testes mais confiáveis ao forçar 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 mantível e testável. Nosso guia sobre Padrões de Design Python para Arquitetura Limpa cobre 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 pacote Python fantástico"
readme = "README.md"
requires-python = ">=3.8"
license = {text = "MIT"}
authors = [
{name = "Seu Nome", email = "voce@exemplo.com"}
]
keywords = ["exemplo", "tutorial", "pacote"]
classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: 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/seuusuario/mypackage"
Documentation = "https://mypackage.readthedocs.io"
Repository = "https://github.com/seuusuario/mypackage"
Issues = "https://github.com/seuusuario/mypackage/issues"
[project.scripts]
mypackage-cli = "mypackage.cli:main"
[tool.setuptools.packages.find]
where = ["src"]
Seções de Configuração Principais
- 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, testing)
- project.scripts: Pontos de entrada de linha de comando
- tool.*: Configuração específica de ferramentas (black, pytest, mypy, etc.)
Escolhendo um Backend de Construção
Setuptools (Opção Padrão)
A opção mais amplamente utilizada e compatível:
[build-system]
requires = ["setuptools>=68.0", "wheel"]
build-backend = "setuptools.build_meta"
Prós: Compatibilidade universal, recursos extensos, ecossistema grande Contras: Configuração mais verbosa, mais lento que alternativas mais novas
Hatchling (Moderno e Rápido)
Backend moderno leve e performático:
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
Prós: Construções rápidas, configuração simples, bons padrões Contras: Menos plugins que setuptools
Poetry (Tudo-em-Um)
Gerenciamento completo de dependências e ambiente:
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
[tool.poetry]
name = "mypackage"
version = "0.1.0"
description = "Um pacote Python fantástico"
authors = ["Seu Nome <voce@exemplo.com>"]
[tool.poetry.dependencies]
python = "^3.8"
requests = "^2.28.0"
Prós: Resolução de dependências, arquivos de bloqueio, fluxo de trabalho integrado Contras: Fluxo de trabalho diferente, área de superfície de ferramenta maior
Flit (Minimalista)
Ferramenta simples para pacotes simples:
[build-system]
requires = ["flit_core >=3.2,<4"]
build-backend = "flit_core.buildapi"
Prós: Extremamente simples, configuração mínima Contras: Recursos limitados para pacotes complexos
Construindo Seu Pacote
Instale as Ferramentas de Construção
# Instale a ferramenta de construção moderna
pip install build
# Ou para Poetry
pip install poetry
# Ou para Hatchling
pip install hatch
Construa Arquivos de Distribuição
Usando o pacote build (funciona com qualquer backend):
# Limpe construções anteriores
rm -rf dist/ build/ *.egg-info
# Construa distribuição de fonte e wheel
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 (wheel)
Usando Poetry:
poetry build
Usando Hatch:
hatch build
Entendendo Formatos de Distribuição
Distribuição de Fonte (sdist) - .tar.gz
- Contém código-fonte e instruções de construção
- O pip dos usuários o constrói durante a instalação
- Inclui testes, docs e outros arquivos de desenvolvimento
Wheel - .whl
- Distribuição binária pré-construída
- Instalação rápida (sem etapa de construção)
- Específico de plataforma ou Python puro
- 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/*
# Envie para TestPyPI primeiro (recomendado)
twine upload --repository testpypi dist/*
# Teste instalação do TestPyPI
pip install --index-url https://test.pypi.org/simple/ mypackage
# Envie para 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 de plataformas CI/CD sem armazenar tokens.
Configuração no PyPI:
- Vá para as configurações do seu projeto PyPI
- Navegue até a seção “Publishing”
- Adicione um novo “pending publisher”
- Configure:
- Owner: Seu nome de usuário/organização do GitHub
- Repository: Nome do repositório
- Workflow:
publish.yml - Environment:
release(opcional mas recomendado)
Workflow do GitHub Actions (.github/workflows/publish.yml):
name: Publish to PyPI
on:
release:
types: [published]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install build dependencies
run: |
python -m pip install --upgrade pip
pip install build
- name: Build package
run: python -m build
- name: Store distribution packages
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: Download distributions
uses: actions/download-artifact@v3
with:
name: python-package-distributions
path: dist/
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
Vantagens:
- Nenhum token de API para gerenciar ou proteger
- Autenticação automática via OIDC
- Segurança aprimorada através de regras de proteção de ambiente
- Rastro de auditoria de todas as publicações
Melhores Práticas
1. Gerenciamento de Versão
Use versionamento semântico (SemVer): MAJOR.MINOR.PATCH
# Instale ferramenta de incremento de versão
pip install bump2version
# Incremente 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 licença apropriada (MIT, Apache 2.0, GPL, etc.) CHANGELOG.md: Documente alterações 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 de Código
# Formatação
black src/ tests/
# Linting
flake8 src/ tests/
# Verificação de tipo
mypy src/
# Ordenação de importação
isort src/ tests/
Integre em ganchos 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 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 a confiabilidade. Para insights sobre o desempenho do Python em diferentes cenários de implantação, veja nossa comparação de desempenho AWS Lambda: JavaScript vs Python vs Golang, que explora como o Python performa em ambientes serverless.
Fluxo de trabalho completo 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: Set up Python
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"
- name: Run tests
run: pytest --cov=mypackage --cov-report=xml
- name: Upload coverage
uses: codecov/codecov-action@v3
with:
file: ./coverage.xml
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: |
pip install black flake8 mypy
- name: Black formatting check
run: black --check src/ tests/
- name: Flake8
run: flake8 src/ tests/
- name: MyPy
run: mypy src/
Armadilhas Comuns e Soluções
Problema 1: Erros de Importação Após Instalação
Problema: Pacote instalado mas importações falham
Solução: Garanta estrutura de pacote adequada com arquivos __init__.py e configuração correta de pyproject.toml:
[tool.setuptools.packages.find]
where = ["src"]
include = ["mypackage*"]
Problema 2: Dependências Ausentes
Problema: Pacote instala mas falha em tempo de execução devido a dependências ausentes
Solução: Declare todas as dependências de tempo de execução em pyproject.toml:
[project]
dependencies = [
"requests>=2.28.0",
"click>=8.1.0",
]
Problema 3: Conflitos de Versão
Problema: Pacote funciona no desenvolvimento mas falha em produção
Solução: Use ambientes virtuais e especifique versões mínimas:
# Crie ambiente isolado
python -m venv .venv
source .venv/bin/activate # No Windows: .venv\Scripts\activate
# Instale em modo editável para desenvolvimento
pip install -e ".[dev]"
Problema 4: Tamanho do Pacote Grande
Problema: 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 de Plataforma
Problema: Pacote funciona em um OS mas falha em outro
Solução: Teste em múltiplas plataformas usando construções de matriz CI/CD (veja exemplo de CI acima)
Checklist de Publicação
Antes de publicar seu pacote no PyPI, verifique:
- Todos os testes passam em versões Python
- Código está formatado e lintado
- README.md está completo com exemplos
- Arquivo LICENSE está incluído
- Número de versão está atualizado
- CHANGELOG.md está atualizado
- Dependências estão especificadas corretamente
- Pacote constrói sem erros (
python -m build) - Pacote testado no TestPyPI
- Documentação está atualizada
- Repositório Git está taggeado com versão
- Lançamento do GitHub é 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='World', help='Name to greet')
def main(name):
"""Exemplo simples de ferramenta CLI"""
click.echo(f'Olá, {name}!')
if __name__ == '__main__':
main()
Para um exemplo real de criação de pacotes Python que interagem com APIs externas, consulte nosso guia sobre Integração do Ollama com Python, que demonstra a construção de clientes Python com integrações de API REST e biblioteca oficial.
Sistemas de Plugin
Habilite 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 versões Python
- nox: Automação de testes flexível (alternativa ao tox)
- pre-commit: Framework de ganchos Git para qualidade de código
- commitizen: Padronize mensagens de commit e versionamento
Plataformas de Documentação
- Read the Docs: Hospedagem gratuita de documentação
- GitHub Pages: Hospede documentação MkDocs ou Sphinx
- pdoc: Gerador simples de documentação de API
Registros 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 privada de pacotes
Monitoramento e Análise
- PyPI Stats: Estatísticas de download para pacotes
- Libraries.io: Monitoramento de dependências e alertas
- Snyk: Varredura de vulnerabilidades de segurança
- Dependabot: Atualizações automáticas de dependências
Conclusão
O empacotamento Python moderno evoluiu para ser amigável ao desenvolvedor com padrões como pyproject.toml, backends de construção poderosos e publicação segura via Publicação Confiável. Seguindo este guia, você pode criar pacotes Python profissionais e mantíveis que atendem seus usuários de forma eficaz.
Pontos principais:
- 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 o versionamento semântico e mantenha changelogs
- Forneça documentação abrangente e exemplos
O ecossistema de empacotamento Python continua a melhorar com melhores 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 mantíveis.
Links Úteis
- Guia de Usuário de Empacotamento Python
- PEP 518 - Especificando Requisitos de Sistema de Construção
- PEP 621 - Armazenando metadados de projeto em pyproject.toml
- Documentação de Publicação Confiável do PyPI
- Documentação do Setuptools
- Documentação do Poetry
- Documentação do Hatch
- TestPyPI
- Autoridade de Empacotamento Python no GitHub
- Versionamento Semântico
- Escolha uma Licença