Sphinx Documentation Build

Verifying HTML autodoc and Word export

Published

31 May 2026 00:00

1 What this page covers

Issues #15 and #16 verify that the rag/ Python module can be built into readable documentation using Sphinx, and that a Word version of the project report can be exported for submission.


2 HTML build — Sphinx autodoc

Sphinx reads the docstrings in rag/ingest.py, rag/query.py, rag/evaluate.py, and rag/logger.py and renders them as cross-linked HTML documentation.

How to build:

sphinx-build -b html docs/_source docs/_build/html

Output: docs/_build/html/index.html

The build uses:

Extension Purpose
myst_parser Parses Markdown source files (.md)
sphinx.ext.autodoc Pulls docstrings from Python modules
sphinx.ext.viewcode Adds “view source” links to each function
sphinx_rtd_theme Read the Docs visual theme

Install dependencies:

uv sync   # myst-parser and sphinx-rtd-theme are in pyproject.toml

3 Word export — Quarto render

The Sphinx ecosystem does not have a maintained docx builder compatible with current Sphinx versions. The project report (quarto/report.qmd) is exported to Word via Quarto, which uses Pandoc internally and produces clean, fully formatted Word documents.

How to build:

quarto render quarto/report.qmd --to docx --output-dir docs/_build

Output: docs/_build/report.docx

This is also available as VS Code Task 10 — Quarto Render Report (docx).


4 Autodoc output preview

import inspect
import rag.query as q

# Show the public API extracted by sphinx autodoc
public_fns = [(name, obj) for name, obj in inspect.getmembers(q, inspect.isfunction)
              if not name.startswith("_")]

for name, fn in public_fns:
    sig = inspect.signature(fn)
    doc_first_line = (inspect.getdoc(fn) or "").split("\n")[0]
    print(f"rag.query.{name}{sig}")
    print(f"  {doc_first_line}")
    print()
rag.query.ask(chain, question: 'str', *, log_path: 'str | Path | None' = None, fallback_llm=None) -> 'dict'
  Run a question through the RAG chain and return answer, sources, scores, and confidence.

rag.query.build_rag_chain(vectorstore, model: 'str' = 'llama3.2', k: 'int' = 4, score_threshold: 'float' = 0.0)
  Build a LangChain LCEL RAG chain with optional similarity-score filtering.

rag.query.confidence_signal(answer: 'str', sources: 'list[dict]', scores: 'list[float] | None' = None, used_fallback: 'bool' = False) -> 'dict'
  Return a lightweight confidence estimate based on answer, sources, and scores.

rag.query.load_chromadb(chroma_dir: str = './chroma_db', ollama_model: str = 'nomic-embed-text') -> langchain_chroma.vectorstores.Chroma
  Load an existing ChromaDB vector store.

rag.query.load_vectorstore(persist_dir: 'str | Path' = 'chroma_db', ollama_model: 'str' = 'nomic-embed-text')
  Load an existing ChromaDB vectorstore from disk.
Code
import rag.logger as lg

public_fns = [(name, obj) for name, obj in inspect.getmembers(lg, inspect.isfunction)
              if not name.startswith("_")]

for name, fn in public_fns:
    sig = inspect.signature(fn)
    doc_first_line = (inspect.getdoc(fn) or "").split("\n")[0]
    print(f"rag.logger.{name}{sig}")
    print(f"  {doc_first_line}")
    print()
rag.logger.is_failed_query(answer: 'str') -> 'bool'
  Return True when the model admitted it could not answer from context.

rag.logger.load_log(path: 'str | Path' = PosixPath('logs/query_log.jsonl')) -> 'list[dict]'
  Read a JSONL query log back into a list of dicts.

rag.logger.log_query(question: 'str', answer: 'str', sources: 'list[dict]', path: 'str | Path' = PosixPath('logs/query_log.jsonl')) -> 'Path'
  Append one query result to a JSONL log file.

rag.logger.replay_failed(path: 'str | Path' = PosixPath('logs/query_log.jsonl')) -> 'list[dict]'
  Return only the entries where ``failed`` is ``True``.

5 Build status

Code
import subprocess, sys

def check_sphinx():
    result = subprocess.run(
        [sys.executable, "-c", "import sphinx; print(sphinx.__version__)"],
        capture_output=True, text=True
    )
    return result.stdout.strip() if result.returncode == 0 else "not installed"

def check_myst():
    result = subprocess.run(
        [sys.executable, "-c", "import myst_parser; print(myst_parser.__version__)"],
        capture_output=True, text=True
    )
    return result.stdout.strip() if result.returncode == 0 else "not installed"

print(f"Sphinx version   : {check_sphinx()}")
print(f"myst-parser      : {check_myst()}")
print(f"Output directory : docs/_build/html/")
print(f"Word export      : docs/_build/report.docx")
print(f"Build command    : sphinx-build -b html docs/_source docs/_build/html")
Sphinx version   : 9.0.4
myst-parser      : 5.1.0
Output directory : docs/_build/html/
Word export      : docs/_build/report.docx
Build command    : sphinx-build -b html docs/_source docs/_build/html

6 Note on Sphinx docx builders

The sphinxcontrib-docxbuilder package listed in the original pyproject.toml does not exist on PyPI. The alternative sphinx-docxbuilder package (2019) is incompatible with Sphinx 7+. Word export is therefore handled by Quarto/Pandoc, which produces better output and requires no additional dependencies beyond Quarto itself.

The sphinxcontrib-docxbuilder entry has been removed from pyproject.toml and from docs/_source/conf.py. The VS Code task has been updated accordingly.