Configurar un entorno de Python con direnv
Aprende a automatizar tu entorno de desarrollo Python usando direnv. Crea un entorno Python reproducible con virtualenv y uv.
Cuando trabajo en un proyecto python o ansible quiero tener un entorno virtual con las dependencias de ese proyecto y que éste se active de forma automática cuando entro a la carpeta del proyecto.
Para ello la mejor herramienta que he encontrado es direnv.
Instalamos direnv con brew:
brew install direnv
Añade a .zshrc:
if (( ${+commands[direnv]} )); then
eval "$(direnv hook zsh)"
fi
De esta forma lo tienes cargado automaticamente en cada shell que abres.
Ahora, en el directorio de tu proyecto, solo tienes que crear un archivo .envrc con un contenido similar a éste que te muestro, que es el que uso para trabajar con proyectos Ansible:
layout python python3
# To generate requirements-controller.txt run `uv pip compile --output-file requirements-controller.txt requirements-controller.in`
watch_file requirements-controller.txt
uv pip sync requirements-controller.txt
# less strict:
#python3 -m pip install --requirement requirements-controller.txt
export ANSIBLE_CONFIG=$PWD/ansible.cfg
export ANSIBLE_PYTHON_INTERPRETER=$VIRTUAL_ENV/bin/python
# Put your secrets in .envrc.private file with the format `export MYSECRET="VALUE"`
source_env_if_exists .envrc.private
Explicación del archivo .envrc
layout python python3: Activa el entorno virtual de python. El virtualenv se crea en un directorio.direnv.watch_file requirements-controller.txt: Vigila el archivorequirements-controller.txty recarga el entorno virtual si cambia. De esta forma las dependencias siempre estarán actualizadas con el archivorequirements-controller.txtuv pip sync requirements-controller.txt: Sincroniza el entorno virtual con el archivorequirements-controller.txt. Ésto instala las dependencias del proyecto en el entorno virtual.export ANSIBLE_CONFIG=$PWD/ansible.cfg: Exporta la variable de entornoANSIBLE_CONFIGaansible.cfg.export ANSIBLE_PYTHON_INTERPRETER=$VIRTUAL_ENV/bin/python: Exporta la variable de entornoANSIBLE_PYTHON_INTERPRETERal entorno virtual de python.source_env_if_exists .envrc.private: Carga las variables de entorno del archivo.envrc.privatesi existe. Esto es util para no subir las variables de entorno privadas al repositorio. Recuerda añadir el archivo.envrc.privatea.gitignore.
La línea python3 -m pip install --requirement requirements-controller.txt reemplazaría a uv pip sync requirements-controller.txt y serías tú quien editaría el archivo requirements-controller.txt para añadir o quitar dependencias, sin necesidad de especificar las dependencias transitivas.
Sin embargo, usando uv pip sync requirements-controller.txt sólo tienes que mantener actualizado el archivo requirements-controller.in y uv se encargará de generar el archivo requirements-controller.txt con las dependencias correctas, incluyendo las dependencias transitivas, resolviendo conflictos automáticamente. Puedes usarlo con uv pip compile --output-file requirements-controller.txt requirements-controller.in.
Funcionamiento
Es todo automático. Cuando entras en el directorio, se ejecuta automaticamente el archivo .envrc y se activa el entorno virtual de python, se exportan las variables de entorno, etc. Cuando sales del directorio, se desactiva automaticamente el entorno virtual de python, las variables de entorno no estarán exportadas, etc.
Seguridad con direnv
Recuerda que cada vez que modifiques el archivo .envrc tienes que ejecutar el comando direnv allow. Ésto es para permitir que direnv ejecute comandos en tu directorio.
Por defecto, las variables de entorno que definas en .envrc solo afectarán al directorio del proyecto y a sus subdirectorios. Si quieres que afecten a todos los directorios, puedes usar el comando direnv export --all.