The cookiecutter project structure is quite popular with Python-based data science projects, which relies on virtual environments to work properly. This is due to the project’s re-usable code being kept in the src/
folder, and thus accessed as a Python module named src
. This is fine as long as you only have one project, but if you have multiple, the modules will begin to clash. Hence, the need for virtual environments.
Although setting up the virtual environments is not an issue, constantly activating and de-activating them can be a pain. This is where direnv comes in, a great little tool to automate activating / deactivating environments depending on the folder you’re currently in.
Installation
direnv’s website provides a variety of ways to install it. On Linux, your package manager should work, so sudo apt-get install direnv
, for example will work. If you’re on macOS, Homebrew is a quick way to install it by typing brew install direnv
.
Once installed, you’ll need to add the following to your ~/.bashrc
file:
eval "$(direnv hook bash)"
The precise command differs depending on your shell, so refer to the website for more details.
Setup (Anaconda)
If you’re using Anaconda, you’ll need to add support for it by making a file called ~/.direnvrc
with the following inside:
layout_anaconda() {
local ANACONDA_HOME="${HOME}/miniconda3/"
PATH_add "$ANACONDA_HOME"/bin
if [ -n "$1" ]; then
# Explicit environment name from layout command.
local env_name="$1"
source activate ${env_name}
elif (grep -q name: environment.yml); then
# Detect environment name from `environment.yml` file in `.envrc` directory
source activate `grep name: environment.yml | sed -e 's/name: //' | cut -d "'" -f 2 | cut -d '"' -f 2`
else
(>&2 echo No environment specified);
exit 1;
fi;
}
For vanilla Python installations or otherwise, refer to their wiki.
Then, in your ~/.bashrc
, add the following lines to ensure the environment name is printed before your PS1
(the >
or $
before your commands) at the terminal:
show_virtual_env() {
if [ -n "$CONDA_DEFAULT_ENV" ]; then
echo "($(basename $CONDA_DEFAULT_ENV))"
fi
}
export show_virtual_env
PS1='$(show_virtual_env)'$PS1
The official wiki lists the export command as export -f show_virtual_env
, the -f
flag being for specifying a function rather than a variable. Despite it being a function, that flag leads to the function contents being printed to the terminal every time the terminal is loaded. Without it, the function still works and the function isn’t printed to the terminal.
Usage (Anaconda)
In your project folder, you’ll need two files, an .envrc
and an environment.yml
. The .envrc
should contain the following:
layout anaconda
The environment.yml
file can be generated by running conda env export > environment.yml
from the terminal, assuming you’ve activated the appropriate environment for this project. Alternatively, you can create this file yourself, as only one line is important:
name: environment_name
To reload your ~/.bashrc
, type source ~/.bashrc
. You should then be able to cd
into various project directories and have your Python virtual environments loading and unloaded according to your project!