Files
mnemosyne/docs/source/conf.py
Robert Helewka f8a2cf0c3d
Some checks failed
CVE Scan & Docker Build / security-scan (push) Successful in 3m12s
CVE Scan & Docker Build / build-and-push (push) Successful in 2m38s
Build & Deploy Docs / build-and-deploy (push) Failing after 1m31s
docs: add Sphinx documentation build and deploy workflow
- Add Gitea Actions workflow to build and deploy docs on push to main
- Generate Sphinx reference documentation for all apps and modules
- Deploy versioned and latest docs via rsync over SSH
2026-05-23 06:11:05 -04:00

98 lines
3.3 KiB
Python

import os
import sys
import tomllib
# The Django package lives at <repo>/mnemosyne/<inner mnemosyne>/. Adding the
# outer mnemosyne/ directory to sys.path lets autodoc resolve every app
# (themis, library, llm_manager, mcp_server) and the project settings module.
sys.path.insert(0, os.path.abspath('../../mnemosyne'))
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mnemosyne.settings')
# Load real .env if present (local dev). In CI there is none and that's fine —
# settings.py provides a default for every env var it reads, so the import
# succeeds either way.
_repo_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
_env_file = os.path.join(_repo_root, 'mnemosyne', '.env')
if os.path.exists(_env_file):
with open(_env_file) as _f:
for _line in _f:
_line = _line.strip()
if not _line or _line.startswith('#') or '=' not in _line:
continue
_key, _val = _line.split('=', 1)
os.environ.setdefault(_key.strip(), _val.strip())
import django # noqa: E402
django.setup()
# Sphinx autodoc calls repr() on every class attribute it documents. Django's
# QuerySet.__repr__ executes a SELECT against the database — which doc builds
# have no business doing. Intercept object_description so QuerySet instances
# render as a static string instead. Mnemosyne's themis app has at least one
# DRF viewset with a class-level queryset attribute, so this matters.
from django.db.models.query import QuerySet # noqa: E402
import sphinx.util.inspect as _sphinx_inspect # noqa: E402
_orig_object_description = _sphinx_inspect.object_description
def _safe_object_description(obj, *args, **kwargs):
if isinstance(obj, QuerySet):
return f'<QuerySet [{obj.model.__name__}]>'
return _orig_object_description(obj, *args, **kwargs)
_sphinx_inspect.object_description = _safe_object_description
# ── Sphinx configuration ──────────────────────────────────────────────────
project = 'Mnemosyne'
copyright = '2026, Mnemosyne Team'
author = 'Mnemosyne Team'
with open(os.path.join(_repo_root, 'pyproject.toml'), 'rb') as _f:
release = tomllib.load(_f)['project']['version']
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.viewcode',
'sphinx.ext.napoleon',
'sphinx.ext.intersphinx',
'sphinx_autodoc_typehints',
'sphinxcontrib.httpdomain',
'sphinxcontrib.mermaid',
'myst_parser',
]
source_suffix = {'.rst': 'restructuredtext', '.md': 'markdown'}
myst_enable_extensions = ['colon_fence', 'deflist', 'tasklist', 'attrs_inline']
myst_heading_anchors = 4
autodoc_default_options = {
'members': True,
'member-order': 'bysource',
'special-members': '__init__',
'undoc-members': True,
'exclude-members': '__weakref__',
}
autodoc_inherit_docstrings = False
napoleon_use_ivar = True
intersphinx_mapping = {
'python': ('https://docs.python.org/3', None),
'django': ('https://docs.djangoproject.com/en/stable/',
'https://docs.djangoproject.com/en/stable/_objects/'),
}
html_theme = 'sphinx_rtd_theme'
html_static_path = ['_static']
html_theme_options = {
'navigation_depth': 4,
'collapse_navigation': False,
'sticky_navigation': True,
'includehidden': True,
'titles_only': False,
}