Five steps to add the 'bling' factor your Python package
Introduction
In previous posts I have shown how to create a Python package.
We started by using Cookicutter to generate a basic structure for our project. We then looked at how to setup and use clean development environments. This was followed by an outline of Python tools for testing and the implementation of the Python package using test-driven development. Finally we looked at how to generate beautiful technical documentation using Sphnix.
Now it is time to show off our hard work. In this post I will show you how to make use of cloud services to host your documentation, run continuous integration tests and distribute your package. Furthermore, we will add neat looking badges to the README file.
Step 1: Host the documentation on readthedocs
You have spent hours documenting your package using Sphinx. It is time to share it with the world. Register with readthedocs and sync your GitHub account with it. Then you can simply select the project that you want readthedocs to host documentation for.
If you are using Sphinx’s autodoc
functionality and your package depends on numpy
/scipy
/matplotlib
you may run into trouble as Readthedocs’ server may not be able to compile the
C extensions. The first thing to try is to go into the advanced settings
section of your project in Readthedocs’ web interface and make sure that the
project is set to install into a virtual environment and that the option to
“Give the virtual environment access to the global site-packages dir” is
selected. The system packages now appear to include numpy
, scipy
, and
matplotlib
so this should go a long way. However, if you are still running
into trouble you may need to
mock out the dependencies.
Step 2: Set up continuous integration testing on Travis Ci
You have spent hours using test-driven development to create a solid Python package. It is time to automate the running of the test suite and to get automatic testing of the code on different versions of Python.
Sign into Travis CI using your GitHub account. Select
the project that you want to test and add a .travis.yml
file to the root
of your code repository.
Below is a simple setup for testing a Python package with no dependencies on
Python versions 2.7, 3.2, and 3.4 using the nose
test runner.
language: python
python:
- "2.7"
- "3.2"
- "3.3"
- "3.4"
script: nosetests
If your code includes dependencies on numpy
and scipy
things get a
little bit trickier as Travis CI can time out trying to install these from source.
The solution is to make use of Miniconda.
The .travis.yml
file below is based on the template from the
conda documentation
and Dan Blanchard’s post
Quicker Travis builds that rely on numpy and scipy using Miniconda.
It installs Miniconda with numpy
, scipy
and nose
and runs the test
suite on Python 2.7, 3.3. and 3.4.
python:
# We don't actually use the Travis Python, but this keeps it organized.
- "2.7"
- "3.3"
- "3.4"
install:
- sudo apt-get update
# We do this conditionally because it saves us some downloading if the
# version is the same.
- if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then
wget https://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O miniconda.sh;
else
wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh;
fi
- bash miniconda.sh -b -p $HOME/miniconda
- export PATH="$HOME/miniconda/bin:$PATH"
- hash -r
- conda config --set always_yes yes --set changeps1 no
- conda update -q conda
# Useful for debugging any issues with conda
- conda info -a
- conda create -q -n test-environment python=$TRAVIS_PYTHON_VERSION numpy scipy nose
- source activate test-environment
- python setup.py install
# command to run tests
script: nosetests
Step 3: Calculate your code coverage using Codecov
As you have developed your code using test-driven development you have a high degree of code coverage. It is time to integrate the code coverage calculation into the Travis CI testing. We will use Codecov to do this.
Sign in using your GitHub account, sync your repos and add the project that you
want to measure the code coverage for. Then edit the .travis.yml
file to
look like the below.
language: python
python:
- "2.7"
- "3.2"
- "3.3"
- "3.4"
script: nosetests
before_install:
pip install codecov
after_success:
codecov
Step 4: Upload your Package to PyPi
You have developed a great Python package, it is time to share it with the world. This is done, most effectively, by uploading it to PyPi.
Peter Down has written a great post explaining how to submit a package to PyPi.
Hosting your package on PyPi makes it easy for people to install using pip
.
Step 5: Add badges to your project’s README file
Finally the part that we have all been waiting for: cool looking badges!
Readthedocs, Travis CI and Codecov all provide badges as part of their service. For the PyPi package we will make use of Version Badge.
Below is part of the reStructuredText markup I use for my tinyfasta
package.
.. image:: https://badge.fury.io/py/tinyfasta.svg
:target: http://badge.fury.io/py/tinyfasta
:alt: PyPI package
.. image:: https://travis-ci.org/tjelvar-olsson/tinyfasta.svg?branch=master
:target: https://travis-ci.org/tjelvar-olsson/tinyfasta
:alt: Travis CI build status (Linux)
.. image:: https://codecov.io/github/tjelvar-olsson/tinyfasta/coverage.svg?branch=master
:target: https://codecov.io/github/tjelvar-olsson/tinyfasta?branch=master
:alt: Code Coverage
.. image:: https://readthedocs.org/projects/tinyfasta/badge/?version=latest
:target: https://readthedocs.org/projects/tinyfasta/?badge=latest
:alt: Documentation Status
The images in the README.rst file gets rendered by GitHub into a neat looking header with the badges below.
Conclusion
You should now have a Python package that looks loved and cared for.
- It is easy to install using
pip
- It has online documentation
- It gets tested every time code is pushed to GitHub
- It has its code coverage measured