Setting up a Python Development Environment to Make Developing a Breeze

Written by Dan Sackett on September 4, 2014

Writing Python in general is a pleasurable experience but what really helps is having a pleasurable development environment too.

For that, the Python community generally relies on VIrtualenv and Pip. Together, they form a powerful combination allowing isolated and reproducible development environments.

Let's see how this works.

To start, we need to first get Pip. In Linux Ubuntu, we can run the following in a terminal:

$ sudo apt-get install python-setuptools
$ sudo easy_install pip

Pip is a package manager for Python and is arguably one of the best package managers in the programming realm. It's simple to use and extremely fast. With it, you can install packages from PyPI, Github repositories, another other packaged Python components.

Let's try installing packages.

Since we will need virtualenv, let's grab that:

$ pip install virtualenv

In your terminal, you'll see that the package is being downloaded and once done, it will be available globally. I'm also going to install another package called Virtualenvwrapper.

$ pip install virtualenvwrapper

With virtualenvwrapper, we get a tool that makes working with virtual environments incredibly easy. It simplifies typical virtualenv commands and gives us a set of hooks to do all kinds of things with.

Now that we have those installed, it's time to set this environment up. In some cases, we can have our virtualenvironment packaged where our application lives but to me, this isn't ideal. You don't need to version control it (and if you'ere not version controlling, shame on you!) since it will be easy to recreate all the site packages as I'll show you in a little.

For this reason, it's good to set up your virtualenvs in a centralized location. This way, you can access all of these files from the same location.

To do this, let's create a new folder and add some lines to our .bashrc.

mkdir ~/.virtualenvs
echo "export WORKON_HOME=~/.virtualenvs" >> ~/.bashrc
echo "source /usr/local/bin/" >> ~/.bashrc
echo "export PIP_VIRTUALENV_BASE=~/.virtualenvs" >> ~/.bashrc
source ~/.bashrc

Now in our home directory we have a folder called .virtualenvs and when we decide to work on a new virtualenv it will search this directory to activate it. Everything is set up to do some basic stuff. Let's go to the terminal.

$ mkvirtualenv myfirstenv
New python executable in myfirstenv/bin/python
Installing setuptools, pip...done.

You'll see in your prompt that myfirstenv is added in parenthesis to denote that you are currently working inside your virtualenvironment. Let's play around with this.

$ pip install requests
Downloading/unpacking requests
  Downloading requests-2.4.0-py2.py3-none-any.whl (457kB): 457kB downloaded
Downloading/unpacking certifi (from requests)
  Downloading certifi-14.05.14.tar.gz (168kB): 168kB downloaded
  Running (path:/home/dan/.virtualenvs/myfirstenv/build/certifi/ egg_info for package certifi

Installing collected packages: requests, certifi
  Running install for certifi

Successfully installed requests certifi
Cleaning up...

We just installed requests with pip to our environment! Let's check that it is really installed.

$ pip list
argparse (1.2.1)
certifi (14.05.14)
pip (1.5)
requests (2.4.0)
setuptools (2.0.2)
wsgiref (0.1.2)

As you can see, requests is included as we expected. Let's make it even clearer where this package now exists.

$ cdsitepackages
$ ls -la

You should see a directory for requests. Notice the path we're on? ~/.virtualenvs/myfirstenv/lib/python2.7/site-packages lives in the .virtualenvs directory that we created earlier. As you can see, we have an isolated environment that can have packages that do not exist on a global scope. Let's try some more commands.

$ cd -
$ deactivate
$workon myfirstenv

These commands are most used in my opinion. To exit a virtualenv use the deactivate command. This will return you to the global scope again. To return to that virtualenv again, use the workon ENV command. This will reactivate the environment and get your installed packages available again. See how pleasurable that is?

Let's take this one step further though. We have hooks that we can leverage to make the workon command even more powerful. If you're like me, you tend to keep all of your web projects in the same directory. For me, I always have a projects directory. Let's use the virtualenv hooks to change into the directory that our project lives and activate it in one command. And when we want to exit that virtualenv, let's go back to the home folder.

With these tools, this is easy.

$ export PROJECT_HOME=~/projects >> ~/.bashrc
$ source ~/.bashrc
$ mkdir ~/projects

We now have specified that all of our projects live in ~/projects. Let's edit some hooks! First, open ~/.virtualenvs/postactivate in your favorite text editor and replace it with the following:

# source postactivate hook

if [ -s $_PROJECT_FILE ]; then
    export _PROJECT_DIR=$(cat $_PROJECT_FILE)
    [ -f $_HOOK ] && . $_HOOK

Save that and let's edit ~/.virtualenvs/postdecative.

# source postdeactivate hook

if [ -n "$_PROJECT_DIR" ]; then
    [ -f $_HOOK ] && . $_HOOK
    unset _PROJECT_DIR

Now let's edit ~/.virtualenvs/postmkvirtualenv

# This hook is run after a new virtualenv is activated.

proj_name=$(echo $VIRTUAL_ENV|awk -F'/' '{print $NF}')
[ ! -d ~/projects/$proj_name ] && mkdir -p ~/projects/$proj_name
add2virtualenv ~/projects/$proj_name
cd ~/projects/$proj_name

And finally let's edit ~/.virtualenvs/predeactivate

# This hook is run before every virtualenv is deactivated.


With all of those saved, we now have a set of hooks that will do a lot of work for us. Let's make sure we are not in a current virtualenv and run deactivate. Let's do the following now:

$ mkproject myfirstproject
New python executable in myfirstproject/bin/python
Installing setuptools, pip...done.
Creating /home/dan/projects/myfirstproject
Setting project for myfirstproject to /home/dan/projects/myfirstproject

(myfirstproject) ~/projects/myfirstproject $ 

Check this out! We just created a virtualenv, created a new folder in ~/projects, and changed into the directory. Now you can freely work on your project and do whatever you need with the isolated packages. When you're finished try to deactivate the project.

$ deactivate

~ $ 

We just moved back to the home directory and deactivated the virtualenv. This kind of workflow makes developing so much easier in my opinion. Note that you now have access to the cdproject command which will change you back into your project root if you traverse the file system.

We only added a few lines to our .bashrc and edited a couple hooks and now we have a great environment to work with. There are quite a few more hooks that you can use so feel free to customize your experience as you see fit.

pip python virtualenvwrapper virtualenv

comments powered by Disqus