Power up your virtualenv

Stefan "hr" Berder // // code

I discovered virtualenvwrapper in early 2012, it’s been my tool of choice when working with python since then. Now, mkvirtualenv is the first command I type when starting a project. Then my workflow used to look something close to:

$ cd ~/codaz/myproject
$ workon myproject
(myproject)$ source myenv

This is very repetitive and long to type. Trying to be a good developer I tend to be as lazy as humanly possible, thankfully virtualenvwrapper is helping us being just that. I’ll show a few commands and some useful user hooks I’m using to streamline repetitive tasks.

I used to have a lot of user hooks to do the job but now with commands like mkproject the whole thing is very simple.

First step is to create a PROJECT_HOME environment variable, in my case I edit ~/.bashrc and add this line near the end:

export PROJECT_HOME=/home/hr/codaz

I then source this file so the variable is available.

$ source ~/.bashrc

Now when creating a new project, I simply use mkproject:

$ mkproject coolapp
New python executable in coolapp/bin/python
Installing setuptools, pip...done.
Creating /home/hr/codaz/coolapp
Setting project for coolapp to /home/hr/codaz/coolapp
(coolapp)$ pwd
/home/hr/codaz/coolapp

Using the mkproject command did the following:

  • create a virtualenv named coolapp
  • create a project folder named coolapp in $PROJECT_HOME
  • create a file with the project folder path in $VIRTUAL_ENV/$VIRTUALENVWRAPPER_PROJECT_FILENAME
  • cd to $PROJECT_HOME/coolapp
  • activate the virtualenv

From now on, activating the virtualenv with workon will also change the directory to our project folder. When using that virtualenv, using cdproject will bring you back to your project folder.

When working on a project, I also often need some environment variables to be set, that’s where I use the hooks. You need to edit $WORKON_HOME/postactivate and $WORKON_HOME/predeactivate so they include:

if [ -f "$VIRTUAL_ENV/$VIRTUALENVWRAPPER_PROJECT_FILENAME" ]; then
    venvrc="$(cat $VIRTUAL_ENV/$VIRTUALENVWRAPPER_PROJECT_FILENAME)/.venvrc"
    if [ -f "$venvrc" ]; then
        source "$venvrc"
    fi
fi

Then in the project folder I create a file called .venvrc with the following skeleton:

# virtualenv env variables
# this file is sourced in postactivate and postdeactivate hooks
# the $VENV variable is used to know which state the project is in

case "$VENV" in
    # virtualenv was active so this is a postdeactivate, CLEAN ALL THE STUFF
    'active')
        unset VENVRC
    ;;
    # virtualenv is getting activated, set the env variables
    *)
        export VENVRC="active"
    ;;
esac

# vim: syntax=sh

This is a good start and much can be stuffed in the .venvrc file.

If you just discovered about the concept of project folder in virtualenv, you can use setvirtualenvproject to set a project for an already existing virtualenv.

There is a bunch of other very powerful commands provided by virtualenvwrapper, you should definitely check it out.

//