Docstring is part of Python script which will keep record of documentation and description of the relevant section in the script. It won’t make any effect upon the execution of the script but whenever needed, the docstring could be pulled out and displayed for users’ reference. Based on that, we can go further to generate dedicated documentation pages/docs for general purpose. At this point, Sphinx is a commonly used package to transform the docstrings in Python script into either HTML, LaTeX or some other suitable formats. Here in this blog, I am going to write down some notes in using Sphinx for building documentation based on the docstring in Python scripts. The steps below could be used as sort of general guidance to set things up with Sphinx.

1. Installation

The official link to Sphinx gives rather detailed instructions about the installation and here I am not going to reproduce those details - refer to Ref. [1].

2. Initial setup

Once Sphinx is installed, we may want to set up the building system initially, following the instruction provided with Sphinx official site - refer to Ref. [2] at this point. It is a common practice to put everything about the documentation building into a single dedicated directory, alongside the Python files containing our docstrings. For example, here following is presented the tree structure for one of my projects,


β”œβ”€β”€ LICENSE.txt

β”œβ”€β”€ …

β”œβ”€β”€ docs

β”œβ”€β”€ requirements.txt

β”œβ”€β”€ rmc_tools

β”œβ”€β”€ …

whereby rmc_tools is a folder containing a whole bunch of Python scripts containing docstrings in each of them and docs is the folder where I put the documentation building system.

3. Documentation tree

After initial setup, we can start to put together the documentation tree so that we can further use Sphinx to build our documentation. Here in my example, the whole documentation tree (in which each file is following the reStructuredText format) is stored in the source directory. The following is presented the overall tree structure for the documentation (i.e. stuff put under docs directory),

β”œβ”€β”€ Makefile
β”œβ”€β”€ make.bat
└── source
β”œβ”€β”€ _static
β”‚Β Β  └── __init__.py
β”œβ”€β”€ conf.py
β”œβ”€β”€ ext_links.rst
β”œβ”€β”€ index.rst
β”œβ”€β”€ install.rst
β”œβ”€β”€ installation
β”‚Β Β  β”œβ”€β”€ rmc_modules_install.rst
β”‚Β Β  └── rmc_tools_install.rst
β”œβ”€β”€ rmc_modules
β”‚Β Β  β”œβ”€β”€ bulk_stuff.rst
β”‚Β Β  β”œβ”€β”€ nano_stuff.rst
β”‚Β Β  └── rmc6f_stuff.rst
β”œβ”€β”€ rmc_modules.rst
β”œβ”€β”€ rmc_tools
β”‚Β Β  β”œβ”€β”€ bulk_shells.rst
β”‚Β Β  β”œβ”€β”€ np_gen.rst
β”‚Β Β  β”œβ”€β”€ np_lin_analyzer.rst
β”‚Β Β  β”œβ”€β”€ np_shells.rst
β”‚Β Β  β”œβ”€β”€ rmc_strain.rst
β”‚Β Β  β”œβ”€β”€ sofq_calib.rst
β”‚Β Β  └── topas4rmc.rst
└── rmc_tools.rst

Then located in docs directory on terminal, we can simply execute make html to build up the documentation HTML pages. Things should start to roll like a charm at this point and following I note down several aspects we may want to pay attention to as we follow the procedures,

rst files could be grouped into dedicated folders and referred to in a separate rst file - like what we have above for the rmc_tools.rst file which contains references to those rst files in rmc_tools folder.

The rst file at the fundamental level should then contain reference to the docstring in Python file. For example in the rmc_tools/bulk_shells.rst file, it refers to the NP_Shells/bulk_shells.py file located in the main project directory. To let the building system find the Python file, we need to tell the building engine where those scripts are located. This can be done through the conf.py file located under source directory. Sometimes, we may think that if we have an entry in a rst file like .. automodule:: RMC_Strain_Analyzer.rmc_strain, it is enough to specify the parent directory where RMC_Strain_Analyzer is located. However, this turns out to be not the case - we need to include the full path to RMC_Strain_Analyzer in the system path as well.</li>

4. Go online

Upload documentation to online service so that it can be accessed by public. To do this, we can use the service provided by readthedocs. Here I will take the combination of readthedocs with GitHub as the example. If we have suitable directory setup as discussed above, e.g. everything concerning the documentation setup is contained in docs directory, and we have the whole project available in GitHub repository, we can set up a readthedocs account using our GitHub account, after which we can then import our GitHub repository holding the documentation project without problem. Once we are done the link between GitHub and readthedocs, any time we push something to our GitHub repository, the documentation will be built automatically and will be made available through readthedocs service.

Sometimes, certain Python scripts involved in the documentation building will try to import external modules, e.g. numpy or whatever - in this case, we need to tell readthedocs service explicitly what external modules we need. Otherwise, readthedocs won’t be able to find those necessary modules on its building server and therefore will fail the corresponding part of documentation building.

As a comprehensive example, the GitHub repository given in Ref. [3] could be used as the template for documentation building with Sphinx.


[1] https://www.sphinx-doc.org/en/master/usage/installation.html

[2] https://www.sphinx-doc.org/en/master/usage/quickstart.html

[3] https://github.com/Kvieta1990/rmc_adv_tools