A Python virtual environment is an important tool for developers when separating project dependencies in isolated environments. If working locally on several Python projects, developers may need to use different Python versions on each.
By doing this, they will be able to install different packages and have different versions of the named packages for each environment.
However, this can generate a lot of compatibility issues unless you manage them correctly using virtual environments. There are many ways to do this and I will highlight two tools to do so: Pyenv and Pipenv.
Python Virtual Environments
In the following image, you can see an abstract example of different Python projects containing the different combinations of packages that you can install:
Each big colored box represents a Python virtual environment. It’s common for certain package versions to be supported only by determined Python versions. Also, you may need a determined version of a package in one project and another version for others. As well as this, a determined version of a package can generate conflicts with packages or Python versions.
Many combinations of compatibility issues can be found but by having those isolated environments you can avoid them. You will be able to install, uninstall, update, etc in one virtual environment, without affecting the rest of them. As mentioned, there are many tools to do this, and I will talk about the ones I find easy to understand and use.
Pyenv is a tool used to manage different Python versions. With this tool you can:
- Install several Python versions.
- Set/change the global(default) Python version in your computer.
- Set/change a Python version locally for a project.
- Create and manage virtual environments.
On macOS, you can install this tool using Homebrew:
brew install pyenv
To install it on other platforms, you can watch this section in the GitHub docs. After the installation, edit your used shell startup script (
.bash_profile, …) adding the following line:
if command -v pyenv 1>/dev/null 2>&1; then eval "$(pyenv init -)" fi
Then reload your shell startup script. An example if you have
cd source .bashrc
That’s it! You have installed Pyenv successfully.
Managing Python Versions
Now let’s take a look at the possible Python versions that you can install through Pyenv, executing:
pyenv install --list
You will see a large list of Python versions. You can pick one to install it, let’s say 3.9.1:
pyenv install 3.9.1
You can run that command with any version that you want to have installed on your computer. To see all the installed versions, just run:
Also, you can set the global version that you want to use in your system, this will be the default one. For example, if you have already installed 3.8.8, you can set it as the global version running:
pyenv global 3.8.8
You can change that, of course, by executing the command again with the desired installed version. If you want to check your global version, just run:
With Pyenv, you can have a global and a local version for each project. To set a local version, go to the project folder in the terminal:
And set the local version, for example, 3.9.1:
pyenv local 3.9.1
This will create a
.python-version file in the folder indicating the current local Python version for the project. Also, if you run
python -V in that folder, you will see the local version, and not the global one.
So, to sum up, you have the following useful commands at your disposal:
pyenv install --listto see the available Python versions you can install.
pyenv versionsto see the installed Python versions.
pyenv global <Python version>to set an installed Python version as global.
pyenv local <Python version>to set an installed Python version for a given project folder.
pyenv uninstall <Python version>to uninstall an already installed Python version.
Pyenv also allows us to manage environments with a plugin called pyenv-virtualenv. However, I prefer to use Pipenv. Let’s take a look.
Pipenv is a tool used to manage the required packages in a Python project. With this tool you can:
- Automatically create or delete a virtual environment.
- Install, uninstall and update packages maintaining the desired versions.
- Set up very quickly a working Python environment.
- Have a list of the installed packages and the corresponding version.
If you use Pipenv in your projects, you will have two special files in the root folder, both generated and changed automatically. Those are:
Pipfile: A file that specifies the installed packages in your virtual environment for development and execution.
Pipfile.lock: A file that specifies which versions of the installed packages (detailed in the Pipfile) has to be used. Also has another important metadata.
With Pipenv, is very easy to work on projects with other developers using the same packages and versions as it provides the files containing all that information. Developers must simply run a command to have the same environment in their own computer.
On macOS, you can install this tool using Homebrew:
brew install pipenv
And that’s it. You’re ready to start! To install it on other platforms, check out this section in the pipenv docs.
Creating Virtual Environments
Now, let’s look at how to create a virtual environment for a Python project. First, go to the project folder:
And then execute:
This will create a virtual environment and:
- If you already have a Pipfile and a Pipfile.lock: it will also install all the specified packages on them.
- If you don’t have a Pipfile and a Pipfile.lock: it will generate them for that environment.
This is how a Pipfile recently created looks like:
[[source]] url = "https://pypi.org/simple" verify_ssl = true name = "pypi" [packages] [dev-packages] [requires] python_version = "3.7"
[packages] section, you will see the installed packages for execution – the ones that your Python program will need to be executed correctly.
[dev-packages] section, you will see the packages that are needed only for development. Also, you can see in that example that the used Python version is
If you use Pyenv, the
pipenv install command will use the global Python version of your system. But as you know, you can specify a local Python version in your project. For example:
pyenv local 3.8.8
And, if you want to use that local Python version, you can indicate that to Pipenv by executing:
pipenv install --python 3.8.
Now, what if you want to delete the created virtual environment to create another one? You can do so by running:
Another important thing to remember is to activate the created virtual environment, which you do by running:
With this command, you “have entered” your virtual environment. In your terminal, you can see if you have already activated the virtual environment, if you see the name between brackets at the beginning of the line, as follows:
There you can see that after the
pipenv shell command has been executed, the name of the virtual environment appeared between brackets at the beginning of the line. To deactivate the virtual environment, just run:
Ok, so you now know how to create, delete, activate and deactivate a virtual environment. Now let’s see how to manage the packages inside them. First, don’t forget to activate the virtual environment. To install a package, for example django-drip-campaings, you can execute:
pipenv install django-drip-campaigns
This command will:
- Install the latest available version of that package.
- Automatically update the Pipfile file adding the package.
- Automatically update the Pipfile.lock file adding the package version and some other important metadata.
Now the Pipfile file looks like this:
[[source]] url = "https://pypi.org/simple" verify_ssl = true name = "pypi" [packages] django-drip-campaigns = "*" [dev-packages] [requires] python_version = "3.8"
As you can see, the package was installed under the
[packages] section. As previously mentioned, in the
[dev-packages] section you only install what’s needed for deployment.
For example, you want to have flake8 in your project, which is only required by the development process. To install it under the
[dev-packages] section, execute:
pipenv install flake8 --dev
After that, you will see something like this in the Pipfile file:
[packages] django-drip-campaigns = "*" [dev-packages] flake8 = "*"
Also, what if you need a specific version of a package? For example – Django, not the latest but the 2.2 version. Then run:
pipenv install django==2.2
Now the Pipfile is updated and will resemble something like:
[packages] django-drip-campaigns = "*" django = "==2.2" [dev-packages] flake8 = "*"
Django package line, you don’t see the “*”, you instead see the specific version indicated in the command. If you need to uninstall a package, for example
django-drip-campaigns, just run:
pipenv uninstall django-drip-campaigns
That command will uninstall the package and remove the information from the Pipfile and Pipfile.lock files. Now suppose you need the latest version of
Django in your project (not the 2.2 version). To update a package to the latest version, you have to:
- Change the
django = "==2.2"line in the Pipfile by
django = "*".
- Then run:
pipenv update django
Alternatively, you can uninstall
Django and then install it again without specifying the version. You can repeat those steps to downgrade a package version instead of upgrading it.
You can do a lot of things with Pipenv, but the previously mentioned throughout are the main features. Pretty easy, right? Now let’s see a summary of the mentioned commands provided by Pipenv:
pipenv installto create a virtual environment.
pipenv install --python <Python version>to create a virtual environment indicating the desired Python version (that you have installed using Pyenv).
pipenv --rmto delete the current virtual environment.
pipenv shellto activate the created virtual environment.
exitto deactivate an already activated virtual environment.
Now let’s take a look at the summary of the commands after the virtual environment has been activated:
pipenv install <package name>to install the latest version of the package under the
pipenv install <package name>==<package version>to install a specified version of a package, under the
pipenv update packageto update a version package (update or downgrade) to the one that you have previously specified in the Pipfile.
--devto the previous commands, Pipenv will do the same but under the
pipenv uninstall <package name>to uninstall a package.
As highlighted throughout, I have presented two different tools for managing Python projects using virtual environments. There are many ways to do this, but I showcased the two I believe to be the most effective.
As tools, Pyenv and Pipenv are tidy and maintainable as well as easy to understand and use. Pyenv is used to manage different Python versions, whereas Pipenv is used to manage Python packages.
I really like using both and I hope you are encouraged to try these tools for Python development. Thank you for reading and stay tuned for more useful content.