Documentation with Sphinx
- Introduction
- Setup
- Autodoc
- Themes
- Using NumPy or Google style docstrings
- Upload to ReadtheDocs
- Breathe: Combining with Doxygen
- Links
- Feedback
Introduction
This article introduces documentation with Sphinx for Python projects and is intended as a quick getting started document.
Sphinx is a documentation generator based on interpretation of reStructuredText (abbr. rst or reST). It is used extensively for Python projects.
Setup
The following gives a very basic setup to get started as quick as possible.
First Install and set up Sphinx:
pip install Sphinx
Now in your python project create a docs/ directory at the top level of your package. Inside the docs/ directory run:
sphinx-quickstart
For basic setup, most questions can take defaults (shown in square brackets) - just press enter.
Below is an example set of answers for project myproj
.
Note: The first question takes default as we’re running in docs/ directory: Note: Make sure to say yes to the autodoc question if you want to auto-generate an API from docstrings. Highly recommended!
Root path for the documentation [.]:
Separate source and build directories (y/n) [n]:
Name prefix for templates and static dir [_]:
Project name:myproj
Author name(s):Steve Hudson
Project version []:0.1.0
Project release [0.1.0]:
Project language [en]:
Source file suffix [.rst]:
Name of your master document (without suffix) [index]:
Do you want to use the epub builder (y/n) [n]:
autodoc: automatically insert docstrings from modules (y/n) [n]:y
doctest: automatically test code snippets in doctest blocks (y/n) [n]:
intersphinx: link between Sphinx documentation of different projects (y/n) [n]:
todo: write “todo” entries that can be shown or hidden on build (y/n) [n]:
coverage: checks for documentation coverage (y/n) [n]:
imgmath: include math, rendered as PNG or SVG images (y/n) [n]:
mathjax: include math, rendered in the browser by MathJax (y/n) [n]:
ifconfig: conditional inclusion of content based on config values (y/n) [n]:
viewcode: include links to the source code of documented Python objects (y/n) [n]:
githubpages: create .nojekyll file to publish the document on GitHub pages (y/n) [n]:
Create Makefile? (y/n) [y]:
Create Windows command file? (y/n) [y]:n
In this case only project name, author name, version, autodoc and Windows command file are non-default.
For following files are created:
_templates/
_static/
_build/
index.rst
conf.py
Makefile
index.rst is the base file containing your toctree (table of contents tree).
conf.py is the configuration file for your project.
You now have a template for your documentation. To build:
make html
And then open in a browser. E.g:
firefox _build/html/index.html
Create a file called readme.rst in the docs directory. This will simply contain a pointer to your project readme file eg:
.. include:: ../README.rst
In index.html list this file without the extension. The toctree in index.rst looks like this:
.. toctree::
:maxdepth: 2
:caption: Contents:
readme
Note that indentation is important in rst.
Now your readme should appear in the documentation.
Note: Before you rebuild always make clean.
make clean; make html
firefox _build/html/index.html
Further Instructions at First Steps with Sphinx
Alternative installation instructions
Autodoc
The pyexample project can be found on github here
Say you have the following directory structure.
pyexample ├── docs │ ├── _build │ ├── conf.py │ ├── index.rst │ ├── Makefile │ ├── readme.rst │ ├── _static │ └── _templates ├── LICENSE ├── pyexample │ ├── __init__.py │ ├── module_mpi4py_1.py │ ├── module_numpy_1.py │ └── module_numpy_2.py ├── README.rst └── setup.py
To use autodoc to extract the docstrings from module_mpi4py_1.py you can do the following.
In docs directory create a file mpi4py_module.rst that contains:
mpi4py Test Module
==================
.. automodule:: module_mpi4py_1
:members:
Now add this file (without extension) to the index.rst
.. toctree::
:maxdepth: 2
:caption: Contents:
readme
mpi4py_module
One more requirement is that autddoc can import the module. This can be achieved by giving the relative path in conf.py by adding these lines. Note the first three may already be there commented out.
import os
import sys
sys.path.insert(0, os.path.abspath('.'))
sys.path.append('../pyexample')
Now rebuild, and the documentation should contain a link to the autogenerated documentation from doc strings.
Note: If you want to show the function signature lines for functions without docstring add :undoc-members:
E.g: In mpi4py_module.rst add:
mpi4py Test Module
==================
.. automodule:: module_mpi4py_1
:members:
:undoc-members:
This can now be repeated for other modules.
To nest sets of modules under the index title see the libEnsemble example. And see the front end on ReadtheDocs
Themes
At time of writing the most popular theme is the Readthedocs theme. To change the theme, find the html_theme
line in conf.py and change. E.g.
html_theme = 'sphinx_rtd_theme'
You may need to install:
pip install sphinx_rtd_theme
Using NumPy or Google style docstrings
To use the NumPy or Google stype docstrings add the napolean extension to the extension list E.g:
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.napoleon']
For mmore info see Support for NumPy and Google style docstrings
Upload to ReadTheDocs
Upload your docs directory to your online repository (e.g. github). Then create an account, if necessary, on ReadtheDocs and import the repo.
See instructions on ReadTheDocs
Note: If you are using autodoc, ReadtheDocs will need to be able to import your code. This may not be possible if you are using C extensions, and this requires you mock these extensions in your conf.py. This will manifest as import errors in the readthedocs build log.
Example of mocking functions in conf.py:
from unittest.mock import MagicMock
class Mock(MagicMock):
@classmethod
def __getattr__(cls, name):
return MagicMock()
MOCK_MODULES = ['argparse', 'numpy', 'mpi4py' , 'scipy', 'petsc4py', 'PETSc']
sys.modules.update((mod_name, Mock()) for mod_name in MOCK_MODULES)
More info at ReadtheDocs FAQ
Breathe: Combining with Doxygen
If you have Doxygen instrumented code which you wish to incorporate into a Sphinx document, you can use the Breathe package.
pip install breathe
Breathe must be able locate the Doxygen produced XML.
E.g: In conf.py modify/add lines of the format:
extensions = ['sphinx.ext.autodoc', 'breathe']
breathe_projects = { "myproject": "../code/src/xml/" }
where ../code/src/xml contains the doxygen XML output.
Create a file in docs/ E.g. doxygen_files.rst
containing:
Doxygen Files
=============
.. autodoxygenindex::
Then add doxygen_files to your toctree in index.
Links
More info at official webpage
Feedback
Any feedback/corrections are welcome: shudson@anl.gov
- If this was helpful, please leave a star on the github page.
- Leave a comment below.
- Email: shudson@anl.gov
- Or fork on github and make a pull request
Back to contents page
Leave a comment