Hide navigation sidebar
Hide table of contents sidebar
Skip to content
Back to top
View this page
Toggle table of contents sidebar

# Design Reference

## Python

When choosing what to document, AutoAPI aims to document anything that is publicly accessible through the actual package when loaded in Python. For example if a function is imported from a submodule into a package, that function is documented in both the submodule and the package. There are some exceptions to this rule:

- Anything that is imported into a module is not documented. Usually a module is where implementations exist. Therefore an import of something is usually for the usage of the implementation, and not as something to be accessed publicly.

- When the module or package defines an `__all__`, only the members named in `__all__` are documented.

- When a configuration option indicates that private or special members should also be documented.

Furthermore, AutoAPI follows the same docstring inheritance rules as `inspect.getdoc()`, with some exceptions:

- The docstrings of the following methods are not inherited because they are usually redundant:

  - `object.__init__()`

  - `object.__new__()`

  - `type.__init__()`

  - `type.__new__()`

## Introduction

We are working with Sphinx, which has an existing way of doing this. Generally, you define a Domain which describes the various language structure, a Class or Method, for example. Then the user will write RST that uses these definitions, and Sphinx will create output from that markup.

    .. py:function:: spam(eggs)

       Spam the foo.

The author of the documentation will have now told Sphinx that the spam function exists in the Python project that is being documented.

### Autogenerated Output

Sphinx then built a series of tools to make the generation of this markup easier and more automatic:

> - Autodoc

> - Autosummary

Autodoc is a Python-only solution that imports the author’s code into memory, and then allows the author to more automatically document full objects. For example, you can document a whole class on a page.

    .. autoclass:: Noodle

This will generate output that looks like:

class Noodle

  Noodle’s docstring.

There are also options for it to include a full listing of the classes attributes, methods, and other things, automatically.

Warning

Remember, this depends on `Noodle` being importable by the Python interpreter running Sphinx.

## Proposed Architecture

The proposed architecture for this project is as follows:

> - A parser will read the source files into an internal representation of the objects that can be documented.

>     - Take the internal representation and generate in-memory rst that corresponds to the Sphinx domain objects.

>     - Sphinx will output HTML based on the doctree generated from the in-memory rst.

In diagram form:

    Code -> Internal Objects -> RST -> Sphinx -> HTML

### File Structure vs. Hierarchy

Specific ID’s should have one specific detail representation. This means that every internal object should only have one place that it is rendered with a `.. <domain>:<type>::` canonical identifier. All other places it is referenced should be in either:

> - A reference

> - A toctree (listing)

### Sphinx Implementation

The user will run a normal make html as part of the experience. The generation and loading will be done as an extension that can be configured.

There will be Sphinx configuration for how things get built:

    autoapi_root = 'api' # Where HTML is generated
    autoapi_dirs = ['yaml'] # Directory of YAML sources

We will then loop over all source files in the `autoapi_dir` and parse them. They will then be output into `autoapi_root` inside the documentation.

## Examples

A nice example of Sphinx Python output similar to what we want:

- http://dta.googlecode.com/git/doc/_build/html/index.html

- Src: https://raw.githubusercontent.com/sfcta/dta/master/doc/index.rst

An example domain for Spec:

- https://subversion.xray.aps.anl.gov/bcdaext/specdomain/trunk/src/specdomain/sphinxcontrib/specdomain.py