loading...

Setup Ubuntu for Python development

victorosilva profile image Victor Silva ・5 min read

Python tips (5 Part Series)

1) Python's type hints 2) Avoid dict overuse in Python 3) Make simple Python types rich 4) My case against the "ternary operator" in Python 5) Setup Ubuntu for Python development

In this tutorial I'll show you how I prepare my machine for Python development after installing Ubuntu or one of its derivatives. There are many ways to do this, with different tools and techniques. Here I am sharing the way that works best for me.

These are the two goals of this process:

  • not to mess with the operating system's Python interpreter;
  • be able to work on projects that use different Python versions and different Python libraries.

As a practical example, we will create three Python projects:

  1. A Django project with Python 3.7;
  2. A Mezzanine project with Python 3.7 too;
  3. A Flask project with Python 2.7.

We will begin with a fresh installation of Ubuntu 19.04.

System dependencies

We will build some Python versions, and for that we will need to install some system dependencies. We'll follow the recommendation of the subsection "Ubuntu/Debian/Mint" of pyenv's wiki's "Suggested build environment" section. As of 2019-06-11, they are:

$ sudo apt-get update; sudo apt-get install --no-install-recommends make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev

So we open a Terminal (Ctrl + Alt + T) and install the dependencies:

We'll also need Git:

$ sudo apt-get install git

Python version management

After the system dependencies we'll install pyenv. Among other things, pyenv lets us install different Python versions in our system.

Below, we're following the "installation" section of pyenv's GitHub page. Be sure to check that page for updated instructions.

Clone pyenv into $HOME/.pyenv

$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv

Update $HOME/.bashrc with the lines below, and restart the shell

export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
if command -v pyenv 1>/dev/null 2>&1; then
  eval "$(pyenv init -)"
fi

Install Python 2.7 and Python 3.7

Note: these may take a long time to complete, for pyenv will download and build CPython from source for each version.

$ pyenv install 2.7.16
$ pyenv install 3.7.3

As we can see in the screenshot, the Python versions have been installed in $HOME/.pyenv/versions. We can run both interpreters directly to verify that they are working properly:

However, we will not be installing libraries in these Python interpreters. They will be the base interpreters for our projects. Actually, each project will have its own isolated Python environment, with its own Python interpreter and its own libraries.

Python isolated environments

virtualenv is a great tool for creating these isolated environments. Installing it on Ubuntu is straightforward:

$ sudo apt-get install virtualenv

The creation of the environments is easy too. We'll create them on the next sessions.

Create the Django project

Let's create a directory $HOME/projects/django_project and then create an isolated Python environment for this project in $HOME/projects/django_project/.venv_django using the Python 3.7.3 that we installed earlier.

$ mkdir ~/projects
$ mkdir ~/projects/django_project
$ cd ~/projects/django_project
$ virtualenv .venv_django --python=$HOME/.pyenv/versions/3.7.3/bin/python

In the screenshot, we can see that an environment was created in the new .venv_django directory, and it contains its own Python interpreter, along with some other tools.

Activate the environment for the Django project

We need to activate this environment so we can use its Python interpreter and install libraries on it. After the activation, executing python (the Python interpreter) or pip (the Python package manager) will use the versions of these tools that are inside the environment.

The activation is essential. If we skip it, we will end up messing with the operating system's Python interpreter, and that's exactly what we don't want to do.

To perform the environment activation, we need to source the script bin/activate located inside the environment directory.

$ source .venv_django/bin/activate

Notice that, when the environment is activated, the prompt is prefixed with the name of the environment's directory.

Install Django and create and run the project in the environment

Now, with the environment properly activated, we can install Django with pip, create the Django project and run it.

$ pip install Django
$ django-admin.py startproject django_project .
$ python manage.py runserver

To quit the Django development server, just hit Ctrl + C.

Now we will create a Python environment for a Mezzanine project, so we must deactivate the currently activated environment (the Django one) and leave the Django project directory:

$ deactivate
$ cd ..

Create the Mezzanine project

In a similar fashion, now we will

  • create the environment for the Mezzanine project (based on Python 3.7.3 again);
  • activate the environment;
  • install the libraries that we need;
  • create and run the project.
$ mkdir mezzanine_project
$ cd mezzanine_project
$ virtualenv .venv_mezzanine --python=$HOME/.pyenv/versions/3.7.3/bin/python
$ source .venv_mezzanine/bin/activate
$ pip install mezzanine
$ mezzanine-project myproject .
$ python manage.py createdb
$ python manage.py runserver

To quit the Django development server (Mezzanine is built on top of Django), just hit Ctrl + C again.

Before moving to the last project (the Flask one), let's deactivate the Mezzanine environment and leave the project directory:

$ deactivate
$ cd ..

Create the Flask project

For the Flask project, the process will be similar, but the environment will be based on Python 2.7.16 instead. Flask doesn't have an autogenerator of basic projects like Django and Mezzanine do, therefore we'll need to write a little bit of code in order to have a minimal Flask application.

$ mkdir flask_project
$ cd flask_project
$ virtualenv .venv_flask --python=$HOME/.pyenv/versions/2.7.16/bin/python
$ source .venv_flask/bin/activate
$ pip install flask
$ touch app.py

Let's enter the following code in the file $HOME/projects/flask_project/app.py:

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World'

Now we can run the Flask app to make sure that it works as expected.

$ flask run

To quit the Flask development server, just hit Ctrl + C. Then, let's deactivate the environment that we created for the Flask project and leave its directory.

$ deactivate
$ cd ..

Wrapping it up

  • We use Pyenv to install different Python interpreters
  • We use virtualenv to create isolated environments for different Python projects
  • We activate each environment before installing the libraries they need
  • When an environment is activated, the prompt is prefixed with the name of the environment's directory
  • We deactivate an environment when we don't need to use it
  • We never touch the operating system's Python interpreter
  • Each environment has its own isolated set of installed libraries, as shown below:

That's it! Do you have a different approach which works best for you?

Python tips (5 Part Series)

1) Python's type hints 2) Avoid dict overuse in Python 3) Make simple Python types rich 4) My case against the "ternary operator" in Python 5) Setup Ubuntu for Python development

Posted on by:

Discussion

markdown guide