Introducción
Publicar un paquete en PyPI permite que otros desarrolladores lo instalen fácilmente con pip. En este artículo se detalla el proceso completo: desde configurar las credenciales hasta subir el paquete con Twine, incluyendo buenas prácticas de seguridad para el manejo de tokens.
Prerrequisitos
Antes de iniciar se debe contar con:
- Cuenta activa en PyPI
- Proyecto Python con
pyproject.tomlconfigurado - Python instalado
Instalar las herramientas de empaquetado:
pip install build twine
Configurar pyproject.toml
El archivo pyproject.toml es el estándar moderno para definir los metadatos y la configuración de empaquetado de un proyecto Python (PEP 517/518). Debe estar en la raíz del proyecto.
A continuación se muestra una estructura completa con las secciones más relevantes:
[build-system]
requires = ["setuptools>=61", "wheel"]
build-backend = "setuptools.backends.legacy:build"
[project]
name = "nombre-del-paquete"
version = "0.1.0"
description = "Descripción corta del paquete"
readme = "README.md"
license = { file = "LICENSE" }
authors = [
{ name = "Tu Nombre", email = "tu@email.com" }
]
keywords = ["python", "ejemplo"]
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
]
requires-python = ">=3.9"
dependencies = [
"requests>=2.28",
]
[project.optional-dependencies]
dev = ["pytest", "ruff"]
[project.urls]
Homepage = "https://github.com/usuario/nombre-del-paquete"
Repository = "https://github.com/usuario/nombre-del-paquete"
Issues = "https://github.com/usuario/nombre-del-paquete/issues"
Los campos más importantes a revisar antes de cada publicación son:
name— debe coincidir exactamente con el nombre registrado en PyPI, en minúsculas y con guionesversion— PyPI no permite publicar la misma versión dos veces; incrementar siguiendo Semantic Versioning (MAJOR.MINOR.PATCH)description— texto corto que aparece en la página del paquete en PyPIreadme— apunta al archivoREADME.md; su contenido se muestra en la página del paqueterequires-python— define la versión mínima de Python compatibledependencies— lista de dependencias que se instalarán automáticamente conpip install
Crear un token de acceso en PyPI
Para publicar de forma segura se recomienda usar un API Token en lugar de usuario y contraseña:
| Paso | Acción | Referencia visual |
|---|---|---|
| 1 | Ingresar a la cuenta de PyPI | https://pypi.org/account/login/ |
| 2 | Ir a API Tokens | ![]() |
| 3 | Crear un nuevo token | ![]() |
| 4 | Seleccionar el alcance | ![]() |
| 5 | Copiar el token | ![]() |
Si se pierde el token, será necesario generar uno nuevo.
Cómo usar el token generado
PyPI muestra estas instrucciones justo después de crear el token. El token reemplaza al usuario y contraseña en cualquier herramienta de publicación:
- Nombre de usuario: siempre
__token__(literal, no tu usuario de PyPI) - Contraseña: el valor completo del token, incluyendo el prefijo
pypi-
La forma más directa es configurar el archivo ~/.pypirc (o %USERPROFILE%\.pypirc en Windows):
[pypi]
username = __token__
password = pypi-AgEIcHlwaS5vcmcCJDQ2Y...
Importante: no incluir este archivo en repositorios Git. Añadirlo a
.gitignore. Para entornos CI/CD o equipos, se recomienda usar variables de entorno en su lugar (ver sección Configurar credenciales con variables de entorno).
Configurar credenciales con variables de entorno
Para entornos CI/CD o equipos, la alternativa más segura al archivo .pypirc es usar variables de entorno, ya que evita almacenar el token en disco y no requiere modificar archivos de configuración.
Windows PowerShell:
$env:TWINE_USERNAME="__token__"
$env:TWINE_PASSWORD="pypi-xxxxxxxxxxxxxxxx"
Linux / macOS:
export TWINE_USERNAME=__token__
export TWINE_PASSWORD=pypi-xxxxxxxxxxxxxxxx
Twine detectará automáticamente estas variables al ejecutar el upload. Para hacerlas permanentes, agregarlas a las variables de entorno del sistema operativo o al archivo ~/.bashrc / ~/.zshrc en Linux y macOS.
Construir y validar el paquete
Con el proyecto configurado y las credenciales listas, el siguiente paso es generar los artefactos de distribución. Desde la raíz del proyecto ejecutar:
python -m build
Se generará la carpeta dist/ con los artefactos listos para publicar:
dist/
├── proyecto-x.y.z.tar.gz
└── proyecto-x.y.z-py3-none-any.whl
Antes de publicar, validar los archivos generados:
twine check dist/*
El resultado esperado es PASSED. Si hay errores de metadatos o en el README, deben corregirse antes de continuar.
Publicar el paquete
Con las credenciales configuradas:
twine upload dist/*
Al finalizar correctamente se mostrará la URL del paquete publicado:
View at:
https://pypi.org/project/<nombre-paquete>/
Publicar nuevas versiones
Antes de cada nueva versión:
- Actualizar la versión en
pyproject.toml - Eliminar artefactos anteriores para evitar conflictos:
# Linux / macOS
rm -rf build dist *.egg-info
# Windows PowerShell
Remove-Item -Recurse -Force build, dist
Luego reconstruir, validar y publicar:
python -m build
twine check dist/*
twine upload dist/*
Errores frecuentes
Error 403 Forbidden — Token inválido, expirado o sin permisos sobre el proyecto. Verificar que el token corresponda a PyPI y no a TestPyPI.
Error 400 File Already Exists — PyPI no permite reemplazar archivos ya publicados. Incrementar la versión en pyproject.toml, reconstruir y volver a publicar.
Error Invalid Distribution — Paquete corrupto o metadatos inválidos. Eliminar los artefactos anteriores, reconstruir y validar antes de subir:
rm -rf build dist *.egg-info
python -m build
twine check dist/*
Conclusión
El flujo completo se resume en tres comandos:
python -m build
twine check dist/*
twine upload dist/*
Usar tokens con alcance limitado, almacenarlos en variables de entorno y ejecutar siempre twine check antes de publicar son las prácticas clave para mantener un proceso de distribución seguro y confiable.



