Publicando no PyPI
A publicação envia seu wheel e sdist construídos para o Python Package Index. O TestPyPI fornece um sandbox; a publicação confiável usa tokens OIDC em vez de senhas.
Receita
uv build
uv publish # usa o token do PyPI do ambienteexport UV_PUBLISH_TOKEN=pypi-AgEIcH...
uv publish --index pypiQuando usar isso:
- Compartilhando uma biblioteca com a comunidade Python ou outras equipes
- Distribuindo pacotes internos para um índice privado
- Automatizando releases de CI
Exemplo de Trabalho
# 1. Construir
uv build
ls dist/
# 2. Testar no TestPyPI
uv publish --index testpypi
uv pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ myapp
# 3. Publicar no PyPI de produção
uv publish# Publicação confiável do GitHub Actions (sem token em segredos)
permissions:
id-token: write
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
- run: uv build
- uses: pypa/gh-action-pypi-publish@release/v1O que isso demonstra:
- Construir antes de publicar (nunca publique a árvore de origem diretamente)
- TestPyPI valida metadados e instalação antes da produção
- A publicação confiável usa GitHub OIDC - sem tokens de longa duração
uv publishenvolve o twine com padrões conscientes do projeto
Mergulho Profundo
Checklist de Publicação
- Versão incrementada em pyproject.toml
- CHANGELOG.md atualizado
uv buildbem-sucedidopip install dist/*.whlfunciona em um venv limpo- Publicação e instalação no TestPyPI verificadas
- Publicação no PyPI de produção
- Tag Git enviada
Autenticação
| Método | Segurança | Configuração |
|---|---|---|
| Publicação confiável | Melhor | Configurações do projeto PyPI + GitHub OIDC |
| Token de API | Bom | Token prefixado com pypi- na variável de ambiente |
| Senha | Descontinuado | Não usar |
Armadilhas
- Publicar sem incremento de versão - O PyPI rejeita versões duplicadas. Correção: Incremente a versão primeiro.
- Token no código-fonte ou logs de CI - credenciais vazadas. Correção: Apenas variáveis de ambiente ou publicação confiável.
- Nome do pacote incorreto - risco de typosquatting ou nome já em uso. Correção: Verifique o nome no PyPI antes da primeira publicação.
- Metadados de README/licença ausentes - página PyPI pobre. Correção:
readme = "README.md"elicenseem[project]. - Publicar sdist sem wheel - instalações lentas para consumidores. Correção: Sempre publique wheel e sdist.
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
| Índice privado | Pacotes internos | Open-source público |
| Instalação via URL Git | Interno não publicado | Biblioteca reutilizável |
| Imagem Docker | Deploy de aplicação | Distribuição de biblioteca |
FAQs
twine ou uv publish?
uv publish para projetos uv. twine funciona universalmente: twine upload dist/*.
Como obtenho uma conta PyPI?
Registre-se em pypi.org. Ative a 2FA. Crie um projeto para publicação confiável.
O que é TestPyPI?
test.pypi.org - sandbox de registro. Conta e tokens separados.
Posso despublicar?
Sim, "yank" (ocultar). Exclusão permanente apenas dentro de 24 horas e raramente.
Como reivindico um nome de pacote?
A primeira publicação vence. Verifique a disponibilidade antes de registrar o nome.
Como publico a partir da CI?
Publicação confiável (recomendado) ou UV_PUBLISH_TOKEN em segredos.
Quais arquivos são enviados?
Tudo em dist/ - tipicamente um .whl e um .tar.gz.
Como adiciono uma descrição no PyPI?
readme = "README.md" em pyproject.toml é renderizado na página do PyPI.
Classificadores?
classifiers = ["Programming Language :: Python :: 3.14"] em [project].
Com que frequência publicar?
Em mudanças significativas. Bibliotecas: releases semver. Aplicações: conforme necessário.
Relacionado
- Noções Básicas de Empacotamento - construir primeiro
- Versionamento e Changelogs - incrementos de versão
- Índices Privados e Espelhos - PyPI interno
- Melhores Práticas de Empacotamento - higiene de release
Versões das Pilhas: Esta página foi escrita para Python 3.14.0, FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, e uv 0.6+.