Sphinx & reStructuredText Reference Portal
A living demonstration of Sphinx capabilities and reStructuredText mastery — from directives and roles to extensions, theming, and Docs-as-Code automation.
Authored by Oleh Shynkarenko, Senior Technical Writer
Overview
Sphinx is the industry-standard documentation engine for Python projects and increasingly adopted across the wider software engineering world. Paired with reStructuredText (reST), it provides a highly expressive, semantic markup language that compiles to HTML, PDF (via LaTeX), ePub, man pages, and more — all from a single plain-text source tree.
Note
reST predates Markdown and was designed specifically for technical documentation, with first-class support for cross-referencing, auto-generated indices, typed roles, and domain-specific markup that Markdown cannot match without heavy plugin ecosystems.
Semantic Markup
reST encodes meaning, not just appearance. Roles like
:py:class:, :ref:, and :term:
make content machine-readable and automatically cross-referenceable.
Extension Ecosystem
Over 200 first- and third-party Sphinx extensions — autodoc, napoleon, mermaid, OpenAPI, nbsphinx — let you automate entire documentation pipelines from source code to published site.
Multi-Format Output
Build HTML, PDF, ePub, man pages, and texinfo from the same source tree using Sphinx builders — no extra conversion tools required.
Docs-as-Code
Plain-text reST files live alongside code in Git. CI/CD pipelines (GitHub Actions, GitLab CI) build and publish docs automatically on every commit — no CMS needed.
reST Syntax Quick Reference
Inline Roles
reStructuredText expresses semantics through roles — inline markup prefixed with a colon. Unlike Markdown's visual-only emphasis, reST roles carry type information that Sphinx uses to generate a fully cross-referenced index:
:strong:`bold text` → **bold text**
:emphasis:`italic text` → *italic text*
:code:`inline_code()` → inline_code()
:command:`sphinx-build` → sphinx-build (shell command)
:file:`/path/to/file.py` → /path/to/file.py
:guilabel:`OK` → OK (UI label)
:kbd:`Ctrl+Shift+P` → Ctrl+Shift+P (keyboard shortcut)
:menuselection:`File --> New`
:doc:`sdk/getting_started` → link to another page in this project
:ref:`home` → link to a labelled anchor (any .rst file)
:py:class:`MyClass` → cross-reference to a Python class
:py:func:`my_module.helper` → cross-reference to a Python function
:envvar:`SPHINX_BUILD_DIR` → an environment variable
:rfc:`7519` → link to RFC 7519 (JWT)
:pep:`517` → link to PEP 517
Admonitions
Sphinx ships with a full palette of admonitions for callouts and alerts:
.. note:: General information worth highlighting
.. tip:: A helpful hint or shortcut
.. important:: Must-know information
.. warning:: Potential issues the reader should watch for
.. danger:: Destructive or irreversible consequences
.. caution:: Proceed with care
.. seealso:: Links to related topics
.. deprecated:: x.y Feature removed in version x.y
.. versionadded:: x.y Feature introduced in version x.y
.. versionchanged:: x.y Behaviour changed in version x.y
Tip
Combine admonitions with the .. only:: directive to show different callouts
per builder — for example, a PDF-specific warning that would not apply to HTML readers.
Section Heading Hierarchy
reST headings are determined by underline (and optional overline) characters. The Python documentation convention, adopted by most Sphinx projects, is:
########
Part
########
========
Chapter
========
Section
-------
Subsection
~~~~~~~~~~
Sub-subsection
^^^^^^^^^^^^^^
Paragraph
"""""""""
Important
The character used is not fixed by the spec — Sphinx assigns levels based on
first-occurrence order within each file. Consistency across a project is
enforced by convention (or a linter such as rstcheck), not the parser.
Directives Deep-Dive
Anatomy of a Directive
Every Sphinx directive follows the same grammar. Understanding this structure is the key to reading and writing any directive — including custom ones:
.. directive-name:: optional-argument
:option-name: option-value
:another-option: value
:flag-option: ← boolean flag, no value needed
Body content — indented by 3 spaces (or 1 tab).
This is the directive's content block. It may contain
nested reST markup, including other directives.
Code Blocks
The .. code-block:: directive supports syntax highlighting via Pygments, which
covers over 500 languages. Key options include :linenos:, :emphasize-lines:,
:caption:, and :dedent::
1# conf.py
2project = "SphinxDocs"
3extensions = [
4 "sphinx.ext.autodoc", # Pull docstrings from Python source
5 "sphinx.ext.napoleon", # Google / NumPy docstring styles
6 "sphinx.ext.viewcode", # Add [source] links to API pages
7 "sphinx.ext.intersphinx", # Cross-project cross-references
8 "sphinxcontrib.mermaid", # Mermaid diagram support
9 "sphinxcontrib.httpdomain", # HTTP API documentation
10]
11html_theme = "sphinx_rtd_theme"
12html_static_path = ["_static"]
13html_logo = "_static/logo.png"
14html_favicon = "_static/favicon.ico"
# Build HTML output
sphinx-build -b html source/ build/html
# Build PDF via LaTeX
sphinx-build -b latex source/ build/latex && make -C build/latex
# Auto-rebuild on save with live reload (requires sphinx-autobuild)
sphinx-autobuild source/ build/html --port 8080
# Check for broken external links
sphinx-build -b linkcheck source/ build/linkcheck
# Rebuild cleanly (ignore cached environment)
sphinx-build -E -b html source/ build/html
# Treat warnings as errors (for CI pipelines)
sphinx-build -W -b html source/ build/html
Includes and Substitutions
reST supports file includes and text substitutions — two powerful tools for maintaining a single source of truth across large documentation sets:
.. |product| replace:: SphinxDocs
.. |version| replace:: 2.4.1
The current version of |product| is |version|.
.. include:: shared/warning_banner.rst
.. literalinclude:: ../../src/my_module.py
:language: python
:lines: 10-35
:caption: Source: my_module.py (lines 10–35)
Sphinx Extensions Comparison
| Extension | Purpose | HTML | Complexity | |
|---|---|---|---|---|
sphinx.ext.autodoc |
Import & render Python docstrings automatically | ✓ Yes | ✓ Yes | Low |
sphinx.ext.napoleon |
Google / NumPy docstring styles | ✓ Yes | ✓ Yes | Low |
sphinx.ext.viewcode |
Add [source] links to API documentation pages | ✓ Yes | ✗ No | Low |
sphinx.ext.intersphinx |
Cross-project cross-references (e.g., link to Python stdlib) | ✓ Yes | ✓ Yes | Medium |
sphinxcontrib.mermaid |
Embed Mermaid diagrams as plain-text source | ✓ Yes | ~ Partial | Low |
sphinxcontrib.httpdomain |
Semantic markup for REST HTTP APIs | ✓ Yes | ✓ Yes | Medium |
nbsphinx |
Embed Jupyter Notebooks with live output | ✓ Yes | ~ Partial | High |
sphinx_rtd_theme |
Read the Docs HTML theme | ✓ Yes | ✗ No | Low |
sphinx.ext.coverage |
Report which Python symbols lack documentation | ✓ Yes | ✗ No | Low |
Tables in reStructuredText
reST provides three table syntaxes. The .. list-table:: directive is the most
maintainable for Docs-as-Code workflows because it does not require manual ASCII
alignment:
Syntax |
Readability |
Best for |
Tooling support |
|---|---|---|---|
Grid table |
Low (ASCII art) |
Simple, narrow content |
All editors; alignment tedious |
Simple table |
Medium |
Column-aligned numeric data |
All editors; no multi-line cells |
|
High |
Complex / multi-line cell content |
Excellent — no manual alignment |
|
High |
Data sourced from external CSV files |
Excellent — reads live |
Grid table example (ASCII art syntax)
+------------------+------------+---------------------+
| Header A | Header B | Header C |
+==================+============+=====================+
| Row 1, Cell 1 | Cell 2 | Cell 3 |
+------------------+------------+---------------------+
| Row 2 | Cell 5 | Cell 6 |
+------------------+------------+---------------------+
Diagrams as Code with Mermaid
With sphinxcontrib-mermaid, diagrams live in version control as plain text —
they are diff-able, reviewable, and never go stale because they live next to the
content they describe.
Sphinx Build Pipeline
flowchart LR
A["Author writes .rst"] --> B{"sphinx-build"}
B --> C["HTML output"]
B --> D["PDF via LaTeX"]
B --> E["ePub output"]
C --> F["Read the Docs"]
C --> G["GitHub Pages"]
D --> H["Print / Download"]
Docs-as-Code CI/CD Sequence
sequenceDiagram
participant Dev as Developer
participant Git as Git / GitHub
participant CI as GitHub Actions
participant RTD as Read the Docs
Dev->>Git: git push
Git->>CI: Trigger workflow
CI->>CI: sphinx-build -W -b html
CI->>CI: sphinx-build -b linkcheck
CI->>RTD: Deploy on success
RTD-->>Dev: Build notification
Autodoc: Python API Documentation
sphinx.ext.autodoc pulls docstrings directly from Python source, keeping docs
and code in sync automatically. Combine it with napoleon to support Google-style
and NumPy-style docstrings:
class TokenManager:
"""Manage API authentication tokens.
Supports Bearer token, API-key, and OAuth 2.0 client-credentials flows.
Tokens are cached in-memory and refreshed automatically before expiry.
Args:
base_url (str): Root URL of the target API.
timeout (int): Request timeout in seconds. Defaults to ``30``.
Raises:
AuthError: When credentials are invalid or have expired.
Example:
>>> mgr = TokenManager("https://api.example.com")
>>> mgr.authenticate(client_id="abc", client_secret="xyz")
>>> mgr.get_token()
'eyJhbGciOiJSUzI1NiIs...'
"""
def authenticate(self, client_id: str, client_secret: str) -> None:
"""Exchange client credentials for an access token (OAuth 2.0).
Args:
client_id (str): OAuth 2.0 client identifier.
client_secret (str): OAuth 2.0 client secret.
"""
.. autoclass:: auth.TokenManager
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
HTTP API Documentation
The sphinxcontrib-httpdomain extension adds a semantic HTTP domain so REST
endpoints are documented with typed parameters, status codes, and request headers
that Sphinx can cross-reference and index:
.. http:get:: /api/v1/users/{user_id}
Retrieve a single user by their unique identifier.
:param user_id: Unique UUID of the user record.
:type user_id: uuid
:reqheader Authorization: ``Bearer <token>``
:reqheader Accept: ``application/json``
:statuscode 200: User record returned successfully.
:statuscode 401: Missing or invalid authentication token.
:statuscode 404: User not found.
**Example response:**
.. code-block:: json
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Oleh Shynkarenko",
"role": "admin",
"created_at": "2026-04-30T09:00:00Z"
}
Docs-as-Code Workflow
The following CI/CD workflow integrates Sphinx into a GitHub Actions pipeline —
building, link-checking, and deploying documentation automatically on every
merge to main:
1name: Build & Deploy Docs
2
3on:
4 push:
5 branches: [main]
6 pull_request:
7 branches: [main]
8
9jobs:
10 build:
11 runs-on: ubuntu-latest
12 steps:
13 - uses: actions/checkout@v4
14
15 - name: Set up Python 3.12
16 uses: actions/setup-python@v5
17 with:
18 python-version: "3.12"
19
20 - name: Install dependencies
21 run: pip install -r requirements.txt
22
23 - name: Build HTML (warnings = errors)
24 run: sphinx-build -W -b html source/ build/html
25
26 - name: Check for broken links
27 run: sphinx-build -b linkcheck source/ build/linkcheck
28
29 - name: Deploy to GitHub Pages
30 if: github.ref == 'refs/heads/main'
31 uses: peaceiris/actions-gh-pages@v4
32 with:
33 github_token: ${{ secrets.GITHUB_TOKEN }}
34 publish_dir: ./build/html
Writing a Custom Sphinx Extension
Custom Python extensions unlock unlimited possibilities — from version badges to
glossary auto-generators. Every extension follows the same setup(app) contract:
from docutils import nodes
from docutils.parsers.rst import Directive, directives
class VersionBadge(Directive):
"""Renders a coloured version badge inline in HTML output."""
required_arguments = 1
option_spec = {"color": directives.unchanged}
def run(self):
version = self.arguments[0]
color = self.options.get("color", "#0f3460")
html = (
f'<span class="badge" style="background:{color};'
f'color:#fff;padding:.2rem .7rem;border-radius:12px;">'
f'v{version}</span>'
)
return [nodes.raw("", html, format="html")]
def setup(app):
app.add_directive("version-badge", VersionBadge)
return {"version": "0.1", "parallel_read_safe": True}
.. version-badge:: 2.4.1
:color: #4ecca3
See also
Getting Started with the RedCore SDK — Step-by-step SDK setup guide
OAuth 2.0 Authentication — OAuth 2.0 authentication flow
System Architecture — System architecture diagrams