Virtual Environments in Python provides an isolated and self contained instance of the version of Python and all other modules or packages that a specific project is dependent on. Virtual Environments appear in the form of directory with the name of the environment we choose and contain the version of Python, scripts, libraries and packages that are available with in the virtual environment.
Table of Contents
- What you will learn
- Working with Virtual Environments
- Create a Virtual Environment
- Activate the Virtual Environment
- Upgrade pip
- Install Modules in activated virtual environment
- Limitations with Virtual Environments venv
- Freezing the Virtual Environment
- Deactivating the Virtual Environment
- Watch 📺 Demonstration of working with Virtual Environment on CentOS
- Video
What you will learn
In this tutorial we will see a brief introduction to virtual environments. By the end of this tutorial you will understand the following:
- Problems when virtual environments are not used
- What is the need for Virtual Environments
- Why it is suggested to work with virtual environments in Python
- How to create, activate deactivate virtual environment in Linux and Windows
- Install a package in activated virtual environment
- Portability limitation of virtual environments
- How to overcome the Portability limitation with pip freeze
Working with Virtual Environments
Suppose that you are working on two different Python Projects and one of the projects requires the very old absinthe version 0.11 of Flask and another requires version 1.1.1.
The problem occurs if you perform pip install flask
directly on a PC level. Because the different projects that you work on or Python applications running on a PC require specific versions of Flask. Installing packages or Python modules at the system level may result in malfunctioning of other Python projects that have version specific requirements of their dependent modules. In order to get rid of this problem, Python has a concept of Virtual Environments.
The beauty of working with Python is it allows you to create and work in isolated environments for each of the Python project you work on a PC.
Virtual Environments in Python provides an isolated and self contained instance of the version of Python and all other modules or packages that a specific project is dependent on. Virtual Environments appear in the form of directory with the name of the environment we choose and contain the version of Python, scripts, libraries and packages that are available with in the virtual environment.
Working in activated virtual environments will scope the installation of Python packages to the active virtual environment. This facilitates working on different Python projects on a single PC that require different versions of the same package.
Create a Virtual Environment
The following is the standard command to set up a virtual environment.
python -m venv {name-of-virtualenv}
-m
: is the module argument that takes the name of the module.venv
: is the name of module to create virtual environment. The standard modulevenv
comes default with installation of Python.{name-of-virtualenv}
: is the name of the virtual environment of our choice.
Create a Virtual Environment named env or any name of your choice by typing the following command. Let’s name our virtual environment as env
Create a Python Virtual Environment in Windows OS
python -m venv env
Create a Python Virtual Environment in Unix based OS
python3 -m venv env
The above command tells the Python to use venv
module that helps to create the virtual environment with the name env
.
Virtual Environment Tree Directory Structure
The created virtual environment env will have the following folder structure
. └───env ├───Include ├───Lib │ └───site-packages │ ├───pip │ │ ├───_internal │ │ │ ├───cli │ │ │ │ └───__pycache__ │ │ │ ├───commands │ │ │ │ └───__pycache__ │ │ │ ├───distributions │ │ │ │ └───__pycache__ │ │ │ ├───models │ │ │ │ └───__pycache__ │ │ │ ├───operations │ │ │ │ └───__pycache__ │ │ │ ├───req │ │ │ │ └───__pycache__ │ │ │ ├───utils │ │ │ │ └───__pycache__ │ │ │ ├───vcs │ │ │ │ └───__pycache__ │ │ │ └───__pycache__ │ │ ├───_vendor │ │ │ ├───cachecontrol │ │ │ │ ├───caches │ │ │ │ │ └───__pycache__ │ │ │ │ └───__pycache__ │ │ │ ├───certifi │ │ │ │ └───__pycache__ │ │ │ ├───chardet │ │ │ │ ├───cli │ │ │ │ │ └───__pycache__ │ │ │ │ └───__pycache__ │ │ │ ├───colorama │ │ │ │ └───__pycache__ │ │ │ ├───distlib │ │ │ │ ├───_backport │ │ │ │ │ └───__pycache__ │ │ │ │ └───__pycache__ │ │ │ ├───html5lib │ │ │ │ ├───filters │ │ │ │ │ └───__pycache__ │ │ │ │ ├───treeadapters │ │ │ │ │ └───__pycache__ │ │ │ │ ├───treebuilders │ │ │ │ │ └───__pycache__ │ │ │ │ ├───treewalkers │ │ │ │ │ └───__pycache__ │ │ │ │ ├───_trie │ │ │ │ │ └───__pycache__ │ │ │ │ └───__pycache__ │ │ │ ├───idna │ │ │ │ └───__pycache__ │ │ │ ├───lockfile │ │ │ │ └───__pycache__ │ │ │ ├───msgpack │ │ │ │ └───__pycache__ │ │ │ ├───packaging │ │ │ │ └───__pycache__ │ │ │ ├───pep517 │ │ │ │ └───__pycache__ │ │ │ ├───pkg_resources │ │ │ │ └───__pycache__ │ │ │ ├───progress │ │ │ │ └───__pycache__ │ │ │ ├───pytoml │ │ │ │ └───__pycache__ │ │ │ ├───requests │ │ │ │ └───__pycache__ │ │ │ ├───urllib3 │ │ │ │ ├───contrib │ │ │ │ │ ├───_securetransport │ │ │ │ │ │ └───__pycache__ │ │ │ │ │ └───__pycache__ │ │ │ │ ├───packages │ │ │ │ │ ├───backports │ │ │ │ │ │ └───__pycache__ │ │ │ │ │ ├───rfc3986 │ │ │ │ │ │ └───__pycache__ │ │ │ │ │ ├───ssl_match_hostname │ │ │ │ │ │ └───__pycache__ │ │ │ │ │ └───__pycache__ │ │ │ │ ├───util │ │ │ │ │ └───__pycache__ │ │ │ │ └───__pycache__ │ │ │ ├───webencodings │ │ │ │ └───__pycache__ │ │ │ └───__pycache__ │ │ └───__pycache__ │ ├───pip-19.2.3.dist-info │ ├───pkg_resources │ │ ├───extern │ │ │ └───__pycache__ │ │ ├───_vendor │ │ │ ├───packaging │ │ │ │ └───__pycache__ │ │ │ └───__pycache__ │ │ └───__pycache__ │ ├───setuptools │ │ ├───command │ │ │ └───__pycache__ │ │ ├───extern │ │ │ └───__pycache__ │ │ ├───_vendor │ │ │ ├───packaging │ │ │ │ └───__pycache__ │ │ │ └───__pycache__ │ │ └───__pycache__ │ ├───setuptools-41.2.0.dist-info │ └───__pycache__ └───Scripts
Activate the Virtual Environment
Once we have the virtual environment created, we need to activate that virtual environment.
Type in the following command based on your operating system to activate the virtual environment.
Activate Python virtual environment for Windows OS
Type the following command to activate Python virtual environment in Windows OS
env\Scripts\activate
Activate Python virtual environment for Unix based OS
Type the following command to activate Python virtual environment in Unix based OS
source ./env/bin/activate
After successful activation of the virtual environment you will see the name of the environment that got created will be prefixed to the command line terminal in rounded brackets. On Windows OS, this looks like
(env) c:\Users\navule\helloflask
If you have given any other name for the virtual environment, you should see the name in closed parentheses accordingly.
Upgrade pip
The first thing you should do after installing and activating a virtual environment is to upgrade pip
. pip
is a module installer in Python. That means, pip
will help us to install Python modules so that we can consume it in our application.
pip
in itself is a module that comes by default with Python installation. There are frequent upgrades to pip
. Hence it is a best practice to upgrade the pip
so that it will always get the dependencies from the trusted sources for our project.
Run the following command to upgrade pip
.
python -m pip install --upgrade pip
Install Modules in activated virtual environment
From now on, you can install any project related modules based on the requirement. Lets say the application needs to have flask module, you perform the module installation by running the command in the virtual environment activated shell as follows:
pip install flask
Now if you look at the site-packages directory you will find the Flask package along with its dependent packages like jinja, werkzeug are also installed.
. └───env ├───Include ├───Lib │ └───site-packages │ ├───click │ │ └───__pycache__ │ ├───Click-7.0.dist-info │ ├───flask │ │ ├───json │ │ │ └───__pycache__ │ │ └───__pycache__ │ ├───Flask-1.1.1.dist-info │ ├───itsdangerous │ │ └───__pycache__ │ ├───itsdangerous-1.1.0.dist-info │ ├───jinja2 │ │ └───__pycache__ │ ├───Jinja2-2.11.1.dist-info │ ├───markupsafe │ │ └───__pycache__ │ ├───MarkupSafe-1.1.1.dist-info │ ├───pip │ │ ├───_internal │ │ │ ├───cli │ │ │ │ └───__pycache__ │ │ │ ├───commands │ │ │ │ └───__pycache__ │ │ │ ├───distributions │ │ │ │ └───__pycache__ │ │ │ ├───index │ │ │ │ └───__pycache__ │ │ │ ├───models │ │ │ │ └───__pycache__ │ │ │ ├───network │ │ │ │ └───__pycache__ │ │ │ ├───operations │ │ │ │ ├───build │ │ │ │ │ └───__pycache__ │ │ │ │ ├───install │ │ │ │ │ └───__pycache__ │ │ │ │ └───__pycache__ │ │ │ ├───req │ │ │ │ └───__pycache__ │ │ │ ├───utils │ │ │ │ └───__pycache__ │ │ │ ├───vcs │ │ │ │ └───__pycache__ │ │ │ └───__pycache__ │ │ ├───_vendor │ │ │ ├───cachecontrol │ │ │ │ ├───caches │ │ │ │ │ └───__pycache__ │ │ │ │ └───__pycache__ │ │ │ ├───certifi │ │ │ │ └───__pycache__ │ │ │ ├───chardet │ │ │ │ ├───cli │ │ │ │ │ └───__pycache__ │ │ │ │ └───__pycache__ │ │ │ ├───colorama │ │ │ │ └───__pycache__ │ │ │ ├───distlib │ │ │ │ ├───_backport │ │ │ │ │ └───__pycache__ │ │ │ │ └───__pycache__ │ │ │ ├───html5lib │ │ │ │ ├───filters │ │ │ │ │ └───__pycache__ │ │ │ │ ├───treeadapters │ │ │ │ │ └───__pycache__ │ │ │ │ ├───treebuilders │ │ │ │ │ └───__pycache__ │ │ │ │ ├───treewalkers │ │ │ │ │ └───__pycache__ │ │ │ │ ├───_trie │ │ │ │ │ └───__pycache__ │ │ │ │ └───__pycache__ │ │ │ ├───idna │ │ │ │ └───__pycache__ │ │ │ ├───msgpack │ │ │ │ └───__pycache__ │ │ │ ├───packaging │ │ │ │ └───__pycache__ │ │ │ ├───pep517 │ │ │ │ └───__pycache__ │ │ │ ├───pkg_resources │ │ │ │ └───__pycache__ │ │ │ ├───progress │ │ │ │ └───__pycache__ │ │ │ ├───pytoml │ │ │ │ └───__pycache__ │ │ │ ├───requests │ │ │ │ └───__pycache__ │ │ │ ├───urllib3 │ │ │ │ ├───contrib │ │ │ │ │ ├───_securetransport │ │ │ │ │ │ └───__pycache__ │ │ │ │ │ └───__pycache__ │ │ │ │ ├───packages │ │ │ │ │ ├───backports │ │ │ │ │ │ └───__pycache__ │ │ │ │ │ ├───ssl_match_hostname │ │ │ │ │ │ └───__pycache__ │ │ │ │ │ └───__pycache__ │ │ │ │ ├───util │ │ │ │ │ └───__pycache__ │ │ │ │ └───__pycache__ │ │ │ ├───webencodings │ │ │ │ └───__pycache__ │ │ │ └───__pycache__ │ │ └───__pycache__ │ ├───pip-20.0.2.dist-info │ ├───pkg_resources │ │ ├───extern │ │ │ └───__pycache__ │ │ ├───_vendor │ │ │ ├───packaging │ │ │ │ └───__pycache__ │ │ │ └───__pycache__ │ │ └───__pycache__ │ ├───setuptools │ │ ├───command │ │ │ └───__pycache__ │ │ ├───extern │ │ │ └───__pycache__ │ │ ├───_vendor │ │ │ ├───packaging │ │ │ │ └───__pycache__ │ │ │ └───__pycache__ │ │ └───__pycache__ │ ├───setuptools-41.2.0.dist-info │ ├───werkzeug │ │ ├───debug │ │ │ ├───shared │ │ │ └───__pycache__ │ │ ├───middleware │ │ │ └───__pycache__ │ │ ├───wrappers │ │ │ └───__pycache__ │ │ └───__pycache__ │ ├───Werkzeug-1.0.0.dist-info │ └───__pycache__ └───Scripts
Limitations with Virtual Environments venv
Virtual Environments are not Portable
Virtual environments are not portable. Virtual Environments will not work if you move them to a different directory within the same PC or across different PCs.
Though the virtual environments offer a great isolation to work with different versions of a module across projects by providing isolation between the projects, they completely take out the freedom of portability.
Hence it is not suggested to check-in the virtual environment directory to the source control. And the relative path of the virtual environment directory must be added to the .gitignore file if you are using git as source control for version tracking.
Freezing the Virtual Environment
To overcome the portability limitation, you can freeze the virtual environment to a text file that has all the module information.
The following command when run in an activated virtual environment will freeze all the modules with version information to a file name of our choice.
pip freeze > requirements.txt
The above command with the help of pip
module freezes the requirements that the active virtual environment is dependent on to the file named requirements.txt. The requirements.txt file will be created by pip if it does not already exists and updates if it exists already.
If we look at contents of requirements.txt, it will show something similar to this.
# c:\Users\navule\helloflask\requirements.txt Click==7.0 Flask==1.1.1 itsdangerous==1.1.0 Jinja2==2.11.1 MarkupSafe==1.1.1 Werkzeug==1.0.0
The file requirements.txt must be checked-in to the version control like git.
Restore the Python packages from requirements.txt
When the repository is ported to the other location or PCs, we can then perform the following activities to restore the packages that our app is dependent on.
- Check out our project on a different PC
- Create a new and fresh virtual environment
- Activate the virtual environment
- Restore/ Install the modules that the app is dependent on from requirements.txt
Run the following command to restore or install the modules from the requirements.txt
pip install -r requirements.txt
The above command tells the pip module of the activated virtual environment to recursively read and install all the modules mentioned in the requirements.txt
When to perform freeze
The freeze of modules is very important whenever we install a new package via pip. Running pip freeze > requirements.txt
will automatically update the existing requirements file and thus when a new developer or a new deployment happens, the new or updated installer packages will be installed with pip install -r requirements.txt
Deactivating the Virtual Environment
Once you are done working with the application, you are suggested to deactivate the virtual environment. Run the following command to deactivate the virtual environment.
deactivate
Watch 📺 Demonstration of working with Virtual Environment on CentOS
Watch 📺 the real demo of creating Virtual Environment in CentOS.
Video
You can watch this video to understand how to work with virtual environments in Python. This video tutorial uses virtualenv
to create virtual environment.
Pingback: Setup Visual Studio Code for Python Development – TutLinks
Pingback: Developing Python Flask Hello World App from scratch – TutLinks
Pingback: Create and Deploy FastAPI app to Heroku – TutLinks
Pingback: Implementing Async REST APIs in FastAPI with PostgreSQL CRUD – TutLinks
Pingback: Debug FastAPI in VS Code IDE – TutLinks
Pingback: Deploy FastAPI app on Google Cloud Platform – TutLinks
Pingback: Deploy FastAPI on Ubuntu and Serve using Caddy 2 Web Server – TutLinks