Gerenciar dependências Python com requirements.txt manual funciona até o projeto crescer — aí vira conflito de versões e builds que quebram sozinhos. O Poetry resolve isso com um lockfile determinístico, grupos de dependências e publicação integrada. Neste guia mostro o fluxo profissional completo.
Vou partir de um projeto novo e evoluir até publicar um pacote.
Por que Poetry
- Lockfile: versões exatas de tudo, incluindo dependências transitivas.
- Grupos: separe dependências de dev, test e docs.
- Ambientes: cria e gerencia o virtualenv sozinho.
- Build e publish: empacota e publica no PyPI com um comando.
Instalando
curl -sSL https://install.python-poetry.org | python3 -
poetry --version
Iniciando um projeto
poetry new meu-projeto
cd meu-projeto
# ou, em projeto existente:
poetry init
Adicionando dependências
poetry add requests pydantic
poetry add --group dev pytest ruff mypy
Isso atualiza o pyproject.toml e o poetry.lock automaticamente.
O pyproject.toml
[tool.poetry]
name = "meu-projeto"
version = "0.1.0"
description = "Exemplo"
authors = ["Voce "]
[tool.poetry.dependencies]
python = "^3.12"
requests = "^2.32"
pydantic = "^2.9"
[tool.poetry.group.dev.dependencies]
pytest = "^8.3"
ruff = "^0.6"
mypy = "^1.11"
Instalando do lock
Em CI ou na máquina de outro dev, o lock garante exatamente as mesmas versões.
poetry install --no-root
Rodando comandos no ambiente
poetry run pytest
poetry run python app.py
# ou entre no shell do venv
poetry shell
Atualizando dependências com cuidado
poetry update requests # atualiza uma
poetry update # atualiza todas (respeitando os ranges)
poetry show --outdated # o que esta defasado
Exportando para requirements.txt
Alguns ambientes ainda pedem requirements. O Poetry exporta.
poetry export -f requirements.txt --output requirements.txt --without-hashes
Build e publicação
poetry build # gera .whl e .tar.gz em dist/
poetry publish # envia ao PyPI (requer credenciais)
Integração com Docker
FROM python:3.12-slim
RUN pip install poetry==1.8.3
WORKDIR /app
COPY pyproject.toml poetry.lock ./
RUN poetry config virtualenvs.create false && poetry install --no-root --only main
COPY . .
CMD ["python", "app.py"]
Boas práticas
- Comite o
poetry.lock— é ele que garante reprodutibilidade. - Fixe versões de ferramentas de dev no grupo dev.
- Use
--only mainem produção (sem dependências de dev). - Atualize dependências em PRs separados, com testes.
Erros comuns
- Não comitar o lock — builds divergem entre máquinas.
- Editar
requirements.txtà mão enquanto usa Poetry. - Misturar pip e poetry no mesmo ambiente.
- Ignorar conflitos de versão e forçar com
--no-deps.
Checklist
poetry inite defina o grupo dev.- Adicione dependências com
poetry add. - Comite o lock.
- Use
poetry installem CI. - Exporte requirements só quando necessário.
Scripts customizados
Automatize tarefas repetitivas com atalhos no pyproject.toml.
[tool.poetry.scripts]
serve = "meu_projeto.cli:main"
poetry run serve
Ambientes isolados por projeto
Por padrão, o Poetry cria um virtualenv por projeto. Para criar dentro da pasta:
poetry config virtualenvs.in-project true
poetry env info --path
Resolvendo conflitos de versão
Quando duas dependências pedem versões incompatíveis, o Poetry aponta o conflito.
poetry add "django>=4.2,<5.0"
Use ranges compatíveis (^) e evite pinos exatos desnecessários, que travam atualizações de segurança.
Monorepo e pacotes locais
poetry add ../minha-lib --editable
CI com Poetry
steps:
- uses: actions/setup-python@v5
with: { python-version: "3.12" }
- run: pip install poetry==1.8.3
- run: poetry install --no-root
- run: poetry run pytest -q
Segurança de dependências
Audite vulnerabilidades regularmente. O pip-audit funciona bem junto ao Poetry.
poetry export -f requirements.txt --without-hashes | pip-audit -r /dev/stdin
Estrutura de pacote recomendada
meu-projeto/
src/meu_projeto/
__init__.py
cli.py
core.py
tests/
pyproject.toml
poetry.lock
Configurando src-layout
[tool.poetry]
packages = [{ include = "meu_projeto", from = "src" }]
Plugins úteis do Poetry
poetry self add poetry-plugin-export
Perguntas frequentes
Poetry ou pip-tools? Poetry integra ambiente, lock e build num só lugar.
Poetry ou uv? O uv é mais rápido; o Poetry é mais maduro em build/publish.
Funciona com Docker? Sim — instale o lock sem criar virtualenv.
Poetry em equipe
Padronize a versão do Poetry para todos. Sem isso, cada dev gera locks ligeiramente diferentes.
# .python-version e uma versao fixada de Poetry no CI
pip install poetry==1.8.3
Pitfalls de resolução
Adicione dependências uma a uma e rode os testes. Atualizar tudo de uma vez esconde qual pacote quebrou.
poetry add pacote@^2.0
poetry run pytest -q
Cache de dependências no CI
- uses: actions/cache@v4
with:
path: ~/.cache/pypoetry
key: poetry-${{ hashFiles('poetry.lock') }}
Publicando em repositório privado
[[tool.poetry.source]]
name = "privado"
url = "https://pypi.minhaempresa.com/simple/"
priority = "supplemental"
Comparando gerenciadores modernos
| Ferramenta | Destaque | Quando usar |
|---|---|---|
| Poetry | Build + publish integrados | Pacotes e apps |
| uv | Velocidade extrema | CI e installs rápidos |
| pip-tools | Simples, só lock | Legado com pip |
| conda | Binários científicos | Data science/CUDA |
Fluxo completo de um projeto novo
poetry new api-ia && cd api-ia
poetry add fastapi "uvicorn[standard]" pydantic
poetry add --group dev pytest ruff mypy
poetry run pytest -q
poetry build
Checando o ambiente
poetry env info
poetry show --tree
poetry check
Integração com pre-commit
repos:
- repo: local
hooks:
- id: tests
name: tests
entry: poetry run pytest -q
language: system
pass_filenames: false
Workspaces e projetos múltiplos
Em um repositório com vários pacotes, o Poetry gerencia cada um com seu próprio pyproject.toml. Dependências locais entram com path.
[tool.poetry.dependencies]
minha-lib = { path = "../minha-lib", develop = true }
Cache e velocidade
poetry config cache-dir ~/.cache/pypoetry
poetry install --no-root --sync # remove o que nao esta no lock
Segurança do lock
O lock registra hashes das distribuições, dificultando ataque de pacote adulterado. Revise PRs que alteram o lock.
Migrando de requirements para Poetry
# em projeto existente
poetry init --no-interaction
# adicione as deps do requirements
poetry add $(cat requirements.txt | grep -v '^#' | sed 's/==/^/' | tr '
' ' ')
poetry install
Documentação de API com Sphinx/MkDocs
poetry add --group docs mkdocs mkdocs-material
poetry run mkdocs serve
Perguntas frequentes (final)
Posso ter só o lock sem Poetry instalado? Não — use poetry export para gerar um requirements do lock.
O Poetry gerencia a versão do Python? Ele exige, mas o pyenv gerencia a instalação.
Vale a pena em scripts pequenos? Em projetos de um arquivo, talvez um venv simples baste.
Erros de iniciante com Poetry
- Rodar
pip installdentro do venv do Poetry e bagunçar o ambiente. - Não fixar a versão do Poetry entre devs e CI.
- Comitar o diretório
.venvpor engano. - Adicionar dependência de dev no grupo principal.
- Ignorar o
poetry checkantes do build.
Checklist final
poetry initcom nome e versão do Python.- Grupos
devedocsseparados. - Lock commitado.
- Scripts úteis declarados.
- CI instala do lock e roda testes.
- Build e publish automatizados.
Comparando gerenciadores modernos
| Ferramenta | Destaque | Quando usar |
|---|---|---|
| Poetry | Build + publish integrados | Pacotes e apps |
| uv | Velocidade extrema | CI e installs rápidos |
| pip-tools | Simples, só lock | Legado com pip |
| conda | Binários científicos | Data science/CUDA |
Poetry em monorepo com workspaces
Quando vários pacotes vivem no mesmo repositório, cada um tem seu pyproject.toml. Dependências internas entram como caminho local, e o Poetry resolve a árvore inteira.
[tool.poetry.dependencies]
nucleo = { path = "../nucleo", develop = true }
api = { path = "../api", develop = true }
poetry install --no-root
Em times maiores, padronize a versão do Poetry em um arquivo e valide no CI, para que ninguém gere um lock divergente.
Ambientes reprodutíveis no CI
- run: pip install poetry==1.8.3
- run: poetry config virtualenvs.in-project true
- run: poetry install --no-root --no-interaction
- run: poetry run pytest -q
Com --no-interaction, o pipeline nunca fica preso esperando input.
Segurança da cadeia de dependências
Audite regularmente. Vulnerabilidades em dependências transitivas são comuns e passam despercebidas sem verificação automatizada.
poetry export -f requirements.txt --without-hashes | pip-audit -r /dev/stdin
Resumo
Poetry traz para o Python a reprodutibilidade que outros ecossistemas já têm. Com lockfile, grupos e build integrados, você elimina o clássico "na minha máquina funciona". Adote desde o início do projeto — migrar depois é mais trabalhoso.
Referência rápida de comandos
poetry new projeto # cria projeto
poetry init # inicializa em projeto existente
poetry add pacote # adiciona dependencia
poetry add --group dev x # dependencia de desenvolvimento
poetry install # instala do lock
poetry update # atualiza dependencias
poetry run pytest # roda comando no venv
poetry build # gera artefatos
poetry publish # publica no PyPI
Fluxo de release de uma biblioteca
poetry version minor # sobe a versao
poetry run pytest -q # valida
poetry build # empacota
poetry publish --username __token__ --password $PYPI_TOKEN
Automatize em uma GitHub Action disparada por tag — cada release fica reprodutível e auditável.
Grupos opcionais
[tool.poetry.group.docs]
optional = true
[tool.poetry.group.docs.dependencies]
mkdocs = "^1.6"
poetry install --with docs
Migrando de requirements para Poetry
poetry init --no-interaction
poetry add $(grep -v '^#' requirements.txt | sed 's/==/^/' | tr '
' ' ')
poetry install
Perguntas frequentes (final)
Posso ter só o lock sem Poetry instalado? Não — use poetry export para gerar um requirements do lock.
O Poetry gerencia a versão do Python? Ele exige, mas o pyenv gerencia a instalação.
Vale a pena em scripts pequenos? Em projetos de um arquivo, talvez um venv simples baste.
