Sphinx API documentation#
Sphinx is a powerful documentation tool, based on reStructuredText.
If you are more comfortable with markdown, you can use MyST
ls
env-1 pipfile pip-tools sphinx-docs.ipynb
environments.ipynb Pipfile requirements.txt
from-script-to-project Pipfile.lock sphinx-docs
cd sphinx-docs
ls
docs docs-2023 docs-done package_to_document __pycache__
We can initialize our docs with the command:
sphinx-quickstart
which will prompt with a few questions to set up the docs directory.
There are two key files created (and several more):
conf.py
- the sphinx configuration fileindex.rst
the first page of our documentation. This is the landing page for our docs
Let’s start by checking out the docs:
make html
in the docs directory, then open _build/index.html
The first thing we are going to do is add the autodoc extension.
autodoc
is an extension that defines directives (commands) for automatically documenting your code.
We add this extension to the conf.py
file
extensions = [
"sphinx.ext.autodoc",
]
Our module myarray
defines an Array
class and an asarray
function. We want to docment these.
Since we went through the trouble of adding docstrings, it would be nice to import those into our docs! That’s what autodoc is for.
Inspecting our module and class, we can see their docstrings:
conda activate UIO-IN3110
python3 -c "import myarray; help(myarray)"
(UIO-IN3110)
Help on package myarray:
NAME
myarray
PACKAGE CONTENTS
myarray
CLASSES
builtins.object
myarray.myarray.Array
class Array(builtins.object)
| Array(shape, *values)
|
| A class defining an API for arrays
|
| Methods defined here:
|
| __add__(self, other)
| Element-wise adds Array with another Array or number.
|
| If the method does not support the operation with the supplied arguments
| (specific data type or shape), it should return NotImplemented.
|
| Args:
| other (Array, float, int): The array or number to add element-wise to this array.
|
| Returns:
| Array: the sum as a new array.
|
| __eq__(self, other)
| Compares an Array with another Array.
|
| If the two array shapes do not match, it should return False.
| If `other` is an unexpected type, return False.
|
| Args:
| other (Array): The array to compare with this array.
|
| Returns:
| bool: True if the two arrays are equal. False otherwise.
|
| __init__(self, shape, *values)
| Make sure that you check that your array actually is an array, which means it is homogeneous (one data type).
|
| Args:
| shape (tuple): shape of the array as a tuple. A 1D array with n elements will have shape = (n,).
| values: The values in the array. These should all be the same data type. Either numeric or boolean.
|
| Raises:
| ValueError: If the values are not all of the same type.
| ValueError: If the number of values does not fit with the shape.
|
| __mul__(self, other)
| Element-wise multiplies this Array with a number or array.
|
| If the method does not support the operation with the supplied arguments
| (specific data type or shape), it should return NotImplemented.
|
| Args:
| other (Array, float, int): The array or number to multiply element-wise to this array.
|
| Returns:
| Array: a new array with every element multiplied with `other`.
|
| __radd__(self, other)
| Element-wise adds Array with another Array or number.
|
| If the method does not support the operation with the supplied arguments
| (specific data type or shape), it should return NotImplemented.
|
| Args:
| other (Array, float, int): The array or number to add element-wise to this array.
|
| Returns:
| Array: the sum as a new array.
|
| __rmul__(self, other)
| Element-wise multiplies this Array with a number or array.
|
| If the method does not support the operation with the supplied arguments
| (specific data type or shape), it should return NotImplemented.
|
| Args:
| other (Array, float, int): The array or number to multiply element-wise to this array.
|
| Returns:
| Array: a new array with every element multiplied with `other`.
|
| __rsub__(self, other)
| Element-wise subtracts this Array from a number or Array.
|
| If the method does not support the operation with the supplied arguments
| (specific data type or shape), it should return NotImplemented.
|
| Args:
| other (Array, float, int): The array or number being subtracted from.
|
| Returns:
| Array: the difference as a new array.
|
| __str__(self)
| Returns a nicely printable string representation of the array.
|
| Returns:
| str: A string representation of the array.
|
| __sub__(self, other)
| Element-wise subtracts an Array or number from this Array.
|
| If the method does not support the operation with the supplied arguments
| (specific data type or shape), it should return NotImplemented.
|
| Args:
| other (Array, float, int): The array or number to subtract element-wise from this array.
|
| Returns:
| Array: the difference as a new array.
|
| is_equal(self, other)
| Compares an Array element-wise with another Array or number.
|
| If `other` is an array and the two array shapes do not match, this method should raise ValueError.
|
| Args:
| other (Array, float, int): The array or number to compare with this array.
|
| Returns:
| Array: An array of booleans with True where the two arrays match and False where they do not.
| Or if `other` is a number, it returns True where the array is equal to the number and False
| where it is not.
|
| Raises:
| ValueError: if the shape of self and other are not equal.
|
| mean(self)
| Computes the mean of the array
|
| Only needs to work for numeric data types.
|
| Returns:
| float: The mean of the array values.
|
| min_element(self)
| Returns the smallest value of the array.
|
| Only needs to work for numeric data types.
|
| Returns:
| float: The value of the smallest element in the array.
|
| variance(self)
| Computes the variance of the array
|
| Only needs to work for numeric data types.
| The variance is computed as: mean((x - x.mean())**2)
|
| Returns:
| float: The mean of the array values.
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
|
| ----------------------------------------------------------------------
| Data and other attributes defined here:
|
| __hash__ = None
FUNCTIONS
asarray(a)
Cast an object to an array
Parameters:
a (Array, iterable): An array or any array-like container.
Returns:
Array:
a, cast as an Array.
If a is already an Array, return it.
DATA
__all__ = ['Array', 'asarray']
FILE
/home/dokken/Documents/src/UiO/UiO-IN3110.github.io/lectures/production/sphinx-docs/package_to_document/src/myarray/__init__.py
(UIO-IN3110)
python3 -c "import myarray; help(myarray.Array.mean)"
Help on function mean in module myarray.myarray:
mean(self)
Computes the mean of the array
Only needs to work for numeric data types.
Returns:
float: The mean of the array values.
(UIO-IN3110)
Let’s get started by creating a new file int he source
directory, with source/api.rst
:
My Array API
============
.. automodule:: myarray
and we can try to build the documentation again with make html
.
We get the following warning
docs/api.rst: WARNING: document isn't included in any toctree
Note
Inspect the package myarray
, both __init__.py
and myarray.py
contains __all__ = [...]
statements.
This is to instruct Python (and autodoc) what members should be included in an import and in documentation.
As we have created the myarray
-package, the module is described by what is in the __init__.py
file. We could also document the module myarray.myarray
explicitly.
head -n5 package_to_document/src/myarray/__init__.py
from myarray.myarray import Array, asarray
__all__ = ["Array", "asarray"](UIO-IN3110)
head -n8 package_to_document/src/myarray/myarray.py
"""
Defines an Array class.
Class template for Arrays, IN 3110 assignment 3
"""
__all__ = ["Array", "asarray"]
(UIO-IN3110)
The toctree (table of contents tree) warning is because our new api.rst
document is not included in any .. toc::
directives.
Sphinx wants to make sure that you can navigate through all the documentation
via table of contents, so it encourages you to include all your documents in
We can add our new document to the top-level table of contents in index.rst
:
.. toctree::
:maxdepth: 2
:caption: Contents:
api.rst
No we can build again with make html
and open _build/html/api.html
.
Note
To build the documentation for a module, it has to be installed on your system.
As myarray
is a proper package, we use python3 -m pip install /path/to/myarray
to install it prior to building with sphinx.
If you really want to avoid making a package, one can modify the sys.path
inside the conf.py
file.
However, this is not recommended!
Next, we can add our function to the documentation:
My Array API
============
.. automodule:: myarray
.. autofunction:: asarray
and build again with make html
, reloading _build/html/api.html
Similarly, we can document our Array
class:
My Array API
============
.. automodule:: myarray
.. autofunction:: asarray
.. autoclass:: Array
now all our top-level items are documented, but we probably want to see our member methods, not just the constructor.
For that, we add the :members:
option to autoclass:
My Array API
============
.. automodule:: myarray
.. autofunction:: asarray
.. autoclass:: Array
:members:
And finally, since we are most interested in “special” methods (__mul__
and friends), we may want to document the special methods as well, which are not included by default in :members:
:
My Array API
============
.. automodule:: myarray
.. autofunction:: asarray
.. autoclass:: Array
:members:
:special-members:
Now we are done setting up our API docs. autodoc has lots of options for controlling which members are
The last step we are going to do is enable another extension called napoleon, which understands special docstring formats, which are widely used. These give nice highlighting and linking for parameters, return types, etc.
extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.napoleon",
]
Now rebuild, and see how much nicer the output is!