Friday, February 1, 2008

Desarrollando con zc.buildout

Siguiendo con el desvío tomado en Huevos y Constructores, abordaremos el desarrollo de paquetes en python usando zc.buildout. La instancia de zope que creamos con zopeproject es un proyecto manejado por buildout, por lo que es de suma importancia entender como funciona este de manera aislada. Para ello crearemos un paquete en python con una implementación de ejemplo.

Por que usar buildout? Dado que queremos hacer fácilmente instalable nuestro paquete por terceras personas, requerimos algún método para empaquetarlo y distribuirlo. Podríamos usar distutil, pero durante el desarrollo con cada cambio hecho al código deberiamos generar la distribución e instalarla antes de hacer una prueba. Adicionalmente, para hacer la instalación se requiere permisología de root.

Otras ventajas de builtout sobre distutils es que este usa setuptools, por lo que podemos resolver los problemas de dependencias y versiones con los que se enfrentaría quien tratara de instalar el paquete. buildout se ocupa además de preconfigurar el paquete antes de hacer la instalación o pruebas.

Para instalar zc.buildout se requiere setuptools y se recomienda virtual-python (veáse Instalando Zope 3).

Para procesar un paquete o aplicación con buildout se requiere un archivo buildout.cfg que defina el entorno que el paquete necesita:
[buildout]
develop=.
...
La estructura del archivo buildout.cfg es una serie de secciones cuyo nombre aparece entre corchetes, seguida por una serie de pares clave=valor que definen la sección. [buildout] es la sección principal y la única requerida.

buildout.cfg define una serie de partes o elementos necesarios para que la aplicación funcione. Cada parte se define en una sección diferente. Cada parte es procesada por un recipe (un programa en python para instalar y actualizar la parte). Las demas lineas de una sección sirver para configurar el recipe. Hay una gran variedad de recipes para distintas funciones, como descargar eggs, compilar aplicaciones, correr la batería de pruebas de un paquete,e tc. En caso de necesidad el desarrollador puede crear sus propios recipes.


Desarrollando un paquete con buildout


Comenzamos desarrollando un paquete normal en python
# mkdir blah
# cd blah

# mkdir src {aquí va el código fuente de los paqutes a desarrollar}
# mkdir src/blah
# ... {se agregan los módulos al paquete blah}
Este paquete será distribuido con setuptools, por lo que debemos crear un archivo blah/setup.py que defina su distribución:
# blah/setup.py
from setuptools import setup, find_packages

setup(name='blah',
version='0.1',
packages=find_packages("src"),
package_dir={"": "src"},
# Notese que los requisitos del paquete son indicados
# aquí para que setuptools pueda generar
# correctamente su egg

install_requires=[ 'zope.tal' ], )
Hasta este punto tenemos un paquete convencional de python, listo para ser distribuído via setuptools. Ahora hay que convertir el directorio de trabajo en un directorio manejado por buildout.

Ahora, se define el archivo buildout.cfg que determinará como generar la aplicación
[buildout]
develop=.
parts=me

[me] recipe=zc.recipe.egg
eggs=zope.tal
Este archivo define una parte llamada 'me', la cual para ser construida requiere el recipe encargado de descargar eggs. El único egg a descargar será zope.tal.

Pero aún falta en manejar este proyecto a traves de buildout. Para crear la infraestructura necesaria, hay que hacer un bootstrap. Este procedimiento se realiza una única vez en la vida del proyecto:
# ruta-hacia-buildout/buildout bootstrap

(Desde luego, buildout debe estar instalado, cosa fácil gracias a easy_install).

buildout creará un directorio bin donde instalará su ejecutable y cualquier otro requerido por las dependencias. Creará además un directorio eggs donde instalará los eggs necesarios por esta aplicación, un directorio develop-eggs donde creará referencia a los eggs que esta aplicación defina y un directorio parts, para ser utilizado por las partes del archivo de configuración.

Ya con toda la infraestructura en su lugar, para asegurar que la aplicación tenga todos sus requerimientos instalados basta con ejecutar
# buildout
Con cada cambio en las dependencias es necesario re-ejecutar el comando, para que satisfaga las nuevas necesidades de la aplicación.

Jugando con las partes y los recipes se puede automatizar el proceso de instalación de las dependencias de la aplicación. Otras funciones determinan si se descargará la versión mas nueva de un paquete o una en especifico.

Se puede generar la distribución de los paquetes por medio de setuptools o por medio de buildout. En el último caso, los comandos son:
# bin/buildout setup . sdist {distribución fuente}
# bin/buildout setup . bdist {binarios}

# bin/buildout setup . bdist_egg {bnarios en eggs}
La fuente autoritativa de zc.buildout se encuentra en http://pypi.python.org/pypi/zc.buildout

No comments: