One of the most popular tools to manage the documentation is Sphinx.
It’s easy to use and comes with some useful features out of the box:
Install Sphinx with pip or pipx:
$ pip install sphinx
Inside your project, run
sphinx-quickstart docs command. It will ask you a few questions about your project and generate the documentation inside
$ sphinx-quickstart docs Welcome to the Sphinx 2.4.2 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: docs 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]: y The project name will occur in several places in the built documentation. > Project name: My Awesome Project > Author name(s): Sebastian Witowski > Project release : 1.0 If the documents are to be written in a language other than English, you can select a language here by its language code. Sphinx will then translate text that it generates into that language. For a list of supported codes, see https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language. > Project language [en]: Creating file docs/source/conf.py. Creating file docs/source/index.rst. Creating file docs/Makefile. Creating file docs/make.bat. Finished: An initial directory structure has been created. You should now populate your master file docs/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.
With Sphinx you will be using reStructuredText to write documentation. reStructuredText is similar to Markdown, but has some custom syntax on top of it - here is a quick instruction on how to use it.
If you really want to use Markdown, use the “recommonmark” extension.
In this workshop, I will stick to the default reStructuredText format.
You will see that Sphinx has generated an
index.rst file for us - this is the main page of your documentation.
To generate the HTML version of the documentation, run:
$ make html Running Sphinx v2.4.2 ... build succeeded. The HTML pages are in build/html.
Finally, open the
build/html/index.html file in the browser to see the HTML version of your documentation:
In the beginning, it’s pretty empty, so let’s fill it up with some content.
You can add more files and folders in the
source directory and link them under the
toctree:: section to create additional pages of your documentation:
.. toctree:: :maxdepth: 2 quickstart.rst tutorials/first_tutorial.rst tutorials/second_tutorial.rst
Daniele splits documentation into four main categories:
Each part of the documentation is equally important, yet each of them requires a different mode of writing. It’s a good framework for writing documentation.
Sphinx lets you extract the documentation from your modules, classes, and functions and gather it all in one place.
First, you need to enable the
autodoc extension in the
# Replace "extensions = " line with: extensions = ['sphinx.ext.autodoc']
If you follow the same directories structure as I do here, then you will also need to add the root of your module to the Sphinx
path in the
conf.py file (otherwise, Sphinx won’t be able to import your modules).
At the top of the
conf.py add the following lines:
Next, create a file called
api.rst and for every module that you want to document, add the following code:
Name_of_the_module ------------------ .. automodule:: my_package.module1 :members:
my_package.module1 should be a valid Python import statement that will work if you run if from the root of your project.
Here is an example of how the
api.rst can look like:
API Docs ======== Math operations --------------- .. automodule:: my_package.math_operations :members: Models ------ .. automodule:: my_package.db.models :members: Helpers ------- .. automodule:: my_package.helpers :members:
If you navigate to the
api.rst page of your documentation, you will see the documentation of your code:
Next to each function, you can see [source] link that will take you to the source code of that function. This link is not enabled by default. If you want to display it, add
'sphinx.ext.viewcode' to the list of extensions in the
If you are building REST APIs using one of the popular tools like the Django REST framework or Flask-RESTPlus, check out SwaggerUI and ReDoc. Both of those tools let you easily generate interactive documentation for your applications:
Flask-RESTPlus has support for Swagger built-in, and in DRF, you can enable it with some plugins.
Finally, you want to make sure that the code examples in your documentation stays up to date. We saw before that it can be achieved with pytest (to test all your .rst files, run
pytest --doctest-glob='*.rst' command).
But we can also test our examples with the help of sphinx.ext.doctest extension.
First, add this extension to the
extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.viewcode', 'sphinx.ext.doctest', ]
Then add some code examples in your documentation files:
.. doctest:: >>> 2 + 2 5
make doctest command. It should detect code examples that fail:
$ make doctest ... Document: index --------------- ********************************************************************** File "index.rst", line 26, in default Failed example: 2 + 2 Expected: 5 Got: 4 ********************************************************************** 1 items had failures: 1 of 1 in default 1 tests in 1 items. 0 passed and 1 failed. ***Test Failed*** 1 failures. Doctest summary =============== 1 test 1 failure in tests 0 failures in setup code 0 failures in cleanup code build finished with problems.
If you are working on an open-source project, you can host your documentation for free online. All you need to do is visit the https://readthedocs.org/ website, create an account, and connect your code repository.
Read the docs will take your Sphinx documentation (it also supports MkDocs) and put it online: