Adding a Django app to Python's Cheese Shop (PyPi and setuptools)

We’ve been doing quite a bit of work on RapidSMS as of late, and one of the neat projects we did was to build an interactive form builder for both SMS and simple XForms. You can check out a little video of it in action if you’d like, it’s pretty neat.

Anyways, RapidSMS has finally been moving to coming in a packaged form, and a few people have showed interest in using our XForms app so I thought I’d see what it took to bring it into the Cheese Shop for easy pip install goodness.

So here’s my little recipe for the next time.

Register with PyPi

First things first, you’ll want to go go create an account on PyPi.

Directory Structure

Next up, package structure.  There’s a lot of debates on this, but here’s what I think seems reasonably sane and is how our rapidsms-xforms project is organized:

rapidsms-xforms/          ; our main setup file       ; definition for extra files to include
     README.rst        ; the README.rst we'll show in PyPi

     docs/             ; our Sphinx docs
     rapidsms_xforms/  ; our Django app code and templates

The three files that are interesting to us here are,, and README.rst. We’ll go into those in detail. You’ll notice that the name of our project on github is actually rapidsms-xforms, while the package name itself is rapidsms_xforms. Converting dashes to underscores seems to be the convention.

Setting up

Ok, let’s look at our Here’s ours:

from setuptools import setup, find_packages


    install_requires = [

    description='Interactive form builder for both XForms and SMS submissions into RapidSMS',

    author='Nicolas Pottier, Eric Newcomer',




        'Development Status :: 4 - Beta',
        'Environment :: Web Environment',
        'Intended Audience :: Developers',
        'License :: OSI Approved :: BSD License',
        'Operating System :: OS Independent',
        'Programming Language :: Python',
        'Framework :: Django',

The interesting bits to pay attention to:

  • we’ve added a __version__ field to our packages, and we pull the PyPi version from that file.
  • we add our dependencies to install_requires, pip will do the rest.
  • the code we want to include is in the rapidsms_xforms package, we just include that in the packages list.
  • we are going to use the contents of the README.rst file, which is what github shows by default on our repo page, to also be our long description on the PyPi pages.

The rest is pretty much boilerplate, obviously substituting your own packages information.

Adding non .py files

Now as is this will work reasonably well, but we’ll be missing our static and templates subdirectories in our rapidsms_xforms dir. By default setuptools is only concerned with .py files, so we have to specify the rest ourselves. That’s where the file comes in:

include README.rst
recursive-include rapidsms_xforms/static *
recursive-include rapidsms_xforms/templates *

Here we specify what other files apart from Python files we want included in our package. We are going to throw in our README.rst, because who doesn’t love those, and then also our static and templates subdirectories.

Testing things out

Ok, let’s test this out by building a source distribution package:

% python sdist
    .. gobs of output ..
% ls dist

Hooray, that looks like a success. Before uploading to the Cheese Shop, I’d recommend untarring that file and making sure the contents look like you expect. Better yet, set up a virtual environment, then throw that package in there and test everything out. Repeat as needed until you feel confident it all looks good.

Uploading to PyPi

Alright, time to upload it to the Cheese Shop, here we go:

% python register sdist upload
running register
running egg_info
  .. gobs of output ..
Submitting dist/rapidsms-xforms-0.1.1.tar.gz to
Server response (200): OK

If you get a 200 back, then things probably worked, wahoo.


That’s it. You should now be able to find your package on PyPi. You’ll also be able to install it using pip:

% pip install rapidsms-xforms


When you need to update, just update your version in your, then rerun the upload command, the rest is taken care of for you.