Gestión de entornos de Python con direnv y pyenv

En este tutorial, repasaremos las herramientas direnv y pyenv para automatizar la administración de entornos de Python.

Introducción

Como desarrolladores de Python, la mayoría de nosotros estamos familiarizados con Entornos virtuales. Una de las primeras cosas que hacemos cuando trabajamos en un nuevo proyecto es crear un entorno. Comúnmente usamos entorno virtual o venv exactamente para ese propósito .

Cada proyecto en el que trabajamos utiliza diferentes paquetes e incluso puede ser compatible con una sola versión de Python.

Hacer algo repetidamente garantiza la automatización. En este artículo, veremos cómo direnv y pyenv pueden ayudarnos a hacer eso.

Como nota al margen, algunos IDE modernos ya automatizaron estos pasos. Por ejemplo, PyCharm creará el entorno virtual al inicializar un proyecto:

Gestión automatizada del entorno de Python de PyCharm

Aunque la automatización de todos estos pasos es una gran victoria si usamos IDE que admitan dichas funcionalidades, una solución más genérica debería ser independiente de IDE.

Los problemas de virtualenv

Imagina que encontramos un proyecto en GitHub y nos gustaría jugar con él. Pyweather es un script simple que solicita el pronóstico del tiempo extendido para nuestra ubicación y lo imprime en la terminal.

Estos son los pasos que seguimos para probar el script en nuestra máquina:

1
2
$ git clone https://github.com/lcofre/pyweather.git
$ cd pyweather

Luego creamos el entorno virtual e instalamos los paquetes que usa el script:

1
2
3
$ virtualenv --python=python3 env
$ source env/bin/activate
(env) $ pip install requirements.txt

Y solo entonces, podemos ejecutar el script:

1
(env) $ ./pyweather.py  

Creamos un entorno virtual y lo guardamos en la carpeta raíz de nuestro proyecto. Mientras estábamos en esa carpeta, tuvimos que activar el entorno con el comando fuente.

Cuando terminemos de trabajar, debemos salir del Entorno Virtual ejecutando deactivate:

1
(env) $ deactivate

Todos esos pasos son nuestra responsabilidad. ¡Cuántas veces nos hemos olvidado de activar un entorno e instalar un paquete de forma global!

Veamos cómo direnv nos ayuda a automatizar esto.

dirección se hizo principalmente para cargar variables de entorno, dependiendo del directorio actual y tiene una extensión para muchos shells.

En este ejemplo, usaremos bash, pero direnv también es compatible con muchos otros shells. Y lo que es más importante para nosotros, nos permite gestionar Python Virtual Environments.

Para instalarlo, ejecutaremos el instalador bash que proporcionan. Podríamos usar el administrador de paquetes de nuestra distribución, pero el instalador bash se asegurará de que instalemos la última versión disponible:

1
$ curl -sfL https://direnv.net/install.sh | bash

Ahora necesitamos conectar direnv a bash. Editaremos ~/.bashrc y luego lo recargaremos:

1
2
$ echo 'eval "$(direnv hook bash)"' >> ~/.bashrc
$ source ~/.bashrc

De esta manera, direnv se vinculará con el shell y se ejecutará siempre antes de cada solicitud. Nunca notaremos que está funcionando en segundo plano.

direnv verificará si es necesario cargar algo en la carpeta actual. Comprueba la existencia de un archivo llamado .envrc, con instrucciones sobre lo que debe cargarse.

Para cargar Python Virtual Environments ejecutamos el comando layout, seguido de la versión de Python:

1
$ echo 'layout python' > .envrc

O si queremos usar Python 3:

1
$ echo 'layout python3' > .envrc

Ejecutar estos le dirá a direnv que busque un ejecutable python o python3 en la ruta.

Tan pronto como creemos el archivo .envrc, se nos advertirá que debemos permitir que direnv acceda a esa carpeta. Hagámoslo ahora mismo:

1
$ direnv allow
1
2
3
4
5
6
7
direnv: loading .envrc
...
New python executable in /home/myuser/untitled/.direnv/python-3.6.9/bin/python3
...
Installing setuptools, pkg_resources, pip, wheel...direnv:
done.
direnv: export +VIRTUAL_ENV ~PATH

Como podemos ver en la salida, el entorno virtual se creó de inmediato. Sin embargo, el indicador no se modifica, por lo que no veremos el nombre del entorno escrito al principio.

Ahora podemos instalar los paquetes que necesitamos como lo hicimos en el entorno que creamos en la sección anterior:

1
$ pip install -r requirements.txt

direnv activará silenciosamente el entorno en segundo plano. Siempre que salgamos del directorio, el entorno se desactivará:

1
$ cd ..
1
direnv: unloading

Si podemos usar cualquier versión de Python que esté instalada en el sistema, direnv es todo lo que necesitamos.

Sin embargo, supongamos ahora que nuestro script pyweather requiere una versión muy específica.

pyenv

pyenv es una utilidad de administración de versiones para Python. Permite, entre otras cosas, cambiar las versiones de Python por proyecto. direnv proporciona soporte para él desde la versión 2.21.0, por lo que juntos pueden darnos un mayor nivel de control sobre la versión que usamos en nuestro entorno.

Comencemos instalando pyenv:

1
$ curl -L https://pyenv.run | bash

Y luego asegurando que siempre estará accesible para nuestra terminal:

1
2
3
4
$ echo 'export PATH="~/.pyenv/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(pyenv init -)"' >> ~/.bashrc
$ echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc
$ source ~/.bashrc

Ahora supongamos que nuestro script pyweather requiere una versión de Python muy específica, 3.6.2.

Primero, necesitamos instalar esa versión de Python:

1
$ pyenv install 3.6.2

Y ahora podemos configurar nuestro proyecto para usar la versión específica:

1
2
$ echo 'layout pyenv 3.6.2' > .envrc
$ direnv allow

Podemos confirmar que todo funciona como se esperaba comprobando la versión de Python en el entorno:

1
$ python --version
1
Python 3.6.2

Si alguna vez necesitamos cambiar la versión de Python, será suficiente que cambiemos el diseño en el archivo .envrc.

Gracias a ambas utilidades podemos cambiar el diseño a cualquier versión de Python, y nuestro entorno virtual se actualizará al instante.

Otra ventaja de usar tanto direnv como pyenv es que podemos versionar nuestro archivo .envrc en nuestro repositorio de proyectos.

De esa manera, todos los colaboradores podrán configurar su entorno según lo previsto por el proyecto, siempre que instalen las utilidades y la versión de Python necesarias.

Conclusión

Los entornos virtuales están separados del flujo de trabajo de desarrollo de Python. Necesitamos recordar configurarlo y activarlo antes de trabajar con nuestro proyecto. Gracias a direnv y pyenv podemos automatizar todo esto, y entrar en la carpeta del proyecto hará todo el trabajo por nosotros en segundo plano.

La instalación de ambas utilidades no es sencilla, pero después de hacerlo una vez nos ahorraremos mucho tiempo. Además, siempre tendremos la certeza de que estamos trabajando con el entorno virtual y la versión de Python adecuados.