Lazy admin’s guide to automated updates (Part 2: Python pip)

Last week we discussed Linux Debian's apt-get update mechanism and how to fully automate essential updates. This week I'd like to demonstrate how to do the same thing for Python. I admit that keeping Python packages up-to-date is probably not half as essential as keeping internet-facing server infrastructure updated. Nonetheless I like to work with the latest versions of packages, as they might fix problems or add features.

PyPI is Python's standardized package repository and pip is the most popular package manager. With pip there are at least three places/options to where you can install a package. Each has it's place in my workflow. Here a quick overview:

System-wide Python installation

Files installed to this location will be available to all users on the system and require root-privileges to install. When installing Python-packages via apt-get, they will be installed to this location as well. While it might seem handy to make some essential packages globally available, it's not a recommended way. You will not only mess up your whole installation, when just testing some things for a single project, but Debian packages are also quite outdated. I strongly recommend to simply leave the system-wide Python installation alone.

User-wide Python installation

Packages installed with the --user parameter will be installed to an individual user's home directory. On Mac OSX this is ~/Library/python. On Linux it should be ~/.python. I generally install to this location on my Macbook to keep frequently used packages available across all projects, I'm working on. It doesn't mess up Apple's Python installation and no root-privileges are required for it. Using it for deployment is not recommended.

Virtualenv Python installation

This is the way to go for deployments and one of the best things about Python. All your Python packages live in a sub-folder of your project. The list of required packages is kept in a file called requirements.txt in your project's root folder. This way you can quickly deploy your app on any server and there is no need to keep your dependencies in a repository. First make sure, you have virtualenv installed. This is the only package, you need to install system-wide:

[cc lang="bash" width="100%"tab_size="4" lines="40" noborder="1" theme="dawn"]
sudo apt-get install python-virtualenv
[/cc]

Next you would put the required packages in a text-file called requirements.txt. The content for a simple web project could look like this:

[cc lang="bash" width="100%"tab_size="4" lines="40" noborder="1" theme="dawn"]
flask
pymongo
[/cc]

Then create a virtual python environment in your project's root path:

[cc lang="bash" width="100%"tab_size="4" lines="40" noborder="1" theme="dawn"]
virtualenv my_virtualenv
source my_virtualenv/bin/activate
pip install -r requirements.txt
[/cc]

This will create a new virtual environment, activate it is prioritized over the system's Python installation and then install all required packages into the virtual environment. The advantages here are that it doesn't need root-permissions and you can always start over by simply deleting the my_virtualenv folder. Nice and clean.

Keeping the packages in your virtualenv up-to-date is also comparatively easy. This will show a list of packages that have an updated version on PyPI:

[cc lang="bash" width="100%"tab_size="4" lines="40" noborder="1" theme="dawn"]
pip list --outdated
[/cc]

To upgrade a single package do

[cc lang="bash" width="100%"tab_size="4" lines="40" noborder="1" theme="dawn"]
pip install --upgrade flask
[/cc]

To upgrade all outdated packages, you can use the command below. It can take a few minutes before you see output, but I find it more stable than the solution presented on Stackoverflow:
[cc lang="bash" width="100%"tab_size="4" lines="40" noborder="1" theme="dawn"]
pip list --outdated | awk '/(^[A-Za-z\-_\.]+) \(/{ print $1 }' | xargs pip install --upgrade
[/cc]

This concludes part 2 of our series on automated package updates in Unix-environments. Next week I will discuss Homebrew, the package manager for Mac OSX.