How to add an API reference

Note

This page was written in the style of a How-to Guide according to The Diátaxis Framework.

This guide shows how to add an API reference page to your documentation.

Pre-requisites

This guide assumes your project already has a working Sphinx documentation project in a folder called docs and the recommended folder structure. If you don’t have it, you can set it up with sphinx-quickstart following the tutorial Create a New Documentation Project.

Set up a new project API reference

If your project doesn’t have a Sphinx-based API reference yet, you need to add "sphinx.ext.autodoc", "sphinx.ext.autosummary" and "sphinx.ext.napoleon" to the extensions variable of docs/conf.py.

Also in docs/conf.py, it is recommended to set the following configuration variables:

So you should have these lines in your docs/conf.py:

autosummary_generate = True
autosummary_generate_overwrite = False
autodoc_typehints = "description"
autodoc_typehints_description_target = "documented_params"
autoclass_content = "both"

For more details about other configuration variables check out the documentation pages of sphinx.ext.autosummary and sphinx.ext.autodoc.

Note

sphinx.ext.autodoc default values might be overridden by sphinx.ext.autosummary. The latter uses Jinja template files that have to be placed in docs/_templates/autosummary. Those files are:

  • docs/_templates/autosummary/base.rst: fallback template.

  • docs/_templates/autosummary/module.rst: for modules.

  • docs/_templates/autosummary/class.rst: for classes.

  • docs/_templates/autosummary/function.rst: for functions.

  • docs/_templates/autosummary/attribute.rst: for attributes.

  • docs/_templates/autosummary/method.rst: for methods.

For more details, check Sphinx’s official documentation.

Create a new API reference page

Now that you have done the basic setup of your API reference you can start creating the pages. There are two main different types of API reference pages:

  • Module pages.

  • Class or function pages.

Create a new module page

In order to create an API reference page for a module you need to follow these steps:

  • Update the docstring of the corresponding __init__.py.

  • Create RST file.

Update docstring

The first thing you need to do is to go to your module’s __init__.py and write just at the start a docstring with reStructuredText (RST) markup like this one:

r"""
################################################
Name of your module (:mod:`name_of_your_module`)
################################################

.. currentmodule:: name_of_your_module

Description of your module.

First category
==============

Description of that category.

.. autosummary::
   :toctree: ../stubs/
   :nosignatures:

   SampleClass
   fetch_smalltable_rows

Second category
===============

Description of that category.

.. autosummary::
   :toctree: ../stubs/
   :nosignatures:

   OtherSampleClass

"""

For more information about how to deal with RST for module docstrings check the Sphinx Guide.

Create RST file

Once you have updated your module’s docstring you need to create a file called docs/apidocs/name_our_your_module.rst. That file should look like this:

.. automodule:: name_of_your_module
    :no-members:
    :no-inherited-members:
    :no-special-members:

Create a new page for a function or class

In order to create an API reference page for a function or a class, these are the steps:

  • Update the docstring.

  • Update the module page.

Update the docstring

First you need to find your function or class in the main code of your project. In Qiskit, we are following the Google Python Style Guide for docstrings. While this is not standard RST, the sphinx.ext.napoleon extension enables Sphinx to parse these docstrings.

If your class has public attributes, they should be documented here in an Attributes section.

class SampleClass:
"""Summary of class here.

Longer class information...
Longer class information...

Attributes:
    likes_spam: A boolean indicating if we like SPAM or not.
    eggs: An integer count of the eggs we have laid.
"""

def __init__(self, likes_spam: bool = False):
    """Initializes the instance based on spam preference.

    Args:
      likes_spam: Defines if instance exhibits this preference.
    """
    self.likes_spam = likes_spam
    self.eggs = 0

def public_method(self):
    """Performs operation blah."""

For functions and methods, document the arguments, return objects and errors in Args, Returns and Raises section.

def fetch_smalltable_rows(
    table_handle: smalltable.Table,
    keys: Sequence[bytes | str],
    require_all_keys: bool = False,
) -> Mapping[bytes, tuple[str, ...]]:
    """Fetches rows from a Smalltable.

    Retrieves rows pertaining to the given keys from the Table instance
    represented by table_handle.  String keys will be UTF-8 encoded.

    Args:
        table_handle: An open smalltable.Table instance.
        keys: A sequence of strings representing the key of each table
        row to fetch.  String keys will be UTF-8 encoded.
        require_all_keys: If True only rows with values set for all keys will be
        returned.

    Returns:
        A dict mapping keys to the corresponding table row data
        fetched. Each row is represented as a tuple of strings. For
        example:

        {b'Serak': ('Rigel VII', 'Preparer'),
        b'Zim': ('Irk', 'Invader'),
        b'Lrrr': ('Omicron Persei 8', 'Emperor')}

        Returned keys are always bytes.  If a key from the keys argument is
        missing from the dictionary, then that row was not found in the
        table (and require_all_keys must have been False).

    Raises:
        IOError: An error occurred accessing the smalltable.
    """

The above code examples were copied from the Google Python Style Guide. Please refer to it for more detailed explanations.

Update the module page

In order to update the module page with your classes and functions you need to add them to the __init__.py of the module(s) in which it’s included. This can be done by adding the name to a toctree like this one:

.. autosummary::
   :toctree: ../stubs/

   SampleClass
   fetch_smalltable_rows