docs (naas_abi_cli.cli.docs)
What it is
CLI tooling to detect stale/missing markdown reference docs for a Python source tree and optionally regenerate them using DocumentationAgent. Includes helpers for file discovery, staleness checks, OpenAI API key resolution, and parallel doc generation.
Public API
Data types
-
RegenerationReason = Literal["missing", "outdated"]
Reason a markdown file should be regenerated. -
@dataclass DocSyncItemsource_file: Path— Python source file.target_file: Path— Expected markdown output path.reason: RegenerationReason—"missing"or"outdated".
Functions
-
iter_python_files(source_root: Path, include_tests: bool = False) -> list[Path]
Recursively lists.pyfiles undersource_root, skipping:- directories:
.git,.venv,venv,__pycache__,.mypy_cache,.pytest_cache,node_modules __init__.py- test files unless
include_tests=True(files namedtest_*.pyor*_test.py)
- directories:
-
target_markdown_path(source_file: Path, source_root: Path, output_root: Path) -> Path
Maps a source file to its markdown path by preserving relative path and replacing suffix with.md. -
needs_regeneration(source_file: Path, target_file: Path) -> tuple[bool, RegenerationReason | None]
Returns whether regeneration is needed:(True, "missing")if target does not exist(True, "outdated")if target mtime < source mtime(False, None)otherwise
-
collect_docs_to_regenerate(source_root: Path, output_root: Path, include_tests: bool = False) -> list[DocSyncItem]
Builds a list ofDocSyncItementries for files whose docs are missing/outdated. -
resolve_openai_api_key() -> str | None
ResolvesOPENAI_API_KEY:- from environment (
os.getenv) - else from local
.envfile (supportsexport KEY=..., comments, and quoted values) - if found in
.env, also setsos.environ["OPENAI_API_KEY"]
- from environment (
-
generate_documentation_for_items(stale_docs: list[DocSyncItem], model: str, workers: int = 10) -> int
UsesDocumentationAgent(model=...)togenerate_and_write(source_file, target_file)for each item.- Runs sequentially if effective worker count is 1
- Otherwise runs in a
ThreadPoolExecutor - Raises
ValueErrorifworkers < 1 - Raises
RuntimeErrorif any file generation fails (shows up to 10 errors) - Returns number of successfully generated files
Click CLI
-
docs— click group nameddocs. -
docs sync(sync_docs(...)) — detects stale docs and optionally generates them. Options:--source PATH(defaultlibs/naas-abi-core/naas_abi_core) — source root directory--output PATH(defaultdocs/reference) — docs output root directory--include-tests— include test files in checks--fail-on-stale— exit non-zero (raisesclick.ClickException) if stale docs exist and--generateis not used--generate— regenerate docs usingDocumentationAgent(requiresOPENAI_API_KEY)--model TEXT(defaultgpt-5.2) — model id passed toDocumentationAgent--workers INT(default10, min1) — parallelism for generation
Configuration/Dependencies
- Environment:
OPENAI_API_KEYrequired only when runningdocs sync --generate- alternatively, a local
.envfile withOPENAI_API_KEY=...(optionallyexport OPENAI_API_KEY=...)
- Python packages:
clicknaas_abi_cli.docs_builder.DocumentationAgent
- Uses filesystem mtimes for staleness detection.
Usage
As a CLI command
# Check for missing/outdated docs (no generation)
python -m naas_abi_cli.cli docs sync --source libs/naas-abi-core/naas_abi_core --output docs/reference
# Generate stale docs (requires OPENAI_API_KEY)
export OPENAI_API_KEY="..."
python -m naas_abi_cli.cli docs sync --generate --workers 4
As a Python module
from pathlib import Path
from naas_abi_cli.cli.docs import collect_docs_to_regenerate, generate_documentation_for_items
stale = collect_docs_to_regenerate(
source_root=Path("libs/naas-abi-core/naas_abi_core"),
output_root=Path("docs/reference"),
)
if stale:
generate_documentation_for_items(stale_docs=stale, model="gpt-5.2", workers=4)
Caveats
- Staleness is based solely on file modification times; content changes without mtime updates won’t be detected.
- Generation failures across threads are aggregated and raised as a single
RuntimeError(up to 10 error details shown). - When
--generateis used, missingOPENAI_API_KEYcauses aclick.ClickException.