Code more, debug less with virtual environments in Python

Protect against unexpected and unwelcome surprises by using venv in Python.
72 readers like this.
woman on laptop sitting at the window

CC BY 3.0 US Mapbox Uncharted ERG

If you've ever shared a neat computer trick, a complex application, or something in between with a friend, then you've probably uttered the phrase, "Well, it works on my computer." No matter how advanced computers become, there seem to be recurrent problems related to the differences in what any two machines have configured or installed. There are ongoing attempts to solve this, and for Python developers, one of the best ways to prevent it is to use virtual environments.

The command to create a virtual environment on Python is:

$ python -m venv ./myproject

To activate a virtual environment:

$ source ./myproject/bin/activate
(myproject)$ 

To install required modules:

(myproject)$ python -m pip install -r requirements.txt

To deactivate a virtual environment:

(myproject)$ deactivate

Virtual environments are an important part of the Python development process. Learn to use them to protect yourself and your users from unexpected and unwelcome surprises. In short, use virtual environments so you can spend more time coding and less time debugging!

Virtual environments in Python

A virtual environment is a temporary adjustment to how Python runs code. A virtual environment is not a virtual machine, nor is it quite a container. In fact, a virtual environment manipulates the environment variables of your shell so that you can execute one known version of Python using a local set of modules.

Life without virtual environments

Without a virtual environment, when you type python or python3 into your terminal, you're launching whatever version of Python is installed on your computer:

$ python --version
Python 2.7.17
$ python3 --version
Python 3.7

On Monday, this might be version X, but on Tuesday, it could suddenly be Python Y, should you happen to update your computer overnight. Quite often, that's not a problem because Python tends to be good at backward compatibility. However, some computers retain very old versions of Python in the interest of legacy support, and some developers write on the cutting edge in their eagerness to use the newest features of the language. This can cause unexpected problems.

The same problem extends to individual Python modules. You might install version Z of the ExamplePyMod module, develop your code, and post your application online. Should someone who installed version X or Y of ExamplePyMod a year ago try to run your code, unexpected compatibility issues could arise. It's also a common problem for developers to take a module for granted. If you use a module so frequently that you practically think of that module as part of Python, then you're likely to forget to add the module as a requirement for running your application.

In both cases, for you to find the root cause of errors, you'd have to audit and update your system or the user's system so that you're both running the same versions of everything involved.

Using virtual environments in Python

A virtual environment temporarily redirects calls to Python to a specific version of Python. For instance, using version Python 3.7 to create a virtual environment ensures that python points to Python 3.7, not Python 2.7 or Python 3.8 or whatever else you may have lying around on your development machine.

For example, here's a virtual environment created with Python 3.7:

# no virtual environment
$ python --version
Python 2.7.17

# virtual environment
$ python3.7 -m venv example37/venv
$ cd example37
$ source ./venv/bin/activate
(venv)$ python
Python 3.7
(venv)$ deactivate

# no virtual environment
$ python --version
Python 2.7.17

Using modules in a virtual environment

Modules are installed locally within the virtual environment. When you're working in a virtual environment, you can install ExamplePyMod and use it all day long, but it will be gone once you leave the virtual environment.

Here's the module installation process:

# no virtual environment
$ python3
>>> import flask
ModuleNotFoundError: No module named 'flask'

# virtual environment
(venv)$ python -m pip install flask
[...]
(venv) bash-4.3$ python -m pip install flask
Collecting flask
  Downloading [...]
Successfully installed [...]
(venv)$ python
>>> from flask import Flask
>>> app = Flask(__name__)
(venv)$ deactivate

# no virtual environment again
$ python3
>>> import flask
ModuleNotFoundError: No module named 'flask'

Restoring a virtual environment with pip

It might seem like a lot of extra work for you to install and reinstall your required modules every time you sit down to hack on code. Actually, the virtual environment system encourages you to keep track of the modules you're using in a requirements.txt file within your project directory. You can process requirements.txt with pip to handle automated installs of all dependencies:

$ cd myproject
$ source ./venv/bin/activate
(venv)$ python -m pip install -r requirements.txt
Installed [...]
$ python
>>> from flask import Flask
>>> import examplepymod

Python also caches required modules, so you're up and running in no time.

For a complete overview of pip and its abilities, download Moshe Zadka's pip cheatsheet.

What to read next
Tags
Seth Kenlon
Seth Kenlon is a UNIX geek, free culture advocate, independent multimedia artist, and D&D nerd. He has worked in the film and computing industry, often at the same time.

Comments are closed.

Creative Commons LicenseThis work is licensed under a Creative Commons Attribution-Share Alike 4.0 International License.