Aller au contenu principal

Documentations versionnées avec Sphinx

· 5 minutes de lecture
Stéphane ROBERT
Consultant DevOps

Jusqu'à peu, j'utilisais mkdocs pour générer les documentations, mais suite au besoin de pouvoir proposer plusieurs versions de la même , je me suis tourné vers Sphinx.

Sphinx permet de :

  • Générer différents formats de sortie: HTML, PDF, EPUB, ...
  • Générer automatiquement la documentation liée à du code pour de nombreux langages,
  • D'étendre ses fonctionnalités avec sa gestion d'extensions.

Par défaut Sphinx les documents sont écrits en reStructuredText. Comme le markdown, le reStructuredText est un langage de balisage léger utilisé notamment dans la documentation du langage Python. Je vous propose ici de mettre en place sphinx avec le support du versioning des documents.

Installer Sphinx

Il faut dans un premier temps installé python :

sudo apt install build-essential python3 python3-pip python3-venv pipenv
pipenv install sphinx
pipenv shell

Ensuite, il faut lancer la commande suivante pour initialiser la structure :

sphinx-quickstart

Répondez juste Y à la première question pour séparer source du build.

C'est dans le répertoire source que vous allez créer vos documents.

Génération de la première version

Il suffit de lancer la commande :

make html
cd build/html

Dans une autre fenêtre shell :

cd build/html
python3 -m http.server

Ouvrer lien http://localhost:8000

Changer le thème pour celui de read the doc

Il existe de très nombreux thèmes, mais ma préférence va à celui du site readthedoc. Pour l'installer il faut ajouter une extension et modifier la configuration qui est géré par le fichier conf.py.

pip install sphinx-rtd-theme

Dans le fichier conf.py remplacer le thème par sphinx_rtd_theme

Maintenant nettoyer et re-générer le site :

make html clean
make html
cd build/html
python3 -m http.server

Installation de sphinx-multiversions

Comme sur le site readthedoc il est possible avec sphinx de générer plusieurs versions de votre documentation. Cela se fait avec l'extension sphinx-multiversion. Sphinx-multiversions utilise soit les branches, soit les tags (là va ma préférence.)

Comme pour les autres modules, il faut l'ajouter en tant que module.

pip install sphinx-multiversion gitpython

Il faut modifier le fichier source/conf.py et intégrer ces différentes modifications :

  • Ajouter l'extension sphinx_multiversion
  • Ajouter des variables permettant d'indiquer à sphinx-multiversions quel tag ou release exploité.

extensions = [
    'sphinx_rtd_theme',
 ...
    'sphinx_multiversion',
]

smv_tag_whitelist = r'^v\d+\.\d+.*$|latest'  # all tags of form v*.*.x and latest
# Whitelist pattern for branches (set to '' to ignore all branches)
smv_branch_whitelist = ''
smv_released_pattern = r'v.*'
smv_latest_version = 'v0.1'
smv_remote_whitelist = None

Ensuite faites un commit de votre code, puis posez les tags v0.1 puis latest et lancer la commande suivante :

sphinx-multiversion source build/html

Et cette fois, vous avez les versions v0.1 et latest (identiques) qui ont été généré dans votre répertoire build.

Ajout du menu de version

Il faut créer un template dans le répertoire source/_templates

{%- if current_version %}
<div class="rst-versions" data-toggle="rst-versions" role="note" aria-label="versions">
  <span class="rst-current-version" data-toggle="rst-current-version">
    <span class="fa fa-book"> Other Versions</span>
    v: {{ current_version.name }}
    <span class="fa fa-caret-down"></span>
  </span>
  <div class="rst-other-versions">
    {%- if versions.tags %}
    <dl>
      <dt>Tags</dt>
      {%- for item in versions.tags %}
      <dd><a href="{{ item.url }}">{{ item.name }}</a></dd>
      {%- endfor %}
    </dl>
    {%- endif %}
  </div>
</div>
{%- endif %}

Régénérer la documentation et vous devriez voir apparaître en bas de la sidebar le menu affichant les différentes versions de votre documentation.

Ajout d'une bannière indiquant si on consulte sur la dernière version de la documentation

Si on affiche une ancienne version de la documentation il faut pour indiquer que ce n'est pas la dernière. Pour cela on va ajouter une bannière qui ne s'affichera que s'il ne s'agit pas de la dernière version (latest ou smv_latest_version.)

Cette fois dans le répertoire source/_templates créer un fichier layout.html et y déposer ce contenu :

{%- extends "!layout.html" %}
 {% block document %}
{% if current_version and latest_version and current_version.name != 'latest' and current_version != latest_version %}
<div class="admonition attention">
  <p class="admonition-title">Attention!</p>
    <p>
    Vous consultez une ancienne version de cette documentation.
    Si vous voulez lire la plus récente, c'est par là <a href="{{ vpathto(latest_version.name) }}">{{latest_version.name}}</a>.
  </p>
</div>
{% endif %}
{{ super() }}
{% endblock %}%

Ici, avec Jinja on surcharge le block document en lui ajoutant devant la version du template ce panneau d'attention.

Redirection vers la dernière version de la documentation

À la source du répertoire, vous pouvez ajouter un fichier index.html redirigeant vers la version latest.

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Refresh" content="0; url=/latest/" />
</head>
<body>
  <p>Suivez <a href="/latest/">ce lien</a>.</p>
</body>
</html>

Ajouter le support du markdown à sphinx

La plupart de mes documentations sont écrites en markdown je vais donc ajouté le support du markdown à sphinx via une autre extension :

pip install --upgrade recommonmark

Dans le fichier de configuration conf.py ajouter l'extension

extensions = [
    'sphinx_rtd_theme',
    ...
    'recommonmark'
    ]

Il ajouter aussi le support des fichiers .md

source_suffix = {
    '.rst': 'restructuredtext',
    '.md': 'markdown',
}

La suite ~~~~

Il existe un nombre très important d'extensions à sphinx. Personnellement j'utilise redoc pour générer les documentations des api. J'ai donc ajouté l'extension sphinxcontrib-redoc qui ajouté à celle de multiversions permet de générer des documentations d'api versionnées intégrant un changelog.