Python Virtual Environment on Ubuntu 18.04 LTS

Personally I dislike pip as a package manager for system packages as it can cause unexpected errors and/or a dependency nightmare. For me, you should always install a package using the distros package manager if available. In Ubuntu’s case, this is apt. As an example of what I mean, recently I installed the awscli tool on Ubuntu from the system package manager and this worked fine. Then later, I installed openstack via pip. I then used the openstack command happily but then later went to use the awscli command again, only to find it is now in a broken state. It looks like pip upgraded a Python package being used by the awscli. While there are things you can do to mitigate these issues, like installing a package for a given user only and not to the system as a whole, I find you can still run into issues.

Here I try to define a process for installing these kind of applications or custom scripts in isolation of each other. I am also quite keen to try and avoid having pip installed globally if possible.

Installation

Assuming this is a fresh installation of Ubuntu, update the system and reboot:

andy@ubuntu18:~$ sudo apt update -y && sudo apt dist-upgrade -y && sudo apt autoremove -y && sudo reboot

Install some required packages:

andy@ubuntu18:~$ sudo apt install build-essential libssl-dev libffi-dev python-dev

Install python-virtualenv and virtualenvwrapper:

andy@ubuntu18:~$ sudo apt install python-virtualenv virtualenvwrapper

Configuration

Find the virtualenvwrapper.sh script:

andy@ubuntu18:~$ sudo find / -iname virtualenvwrapper.sh
/usr/share/virtualenvwrapper/virtualenvwrapper.sh

And the copy it to your home directory and make it executable:

andy@ubuntu18:~$ mkdir -pv ~/.local/bin
mkdir: created directory '/home/andy/.local'
mkdir: created directory '/home/andy/.local/bin'

andy@ubuntu18:~$ sudo cp -v /usr/share/virtualenvwrapper/virtualenvwrapper.sh ~/.local/bin/
'/usr/share/virtualenvwrapper/virtualenvwrapper.sh' -> '/home/andy/.local/bin/virtualenvwrapper.sh'

andy@ubuntu18:~$ sudo chmod -v u+x ~/.local/bin/virtualenvwrapper.sh 
mode of '/home/andy/.local/bin/virtualenvwrapper.sh' changed from 0644 (rw-r--r--) to 0744 (rwxr--r--)

Create a directory to store files relating to your projects virtual environment dependencies:

andy@ubuntu18:~$ mkdir -pv ~/.virtualenvs
mkdir: created directory '/home/andy/.virtualenvs'

Create a directory to store your projects source files:

andy@ubuntu18:~$ mkdir -pv ~/Devel
mkdir: created directory '/home/andy/Devel'

The below line adds an entry to your ~/.bashrc file:

andy@ubuntu18:~$ echo -en '\n\n#virtualenvwrapper\nexport VIRTUALENVWRAPPER_PYTHON=/usr/bin/python\nexport WORKON_HOME=~/.virtualenvs\nsource ~/.local/bin/virtualenvwrapper.sh\nexport PROJECT_HOME=~/Devel\n' >> ~/.bashrc

You will also need to source it to read in the new changes without logging out and back in from your shell:

andy@ubuntu18:~$ source ~/.bashrc

Usage

As an example use case, I will create a project to manage a simple Python project that makes use of the Python requests package. Below we create a project called whatsmyip.

andy@ubuntu18:~$ mkproject whatsmyip

This will create some files required for your environment within ~/.virtualenvs. You may have also noticed that the command prompt has changed to indicate the project you are currently working on. It also indicates you working directory has changed to ~/Devel/whatsmyip. This is shown below:

(whatsmyip) andy@ubuntu18:~/Devel/whatsmyip$ 

The above will create a project using Python 2. If Python 3 is required, use the following:

andy@ubuntu18:~$ mkproject -p /usr/bin/python3 whatsmyip

Create a new file called main.py.

(whatsmyip) andy@ubuntu18:~/Devel/whatsmyip$ vim main.py

With the following contents:

import requests

response = requests.get('https://httpbin.org/ip')

print('Your IP is {0}'.format(response.json()['origin']))

Because this script has a dependency on the requests module, you won’t yet be able to run it. First you will need to install requests with pip as follows:

(whatsmyip) andy@ubuntu18:~/Devel/whatsmyip$ pip install requests

Now if you run the script, it should return your public-facing IP:

(whatsmyip) andy@ubuntu18:~/Devel/whatsmyip$ python main.py 
Your IP is 129.123.5.17, 129.123.5.17

To stop working on a project, issue the deactivate command:

(whatsmyip) andy@ubuntu18:~/Devel/whatsmyip$ deactivate
andy@ubuntu18:~/Devel/whatsmyip$ cd
andy@ubuntu18:~$ 

Note at this point, you do not have access to pip outside of your virtual environment.

andy@ubuntu18:~$ which pip
andy@ubuntu18:~$ 

To list the available projects, issue the workon command:

andy@ubuntu18:~$ workon
whatsmyip

Or you could also use lsvirtualenv:

apike@ubuntu18:~$ lsvirtualenv 
whatsmyip
=========

We clearly just have one project here. To select it and start working on it, issue the below.

apike@ubuntu18:~$ workon whatsmyip
(whatsmyip) andy@ubuntu18:~/Devel/whatsmyip$ 

Again, note you do have access to pip now.

(whatsmyip) andy@ubuntu18:~/Devel/whatsmyip$ which pip
/home/andy/.virtualenvs/whatsmyip/bin/pip

Finally, to remove the project, first deactivate and then remove the project using rmvirtualenv:

andy@ubuntu18:~$ rmvirtualenv whatsmyip

Be the first to comment

Leave a Reply