Sphinx

Automation the building of the sphinx project when a source file was changed

Create makedoc.py script in your project folder.

$ touch ~/projects/shmakovpn_tools/makedoc.py
import os
SCRIPT_DIR: str = os.path.dirname(os.path.abspath(__file__))


def run_sphinx():
    docs_dir: str = os.path.join(SCRIPT_DIR, 'docs')
    docs_source_dir: str = os.path.join(docs_dir, 'source')
    build_dir: str = os.path.join(docs_dir, 'build')
    html_dir: str = os.path.join(build_dir, 'html')
    os.system('sphinx-build -b html "%s" "%s"' % (docs_source_dir, html_dir))
    print('__END__')


if __name__ == '__main__':
    run_sphinx()

Place your project documentation source files into docs/source folder, the run

$ workon shmakovpn_tools  # switch to needed virtual environment
$ python ~/projects/shmakovpn_tools/makedoc.py
...
...
__END__

Install inotify-tools

Under Ubuntu.

# apt install -y inotify-tools

Under Centos 8.

# dnf install -y epel-release
# dnf install -y inotify-tools

Create auto_makedoc.sh in your project folder.

$ touch ~/projects/shmakovpn_tools/auto_makedoc.sh
$ chmod +x ~/projects/shmakovpn_tools/auto_makedoc.sh
#!/bin/bash

# Runs `sphinx build` when files in ./docs/source was changed, uses inotifywait for watching files changes
# Author: shmaovpn <shmakovpn@yandex.ru>
# Date: 2020-09-06

# Requirements:
# Ubuntu: inotify-tools
# Centos 8: inotify-tools (from epel repository)

SCRIPT_DIR="$(dirname $0)"
DOCS_SOURCE_DIR="${SCRIPT_DIR}/docs/source"

# Checking that a VIRTUALENV is activated, exit otherwise
if ! test ${VIRTUAL_ENV} ; then
    echo "A vitrualenv is not activated. \$VIRTUAL_ENV is null"
    exit 1
fi

# Checking that *inotifywait* is installed
if ! which inotifywait > /dev/null 2>&1 ; then
    echo "*inotifywait* is not installed. Install package *inotify-tools*."
    exit 1
fi

# `inotifywait -r -m -e modify -e move -e crate -e delete watching_dir` generates multiple events
# when a file was saved used vim or something else
# but we want to run `sphinx build` only once when a file was changed.
# Thus `while true` is used.
# inotifywait (without *-m* key) generates one event then stops,
# then makedoc.py runs `shpihx build` 
# then next iteration of infinitive cicle `while true` starts `inotifywait -m` once again

while true; do
    inotifywait -r -e modify -e move -e create -e delete ${DOCS_SOURCE_DIR} 2>/dev/null \
        && python ${SCRIPT_DIR}/makedoc.py
done

Run auto_makedoc.sh in another terminal. Create or modify any of documentation source file.

View your documentation on another host.

What do you do if your project is on another host? You can use something like VNC or SSH with -X. But if the development server doesn’t have GUI? There are several kinds of possible solutions. One of which is share docs/build/html directory using HTTP.

Let’s use docker for this.

Install docker.

# dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# dnf install -y docker-ce --nobest
# systemctl enable docker
# systemctl start docker
# usermod -aG docker shmakovpn # add your non-root user to docker group

Login under your non-root user and run:

$ docker run hello-world

Run nginx under docker.

$ docker run -i -t -p 80:80 -v ~/projects/shmakovpn_tools/docs/build/html:/usr/share/nginx/html:ro -d nginx

Open http://server_ip on your computer with GUI.

Configure Sphinx to use tabs and rtd-theme.

Install packages.

$ workon shmakovpn # switch to your virtual environment
$ pip install sphinx-rtd-theme
$ pip install sphinx-tabs

Change extenstions section of ~/projects/shmakovpn_tools/docs/source/conf.py:

extenstions = [
    'sphinx.ext.autodoc',
    'sphinx.ext.intersphinx',
    'sphinx.ext.viewcode',
    'sphinx.ext.todo',
    'sphinx_tabs.tabs',
]

And html_theme:

html_theme = 'sphinx_rtd_theme'

Also, if you want to user sphinx-tabs with readthedocs.io, create file ~/projects/shmakovpn_tools/docs/requirements.txt:

sphinx-tabs

Warning

Latex doesn’t work with sphinx-tabs