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.
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/ setup.py ; our main setup file MANIFEST.in ; 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 setup.py, MANIFEST.in, 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 setup.py
Ok, let’s look at our setup.py. Here’s ours:
from setuptools import setup, find_packages setup( name='rapidsms-xforms', version=__import__('rapidsms_xforms').__version__, license="BSD", install_requires = [ "rapidsms", "django-uni-form" ], description='Interactive form builder for both XForms and SMS submissions into RapidSMS', long_description=open('README.rst').read(), author='Nicolas Pottier, Eric Newcomer', firstname.lastname@example.org', url='http://github.com/nyaruka/rapidsms-xforms', download_url='http://github.com/nyaruka/rapidsms-xforms/downloads', include_package_data=True, packages=['rapidsms_xforms'], zip_safe=False, classifiers=[ '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
__init__.py, 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_xformspackage, we just include that in the
- 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
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
MANIFEST.in 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
Testing things out
Ok, let’s test this out by building a source distribution package:
% python setup.py sdist .. gobs of output .. % ls dist rapidsms-xforms-0.1.0.tar.gz
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 setup.py register sdist upload running register running egg_info .. gobs of output .. Submitting dist/rapidsms-xforms-0.1.1.tar.gz to http://pypi.python.org/pypi 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
__init__.py, then rerun the upload command, the rest is taken care of for you.