Shiro's blog

How to document a Python API?

Translations: fr


The Sphinx

Documentation is often seen by developpers as a chore, but it is an essential part of any project. Without it, users are left without clues even if they have a great interest in your project.

In an API, be it internal to an enterprise or in the free world, it means that frontend developpers interfacing with your API have no other means than to read your code. How would anyone call that a mature project?

Despite of this being common, tools exists that ease the developpers in documenting a project. It makes it so easy that it's almost a sin not to document a project nowadays. It is even easier with APIs thanks to automatic discovery of endpoints.

Keeping in mind existing framework integrations, this article especially targets people using either Flask, Bottle or Tornado.

Include the documentation in the docstrings

One of the problems that surfaces the most often about documentation is obsolesence. Developpers changes the code, but not documentation that goes along with it… The approach I suggest mitigate this by putting the documentation in the code. It's way easier to update documentation when you see it while coding!

The tip is to use docstrings of your application's endpoints' views to include informations that will appear in the generated documentation.

For those who don't know, a docstring is a string placed before the first statement of a function. It's here to inform the reader about the function's input and output as well as the inner working if necessary. Here's an example:

def foo():
    """This is a docstring"""

With Sphinx, you can include lot of informations in the endpoint's docstring:

  • Headers used
  • What the endpoint returns
  • The expected request body
  • The query strings available
  • The URL parameters
  • Status codes

The syntax is the following:

:<location> <name>: <description>

The location is the documented source, for example the URL or the body of the response.

The name is the one used by a parameter or field.

Description can be diverse but will generaly include usage details of the endpoint.

To have a better look, let's see an example:

def get_user(id):
    """Return data about an user referenced by in id

    :param id: The id of the wanted user
    :query details: If it is passed, more data are returned
    :status 200: User is found and returned
    :status 404: No user was found with this id

You can see that the syntax is as readable for a human as it is for a computer. By putting it in the docstring, it can be helpful to documentation generation and API developpers.

You can take a look at the documentation of the syntax for more details.

Install and setup Sphinx

As any Python lib, you can install it with pip:

pip install Sphinx

To begin the documentation fo a project, Sphinx has an helpful command that setup everything for you after a few questions through prompts. It's called sphinx-quickstart.

When a value is between square brackets, it is a default value, which'll be used if you don't type anything.

The root path for documentation is "docs" by convention.

I suggest you split source and build directories, because that's what I'll do in this tutoriel and it'll be easier to follow.

You can fill other fields in respect with your preferences or let the default values.

Automatic documentation of an application's endpoints

Load the extention

To automatically generate endpoints' documentation, we'll need to activate the extension which have that feature for your framework. Depending on it, it will be one of those:

  • sphinxcontrib.autohttp.flask
  • sphinxcontrib.autohttp.bottle
  • sphinxcontrib.autohttp.tornado

When identified, put it in the extension list, in the file docs/source/ (The file can differ if you used different choices during sphinx-quickstart)

Access the modules

The generation of the documentation happens in the directory docs. Thus, you'll probably need to uncomment those lines at the beginning of

import os
import sys

sys.path.insert(0, os.path.abspath('../..'))

Beware, the path inserted is not the default if you split source and build like me.

Insert documentation of the endpoints in the build

It is time for us to add in the documentation files a directive that will automatically document your API. I will show one way to do it, but you will surely want to customize it afterward. Bear with me.

Here again, the directive differs in respect to the framework you use. You can find them here. I will set my exemple with Flask but use yours among these:

  • autoflask
  • autobottle
  • autotornado

For me, the directive will be placed in docs/source/endpoints.rst, which will be linked to in the index of the documentation.


Endpoints' documentation

.. autoflask::


Welcome to Example API's documentation!

.. toctree::
   :maxdepth: 2
   :caption: Contents:


Indices and tables

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

In this example, the Flask application would be in a example/ file in an object named app.

At this point, you should be able to generate the documentation and see your endpoints appear. If you accepted to have a Makefile during sphinx-quickstart, you can simply use:

make -C docs html

You can then open it in your browser, for example firefox, with:

firefox docs/build/html/index.html

Expose the documentation publicly

It is now your duty to make this documentation available to your API users, to make it useful!

This could be an article itself since the hosting solutions are many, but some are more accessible than others. None will be detailed here, but here are some simple suggestions to begin:

  • Include instructions to compile the documentation in README.rst or
  • Host the documentation on github pages.
  • Host the documentation on a CDN.