Johannes Hoff Johannes Hoff - 1 month ago 13
Python Question

What's the standard way to package a python project with dependencies?

I have a python project that has a few dependencies (defined under

install_requires
in setup.py). My ops people requires a package to be self contained and only depend on a python installation. The litmus test would be that they're able to get a zip-file and then unzip and run it without an internet connection.

Is there an easy way to package an install including dependencies? It is acceptable if I have to build on the OS/architecture that it will eventually be run on.

For what it's worth, I've tried both
setup.py build
and
setup.py sdist
, but they don't seem to fit the bill since they do not include dependencies. I've also considered
virtualenv
(which could be installed if absolutely necessary), but that has hard coded paths which makes it less than ideal.

Answer

There are a few nuances to how pip works. Unfortunately, using --prefix vendor to store all the dependencies of the project doesn't work if any of those dependencies, or dependencies of dependencies are installed into a place where pip can find them. It will skip those dependencies and just install the rest to your vendor folder.

In the past I've used virtualenv's --no-site-packages option to solve this issue. At one company we would ship the whole virtualenv, which includes the python binary. In the interest of only shipping the dependencies, you can combine using a virtualenv with the --prefix switch on pip to give yourself a clean environment that installs to the right place.

I'll provide an example script that creates a temporary virtualenv, activates it, then installs the dependencies to a local vendor folder. This is handy if you are running in CI.

#!/bin/bash

tempdir=$(mktemp -d -t project.XXX) # create a temporary directory
trap "rm -rf $tempdir" EXIT         # ensure it is cleaned up
# create the virtualenv and exclude packages outside of it
virtualenv --python=$(which python2.7) --no-site-packages $tempdir/venv
# activate the virtualenv
source $tempdir/venv/bin/activate    
# install the dependencies as above
pip install -r requirements.txt --prefix=vendor
Comments