Virtualenv: aislando nuestro entorno python.


Con el fin de facilitarnos el despliegue, siempre resulta interesante crear un entorno aislado para realizar pruebas. Lo ideal sería disponer de un entorno en local lo más parecido posible al entorno remoto.

Pues esto es posible gracias a VirtualEnv .

Instalación

Podemos disponer de VirtualEnv en Windows, GNU/Linux y Mac, ya que es python y, por tanto, portable.

Los detalles... se los dejo a la instalación estándar, ya que éstos pueden variar con facilidad. Es paquete Debian oficial, lo que puede facilitar mucho las cosas :D

Despliegue del entorno

Crear un entorno es tan complejo como:

$ virtualenv ENTORNO

Sustituyendo "ENTORNO" por el nombre del entorno a utilizar.

Podemos utilizar la opción -p para indicar la versión de python a utilizar:

$ virtualenv ENTORNO -p /usr/bin/python2.7

También disponemos de la opción "--no-site-packages", que nos aísla aún más del sistema de paquetes del sistema.

Activándolo

Para activar el entorno virtual basta con ejecutar source sobre uno de los archivos de nuestro entorno:

$ source ENTORNO/bin/activate
(ENTORNO)$

Para desactivarlo, basta ejecutar deactivate, que se encontrará disponible cuando estemos dentro del entorno:

(ENTORNO)$ deactivate
$

Ejemplo completo

Voy a crear un entorno y activarlo, demostrando que no estamos utilizando el entorno habitual en la máquina:

$ python --version
Python 2.6.7
$ virtualenv PYTHON27 -p /usr/bin/python2.7
Running virtualenv with interpreter /usr/bin/python2.7
New python executable in PYTHON27/bin/python2.7
Also creating executable in PYTHON27/bin/python
Installing distribute....................................................................................................................................................................................done.
$ source PYTHON27/bin/activate
(PYTHON27)$ python --version
Python 2.7.2+
(PYTHON27)$ deactivate
$ python --version
Python 2.6.7
$

Instalando aplicaciones

Con el fin de poder instalar aplicaciones, nuestro entorno cuenta con dos potentes programas: distribute e easy_install .

Tendremos que ejecutar easy_install de dentro de nuestro entorno, aunque podemos hacerlo sin entrar en él. es recomendable haber creado el entorno con la opción --no-site-packages.

Por ejemplo, para instalar django:

$ virtualenv ENTORNO --no-site-packages
New python executable in ENTORNO/bin/python
Installing distribute....................................................................................................................................................................................done.
$ ./ENTORNO/bin/easy_install django
Searching for django
Reading http://pypi.python.org/simple/django/
Reading http://www.djangoproject.com/
Best match: Django 1.3
Downloading http://pypi.python.org/packages/source/D/Django/Django-1.3.tar.gz#md5=1b8f76e91c27564708649671f329551f
Processing Django-1.3.tar.gz
Running Django-1.3/setup.py -q bdist_egg --dist-dir /tmp/easy_install-y5FyOE/Django-1.3/egg-dist-tmp-1DI_wu
zip_safe flag not set; analyzing archive contents...
[...]
Adding Django 1.3 to easy-install.pth file
Installing django-admin.py script to ENTORNO/bin

Installed ENTORNO/lib/python2.6/site-packages/Django-1.3-py2.6.egg
Processing dependencies for django
Finished processing dependencies for django
$

Automatizando el proceso

Es posible que necesitemos repetir este proceso muy a menudo, incluso en máquinas en las que no tengamos virtualenv.

Para ello podemos crearnos un pequeño script con las siguientes condiciones:

  • Importaremos virtualenv.
  • Crearemos el método "after_install", que admite dos parámetros: opciones y Directorio de instalación.
  • El script anterior se embeberá en una llamada a virtualenv.create_bootstrap_script, y guardaremos el resultado en disco.

De esta manera, nuestro script creará un nuevo script que es el que podemos redistribuir y ejecutar en máquinas en las que virtualenv no está disponible.

Veamos un ejemplo:

#!/usr/bin/python
# -*- coding:utf-8; tab-width:4; mode:python -*-
# Fichero "bootstrap-template.py

import virtualenv, textwrap
output = virtualenv.create_bootstrap_script(textwrap.dedent("""
import os, subprocess

def after_install(options, homedir):
    packages = ['django', 'django-registration']

    etc = join(homedir, 'etc')
    if not os.path.exists(etc):
        os.makedirs(etc)

    bindir = join(homedir, 'bin')
    easyinstallpath = join(bindir, 'easy_install')

    for each in packages:
        subprocess.call([easyinstallpath, each])
"""))
f = open('bootstrap.py', 'w').write(output)

Que no os despiste la instrucción textwrap.dedent, que es para que las triples comillas no nos jueguen malas pasadas en el código subyacente.

Posiblemente sea buena idea mantener el script en otro fichero y leerlo, con el fin de tener resaltado de sintaxis.

En este ejemplo comprobaréis que estoy instalando django y django-registration.

Usos

Habitualmente, se utiliza virtuelenv junto con fabric , pero dejo este tutorial para otra ocasión.

Podemos utilizarlo para aislar un sistema, sin necesidad de cargar toda una máquina virtual.

También podemos usarlo para tener sistemas fácilmente replicables.

Más información

Debo advertir que la documentación sobre virtualenv deja bastante que desear :(, pero aquí tenéis algunos enlaces para solucionar este problema:

Bradley Wright: "Python virtualenv quickstart with Django"

Cactus: "Basic Django deployment with virtualenv, fabric, pip and rsync"

Jacobian: Django Deployment Workshop


Comentarios

Comments powered by Disqus