Getting started with virtualenv

Python has a pretty extensive standard library, and thousands of third party packages. Thankfully virtualenv makes it easy to work with isolated environments. This is great because it allows you to easily have different versions of the same library installed concurrently.

What is a virtual environment?

In Python a "virtual environment" is a directory containing it's own Python binary, and optionally it's own set of Python packages. Each environment can be updated independently without affecting the other.

Virtualenv for Python 2

On CentOS virtualenv is available from the package manager:

yum install python-virtualenv

Alternatively you can use pip to install virtualenv:

pip install virtualenv

Note: the virtualenv installation docs explicitly warn against using pip before version 1.3 and virtualenv before version 1.9. This is because downloads from PyPI will not be over SSL.

Virtualenv for Python 3

The Python 3 standard library (v3.3 and up) comes with the venv modules that can be used to create virtual environments. It can be called by running the following:

python -m venv

Instead of:

virtualenv

Note: venv and virtualenv are not identical. virtualenv predates venv and relies on a number of hacks which aren't required for later versions of Python due to the changes made for PEP 405.

Creating a virtual environment

To create a new virtual environment, just run the virtualenv command followed by a destination directory:

[bob@virtualenv ~]$ virtualenv my-first-env
New python executable in my-first-env/bin/python
Installing Setuptools...............done.
Installing Pip......................done.

This will create a directory containing the virtual environment:

[bob@virtualenv ~]$ ls -ld my-first-env/
drwxrwxr-x. 5 bob bob 52 Nov 29 22:39 my-first-env/

To start using the environment source the activate script:

[bob@virtualenv ~]$ source my-first-env/bin/activate
(my-first-env)[bob@virtualenv ~]$

Installing packages

Once you've activated your environment additional packages can be installed using pip. New packages will only be installed in the environment you're working in and won't affect other environments or system libraries:

(my-first-env)[bob@virtualenv ~]$ pip install bottle
Downloading/unpacking bottle
  Downloading bottle-0.12.10.tar.gz (69kB): 69kB downloaded
  Running setup.py egg_info for package bottle

Installing collected packages: bottle
  Running setup.py install for bottle
    changing mode of build/scripts-2.7/bottle.py from 664 to 775

    changing mode of /home/bob/my-first-env/bin/bottle.py to 775
Successfully installed bottle
Cleaning up...
(my-first-env)[bob@virtualenv ~]$ pip list
bottle (0.12.10)
pip (1.4.1)
setuptools (0.9.8)
wsgiref (0.1.2)

Note: you don't need to be root to install packages in a virtual environment.

Switching environments

Say you now need to work on an application which uses a legacy version of the bottle module. First run deactivate to leave your old environment behind:

(my-first-env)[bob@virtualenv ~]$ deactivate
[bob@virtualenv ~]$

Then create a new environment, activate it and use pip to install an older version of the module:

[bob@virtualenv ~]$ virtualenv old-bottle
New python executable in old-bottle/bin/python
Installing Setuptools............................done.
Installing Pip...................................done.
[bob@virtualenv ~]$ source old-bottle/bin/activate
(old-bottle)[bob@virtualenv ~]$ pip install bottle==0.11.7
Downloading/unpacking bottle==0.11.7
  Downloading bottle-0.11.7.tar.gz (60kB): 60kB downloaded
  Running setup.py egg_info for package bottle

Installing collected packages: bottle
  Running setup.py install for bottle
    changing mode of build/scripts-2.7/bottle.py from 664 to 775

    changing mode of /home/bob/old-bottle/bin/bottle.py to 775
Successfully installed bottle
Cleaning up...
(my-first-env)[bob@virtualenv ~]$ pip list
bottle (0.11.7)
pip (1.4.1)
setuptools (0.9.8)
wsgiref (0.1.2)

At this point you can quickly switch between different versions of the bottle module by changing environments:

(my-first-env)[bob@virtualenv ~]$ python -c 'import bottle;print bottle.__version__'
0.12.10
(my-first-env)[bob@virtualenv ~]$ source old-bottle/bin/activate
(old-bottle)[bob@virtualenv ~]$ python -c 'import bottle;print bottle.__version__'
0.11.7

Removing environments

Because environments are just directories, they can be easily removed with rm:

[bob@localhost ~]$ rm -rf old-env/

Note: if you are using the environment, make sure you run deactivate before you remove it.

Using requirements.txt files

Python projects will normally list the packages they require in a file called requirements.txt. This is just a text file which might look something like this:

bottle>=0.12.0
requests==2.12.1

To install the packages in a requirements file use the -r or --requirement option:

(testing)[bob@virtualenv ~]$ pip install --requirement requirements.txt

The easiest way to create a requirements file is to use pip freeze:

(testing)[bob@virtualenv ~]$ pip freeze  --local > requirements.txt
(testing)[bob@virtualenv ~]$ cat requirements.txt
bees==0.01
bottle==0.12.10
requests==2.12.1

Note: the --local option is used to work around a bug in Python 2.7 (issue 12218). It shouldn't be required in later versions of Python.