First of all, if you are a python package maintainer that I personally linked to this blog post, welcome and thank you for your time.

If you are a python package maintainer that does not have a Sphinx documentation, here you will understand why it is so important for the python ecosystem, and how easy is to document.

At the bottom of the post there is a short tutorial on how to do it quickly and easily.

What is Sphinx ?

You might not have heard of Sphinx, but has certainly visited beautiful documentation powered by it, here are some examples:

Sphinx is python’s most widely used tool for generating documentations.

It uses python’s default markup language reST, and provides a powerful extension API that allows defining custom directives that can be distributed as python packages themselves.

Sphinx comes with builtin extensions for python package maintainers, in autodoc.

The Autodoc Extension

Sphinx comes with the builtin extension autodoc, generates API reference to python with little effort.

Some of the most famous python packages make use of this, for example the Flask API Reference or the Boto3 EC2 Reference.

As long as your python code have Docstrings the visual structure of autodoc-generated pages is the same.

If Autodoc generates a concise visual structure, but there another builtin extension that comes into play: intersphinx.

The Intersphinx Extension

Did you know that most HTML documentations generated with Sphinx have a binary file named objects.inv ?

This is because the builtin extension intersphinx indexes all the autodoc references by the qualified name of their members.

To test this by yourself, simply append /objects.inv to the root documentation url of any project.

Examples:

Requests https://requests.kennethreitz.org/en/master/objects.inv
Flask https://flask.palletsprojects.com/en/1.1.x/objects.inv

Referencing classes and functions from external projects

Suppose you want your docs to reference links to API references of classes and functions from the requests package.

Edit your project’s Sphinx configuration, adding the following snippet:

usually under "docs/souce/conf.py" (or "docs/conf.py")
intersphinx_mapping = {
    "flask": ("https://flask.palletsprojects.com/en/1.1.x/", None),
    "requests": ("https://requests.kennethreitz.org/en/master/", None),
}

Now you can reference using the directives of the python domain of Sphinx.

Inside your python code:
def make_api_request():
    """calls :py:func:`requests.post` against our API.
    """

Make sure your package is in sys.path, use the setting doctest_path.

from os.path import abspath, dirname, join

docs_source_path = abspath(dirname(__file__))
project_root = abspath(join(docs_source_path, "..", ".."))

doctest_path = [project_root]

Publishing to Read The Docs

  1. Signup to https://readthedocs.org/, supports Github authentication.
  2. Import your project from the git repository.
  3. Readthedocs will do a lot of work for you

Conclusion

If you already published a package, invest little time and get great docs with Sphinx + Autodoc. That way other package documentations can link to yours directly.

I will personally submit pull-requests to some libraries that I link to but have no sphinx docs.

Writing Docstrings

Use the napoleon extension to write Google-style docstrings.