Documentation

Last updated on 2026-10-07 | Edit this page

Overview

Questions

  • How can I use text in Python files as a source of documentation?

Objectives

  • Setup Sphinx
  • Build documentation using text in the Python files

Use the following commands if you want to save your work from the previous episode

BASH

$ git add Makefile pylintrc src/analysis/copuntwords.py src/analysis/testzipf.py src/plotscripts/plotcounts.py
$ git commit -m "my work"

Now use the following to get files for this episode from the branch 06-documentation

BASH

$ git switch -c my-06-branch remotes/origin/06-documentation
$ git ls-files

which should yield

OUTPUT

.gitignore
Makefile
books/abyss.txt
books/isles.txt
docs/source/_templates/custom-module-template.rst
docs/source/autodoc.rst
docs/source/conf.py
docs/source/index.rst
pylintrc
src/TeX/local.bib
src/TeX/report.tex
src/analysis/countwords.py
src/analysis/testzipf.py
src/plotscripts/plotcounts.py
tests/test_countwords.py
tests/test_plotcounts.py
tests/test_testzipf.py

In this episode, we will walk through setting up Sphinx for documentation from scratch, but first let’s again peek at the reuslt with the following:

BASH

$ make doc

The tail of the result is

OUTPUT

writing output... [100%] index
generating indices... genindex py-modindex done
highlighting module code... [100%] plotscripts.plotcounts
writing additional pages... search done
dumping search index in English (code: en)... done
dumping object inventory... done
build succeeded, 3 warnings.

The HTML pages are in build/docs/html.

and we can view the result with

BASH

firefox build/docs/html/index.html &

Navigate to plotscripts:plotcounts and note that the page has information from running python src/plotscripts/plotcounts -h, the definition line of each function, and the docstring of each function.

Start from scratch


Now we will remove the built files, move the doc directory aside and start from scratch

BASH

$ make clean
$ mv docs safe_docs
$ sphinx-quickstart docs

OUTPUT

Welcome to the Sphinx 8.2.3 quickstart utility.

Please enter values for the following settings (just press Enter to
accept a default value, if one is given in brackets).

Selected root path: .

You have two options for placing the build directory for Sphinx output.
Either, you use a directory "_build" within the root path, or you separate
"source" and "build" directories within the root path.
> Separate source and build directories (y/n) [n]:

Here are how to answer the questions:

BASH

> Separate source and build directories (y/n) [n]: y
> Project name: Zipf
> Author name(s): Bat Masterson
> Project release []:
> Project language [en]: 

OUTPUT

Creating file /ROOT-PATH/source/conf.py.
Creating file /ROOT-PATH/source/index.rst.
Creating file /ROOT-PATH/Makefile.
Creating file /ROOT-PATH/make.bat.

Finished: An initial directory structure has been created.

You should now populate your master file /path/source/index.rst and create other documentation
source files. Use the Makefile to build the docs, like so:
   make builder
where "builder" is one of the supported builders, e.g. html, latex or linkcheck.

Let’s see what sphinx-quickstart installed and compare it to safe_docs

BASH

$ ls docs safe_docs

OUTPUT

docs:
Makefile  build  make.bat  source

safe_docs:
source

Our Makefile in the root directory has the following block:

## docs                : Run Sphinx to create documentation
.PHONY : docs
docs : build/docs/html/index.html

build/docs/html/index.html: docs/source/conf.py docs/source/index.rst
        sphinx-build -M html "docs/source" "build/docs"

That block replaces what we need in docs/Makefile and it directs the output from docs/build to build/docs. So we remove the extraneous files in docs/ and look at docs/source

BASH

$ rm -rf docs/Makefile docs/build docs/make.bat
$ ls -R docs/source

OUTPUT

docs/source/:
_static  _templates  conf.py  index.rst

docs/source/_static:

docs/source/_templates:

Now comparing to safe_docs/

BASH

$ ls -R safe_docs

we find that the relevant files are::

  • source/_templates/custom-module-template.rst
  • source/autodoc.rst
  • source/conf.py
  • index.rst

Now look at the differences

BASH

$ sdiff -s safe_docs/source/index.rst docs/source/index.rst 

OUTPUT

   sphinx-quickstart on Sat Oct  3 20:14:28 2026.	      |	   sphinx-quickstart on Mon Oct  5 21:37:05 2026.
   Trees of docstrings <autodoc>			      <

So, we need a line in index.rst that invokes autodoc

Next check conf.py

BASH

$ sdiff -s safe_docs/source/index.rst docs/source/index.rst

The significant part of the output is

OUTPUT


							      >	extensions = []
							      >
extensions = '''sphinx_jinja sphinx.ext.autodoc sphinx.ext.vi <
    sphinx.ext.mathjax sphinx.ext.intersphinx sphinx.ext.cove <
    sphinx.ext.doctest sphinx.ext.autosummary		      <
    sphinx.ext.autosectionlabel sphinx.ext.napoleon	      <
    sphinx_argparse_cli'''.split()			      <
autosummary_generate = True				      <
templates_path = ['_templates']				      <

Before we put that block in docs/source/index.rst, we will look at the other two relevant files to get a feel for what’s going on

BASH

$ cat safe_docs/source/autodoc.rst

OUTPUT

Autodoc
=======

We use the autodoc feature of sphinx to extract documentation from
docstrings in Python scripts.  The autosummary feature of sphinx
recursively descends directory trees extracting documentation.  The
table below provides access to the roots of the extracted
documentation trees and indirectly to individual docstrings.

.. autosummary::
   :toctree: _autosummary
   :template: custom-module-template.rst
   :recursive:

   analysis
   plotscripts

Elsewhere in the documentation we can link to nodes
in trees.  For example, here is a link to the docstring of the code
that :doc:`makes for countwords.py
<_autosummary/analysis.countwords>`.

We can see the result of this block by searching for “autodoc” in the browser. The interesting bit is the autosummary block. Entering “sphinx autosummary” into Google brings up a helpful AI Overview and the documentation. Let’s look at the documentation. The “toctree” and “recursive” options are sort of clear, but we’ll need to look at custom-module-template.rst to understand the “template” option.

BASH

$ less safe_docs/source/_templates/custom-module-template.rst

Yuck! If we ever understood all of that, it was a long time ago. However, we do want to point out a key feature that we find by searching for “cli”. That extension captures the output of eg, “python plotcounts.py -h” and formats it.

Fixing up docs/source

So here’s the plan::

  1. Simply copy custom-module-template.rst and autodoc.rst from safe_docs to docs
  2. Edit conf.py and index.rst
  3. Build the docs

BASH

$ make docs
$ firefox build/docs/html/index.html
Key Points
  • Sphinx can move information from Python souce files to documentation
  • That supports the DRY principal
  • It also supports having good information in Python source files