Django + virtualenv + pip

No lo tenía claro, pero cuando entendí lo que suponía y cómo se trabajaba con virtualenv + pip me decidí a probarlo. Voy a intentar explicar como se utilizan estas herramientas de una forma genérica, para hacernos una idea de lo que significa y los casos en los que se pueden aplicar. A grandes rasgos:

  • Django: Framework en python, creo que no necesita mucha más explicación.
  • Virtualenv: Herramienta necesaria para crear un entorno virtual de python, con las versiones específicas de los paquetes y/o dependencias que hagan falta para el proyecto.
  • Pip: Gestor/Instalador de esos paquetes (similar a easy_install).

Con estas herramientas intentaremos instalar un entorno virtual independiente para gestionar todas las dependencias de nuestro proyecto.

Instalación del entorno virtualenv + pip

Primero instalamos pip, que como hemos mencionado anteriormente, es el gestor de paquetes con el que vamos a instalar el resto de componentes. Tiramos de easy_install para instalarlo. Una vez instalado pip, instalamos también virtualenv y tendremos la base necesaria para seguir trabajando:

$ sudo easy_install pip
$ pip install virtualenv

Vamos a crear el entorno. Supongamos 2 directorios de trabajo, src/ y env/. El directorio src/ lo destinaremos al código fuente (podemos tirar de repositorio o iniciar nuestro proyecto directamente ahí), en env/ meteremos todos los paquetes y dependencias del proyecto, osea el entorno:

$ mkdir -p foo/{env,src}
$ cd foo/
$ virtualenv --distribute --no-site-packages env/
New python executable in env/bin/python
Installing distribute........................................done.

Ahora ya estamos preparados para instalar las aplicaciones/dependencias dentro del entorno de trabajo, lo haremos "desde fuera" con la opción -E:

$ pip -E env/ install django
Downloading/unpacking django
  Downloading Django-1.2.4.tar.gz (6.4Mb): 6.4Mb downloaded
  Running setup.py egg_info for package django
[...]
Successfully installed django
Cleaning up...
$ sudo pip -E env/ install -e hg+https://bitbucket.org/ubernostrum/django-registration#egg=django-registration
$ sudo pip -E env/ install -e git+https://github.com/flashingpumpkin/django-socialregistration.git#egg=django-socialregistration
[instalamos el resto de dependencias]

Vamos a comprobar que todo está correcto, para ello utilizamos una herramienta que se llama yolk, capaz de listar todos los paquetes que tenemos instalados en el entorno, primero instalamos esa herramienta, luego entramos en el entorno y la ejecutamos (aunque podríamos hacer lo mismo con la orden pip freeze como se muestra a continuación):

$ pip -E env/ install yolk
$ source env/bin/activate
(env)$ yolk -l
Django          - 1.2.4        - active 
Python          - 2.6.6        - active development (/usr/lib/python2.6/lib-dynload)
distribute      - 0.6.14       - active 
pip             - 0.8.1        - active 
wsgiref         - 0.1.2        - active development (/usr/lib/python2.6)
yolk            - 0.4.1        - active 

Nota: Como se puede ver en el ejemplo de arriba, para entrar en el entorno que hemos creado usamos el comando source env/bin/activate, para salir del mismo usamos el comando deactivate.

(env)$ pip freeze
Django==1.2.4
distribute==0.6.14
wsgiref==0.1.2
yolk==0.4.1

Ahora que tenemos más o menos clara la forma de actuar, vamos a hacer un freeze y guardar el archivo de requisitos dentro del repositorio para poder volver a reproducirlo en cualquier otra máquina. Insisto, todos estos comandos pueden ejecutarse dentro del entorno (env) o fuera del mismo con la opción -E entorno de pip:

(env)$ cd foo/src/
(env)$ pip freeze > requirements.txt
(env)$ cat requirements.txt 
Django==1.2.4
South==0.7.3
distribute==0.6.14
wsgiref==0.1.2
yolk==0.4.1
(env)$ deactivate
$

Y ya podemos empezar a programar el proyecto en dentro de src/.

Replicando el entorno

Suponemos ahora que estamos en otra máquina -aunque en el ejemplo seguimos en la misma- donde queremos montar de nuevo todo el entorno. Primero creamos de nuevo la estructura anterior y luego hacemos un pull del repositorio la carpeta src/ (como estamos en la misma máquina lo simulando haciendo un cp :P):

$ mkdir -p bar/{env,src}
$ cp -r foo/src/* bar/src

Y ahora procuramos recrear el entorno, primero hacemos un entorno nuevo y vacío en bar/env/ y luego instalamos todo lo que hemos logueado en el requirements.txt:

$ virtualenv --distribute --no-site-packages bar/env/
$ pip install -E bar/env/ -r bar/src/requirements.txt 
...
Successfully installed Django South ... yolk
Cleaning up...

Comprobamos que todo esté correcto:

$ source bar/env/bin/activate
(env)$ pip freeze
Django==1.2.4
distribute==0.6.14
wsgiref==0.1.2
yolk==0.4.1
(env)$ deactivate
$

Conclusión

Virtualenv y pip forman una combinación excelente de elementos para hacer de un proyecto un ente sin dependencias frustradas y con todos los requisitos y versiones específicas para garantizar el correcto funcionamiento del mismo. Ahora, por lo que me han contado, debería interesarme en Fabric para automatizar los deploys y seguir haciendo magia.

Referencias

django code

About the author

Óscar
has doubledaddy super powers, father of Hugo and Nico, husband of Marta, *nix user, Djangonaut and open source passionate.