This post has a very narrow scope. It’s only about generating docs from
docstrings
. It won’t be covering any other use case forSphinx
, nor will it be covering anything aboutreStructuredText
.
I’ve been playing with Sphinx
recently to generate documentation from the docstrings
in my packages and modules, and I wanted to put down what I learned in black and white before I forget everything.
Eventually, I will add full documentation and probably add support for Read the Docs, but for now I wanted a quick-and-dirty tutorial that I can refer to when/if my memory gets hazy.
The Project
Years ago, I created a version of the classic game Hangman to run in a terminal. This tiny little fella seemed to me a great candidate for which to generate my first-ever docs with Sphinx
.
Just prior to writing this article, I took the following steps to create a
requirements.txt
file that will be used to installSphinx
and its dependencies.If there are any questions about what this is doing, check out my primer on
virtualenv
.$ cd hangman $ virtualenv venv $ . venv/bin/activate (venv) $ (venv) $ pip install sphinx (venv) $ pip freeze > requirements.txt (venv) $ (venv) $ deactivate $ rm -rf venv
I then committed this file and pushed it to my GitHub. Later, I high-fived a rando.
Let’s get started!
Enter Sandman Sphinx
Here are two ways to generate the docstrings
as docs. I’m sure there are more!
A not-so great way
All of the tutorials on Sphinx
that I read had me start with the sphinx-quickstart
command. This invoked a sort of wizard that had me answer a number of questions about my project, and I accepted most of the default answers.
This then generated the following files:
conf.py
index.rst
Makefile
In addition, it created the following directories:
_build
_static
_templates
The only one that will have content added for my purposes is _build
, which will store the html
that will be generated.
At this point, the tutorials had me opening the conf.py
to uncomment certain lines and add other lines. Still others also had me editing the index.rst
file. Red flags everywhere. I’m not going to document those changes here, since there is a better way to do this.
I then would create the .rst
(reStructuredText
) files from the project modules using the sphinx-apidoc
command before finally calling make html
to generate all the html
from the .rst
files.
The
sphinx-apidoc
command uses thesphinx.ext.autodoc
extension to generate documentation fromdocstrings
. Without this extension enabled, the goal of this article wouldn’t be met. In other words, it would no worky.
So, I was doing the following:
sphinx-quickstart
- futzing around with both
conf.py
andindex.rst
sphinx-apidoc
make html
It goes without saying that BT no likey this process.
With a bit of playing around, I managed to get this down to two steps:
sphinx-apidoc
make html
Let’s look at that now.
A better way
Here are the commands I ran that were satisfactory to me. Explanations follow:
$ virtualenv venv
$ . venv/bin/activate
(venv) $
(venv) $ mkdir docs && cd docs
(venv) $
(venv) $ sphinx-apidoc -h (1)
(venv) $
(venv) $ sphinx-apidoc \
> --full \ (2)
> --append-syspath \ (3)
> --doc-author btoll \
> --doc-project Hangman \
> --doc-version 0.1.0 \
> --output-dir . \ (4)
> .. (5)
(venv) $
(venv) $ make html (6)
Notes:
-
Having a look at the configuration options for
sphinx-apidoc
informed the ones I chose to create the.rst
files. -
This will generate a full project with
sphinx-quickstart
. The other options will influence its configuration, so there’s no need to openconf.py
and futz around (i.e., step #2 in a not-so great way). -
This tells
Sphinx
to append the value of ofmodule_path
tosys.path
. This will be necessary to find the modules from which to generate the.rst
files. -
The directory to which to write the generated
.rst
s. This indicates thecwd
. -
The positional
module_path
argument. Since--append-syspath
is defined, it will append this value tosys.path
, which is what we want (it tellsSphinx
to look one directory abovedocs/
to find the modules to transpile to.rst
. -
Builds the
html
from the generated.rst
files that we just created withsphinx-apidoc
. This is shorthand forsphinx-build
, see the Makefile and runmake help
.
Be sure to have a look at
conf.py
andindex.rst
to see all of the values written to them.
We can now take a gander at the docs by running the built-in Python web server:
(venv) $ python -m http.server -d _build/html --bind 127.0.0.1 6157
And that’s it! Congratulations, you’ve now created documentation for your amazing and disruptive software project that other people will probably never use!
Weeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
There are a lot of themes for
Sphinx
if the defaultalabaster
theme isn’t up your street.
Conclusion
This probably just scratches the surface of what Sphinx
can do, although it satisfies my use case of generating docs from the docstrings
in the code. If I were looking to generate docs for a production site, I would tweak this some more, but I’m happy with the results so far.
The next step would be to containerize this.
I conclude that this is indeed a conclusion to this fabulous article.