Skip to content

Instantly share code, notes, and snippets.

@nabucosound
Last active December 19, 2015 08:09
Show Gist options
  • Save nabucosound/5923919 to your computer and use it in GitHub Desktop.
Save nabucosound/5923919 to your computer and use it in GitHub Desktop.
I always forgot to get packaging done right on the first try. It is a task that we don't do every day, so I created this how-to gist. It helps out creating packages hosted on GitHUb, listed on PyPi and its documentation hosted on ReadTheDocs.

Python packages on PyPi, Github and ReadTheDocs

I always forgot to get packaging done right on the first try. It is a task that we don't do every day, so I created this how-to gist. It helps out creating packages hosted on GitHUb, listed on PyPi and its documentation hosted on ReadTheDocs.

Package scaffolding

For the basics, I use to follow this guide, but of course there is plenty of reference documents, tutorials, etc, on the internets.

Make sure you follow version 2.0 of the metadata format using this PEP, otherwise Pip will consider your package as a pre-release:

http://www.python.org/dev/peps/pep-0426/

http://www.pip-installer.org/en/latest/logic.html#pre-release-versions

Documentation folder

In your root folder, you must create a docs folder that will contain the .rst files that Sphinx will use to build the documentation necessary for ReadTheDocs. Following the getting started guide from Read The Docs is usually enough.

Worth mention is that you can create a separate virtualenv, install Sphinx there and use it to build the docs. No need to clutter your Pip requirements.txt or any other package management system you use with an Sphinx dependency!

Package data

If you want the statics, templates and docs folders to be included in your package — along with all the files and subfolders — , do not forget to add the following lines in your MANIFEST.in (replace [yourapp]):

recursive-include [yourapp]/static *
recursive-include [yourapp]/templates *
recursive-include docs *

Note that adding these recursive-includes will add the files and folders to your distribution package but NOT make setup.py install them. You need to have package_data for that (distutils).

Setup.py

In order to create the setup.py, I copy and edit one of the existing ones on any of Nomadblue's projects. For example the one from django-nomadlytics or django-nomad-notifier.

On this file, one of the most important parameters while calling setup() is to provide a valid URL in the download_url. This param is constructed using the __version__ value defined somewhere in our code (note that we usually do it in the __init__.py root file of our project).

So for the URL to exist, we must tag our repository with the same name name as our __version__ returns (e.g. 0.1), plus prepending a "v" letter. The tag must be pushed to GitHub, so that the zip release download URL will be created:

git tag -a v0.1 -m "First version of app"
git push --tags
git push

Publishing on PyPi

Although we have defined a zip file in our GitHub repository as the source for the package managers (e.g. Pip) to download and install, setuptools usually crawls lots of pages looking for any download url that looks like what the installation needs. This means that if we use upload as part of our process, every time we run something like pip install mypackage, it will download and use the file uploaded on PyPi and not on Gitub. So we only register the package on PyPi:

python setup.py register

If we do not care, we can always register our metadate, create a source distribution and upload it with:

python setup.py register sdist upload

Webhooks

It is a good idea to link a webhook between GitHub and ReadTheDocs, so each time we push a new commit with changes on the documentation files ReadTheDocs will build it:

https://docs.readthedocs.org/en/latest/webhooks.html

Version update

Do not forget to:

  • Update your CHANGELOG with the new release changes.
  • Edit your docs/conf.py to update version and release settings (so the documentation title will show the proper release version number)
  • Go to the Versions admin section of ReadTheDocs to Choose Active Versions for the project.

Troubleshooting

If you have missed something at this point you may want to re-build, for example, your GitHub release zip file. As the file is generated through the git tag, you can delete and re-create such tag:

git tag -d v0.1
git push origin :refs/tags/v0.1
git tag -a v0.1 -m "First version of app"
git push --tags
git push

If, while trying to register your app, PyPi answers a 401, check you that your username and password is properly set on your ~/.pypirc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment