Saltar al contenido principal
Avanzado⏱ 1.5 horas
Prerequisitos: Módulos y Paquetes · Entornos Virtuales
Módulo 08: Herramientas ProfesionalesLección 3 de 5
60% completado

Empaquetado y Distribución en Python

🗺️ Mapa de la Lección

⏱ 1.5 horas🔵 Avanzado

🎯 Qué aprenderás

  • Crear estructura de paquetes Python
  • Configurar setup.py o pyproject.toml
  • Gestionar dependencias y metadatos
  • Instalar paquetes en modo desarrollo
  • Publicar paquetes en PyPI (opcional)

🌍 Para qué te sirve

  • Crear bibliotecas reutilizables
  • Compartir código entre proyectos del equipo
  • Publicar en PyPI para uso público
  • Distribuir herramientas internas de empresa
  • Crear paquetes instalables con pip
  • Gestionar versiones y actualizaciones

🎯 ¿Por qué aprender empaquetado?​

Tienes un módulo útil que quieres compartir. Podrías decirle a la gente "copia este archivo a tu proyecto", pero eso no escala. ¿Qué pasa si actualizas el módulo? ¿Cómo manejan las dependencias?

El empaquetado es esencial porque:

  • Compartir código profesionalmente: otros pueden instalar con pip install
  • Gestión de versiones: usuarios pueden elegir qué versión usar
  • Dependencias automáticas: pip instala todo lo necesario
  • Distribución fácil: un comando para instalar en cualquier máquina
  • Estándar de la industria: forma profesional de compartir código Python

🌍 Casos reales donde se usa​

El empaquetado está en todos los proyectos que se comparten:

  • Crear bibliotecas reutilizables: Código que otros pueden usar
  • Compartir código en equipo: Módulos compartidos entre proyectos
  • Publicar en PyPI: Hacer tu código disponible públicamente
  • Distribuir herramientas internas: Paquetes privados para tu empresa
  • Gestionar versiones: Controlar qué versión usa cada proyecto
  • Instalación simple: pip install en lugar de copiar archivos

Ejemplo real: Librerías como requests, pandas, django están empaquetadas. Puedes instalarlas con pip install requests en lugar de descargar y copiar archivos manualmente.

💡 Concepto base​

El empaquetado organiza tu código como un paquete que otros pueden instalar con pip install tu-paquete. Es la forma profesional de compartir código Python.

Lo genial de Python: Puedes crear paquetes con setuptools o poetry, y distribuirlos fácilmente a través de PyPI o repositorios privados.

# Estructura básica de un paquete
mi_paquete/
__init__.py
modulo.py
setup.py # o pyproject.toml
# Instalar en modo desarrollo
pip install -e .

# O publicar en PyPI
python setup.py sdist bdist_wheel
twine upload dist/*
Resultado esperado:
# Después de pip install -e .
# Puedes importar tu paquete desde cualquier lugar
import mi_paquete
🌮 Analogía culinaria

El empaquetado es como crear un kit de ingredientes pre-empacado para preparar chilaquiles al pastor. En lugar de que cada cocinero tenga que buscar y comprar todos los ingredientes por separado, tú creas un paquete completo con todo lo necesario (tortillas, salsa, queso, pastor, especias) y otros pueden simplemente "instalar" tu paquete y empezar a cocinar. Es como crear una marca de comida que otros pueden usar fácilmente. Un comando (pip install) y todo está listo.

Para principiantes

Antes de continuar: Asegúrate de entender Módulos y Entornos Virtuales. El empaquetado es avanzado pero esencial si quieres compartir código profesionalmente.

Estructura Básica de un Paquete​

Estructura de Directorios​

mi_paquete/
├── LICENSE
├── README.md
├── setup.py
├── requirements.txt
├── mi_paquete/
│ ├── __init__.py
│ ├── modulo1.py
│ └── modulo2.py
└── tests/
├── __init__.py
└── test_modulo1.py

setup.py Básico​

from setuptools import setup, find_packages

setup(
name="mi_paquete",
version="0.1.0",
packages=find_packages(),
install_requires=[
"requests>=2.25.1",
"pandas>=1.2.0",
],
author="Tu Nombre",
author_email="tu@email.com",
description="Descripción corta del paquete",
long_description=open("README.md").read(),
long_description_content_type="text/markdown",
url="https://github.com/usuario/mi_paquete",
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
python_requires=">=3.6",
)

Creación de Paquetes​

Configuración de pyproject.toml​

[build-system]
requires = ["setuptools>=42", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "mi_paquete"
version = "0.1.0"
description = "Descripción del paquete"
readme = "README.md"
authors = [
{name = "Tu Nombre", email = "tu@email.com"}
]
license = {file = "LICENSE"}
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
]
requires-python = ">=3.6"
dependencies = [
"requests>=2.25.1",
"pandas>=1.2.0",
]

[project.urls]
Homepage = "https://github.com/usuario/mi_paquete"
Documentation = "https://mi_paquete.readthedocs.io/"

requirements.txt​

requests>=2.25.1
pandas>=1.2.0
pytest>=6.0.0
black>=21.0.0
flake8>=3.9.0

Distribución​

Construir el Paquete​

# Instalar herramientas necesarias
pip install build twine

# Construir el paquete
python -m build

# Verificar el paquete
twine check dist/*

Subir a PyPI​

# Subir a PyPI
twine upload dist/*

# Subir a TestPyPI (para pruebas)
twine upload --repository testpypi dist/*

Entornos Virtuales​

Crear y Activar​

# Crear entorno virtual
python -m venv venv

# Activar en Windows
venv\Scripts\activate

# Activar en Unix/MacOS
source venv/bin/activate

requirements.txt​

# requirements.txt
# Dependencias de producción
requests==2.25.1
pandas==1.2.0

# Dependencias de desarrollo
pytest==6.0.0
black==21.0.0
flake8==3.9.0

Buenas Prácticas​

  1. Versionado Semántico
# setup.py
setup(
version="1.2.3", # MAJOR.MINOR.PATCH
# ...
)
  1. Manejo de Dependencias
# setup.py
setup(
install_requires=[
"requests>=2.25.1,<3.0.0", # Rango de versiones
"pandas>=1.2.0",
],
extras_require={
"dev": [
"pytest>=6.0.0",
"black>=21.0.0",
],
},
)
  1. Documentación
# setup.py
setup(
long_description=open("README.md").read(),
long_description_content_type="text/markdown",
project_urls={
"Documentation": "https://mi_paquete.readthedocs.io/",
"Source": "https://github.com/usuario/mi_paquete",
},
)

Ejemplos Avanzados​

Paquete con Código C​

# setup.py
from setuptools import setup, Extension

module = Extension(
"mi_modulo",
sources=["mi_modulo.c"],
include_dirs=["include"],
libraries=["m"],
)

setup(
name="mi_paquete",
version="0.1.0",
ext_modules=[module],
# ...
)

Paquete con Datos​

# setup.py
setup(
# ...
package_data={
"mi_paquete": [
"datos/*.json",
"config/*.yaml",
],
},
include_package_data=True,
)

Scripts de Consola​

# setup.py
setup(
# ...
entry_points={
"console_scripts": [
"mi_comando=mi_paquete.cli:main",
],
},
)

Herramientas de Desarrollo​

black​

# pyproject.toml
[tool.black]
line-length = 88
target-version = ['py36', 'py37', 'py38']
include = '\.pyi?$'

flake8​

# setup.cfg
[flake8]
max-line-length = 88
extend-ignore = E203
exclude = .git,__pycache__,build,dist

pytest​

# pytest.ini
[pytest]
testpaths = tests
python_files = test_*.py
python_functions = test_*

Consejos​

  1. Usa versionado semántico
  2. Mantén las dependencias actualizadas
  3. Incluye documentación clara
  4. Prueba el paquete antes de distribuir
  5. Usa entornos virtuales

Recursos Adicionales​

Documentación Oficial​

Bibliografía Recomendada​

  • Python Tricks (Dan Bader) - Capítulo sobre empaquetado
  • Effective Python (Brett Slatkin) - Item 84: Write Docstrings for Every Function, Class, and Module
  • The Hitchhiker's Guide to Python (Kenneth Reitz) - Sección sobre packaging
  • Python Packaging User Guide (https://packaging.python.org/) - Guía oficial completa

Conceptos Relacionados​


Siguiente paso​

Ahora que sabes empaquetar código, aprende a escribir tests para asegurar su calidad. Continúa con: Testing