Virtual Environments in Python Made Easy

Virtual Environments in Python Made Easy

Most Python newcomers don’t know how to set up a development environment that follows the latest standards used by professional programmers. This tutorial will teach you how to properly create a fully working Python development environment using industry-accepted best practices.

Virtual Environments

A virtual environment helps us to solve project dependency conflicts by creating isolated environments. These “isolated environments” contain all the goodies Python programmers might need to develop their projects.

Virtual environments include a fresh duplicate of Python binaries, and a standalone copy of the entire Python standard library. That’s why it can work by itself.

Using virtual environments give us the following advantages:

  • we’re able to maintain our local machine packages intact
  • we can share dependencies with others with a requirements.txt file
  • we can deploy a Python app in a dedicated server (PythonAnyWhere, Heroku, and so forth)

The Need for Virtual Environments

I use many libraries for my projects. Among them are three web application development frameworks, and there are other libraries I’d like to explore in future. This serves as the main argument that serious projects in Python depend on other packages written by other developers.

If you’re a Django developer, I’m confident you use Django rest framework to create powerful rest APIs, Django Debug Toolbar for gathering various debug information about the current request/response, Celery for taking care of real-time operations, and scheduling as well, and so on.

For example, I rely heavily on the requests package for some of my projects, and a Django web application I’m currently working on depends on version 2.3.0. According to the official documentation, at the time of writing the latest version of this package is version 3.2.

Let’s suppose I go ahead and install the latest version of the library on my Ubuntu machine because I need it for another project. Everything seems to work fine until I try to make use of my older project, which worked fine with 2.3.0. Suddenly, everything is broken.

What happened? Maybe the API of the latest version of Django has changed since version 2.3.0? The reason doesn’t matter at this point, as my older project is broken and no longer works.

A conflict between two projects has been created. They make use of the same library, but they require different versions of it.

Various packages solve this problem. Let’s see some that stand out.

Before Starting

In this tutorial, we’ll be using Python 3, so let’s start by checking your Python installation.

To do this, open up a terminal — cmd/PowerShell on Windows — and type the following command:

python --version Python 3.9.5 # My result 

Note: Most macOS and Linux systems have Python installed. You can check the Python installation guide if you’re using Windows.

If you didn’t get a result of the form Python 3.x there are two options:

  • if this command returned a Python 2.x version, you’ll need to use python3 along with this tutorial
  • if you got an Unknown command error, try to run python3, and if you get another error, follow the Python installation guide

You can proof the existence of the python3 binary by checking its version:

python3 --version Python 3.9.5 

Note: if the command above worked, you’ll need to run python3 instead of python.

Now that you know which Python command runs on your machine, let’s get into virtual environments.

Built-in venv Module

Let’s use the built-in Python venv module to create your first virtual environment.

Note: to use this module you need Python 3.3 or greater installed in your system.

To create a Python virtual environment with venv, type the following command:

python -m venv virt1 

Note: the -m flag means Python is running the built-in venv module as a script.

This will create a virtual environment with the name of virt1, but this is just an argument. You can create the virtual environment with any name you want.

Everything installed in the virt1 directory won’t affect the global packages or system-wide installations, thus avoiding dependency conflicts.

Activating Virtual Environments

It’s crucial to know that each time we want to use a created virtual environment, we need to activate it with the following command:

source virt1/bin/activate 

This won’t work in every system, so you can check the table below to have a clear idea of which command to use:

Platform Shell Command to activate virtual environment
POSIX bash/zsh $ source (venv-name)/bin/activate
fish $ source (venv-name)/bin/activate.fish
csh/tcsh $ source (venv-name)/bin/activate.csh
PowerShell Core $ (venv-name)/bin/Activate.ps1
Windows cmd.exe C:> (venv-name)Scriptsactivate.bat
PowerShell PS C:> (venv-name)ScriptsActivate.ps1

Note: the $ sign on POSIX and the C:>, PS C:> signs on Windows aren’t part of the command.

As you may notice, I’m using a bash shell in a POSIX (macOS and Linux), which is why I’m running the command above.

After the environment is created

Once the virtual environment gets activated, the terminal prompt changes a bit.

Activated environment

The following command lets you deactivate the virtual environment:

deactivate 

Note how your terminal prompt has changed again.

Deactivated environment

Now activate your virtual environment again and use the which command to check the Python binary that’s being used:

source virt1/bin/activate which python 

If everything worked well, you should get something similar to the following output:

/home/daniel/tests/python-tests/venvs/virt1/bin/python 

If you deactivate and which again, you should get a different output:

deactivate /usr/bin/python 

This is because, when working inside a virtual environment, the binary copy placed inside that environment is being used. The same applies to packages.

Continue reading Virtual Environments in Python Made Easy on SitePoint.