TIL - Automatically Set Your virtualenv
·321 words·2 mins
TIL
python
poetry
hatch
venv
direnv
I’m a big fan of using direnv to set project-specific env variables. And at one point I was using it to automatically activate my poetry virtualenv whenever I entered the directory per this function. However, lately I’ve also been playing with hatch or just calling python -m venv
directly, so I wanted to work out a way to have a unified approach.
This is what I came up with, and I’m sure there is a more elegant way to do this, but it works, and that’s what matters for now.
First, you add the following functions to ~/.config/direnv/direnvrc
:
layout_env() {
if [[ ! -f pyproject.toml ]]; then
log_error 'No pyproject.toml found. Cannot determine appropriate env to activate.'
exit 2
fi
grep -q poetry pyproject.toml
retVal=$?
if [ $retVal -ne 0 ]; then
grep -q hatch pyproject.toml
hatchVal=$?
if [ $hatchVal -ne 0 ]; then
layout_venv
else
layout_hatch
fi
else
layout_poetry
fi
}
layout_poetry() {
if [[ ! -f pyproject.toml ]]; then
log_error 'No pyproject.toml found. Use `poetry new` or `poetry init` to create one first.'
exit 2
fi
local VENV=$(dirname $(poetry run which python))
export VIRTUAL_ENV=$(echo "$VENV" | rev | cut -d'/' -f2- | rev)
export POETRY_ACTIVE=1
PATH_add "$VENV"
}
layout_hatch() {
if [[ ! -f pyproject.toml ]]; then
log_error 'No pyproject.toml found! Create one first using your preferred tools.'
exit 2
fi
local VENV=$(dirname $(hatch -q run which python))
export VIRTUAL_ENV=$(echo "$VENV" | rev | cut -d'/' -f2- | rev)
export HATCH_ENV_ACTIVE="default"
PATH_add "$VENV"
}
layout_venv() {
if [[ ! -d .venv ]]; then
log_error 'No local virtual env exists yet. Create one using python -m venv --prompt . .venv'
exit 2
fi
local VENV=".venv/bin"
export VIRTUAL_ENV=$(echo "$VENV" | rev | cut -d'/' -f2- | rev)
PATH_add "$VENV"
}
Then in any project directory’s .envrc
add a single line:
layout_env
After making your changes, run direnv allow
to approve the modified file for use and you’ll be good to go!