This document explains the Sphinx documentation setup for ACCV-Lab.
The documentation system provides:
- Explicit namespace package configuration through
namespace_packages_config.py - Dynamic documentation generation for each configured namespace package
- Comprehensive API reference with auto-generated content (extracted from docstrings)
- Referenced directories mirroring to access files from the individual namespace packages in the
documentation by
- collecting all the needed files from the individual namespace packages
- without introducing duplicates
- and while not breaking any relative path references to files inside the package documentation & additional
locations such as e.g. an
examplesdirectory from which files need to be displayed in the documentation.
⚠️ Important: When using links and file paths inside documents (.md/.rst) and directives (e.g.,include,image,literalinclude) inside the documentation of the contained packages, it is recommended to use relative paths (which will be understood as relative to the current document) rather than absolute paths. This keeps package docs portable, and the links are valid both in the original package directory and when mirrored into the main documentation location (docs/contained_package_docs_mirror/<package>/docs/; see the Comprehensive Documentation Structure section).
ℹ️ Note: When using relative paths inside docstrings (e.g. to insert images), these paths are understood as relative to the documentation file which includes the docstring (e.g. the file containing the
autodocdirective). In this case, absolute paths can be used.
The system uses explicit namespace package configuration via namespace_packages_config.py
(see the How It Works section in the Development Guide).
The documentation generation makes use of multiple scripts:
generate_new_namespace_package_docs.py: Creates documentation structure for new namespace packages- Template-based: Uses consistent templates for all namespace packages (but generated files may be modified as needed)
- Safe regeneration: Only creates missing files if no
index.rstis present for the namespace package
update_docs_index.py: Updates main index file by including references to newly added namespace packagesmirror_referenced_dirs.py: Mirrors (symlinks by default) thedocsdirectory and other needed directories from the individual packagessync_root_readme_for_docs.py: Copies the project rootREADME.mdintodocs/project_overview/README.md, adjusting guide links so that the same overview content works both when viewing the originalREADME.mdfile and inside the built documentation
ℹ️ Note: Documentation will only be generated for packages listed in the
NAMESPACE_PACKAGESconfiguration. Packages not in this list will be ignored during the documentation build process (also see the Development Guide).
ℹ️ Note: The documentation generation scripts are automatically run during the documentation build process (see also the
Generation Scriptssubsection in the Technical Details section). You do not need to run them manually.
docs/
├── conf.py # Sphinx configuration using namespace_packages_config
├── index.rst # Main documentation index
├── generate_new_namespace_package_docs.py # Creates structure for new namespace packages
├── update_docs_index.py # Updates navigation and indices
├── mirror_referenced_dirs.py # Mirrors referenced directories (symlinks by default)
├── sync_root_readme_for_docs.py # Syncs project root README into docs/project_overview
├── Makefile # Build commands
├── requirements.txt # Documentation dependencies
├── project_overview/ # Synced copy of the project root README used as docs overview
├── contained_package_docs_mirror/ # Mirrored package documentation via symlinks (or copies)
│ ├── example_package/ # Example namespace package docs (representative)
│ │ ├── docs/ # Documentation files
│ │ │ ├── index.rst # Namespace package overview
│ │ │ ├── intro.rst # Introduction (manual content)
│ │ │ └── api.rst # API reference (auto-generated)
│ │ └── examples/ # Additional mirrored directory (referenced in docs)
│ └── [other_packages]/ # Other configured namespace packages
├── common/ # Shared documentation resources
├── _static/css/
│ └── custom.css # Custom styling
└── _build/ # Built documentation output
Notes:
- The
docs/contained_package_docs_mirrorstructure shows the build-time documentation mirrored via symlinks (or copies) - While only the
example_packageis shown in detail here, the actual documentation will contain all configured namespace packages - If you need to refer one contained package documentation from another contained package documentation, you can do this by using relative paths according to this structure or by using absolute paths
packages/
└── example_package/ # Example namespace package (representative)
├── docs/ # Source documentation files
│ ├── index.rst # Namespace package overview
│ ├── intro.rst # Introduction (manual content)
│ └── api.rst # API reference (auto-generated)
├── docu_referenced_dirs.txt # List of additional directories to copy
├── examples/ # Example code (mirrored and referenced by docs)
└── [other_dirs]/ # Other package directories
Notes:
- The
packages/example_package/structure shows the source documentation that gets mirrored during build ⚠️ Important: Content should be edited in the source locations (packages/<package_name>/docs/), not in the mirrored locations- In case of the
example_package, theexamples/directory is mirrored to maintain documentation references to example code. This can be achieved by listing it in thedocu_referenced_dirs.txtfile (see Referenced Directories Configuration) - While we focus on the
example_packagepackage, the documentation setup of other packages is analogous
⚠️ Important: To ensure correct generation of the API documentation, theACCV-Labpackage (i.e. all relevant namespace packages) needs to be installed first before generating the documentation. API documentation for non-installed namespace packages may be empty.For packages installed in normal (non-editable) mode, changes to code or docstrings are only picked up after reinstalling the affected packages (for example via
./scripts/install_local.sh) and then rebuilding the documentation. When using editable installs, changes to pure-Python code and docstrings are typically visible on the next docs build, but changes coming from compiled extensions still require rebuilding/reinstalling those extensions.
To add a new namespace package and its documentation, see Adding a new Package: Step-by-Step Process. Setting up the documentation for a new namespace package (including how to build it locally) is described in the Building Documentation Locally section.
ℹ️ Note: New namespace package must be added to the
NAMESPACE_PACKAGESlist innamespace_packages_config.pyfor template generation to work (see Development Guide for details).
Each namespace package can specify additional directories that are referenced by its documentation using a
docu_referenced_dirs.txt file in the package root directory.
File location: packages/<package_name>/docu_referenced_dirs.txt
Example (for example_package):
# This file lists additional directories (besides docs) that are referenced by documentation
# The docs directory is always mirrored automatically
# Add one directory name per line, without the docs directory
# Lines starting with # are comments and are ignored
examples
Default behavior: If docu_referenced_dirs.txt doesn't exist, only the docs directory is mirrored.
Purpose: This ensures that e.g. files included in the documentation (images, code examples, test files, etc.) can still be found after the documentation is mirrored to the build location.
Note that:
- The
docsdirectory is always mirrored automatically and should not be listed in this file - Lines starting with
#are treated as comments and ignored - Empty lines are ignored
- Only list additional directories that are referenced by your documentation. Note that the API documentation does not rely on this mirroring, but is extracted from the installed packages.
Quick build using the script (can be run from any directory, example shows running from the project root directory):
./scripts/build_docs.shCapture Sphinx warnings in a dedicated file:
./scripts/build_docs.sh --warning-file docs/_build/sphinx-warnings.logThis is useful for CI and other automation that wants to inspect warnings separately from the console output.
Relative warning-file paths are resolved from the project root. The warning file captures Sphinx warnings from
the selected builder (HTML by default, PDF with --pdf, or spelling with --spelling). In spelling mode, this
is separate from spelling findings, which are still written to docs/_build/spelling/output.txt.
Manual build:
cd docs
pip install -r requirements.txt
make htmlDevelopment with auto-rebuild:
cd docs
make livehtmlBuild Process Details:
- The build process automatically runs the necessary scripts (see Generation Scripts) in sequence
- The
htmltarget ensures all scripts run before building - The
livehtmltarget also runs the scripts for development builds - When running spelling via the script, the generation scripts are executed first to ensure mirrored package
docs are up to date. Spelling findings are written to
docs/_build/spelling/output.txt.
ℹ️ Note:
make livehtmlwatches thedocs/tree and mirrored package documentation, but:
- It does not rerun the
sync_root_readme_for_docs.pyscript when you edit the project rootREADME.md. This means that if you change the rootREADME.mdand want to see those changes reflected indocs/project_overview/README.md, you need to restartmake livehtml(or runmake sync-readmeonce before continuing to work).- It does not reinstall or rebuild packages for you. This means that if you change the docstrings in the source tree of a package, you need to reinstall the package (for example via
./scripts/install_local.sh) and then restartmake livehtmlto see updated docstrings.
Spell-checking with sphinxcontrib-spelling:
-
Quick run using the script:
./scripts/build_docs.sh --spelling
This runs the doc generation steps, and executes the Sphinx spelling builder. Results are written to
docs/_build/spelling/output.txt. -
Manual run:
pip install sphinxcontrib-spelling pyenchant cd docs make generate make spellingThe spelling report will be at
_build/spelling/output.txt. -
Note: On some Linux systems you may need a system-level Enchant library. If you see errors related to Enchant, install it via your package manager (e.g.,
sudo apt install enchant-2on Debian/Ubuntu). -
Whitelisting words (project-specific words or general words which are not part of the used dictionary):
- Add words (one per line) to
docs/spelling_wordlist.txt(e.g.,namespace,ACCV-Lab). - Re-run the spelling check. These words will no longer be flagged.
- Add words (one per line) to
Each namespace package documentation is located in packages/<package_name>/docs/ and is automatically
mirrored to docs/contained_package_docs_mirror/<package_name>/docs/.
Example structure (for example_package):
intro.rst: Manual introduction and overview (customize this)api.rst: Auto-generated API reference (the file can be modified e.g. to add short sections, but the API is auto-extracted)index.rst: Table of contents for the namespace package as well as the "entry point". This file needs to be present in the folder.
⚠️ Important: When editing documentation, work directly in thepackages/<package_name>/docs/directory, not in thedocs/contained_package_docs_mirror/<package_name>/docs/directory.Example: For
example_package, edit files inpackages/example_package/docs/, not indocs/contained_package_docs_mirror/example_package/docs/.
Note that index.rst is the "entry point" which is referenced by the ACCV-Lab documentation and needs to
be present. All other files may be changed (e.g. removed, renamed) and new files may be added. In this case,
ensure that within the namespace package, all the needed files are referenced from index.rst (either
directly or indirectly).
Possible modifications include:
- Modify
docs/conf.pyfor Sphinx configuration - Edit
docs/_static/custom.cssfor styling - Add shared content in
docs/common/ - Update
docs/index.rstfor main navigation
ℹ️ Note: The high-level project overview used in the documentation is sourced from the project root
README.mdand mirrored intodocs/project_overview/README.mdbysync_root_readme_for_docs.py. Edit the rootREADME.mdrather than the mirrored copy; the docs build will keep them in sync.
⚠️ Important: When modifying the documentation in these ways, make sure to not break the documentation generation for any of the namespace packages.
The build adds several custom features that improve code inclusion, device notes in API docs, and table
readability. These are configured in docs/conf.py, implemented in:
docs/_ext/note_literalinclude.py(note-literalinclude directive)docs/_ext/module_docstring.py(module-docstring directive)docs/_ext/markdown_note_admonitions.py(Markdown “Note/Important” → admonitions)docs/conf.py(autodoc device-note processing and configuration)docs/_static/css/custom.css(styling for.device-note,no-scroll, and autosummary tables)
and styled via docs/_static/css/custom.css.
- Include code files and automatically highlight “note blocks” inside the code (e.g., lines starting with a note tag and their continued lines).
- Example:
.. note-literalinclude:: ../examples/basic_usage.py
:language: python
:caption: Simple usage example
:note-tag: #@NOTE;# @NOTE # optional, defaults to '#@NOTE;# @NOTE'
:note-cont: # # optional, defaults to '#'
:highlight-notes: true # optional, defaults to true- Behavior: Lines starting with any tag in
:note-tag:(default:#@NOTEor# @NOTE) are highlighted, and highlighting continues on subsequent lines that start with the continuation prefix (default:#) until a non-matching line is encountered. - If
:highlight-notes:isfalse, it behaves like a normalliteralinclude.
- Render the top-level docstring of a Python module directly:
.. module-docstring:: ../../packages/example_package/accvlab/example_package/__init__.py- Behavior: Reads and parses the given module file and renders only its module-level docstring at the place of the directive. Note that in contrast to the API documentation, the docstring is read directly from the indicated file and not from the installed package. This is e.g. useful for docstrings originating from examples, which are not part of the installed package.
- Converts Markdown blockquoted notes into Sphinx admonitions at build time, while keeping the Markdown source readable in GitHub/IDEs.
- Implemented in:
docs/_ext/markdown_note_admonitions.py - How to write notes in Markdown (examples):
> **ℹ️ Note**: Short tip for the reader.
> **⚠️ Important**: Crucial warning users must not miss.- Accepted variants:
- With or without symbols:
ℹ️,ⓘ,(i),i,!,⚠️ - With or without bold around the word
- With or without a trailing colon after “Note”/“Important”
- Examples that also convert:
- With or without symbols:
> Note: ...
> **Note** ...
> ! Important ...
> (i) Note ...
> ⚠️ Important ...ℹ️ Note: Multi-line notes are supported. In this case, all lines must start with
>, and the whole so defined block will be converted to an admonition.
ℹ️ Note: When using the MyST Markdown parser (used in the Sphinx documentation), you can also use the built-in fenced admonitions (for example
```{note}/```{important}as opening fences). However, the blockquote-based syntax described here is meant to be compatible with plain Markdown viewers (such as GitHub or IDEs), also highlighting the note/important text if it is not converted to a Sphinx admonition. Therefore, this blockquote-based syntax is preferred for files that should work both as standalone.mdfiles and as part of the built documentation. If the file is only used as part of the built documentation, the fenced admonitions should be used instead.
- Scope:
- Only blockquotes are converted (lines starting with
>). Plain list items or inline text containing “Note:”/“Important:” are not converted. - Nested blockquotes inside lists are supported (the quoted block is converted).
- Only blockquotes are converted (lines starting with
- Autodoc-rendered Python docstrings can show a highlighted “device” note at the top by adding one of the
following markers as a separate line in the docstring:
:gpu:→ renders a note that inputs are expected on GPU:cpu:→ renders a note that inputs are expected on CPU:device: <TEXT>→ renders a note that inputs are expected on the specified device text (e.g.,GPU,CPU)
- Example (Python):
def my_function(x):
"""Short description.
:gpu:
More details about usage...
"""
...- Behavior: During autodoc processing, these markers are detected and replaced with an emphasized note at
the top of the rendered docstring. The note is styled with the
.device-noteCSS class.
- To avoid horizontal scrolling and allow wrapping for specific tables, use the
no-scrolltable class:
.. table:: Example table
:class: no-scroll
+------------------+---------------------+
| Column A | Column B |
+------------------+---------------------+
| Long content ... | More long content … |
+------------------+---------------------+- Autosummary tables are styled to wrap cell contents automatically; no additional class is required.
The configuration includes:
- Explicit namespace package import from
namespace_packages_config.py(in the helper scripts) - Local extension path setup (
docs/_ext); autodoc imports installed ACCV-Lab packages - Extension configuration for autodoc, autosummary, and more
- Theme configuration with Read the Docs theme
- Cross-reference setup with intersphinx
- Standard Sphinx targets: html, clean, etc.
- Custom targets:
generate: Runs all documentation generation scripts for namespace packagessync-readme: Syncs the project rootREADME.mdintodocs/project_overview/README.mdwith adjusted linkslivehtml: Development build with auto-reload (also runssync-readmeandgeneratebefore starting)
- Development support: Live reload and other dev features
- Dependency installation: Installs documentation requirements from
docs/requirements.txt - Complete build process: Generation + Sphinx build
- Warning capture: Can write Sphinx warnings from the build to a dedicated file via
--warning-file - Browser integration: Optionally opens documentation
- Error handling: Provides clear error messages
- Location: Can be run from any directory (script automatically determines project root)
The docs/requirements.txt file contains the Python packages needed for building documentation (separate from
the per-package runtime dependencies defined in each package's pyproject.toml):
- Sphinx and related extensions
- Theme packages
- Other documentation-specific dependencies
namespace_packages_config.py: Shared namespace package configuration (PROJECT ROOT)docs/conf.py: Sphinx configuration using shared configdocs/index.rst: Main documentation index with navigation. Note that this file contains a template for including the namespace packages, as well as an auto-generated table of contents for the namespace packages using the template (see the comments in the file for more details).docs/requirements.txt: Documentation dependencies
The documentation build relies on the helper scripts described in the Dynamic Documentation Generation section. These scripts are invoked automatically as part of the docs build; you normally do not need to run them manually.
packages/<package_name>/docs/index.rst: Namespace package overview (source)packages/<package_name>/docs/intro.rst: Manual introduction content (source)packages/<package_name>/docs/api.rst: Auto-generated API reference (source)packages/<package_name>/docu_referenced_dirs.txt: List of directories containing files used in the documentation in addition todocs(to mirror into the documentation source directory).docs/contained_package_docs_mirror/<package_name>/docs/: Mirrored documentation (symlink to the individual packages by default)docs/contained_package_docs_mirror/<package_name>/[other_dirs]/: Additional mirrored directories as specified indocu_referenced_dirs.txt
The individual .rst files for individual namespace packages can be changes (content, filenames, number of
files, etc.), but index.rst is required as it is used as the "entry point" from the overarching
documentation into the individual namespace package documentation.
docs/common/: Shared documentation resourcesdocs/_static/custom.css: Custom styling (applied to all namespace packages)
scripts/build_docs.sh: Comprehensive build script (can be run from any directory)docs/Makefile: Standard Sphinx build commands