Las mejores aplicaciones Python de fuente abierta tienen un excelente empaquetamiento. Aprenda más sobre lo que es el empaquetamiento y su implementación básica. Luego, vaya un paso más allá y descubra la asignación de versiones y la distribución en cuanto a cómo se relacionan con el empaquetamiento.

Patrick T. Altman, VP of Engineering, Eldarion

Photo of Patrick AltmanPatrick Altman es un desarrollador principal el Pinax y ha creado y contribuye a muchos otros proyectos de fuente abierta. Actualmente es VP de Ingeniería en Eldarion. Anteriormente, fue el Director de Ingeniería de Software en StudioNow, la cual se vendió posteriormente a AOL. Actualmente vive en Nashville, Tennessee, con su esposa y tres hijos.



06-02-2012

El primer plano de un proyecto exitoso de fuente abierta es el empaquetamiento. Un ingrediente clave para el buen empaquetamiento es la asignación de versiones. Como el proyecto es de fuente abierta, usted deseará publicar su paquete para hacer realidad todos los beneficios que ofrece la comunidad de fuente abierta. Las diferentes plataformas y lenguajes tienen diferentes mecanismos para empaquetamiento, pero este artículo se enfoca específicamente en Python y su ecosistema de empaquetamiento. El artículo trata la mecánica de empaquetamiento para darle una base sobre la cual crecer y proporciona suficientes ejemplos gráficos para que usted comience de inmediato.

¿Por qué preocuparse por el empaquetamiento?

Más allá de simplemente ser lo correcto, existen tres razones prácticas para empaquetar su software:

  • Facilidad de uso
  • Estabilidad (con asignación de versión)
  • Distribución

Es un acto de consideración hacia sus usuarios hacer que la aplicación se instale con el menor esfuerzo posible. El empaquetamiento hace que su software sea más accesible y fácil de utilizar. Si su software es más fácil de usar, será más fácil que los usuarios comiencen a usarlo. Al publicar su paquete en el Índice de Paquetes Python (PyPI), usted hará que este sea más accesible a través de recursos como pip o easy_install. (Vea Recursos para encontrar enlaces sobre más información sobre estas herramientas).

Además, al asignar versiones a sus paquetes, usted permite que los usuarios vinculen la dependencia en sus proyectos a su software para una versión en particular. Por ejemplo, vincular Pinax a la versión 0.9a2.dev1017 se expresaría como:

Pinax==0.9a2.dev1017

Esto obligaría a que el proyecto utilizara el release 0.9a2.dev1017 de Pinax.

La asignación de versión garantiza mayor estabilidad en caso de la publicación de cambios que puedan tener interfaces diferentes en su software. Esto permite a los usuarios saber exactamente lo que están obteniendo y les facilita rastrear las diferencias entre releases. Además, los desarrolladores de proyecto pueden saber exactamente frente a qué están codificando.

Un método común para publicar paquetes en el PyPI (o en su propio servidor de distribución) es crear una distribución fuente para cargar. Una distribución fuente es una manera estándar de empaquetar la fuente de su proyecto como una unidad de distribución. Existen formas para crear distribuciones binarias, pero para los propósitos de la fuente abierta, también tiene sentido distribuir su fuente. Crear distribuciones fuente facilita que las personas usen herramientas que buscarán el software en Internet, lo descarguen y lo instalen automáticamente. Este proceso ayuda no solo al desarrollo local, sino también a las implementaciones de su software.

Así, al facilitar que los usuarios integren e instalen su software, utilizando una buena asignación de versión que permita una técnica de vinculación confiable, y luego publicando su paquete para mayor distribución, usted tendrá mayores oportunidades para que su proyecto sea exitoso y obtenga una adopción más amplia. Una adopción más amplia puede llevar a mayores contribuciones—algo que seguramente todo desarrollador de fuente abierta desea.


Anatomía de un archivo setup.py

Uno de los propósitos del script setup.py es servir como un ejecutable que usted puede ejecutar para empaquetar su software y cargarlo a los servidores de distribución. El script setup.py puede variar un poco en contenido a medida que usted navega entre repositorios Python populares. Este artículo se enfoca en lo básico. Consulte la sección Recursos para explorar un poco más por usted mismo(a).

Usted puede usar el archivo setup.py para muchas tareas diferentes, pero aquí usted crea una que le permitirá ejecutar los siguientes comandos:

python setup.py register
python setup.py sdist upload

El primer comando, register, toma la información proporcionada en la función setup() del script setup.py y crea una entrada en el PyPI para su paquete. Este no cargará nada; en lugar de ello, creará los metadatos. Los siguientes dos comandos están encadenados entre sí: sdist upload construye una distribución fuente y luego la carga al PyPI. No obstante, hay algunos prerrequisitos, como configurar su archivo de configuración .pypirc y escribir efectivamente el contenido del setup.py.

Primero, configure su archivo .pypirc. Este debe residir en su directorio de inicio (home), el cual puede variar dependiendo de su sistema operativo. En UNIX®, Linux® y Mac OS X, usted puede acceder allí escribiendo cd ~/. El archivo debe contener sus credenciales PyPI como se muestra en el Listado 1.

Listado 1. Un archivo .pypirc típico
[distutils]
index-servers =
    pypi

[pypi]
username:xxxxxxxxxxxxx
password:xxxxxxxxxxxxx

Luego, vaya a PyPI y registre una cuenta (no se preocupe: es gratuita). Ingrese el nombre de usuario y contraseña que creó en PyPI en su archivo .pypirc, y asegúrese de que el archivo se llame ~/.pypirc.

Ahora, al escribir su script setup.py usted debe decidir qué desea que aparezca en la página de índice PyPI y cómo desea que se llame su proyecto. Comience copiando la plantilla para setup.py que utilizo para los proyectos (vea el Listado 2). Saltando las importaciones y funciones, observe la parte inferior de la plantilla y lo que necesite cambiar para que se ajuste a su proyecto. Consulte Recursos donde hay un enlace hacia el script completo.

Listado 2. Plantilla setup.py
PACKAGE = ""
NAME = ""
DESCRIPTION = ""
AUTHOR = ""
AUTHOR_EMAIL = ""
URL = ""
VERSION = __import__(PACKAGE).__version__

setup(
    name=NAME,
    version=VERSION,
    description=DESCRIPTION,
    long_description=read("README.rst"),
    author=AUTHOR,
    author_email=AUTHOR_EMAIL,
    license="BSD",
    url=URL,
    packages=find_packages(exclude=["tests.*", "tests"]),
    package_data=find_package_data(
			PACKAGE,
			only_in_packages=False
	  ),
    classifiers=[
        "Development Status :: 3 - Alpha",
        "Environment :: Web Environment",
        "Intended Audience :: Developers",
        "License :: OSI Approved :: BSD License",
        "Operating System :: OS Independent",
        "Programming Language :: Python",
        "Framework :: Django",
    ],
    zip_safe=False,
)

Primero, note que esta plantilla espera que su proyecto tenga dos archivos diferentes. El primero se utiliza para long_description: Este lee el contenido del archivo README.rst que está en el mismo directorio que setup.py y pasa el contenido como una cadena de caracteres al parámetro long_description . Este archivo llena la página de destino en el PyPI, por lo que es una buena idea describir brevemente el proyecto y mostrar ejemplos de uso en este archivo. El segundo archivo es el archivo __init__.py del paquete. Este no se menciona aquí de forma explícita, pero la línea que establece la variable de VERSION importa su paquete y cuando lo hace, Python necesita un archivo __init__.py y espera una variable definida en ese módulo llamada __version__. Por ahora, defínalo simplemente como una cadena de caracteres:

# __init__.py
__version__ = "0.1"

Observemos ahora el resto de las entradas:

  • PACKAGE es el paquete Python de su proyecto. Es la carpeta de nivel superior que contiene el módulo __init__.py que debería estar en el mismo directorio que su archivo setup.py—por ejemplo:
    /-
      |- README.rst
      |- setup.py
      |- dogs 
         |- __init__.py
         |- catcher.py

    De esta forma, dogs sería su paquete aquí.

  • NAME normalmente es similar o el mismo nombre de su PACKAGE pero puede ser el que usted desee. El NAME es como las personas llamarán a su software, el nombre bajo el cual su software es listado en el PyPI y—más importante aún—bajo el cual lo instalarán los usuarios (por ejemplo, pip install NAME).
  • DESCRIPTION es simplemente una corta descripción de su proyecto. Una frase será suficiente.
  • AUTHOR y AUTHOR_EMAIL son lo que sus nombres indican: su nombre y su dirección de email. Esta información es opcional, pero es una buena práctica suministrar una dirección de email si las personas desean contactarle con respecto al proyecto.
  • URL es el URL del proyecto. Este URL puede ser un website del proyecto, el repositorio Github, o cualquier URL que usted desee. De nuevo, esta información es opcional.

Es posible que usted también desee proporcionar la licencia y los clasificadores. Para más información sobre la creación de un archivo setup.py consulte la documentación Python. (Vea Recursos.)


Asignación de Versiones

La asignación de versiones es un tema por sí mismo, pero vale la pena mencionarlo en el contexto del empaquetamiento, dado que un buen empaquetamiento incluye la asignación adecuada de versión. La asignación de versión es una forma de comunicación con sus usuarios y también les permite crear más estabilidad y confiabilidad en sus productos. Mediante la asignación de versiones usted le dice a sus usuarios que ha cambiado algo y está proporcionado los límites explícitos sobre dónde ocurrieron tales cambios.

Usted puede encontrar un estándar para asignación de versiones a paquetes Python en la Propuesta de Mejora Python (PEP) 386. (Vea Recursos.) Esta describe reglas prácticas. Incluso si usted no lee o no entiende o incluso si no está de acuerdo con la PEP, sería algo inteligente seguirla, dado que es lo que cada vez más los desarrolladores Python están acostumbrados a ver.

Adicionalmente, la asignación de versiones no solo es para releases estables que usted carga a PyPI sino que también es útil para el desarrollo de releases usando el sufijo devNN . Normalmente no es bueno cargar estas versiones dev al PyPI, pero usted todavía puede ponerlas a disposición públicamente configurando su propio servidor de distribución público (o privado); luego, los usuarios que deseen usar la versión más moderna pueden referenciar esto en su archivo pip requirements.txt. Estos son algunos ejemplos de asignación de versión:

1.0.1        # 1.0.1 release final
1.0.2a       # 1.0.2 Alpha (para Alpha, después de releases Dev)
1.0.2a.dev5  # 1.0.2 Alpha, release Dev #5

Publicación

Generalmente las personas no van a encontrar e instalar su software si este no está publicado. La mayoría de las veces usted deseará publicar sus paquetes en PyPI. Después de que usted configura su archivo de configuración .pypirc, el comando upload que usted pasa a setup.py transmite su paquete a PyPI. Normalmente usted hace esto en conjunto con la creación de una distribución fuente:

python setup.py sdist upload

Si usted está usando su propio servidor de distribución, añada una sección para autorización en su archivo .pypirc para esta nueva ubicación y refiérase a ella por nombre cuando sube:

python setup.py sdist upload -r mydist

Configure su propio servidor de distribución

La principal razón para utilizar su propio servidor de distribución en fuente abierta es proporcionar un sitio para publicar releases dev, dado que PyPI en realidad solo debería consistir de releases estables. Por ejemplo, usted probablemente desearía:

pip install MyPackage

... para instalar el último release estable disponible en el PyPI. Sin embargo, si usted añade releases dev posteriores, ese comando terminará instalando el último periodo de release, es decir, su release dev. Generalmente siempre es bueno vincular un release, pro no todos los usuarios lo hacen. Por lo tanto, asegúrese de que al no especificar un número de versión siempre se retorne el último release estable.

Una forma de tener todas las ventajas (exponer solo releases estables para el uso predeterminado de pip) y ninguna desventaja (permitir que los usuarios instalen releases dev) es hospedar en su propio servidor de distribución. El proyecto Pinax hace esto para todos sus releases dev en http://dist.pinaxproject.com. (Vea Recursos.)

El servidor de distribución es simplemente un índice servido sobre Hypertext Transfer Protocol (HTTP) de archivos en su servidor. Este debe tener la siguiente estructura de archivos:

/index-name/package-name/package-name-version.tar.gz

Usted puede luego hacer que el servidor sea privado si así lo desea, configurando Basic-Auth en su servidor Web. Usted tal vez desee añadir también algún recurso para cargar distribuciones fuente. Para hacerlo, usted necesita añadir código para manejar la carga, analizar el nombre de archivo y crear las rutas de directorio que coincidan con el esquema de arriba. Esta estructura está en su lugar para el proyecto Pinax, el cual hospeda bastantes repositorios.


pip y virtualenv

Aunque este artículo se ha enfocado principalmente en el empaquetamiento, esta sección describe el consumo de paquetes, proporcionando un poco de reconocimiento en cuanto a lo que el buen empaquetamiento y la asignación de versiones brinda a los usuarios.

pip es una herramienta que usted puede instalar directamente, pero recomiendo usarla como parte de virtualenv. (Vea Recursos.) Recomiendo usar virtualenv para todo lo relacionado con Python, dado que mantiene limpios sus entornos Python. Así como una máquina virtual puede permitirle ejecutar múltiples sistemas operativos conjuntamente, virtualenv le permite ejecutar múltiples entornos Python conjuntamente. Yo no instalo nada en mi sistema Python sino que en lugar de ello creo un nuevo virtualenv para cada nuevo proyecto o recurso en el que trabajo.

Ahora que ha instalado virtualenv usted puede jugar por un momento:

$ mkvirtualenv —no-site-packages testing
$ pip install Pinax
$ pip freeze|grep Pinax
$ pip uninstall Pinax
$ pip install —extra-index-url=http://dist.pinaxproject.com/fresh-start/ 
    Pinax==0.9a2.dev1017
$ pip freeze|grep Pinax

Note que la primera instalación pip fue descargada e instalada desde PyPI. pip freeze muestra todas las versiones y paquetes instalados en su actual virtualenv. pip uninstall hace exactamente lo que usted puede estar pensando que hace: se desinstala del virtualenv. Luego, usted instala una versión dev del repositorio de inicio desde cero http://dist.pinaxproject.com para obtener la versión de desarrollo de Pinax versión 0.9a2.dev1017.

Sin ir a websites, descargar tarballs y código symlinking a un paquete de sitio. (Así es como yo solía hacerlo y me causó bastantes problemas). Sus usuarios obtienen todo esto como resultado de un buen empaquetamiento, publicación y asignación de versión de su proyecto.


Conclusión

El resultado final es que bien vale la pena tomarse algún tiempo para aprender el arte y la ciencia del empaquetamiento. Usted obtendrá mejor adopción por parte de los usuarios gracias a esta facilidad de instalación y a estabilidad que la asignación de versión a sus paquetes les brinda. Al utilizar la plantilla setup.py suministrada en Recursos y cubierta en este artículo, usted deberá estar en capacidad de empaquetar su proyecto rápida y fácilmente. La comunicación con sus usuarios mediante la asignación de versiones adecuada es considerado para con sus usuarios, facilitándoles rastrear cambios entre un release y otro. Finalmente, a medida que pip y virtualenv logran una adopción más amplia, la dependencia en los paquetes publicados—bien sea en el PyPI o en sus propios servidores de distribución—aumenta. Por lo tanto, asegúrese de publicar los proyectos que desee compartir con el mundo.

Espero que este artículo le haya proporcionado suficiente para que inicie. El área Recursos le proporciona documentación para ayudarle a profundizar más. Si tiene preguntas, ingrese a Freenode donde podrá encontrarme en las salas de conversación como #pinax y #django-social (con el alias "paltman") o en Twitter (@paltman).

Recursos

Aprender

Obtener los productos y tecnologías

  • Descargue y aprenda más sobre pip.
  • Descargue y aprenda más sobre virtualenv.
  • Encuentre la plantilla setup.py usada en este artículo.
  • Explore Pinax, una plataforma de fuente abierta construida sobre Django.
  • Innove en su próximo proyecto de desarrollo de fuente abierta con software de prueba IBM.

Comentar

Comentarios

developerWorks: Ingrese

Los campos obligatorios están marcados con un asterisco (*).


¿Necesita un IBM ID?
¿Olvidó su IBM ID?


¿Olvidó su Password?
Cambie su Password

Al hacer clic en Enviar, usted está de acuerdo con los términos y condiciones de developerWorks.

 


La primera vez que inicie sesión en developerWorks, se creará un perfil para usted. La información en su propio perfil (nombre, país/región y nombre de la empresa) se muestra al público y acompañará a cualquier contenido que publique, a menos que opte por la opción de ocultar el nombre de su empresa. Puede actualizar su cuenta de IBM en cualquier momento.

Toda la información enviada es segura.

Elija su nombre para mostrar



La primera vez que inicia sesión en developerWorks se crea un perfil para usted, teniendo que elegir un nombre para mostrar en el mismo. Este nombre acompañará el contenido que usted publique en developerWorks.

Por favor elija un nombre de 3 - 31 caracteres. Su nombre de usuario debe ser único en la comunidad developerWorks y debe ser distinto a su dirección de email por motivos de privacidad.

Los campos obligatorios están marcados con un asterisco (*).

(Por favor elija un nombre de 3 - 31 caracteres.)

Al hacer clic en Enviar, usted está de acuerdo con los términos y condiciones de developerWorks.

 


Toda la información enviada es segura.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=90
Zone=tecnologia Java
ArticleID=791661
ArticleTitle=Una guía al empaquetamiento Python
publish-date=02062012