From bacf17b93057a2c10a97c642eb56821f9f8af48a Mon Sep 17 00:00:00 2001 From: Vishesh 'ironeagle' Bangotra Date: Fri, 11 Sep 2026 05:37:56 +0530 Subject: [PATCH] feat: add --api OpenAPI build mode with docs/api scheme and lib-prefixed nav --- docforge.nav.yml | 44 +-- docforge/cli/api_utils.py | 114 ++++++++ docforge/cli/api_utils.pyi | 13 + docforge/cli/commands.py | 98 +++++-- docforge/cli/commands.pyi | 2 + docforge/cli/mkdocs_utils.py | 169 ++++++++++- docforge/cli/mkdocs_utils.pyi | 11 +- docforge/nav/spec.py | 19 +- docforge/templates/mkdocs.api.yml | 16 + .../{mkdocs.sample.yml => mkdocs.common.yml} | 24 +- docforge/templates/mkdocs.lib.yml | 19 ++ docs/lib/cli/api_utils.md | 3 + docs/mcp/index.json | 2 +- docs/mcp/modules/docforge.cli.api_utils.json | 102 +++++++ docs/mcp/modules/docforge.cli.commands.json | 119 +++++++- docs/mcp/modules/docforge.cli.json | 238 ++++++++++++++- .../modules/docforge.cli.mkdocs_utils.json | 17 +- docs/mcp/modules/docforge.json | 273 ++++++++++++++++-- docs/mcp/modules/docforge.nav.json | 35 ++- docs/mcp/modules/docforge.nav.resolver.json | 9 +- docs/mcp/modules/docforge.nav.spec.json | 17 +- docs/mcp/nav.json | 4 + mkdocs.yml | 89 +++--- pyproject.toml | 1 + tests/cli/test_build_api.py | 134 +++++++++ tests/cli/test_build_mkdocs.py | 6 +- 26 files changed, 1404 insertions(+), 174 deletions(-) create mode 100644 docforge/cli/api_utils.py create mode 100644 docforge/cli/api_utils.pyi create mode 100644 docforge/templates/mkdocs.api.yml rename docforge/templates/{mkdocs.sample.yml => mkdocs.common.yml} (62%) create mode 100644 docforge/templates/mkdocs.lib.yml create mode 100644 docs/lib/cli/api_utils.md create mode 100644 docs/mcp/modules/docforge.cli.api_utils.json create mode 100644 tests/cli/test_build_api.py diff --git a/docforge.nav.yml b/docforge.nav.yml index c152294..0e87587 100644 --- a/docforge.nav.yml +++ b/docforge.nav.yml @@ -1,26 +1,30 @@ -home: index.md +home: lib/index.md groups: Loaders: - - loaders/index.md - - loaders/griffe_loader.md + - lib/loaders/index.md + - lib/loaders/griffe_loader.md Models: - - models/index.md - - models/module.md - - models/object.md - - models/project.md + - lib/models/index.md + - lib/models/module.md + - lib/models/object.md + - lib/models/project.md Navigation: - - nav/index.md - - nav/spec.md - - nav/resolver.md - - nav/mkdocs.md + - lib/nav/index.md + - lib/nav/spec.md + - lib/nav/resolver.md + - lib/nav/mkdocs.md Renderers: - - renderers/index.md - - renderers/base.md - - renderers/mkdocs_renderer.md - - renderers/mcp_renderer.md + - lib/renderers/index.md + - lib/renderers/base.md + - lib/renderers/mkdocs_renderer.md + - lib/renderers/mcp_renderer.md CLI: - - cli/index.md - - cli/main.md - - cli/commands.md - - cli/mcp_utils.md - - cli/mkdocs_utils.md + - lib/cli/index.md + - lib/cli/main.md + - lib/cli/commands.md + - lib/cli/api_utils.md + - lib/cli/mcp_utils.md + - lib/cli/mkdocs_utils.md +icon: + logo: material/file-document-multiple + repo: fontawesome/brands/github \ No newline at end of file diff --git a/docforge/cli/api_utils.py b/docforge/cli/api_utils.py new file mode 100644 index 0000000..cb760c7 --- /dev/null +++ b/docforge/cli/api_utils.py @@ -0,0 +1,114 @@ +""" +# Summary + +Utilities for building API documentation from an OpenAPI specification. +""" + +import json +from dataclasses import dataclass +from pathlib import Path + +import click + +SWAGGER_SPEC_FILENAME = "openapi.json" + + +@dataclass +class OpenAPIMetadata: + """ + Metadata derived from the ``info`` block of an OpenAPI specification. + + Attributes: + site_name: Spec title, used as the MkDocs site name. + site_description: Spec description, used as the site description. + site_author: Contact name (fallback: contact email), used as the + site author. + """ + + site_name: str + site_description: str | None + site_author: str | None + + +def load_openapi_spec(spec_path: Path) -> dict: + """ + Load and validate an OpenAPI specification from a JSON file. + + Args: + spec_path: Path to the OpenAPI JSON specification file. + + Returns: + dict: + The parsed OpenAPI specification. + + Raises: + click.ClickException: + If the file cannot be read or the ``info`` block is invalid. + """ + if not spec_path.exists(): + raise click.ClickException(f"OpenAPI spec not found: {spec_path}") + + try: + data = json.loads(spec_path.read_text(encoding="utf-8")) + except (json.JSONDecodeError, OSError) as exc: + raise click.ClickException(f"Unable to read OpenAPI spec: {exc}") from exc + + if not isinstance(data, dict): + raise click.ClickException("OpenAPI spec must be a JSON mapping") + + info = data.get("info") + if not isinstance(info, dict) or not isinstance(info.get("title"), str): + raise click.ClickException("OpenAPI spec missing 'info.title'") + + return data + + +def derive_metadata(spec: dict) -> OpenAPIMetadata: + """ + Derive MkDocs site metadata from an OpenAPI spec ``info`` block. + + Args: + spec: Parsed OpenAPI specification. + + Returns: + OpenAPIMetadata: + Site name, description, and author derived from the spec. + """ + info = spec["info"] + + contact = info.get("contact") + if isinstance(contact, dict): + author = contact.get("name") or contact.get("email") + else: + author = None + + return OpenAPIMetadata( + site_name=info.get("title", ""), + site_description=info.get("description"), + site_author=author, + ) + + +def generate_api_sources(spec: dict, docs_dir: Path) -> None: + """ + Generate swagger-enabled Markdown sources and the spec copy. + + The specification is written as ``openapi.json`` inside ``docs_dir`` and + an ``index.md`` embedding the swagger UI is generated alongside it. + + Args: + spec: Parsed OpenAPI specification. + docs_dir: Directory (for example ``docs/api``) where the swagger + sources are written. + """ + docs_dir.mkdir(parents=True, exist_ok=True) + + spec_path = docs_dir / SWAGGER_SPEC_FILENAME + spec_json = json.dumps(spec, indent=2) + if not spec_path.exists() or spec_path.read_text(encoding="utf-8") != spec_json: + spec_path.write_text(spec_json, encoding="utf-8") + + index_path = docs_dir / "index.md" + content = "# API Reference\n\n" f'\n' + if not index_path.exists() or index_path.read_text(encoding="utf-8") != content: + index_path.write_text(content, encoding="utf-8") diff --git a/docforge/cli/api_utils.pyi b/docforge/cli/api_utils.pyi new file mode 100644 index 0000000..f7c1f13 --- /dev/null +++ b/docforge/cli/api_utils.pyi @@ -0,0 +1,13 @@ +from dataclasses import dataclass +from pathlib import Path +from typing import Any + +@dataclass +class OpenAPIMetadata: + site_name: str + site_description: str | None + site_author: str | None + +def load_openapi_spec(spec_path: Path) -> dict[Any, Any]: ... +def derive_metadata(spec: dict[Any, Any]) -> OpenAPIMetadata: ... +def generate_api_sources(spec: dict[Any, Any], docs_dir: Path) -> None: ... diff --git a/docforge/cli/commands.py b/docforge/cli/commands.py index 1bf8491..05ca0b6 100644 --- a/docforge/cli/commands.py +++ b/docforge/cli/commands.py @@ -10,7 +10,7 @@ from pathlib import Path import click -from docforge.cli import mcp_utils, mkdocs_utils +from docforge.cli import api_utils, mcp_utils, mkdocs_utils from docforge.loaders import GriffeLoader @@ -28,19 +28,25 @@ def cli() -> None: @cli.command() @click.option("--mcp", is_flag=True, help="Build MCP resources") @click.option("--mkdocs", is_flag=True, help="Build MkDocs site") +@click.option("--api", is_flag=True, help="Build API docs from an OpenAPI spec") @click.option( "--module-is-source", is_flag=True, help="Module is source folder and to be treated as root folder", ) @click.option("--module", help="Python module to document") +@click.option( + "--openapi-spec", + type=click.Path(path_type=Path), + help="Path to the OpenAPI JSON specification", +) @click.option("--project-name", help="Project name override") @click.option("--site-name", help="MkDocs site name") @click.option( "--docs-dir", type=click.Path(path_type=Path), - default=Path("docs/lib"), - help="Directory for MD sources", + default=Path("docs"), + help="MkDocs documentation root", ) @click.option( "--nav", @@ -67,8 +73,10 @@ def cli() -> None: def build( mcp: bool, mkdocs: bool, + api: bool, module_is_source: bool, module: str | None, + openapi_spec: Path | None, project_name: str | None, site_name: str | None, docs_dir: Path, @@ -81,14 +89,13 @@ def build( Build documentation artifacts. This command performs the full documentation build pipeline: - - 1. Introspects the Python project using Griffe - 2. Generates renderer-specific documentation sources - 3. Optionally builds the final documentation output + style of the selected platform, generates renderer-specific + documentation sources, and optionally builds the final output. Depending on the selected options, the build can target: - - MkDocs static documentation sites + - MkDocs static documentation sites for library reference docs + - Swagger-enabled API docs generated from an OpenAPI spec - MCP structured documentation resources Args: @@ -96,7 +103,10 @@ def build( Enable MCP documentation generation. mkdocs (bool): - Enable MkDocs documentation generation. + Enable MkDocs library documentation generation. + + api (bool): + Enable API documentation generation from an OpenAPI spec. module_is_source (bool): Treat the specified module directory as the project root. @@ -104,6 +114,9 @@ def build( module (Optional[str]): Python module import path to document. + openapi_spec (Optional[Path]): + Path to the OpenAPI JSON specification used for API docs. + project_name (Optional[str]): Optional override for the project name. @@ -111,7 +124,7 @@ def build( Display name for the MkDocs site. docs_dir (Path): - Directory where Markdown documentation sources will be generated. + Shared documentation root used as the MkDocs ``docs_dir``. nav_file (Path): Path to the navigation specification file. @@ -129,27 +142,72 @@ def build( click.UsageError: If required options are missing or conflicting. """ - if not mcp and not mkdocs: - raise click.UsageError("Must specify either --mcp or --mkdocs") + if not mcp and not mkdocs and not api: + raise click.UsageError("Must specify either --mcp, --mkdocs, or --api") + + if api: + if not openapi_spec: + raise click.UsageError("--openapi-spec is required for API build") + if site_name and not mkdocs: + raise click.UsageError( + "--site-name cannot be overridden for API build; " + "the OpenAPI spec provides the site name" + ) + + if (mkdocs or mcp) and not module: + raise click.UsageError( + "--module is required for MkDocs build" + if mkdocs + else "--module is required for MCP build" + ) + + spec: dict | None = None + if api: + spec = api_utils.load_openapi_spec(openapi_spec) if mkdocs: - if not module: - raise click.UsageError("--module is required for MkDocs build") - if not site_name: - site_name = module - - click.echo(f"Generating MkDocs sources in {docs_dir}...") + lib_dir = docs_dir / "lib" + click.echo(f"Generating MkDocs sources in {lib_dir}...") mkdocs_utils.generate_sources( module, - docs_dir, + lib_dir, project_name, module_is_source, readme_dir=mkdocs_yml.parent, ) + if api: + api_dir = docs_dir / "api" + click.echo(f"Generating API sources in {api_dir}...") + api_utils.generate_api_sources(spec, api_dir) + + if mkdocs or api: + modes: list[str] = [] + if mkdocs: + modes.append("lib") + if api: + modes.append("api") + + site_description: str | None = None + site_author: str | None = None + effective_site_name = site_name or module + + if api: + metadata = api_utils.derive_metadata(spec) + effective_site_name = metadata.site_name + site_description = metadata.site_description + site_author = metadata.site_author + click.echo(f"Generating MkDocs config {mkdocs_yml}...") mkdocs_utils.generate_config( - docs_dir, nav_file, template, mkdocs_yml, site_name + docs_dir, + nav_file, + template, + mkdocs_yml, + effective_site_name, + modes=modes, + site_description=site_description, + site_author=site_author, ) click.echo("Running MkDocs build...") diff --git a/docforge/cli/commands.pyi b/docforge/cli/commands.pyi index 0c1f1ec..1638a22 100644 --- a/docforge/cli/commands.pyi +++ b/docforge/cli/commands.pyi @@ -8,8 +8,10 @@ cli: Group def build( mcp: bool, mkdocs: bool, + api: bool, module_is_source: bool, module: str | None, + openapi_spec: Path | None, project_name: str | None, site_name: str | None, docs_dir: Path, diff --git a/docforge/cli/mkdocs_utils.py b/docforge/cli/mkdocs_utils.py index 5ab4d4d..da0d63e 100644 --- a/docforge/cli/mkdocs_utils.py +++ b/docforge/cli/mkdocs_utils.py @@ -5,6 +5,7 @@ Utilities for working with MkDocs in the doc-forge CLI. """ import os +from collections.abc import Iterable from importlib import resources from pathlib import Path @@ -74,6 +75,9 @@ def generate_config( template: Path | None, out: Path, site_name: str, + modes: Iterable[str] | None = None, + site_description: str | None = None, + site_author: str | None = None, ) -> None: """ Generate an `mkdocs.yml` configuration file. @@ -82,16 +86,21 @@ def generate_config( with a navigation structure derived from the docforge navigation specification. + The ``docs_dir`` is always written relative to the MkDocs root and is + expected to be the shared documentation parent (for example ``docs``), + with generated sources nested under ``lib/`` or ``api/`` subdirectories. + Args: docs_dir (Path): - Directory containing generated documentation Markdown files. + Shared documentation root used as the MkDocs ``docs_dir``. nav_file (Path): Path to the `docforge.nav.yml` navigation specification. template (Optional[Path]): - Optional path to a custom MkDocs configuration template. If not - provided, a built-in template will be used. + Optional path to a fully custom MkDocs configuration template. + If not provided, built-in templates are merged; the provided + template replaces the built-in templates entirely. out (Path): Destination path where the generated `mkdocs.yml` file will be written. @@ -99,6 +108,17 @@ def generate_config( site_name (str): Display name for the generated documentation site. + modes (Optional[Iterable[str]]): + Documentation modes to enable. Each mode contributes its own + built-in template fragment (for example ``lib`` or ``api``), + merged on top of the shared ``mkdocs.common.yml`` template. + + site_description (Optional[str]): + Optional site description written into the configuration. + + site_author (Optional[str]): + Optional site author written into the configuration. + Raises: click.FileError: If the navigation specification or template file cannot be found. @@ -110,26 +130,145 @@ def generate_config( resolved = resolve_nav(spec, docs_dir) nav_block = MkDocsNavEmitter().emit(resolved) - # Load template - if template is not None: - if not template.exists(): - raise click.FileError(str(template), hint="Template not found") - data = yaml.safe_load(template.read_text(encoding="utf-8")) - else: - text = ( - resources.files("docforge.templates") - .joinpath("mkdocs.sample.yml") - .read_text(encoding="utf-8") - ) - data = yaml.safe_load(text) + data = _load_template(template, modes) data["site_name"] = site_name + if site_description: + data["site_description"] = site_description + if site_author: + data["site_author"] = site_author data["docs_dir"] = Path(os.path.relpath(docs_dir, out.parent)).as_posix() data["nav"] = nav_block + if spec.icon: + theme = data.setdefault("theme", {}) + if not isinstance(theme, dict): + theme = {} + theme["icon"] = spec.icon + data["theme"] = theme + out.write_text(yaml.safe_dump(data, sort_keys=False), encoding="utf-8") +def _load_template( + template: Path | None, + modes: Iterable[str] | None, +) -> dict: + """ + Load the MkDocs configuration template. + + When a custom template path is provided, it is used as-is. Otherwise the + shared ``mkdocs.common.yml`` template is deep-merged with the fragments + contributed by each enabled mode (``lib`` or ``api``). + + Args: + template (Optional[Path]): + Optional fully custom template that replaces the built-ins. + + modes (Optional[Iterable[str]]): + Documentation modes whose template fragments should be merged. + + Returns: + dict: + Merged MkDocs configuration mapping. + + Raises: + click.FileError: + If a referenced template file cannot be found. + """ + if template is not None: + if not template.exists(): + raise click.FileError(str(template), hint="Template not found") + return yaml.safe_load(template.read_text(encoding="utf-8")) + + data: dict = {} + active_modes = list(modes) if modes else ["lib"] + parts = ["common", *active_modes] + + seen: set[str] = set() + for part_name in parts: + if part_name in seen: + continue + seen.add(part_name) + + text = ( + resources.files("docforge.templates") + .joinpath(f"mkdocs.{part_name}.yml") + .read_text(encoding="utf-8") + ) + part: dict = yaml.safe_load(text) + data = _deep_merge(data, part) + + return data + + +def _item_name(item: object) -> str: + """ + Return the identifying name of a list entry. + + String entries identify as themselves; mapping entries identify by their + first key. This is used to deduplicate plugin and extension lists. + + Args: + item: List entry, either a string or a single-key mapping. + + Returns: + str: + The identifying name of the entry. + """ + if isinstance(item, dict): + return next(iter(item.keys()), "") + return str(item) + + +def _merge_list(base: list, added: list) -> list: + """ + Merge two lists, preserving order and dropping duplicates by name. + + Args: + base: Existing list entries. + added: Entries to append when not already present. + + Returns: + list: + Merged list with duplicates removed. + """ + result = list(base) + names = {_item_name(item) for item in result} + for item in added: + name = _item_name(item) + if name not in names: + result.append(item) + names.add(name) + return result + + +def _deep_merge(base: dict, part: dict) -> dict: + """ + Deep merge a template fragment into a base configuration. + + Mappings are merged recursively, while lists are combined by + deduplicating entries by their identifying name. Non-container values in + the fragment override the base. + + Args: + base: Configuration being built up. + part: Template fragment to merge into the base. + + Returns: + dict: + The merged configuration. + """ + for key, value in part.items(): + if isinstance(value, dict) and isinstance(base.get(key), dict): + base[key] = _deep_merge(base[key], value) + elif isinstance(value, list) and isinstance(base.get(key), list): + base[key] = _merge_list(base[key], value) + else: + base[key] = value + return base + + def build(mkdocs_yml: Path) -> None: """ Build the MkDocs documentation site. diff --git a/docforge/cli/mkdocs_utils.pyi b/docforge/cli/mkdocs_utils.pyi index c239ccb..a7e4613 100644 --- a/docforge/cli/mkdocs_utils.pyi +++ b/docforge/cli/mkdocs_utils.pyi @@ -1,3 +1,4 @@ +from collections.abc import Iterable from pathlib import Path def generate_sources( @@ -5,9 +6,17 @@ def generate_sources( docs_dir: Path, project_name: str | None = None, module_is_source: bool | None = None, + readme_dir: Path | None = None, ) -> None: ... def generate_config( - docs_dir: Path, nav_file: Path, template: Path | None, out: Path, site_name: str + docs_dir: Path, + nav_file: Path, + template: Path | None, + out: Path, + site_name: str, + modes: Iterable[str] | None = None, + site_description: str | None = None, + site_author: str | None = None, ) -> None: ... def build(mkdocs_yml: Path) -> None: ... def serve(mkdocs_yml: Path) -> None: ... diff --git a/docforge/nav/spec.py b/docforge/nav/spec.py index dd87b37..bcbf8a8 100644 --- a/docforge/nav/spec.py +++ b/docforge/nav/spec.py @@ -23,12 +23,16 @@ class NavSpec: ``index.md``). groups: Mapping of navigation group titles to lists of file patterns or glob expressions. + icon: Optional mapping of theme icon entries (for example + ``{"logo": "material/code-tags"}``) injected into the MkDocs + theme as ``theme.icon``. """ def __init__( self, home: str | None, groups: dict[str, list[str]], + icon: dict[str, str] | None = None, ) -> None: """ Initialize a NavSpec instance. @@ -37,9 +41,12 @@ class NavSpec: home: Relative path to the home document. groups: Mapping of group names to lists of path patterns (glob expressions). + icon: Optional mapping of theme icon entries applied to the + generated MkDocs configuration. """ self.home = home self.groups = groups + self.icon = icon @classmethod def load(cls, path: Path) -> "NavSpec": @@ -67,6 +74,7 @@ class NavSpec: home = data.get("home") groups = data.get("groups", {}) + icon = data.get("icon") if home is not None and not isinstance(home, str): raise ValueError("home must be a string") @@ -82,7 +90,15 @@ class NavSpec: ): raise ValueError(f"group '{key}' must be a list of strings") - return cls(home=home, groups=groups) + if icon is not None and ( + not isinstance(icon, dict) + or not all( + isinstance(k, str) and isinstance(v, str) for k, v in icon.items() + ) + ): + raise ValueError("icon must be a mapping of strings") + + return cls(home=home, groups=groups, icon=icon) def all_patterns(self) -> list[str]: """ @@ -131,4 +147,5 @@ def load_nav_spec(path: Path) -> NavSpec: return NavSpec( home=data.get("home"), groups=data.get("groups", {}), + icon=data.get("icon"), ) diff --git a/docforge/templates/mkdocs.api.yml b/docforge/templates/mkdocs.api.yml new file mode 100644 index 0000000..89cfd3e --- /dev/null +++ b/docforge/templates/mkdocs.api.yml @@ -0,0 +1,16 @@ +theme: + features: + - toc.integrate + - header.autohide + - announce.dismiss + - footer.social + + - content.code.select + - content.code.line_numbers + - content.tooltips + +plugins: + - search + - swagger-ui-tag + - neoteroi.mkdocsoad: + use_pymdownx: true \ No newline at end of file diff --git a/docforge/templates/mkdocs.sample.yml b/docforge/templates/mkdocs.common.yml similarity index 62% rename from docforge/templates/mkdocs.sample.yml rename to docforge/templates/mkdocs.common.yml index 3d17c33..39bcadd 100644 --- a/docforge/templates/mkdocs.sample.yml +++ b/docforge/templates/mkdocs.common.yml @@ -29,26 +29,6 @@ theme: - search.share - search.suggest -plugins: - - search - - mkdocstrings: - handlers: - python: - paths: ["."] - options: - docstring_style: google - show_source: false - show_signature_annotations: true - separate_signature: true - merge_init_into_class: true - inherited_members: true - annotations_path: brief - show_root_heading: true - group_by_category: true - show_category_heading: true - show_object_full_path: false - show_symbol_type_heading: true - markdown_extensions: - pymdownx.superfences - pymdownx.inlinehilite @@ -57,7 +37,6 @@ markdown_extensions: - admonition - pymdownx.details - - pymdownx.superfences - pymdownx.highlight: linenums: true anchor_linenums: true @@ -76,3 +55,6 @@ markdown_extensions: - pymdownx.caret - pymdownx.tilde - pymdownx.mark + +extra_css: + - https://unpkg.com/dracula-prism/dist/css/dracula-prism.css \ No newline at end of file diff --git a/docforge/templates/mkdocs.lib.yml b/docforge/templates/mkdocs.lib.yml new file mode 100644 index 0000000..431d4ba --- /dev/null +++ b/docforge/templates/mkdocs.lib.yml @@ -0,0 +1,19 @@ +plugins: + - search + - mkdocstrings: + handlers: + python: + paths: ["."] + options: + docstring_style: google + show_source: false + show_signature_annotations: true + separate_signature: true + merge_init_into_class: true + inherited_members: true + annotations_path: brief + show_root_heading: true + group_by_category: true + show_category_heading: true + show_object_full_path: false + show_symbol_type_heading: true \ No newline at end of file diff --git a/docs/lib/cli/api_utils.md b/docs/lib/cli/api_utils.md new file mode 100644 index 0000000..62040b8 --- /dev/null +++ b/docs/lib/cli/api_utils.md @@ -0,0 +1,3 @@ +# Api Utils + +::: docforge.cli.api_utils diff --git a/docs/mcp/index.json b/docs/mcp/index.json index 22bf131..9055418 100644 --- a/docs/mcp/index.json +++ b/docs/mcp/index.json @@ -1,6 +1,6 @@ { "project": "docforge", "type": "docforge-model", - "modules_count": 22, + "modules_count": 23, "source": "docforge" } \ No newline at end of file diff --git a/docs/mcp/modules/docforge.cli.api_utils.json b/docs/mcp/modules/docforge.cli.api_utils.json new file mode 100644 index 0000000..547c81a --- /dev/null +++ b/docs/mcp/modules/docforge.cli.api_utils.json @@ -0,0 +1,102 @@ +{ + "module": "docforge.cli.api_utils", + "content": { + "path": "docforge.cli.api_utils", + "docstring": "# Summary\n\nUtilities for building API documentation from an OpenAPI specification.", + "objects": { + "json": { + "name": "json", + "kind": "alias", + "path": "docforge.cli.api_utils.json", + "signature": "", + "docstring": null + }, + "dataclass": { + "name": "dataclass", + "kind": "alias", + "path": "docforge.cli.api_utils.dataclass", + "signature": "", + "docstring": null + }, + "Path": { + "name": "Path", + "kind": "alias", + "path": "docforge.cli.api_utils.Path", + "signature": "", + "docstring": null + }, + "click": { + "name": "click", + "kind": "alias", + "path": "docforge.cli.api_utils.click", + "signature": "", + "docstring": null + }, + "SWAGGER_SPEC_FILENAME": { + "name": "SWAGGER_SPEC_FILENAME", + "kind": "attribute", + "path": "docforge.cli.api_utils.SWAGGER_SPEC_FILENAME", + "signature": null, + "docstring": null + }, + "OpenAPIMetadata": { + "name": "OpenAPIMetadata", + "kind": "class", + "path": "docforge.cli.api_utils.OpenAPIMetadata", + "signature": "", + "docstring": "Metadata derived from the ``info`` block of an OpenAPI specification.\n\nAttributes:\n site_name: Spec title, used as the MkDocs site name.\n site_description: Spec description, used as the site description.\n site_author: Contact name (fallback: contact email), used as the\n site author.", + "members": { + "site_name": { + "name": "site_name", + "kind": "attribute", + "path": "docforge.cli.api_utils.OpenAPIMetadata.site_name", + "signature": null, + "docstring": null + }, + "site_description": { + "name": "site_description", + "kind": "attribute", + "path": "docforge.cli.api_utils.OpenAPIMetadata.site_description", + "signature": null, + "docstring": null + }, + "site_author": { + "name": "site_author", + "kind": "attribute", + "path": "docforge.cli.api_utils.OpenAPIMetadata.site_author", + "signature": null, + "docstring": null + } + } + }, + "load_openapi_spec": { + "name": "load_openapi_spec", + "kind": "function", + "path": "docforge.cli.api_utils.load_openapi_spec", + "signature": "", + "docstring": "Load and validate an OpenAPI specification from a JSON file.\n\nArgs:\n spec_path: Path to the OpenAPI JSON specification file.\n\nReturns:\n dict:\n The parsed OpenAPI specification.\n\nRaises:\n click.ClickException:\n If the file cannot be read or the ``info`` block is invalid." + }, + "derive_metadata": { + "name": "derive_metadata", + "kind": "function", + "path": "docforge.cli.api_utils.derive_metadata", + "signature": "", + "docstring": "Derive MkDocs site metadata from an OpenAPI spec ``info`` block.\n\nArgs:\n spec: Parsed OpenAPI specification.\n\nReturns:\n OpenAPIMetadata:\n Site name, description, and author derived from the spec." + }, + "generate_api_sources": { + "name": "generate_api_sources", + "kind": "function", + "path": "docforge.cli.api_utils.generate_api_sources", + "signature": "", + "docstring": "Generate swagger-enabled Markdown sources and the spec copy.\n\nThe specification is written as ``openapi.json`` inside ``docs_dir`` and\nan ``index.md`` embedding the swagger UI is generated alongside it.\n\nArgs:\n spec: Parsed OpenAPI specification.\n docs_dir: Directory (for example ``docs/api``) where the swagger\n sources are written." + }, + "Any": { + "name": "Any", + "kind": "alias", + "path": "docforge.cli.api_utils.Any", + "signature": "", + "docstring": null + } + } + } +} \ No newline at end of file diff --git a/docs/mcp/modules/docforge.cli.commands.json b/docs/mcp/modules/docforge.cli.commands.json index 66e93c2..5397439 100644 --- a/docs/mcp/modules/docforge.cli.commands.json +++ b/docs/mcp/modules/docforge.cli.commands.json @@ -18,6 +18,108 @@ "signature": "", "docstring": null }, + "api_utils": { + "name": "api_utils", + "kind": "module", + "path": "docforge.cli.commands.api_utils", + "signature": "", + "docstring": "# Summary\n\nUtilities for building API documentation from an OpenAPI specification.", + "members": { + "json": { + "name": "json", + "kind": "alias", + "path": "docforge.cli.commands.api_utils.json", + "signature": "", + "docstring": null + }, + "dataclass": { + "name": "dataclass", + "kind": "alias", + "path": "docforge.cli.commands.api_utils.dataclass", + "signature": "", + "docstring": null + }, + "Path": { + "name": "Path", + "kind": "alias", + "path": "docforge.cli.commands.api_utils.Path", + "signature": "", + "docstring": null + }, + "click": { + "name": "click", + "kind": "alias", + "path": "docforge.cli.commands.api_utils.click", + "signature": "", + "docstring": null + }, + "SWAGGER_SPEC_FILENAME": { + "name": "SWAGGER_SPEC_FILENAME", + "kind": "attribute", + "path": "docforge.cli.commands.api_utils.SWAGGER_SPEC_FILENAME", + "signature": "", + "docstring": null + }, + "OpenAPIMetadata": { + "name": "OpenAPIMetadata", + "kind": "class", + "path": "docforge.cli.commands.api_utils.OpenAPIMetadata", + "signature": "", + "docstring": "Metadata derived from the ``info`` block of an OpenAPI specification.\n\nAttributes:\n site_name: Spec title, used as the MkDocs site name.\n site_description: Spec description, used as the site description.\n site_author: Contact name (fallback: contact email), used as the\n site author.", + "members": { + "site_name": { + "name": "site_name", + "kind": "attribute", + "path": "docforge.cli.commands.api_utils.OpenAPIMetadata.site_name", + "signature": "", + "docstring": null + }, + "site_description": { + "name": "site_description", + "kind": "attribute", + "path": "docforge.cli.commands.api_utils.OpenAPIMetadata.site_description", + "signature": "", + "docstring": null + }, + "site_author": { + "name": "site_author", + "kind": "attribute", + "path": "docforge.cli.commands.api_utils.OpenAPIMetadata.site_author", + "signature": "", + "docstring": null + } + } + }, + "load_openapi_spec": { + "name": "load_openapi_spec", + "kind": "function", + "path": "docforge.cli.commands.api_utils.load_openapi_spec", + "signature": "", + "docstring": "Load and validate an OpenAPI specification from a JSON file.\n\nArgs:\n spec_path: Path to the OpenAPI JSON specification file.\n\nReturns:\n dict:\n The parsed OpenAPI specification.\n\nRaises:\n click.ClickException:\n If the file cannot be read or the ``info`` block is invalid." + }, + "derive_metadata": { + "name": "derive_metadata", + "kind": "function", + "path": "docforge.cli.commands.api_utils.derive_metadata", + "signature": "", + "docstring": "Derive MkDocs site metadata from an OpenAPI spec ``info`` block.\n\nArgs:\n spec: Parsed OpenAPI specification.\n\nReturns:\n OpenAPIMetadata:\n Site name, description, and author derived from the spec." + }, + "generate_api_sources": { + "name": "generate_api_sources", + "kind": "function", + "path": "docforge.cli.commands.api_utils.generate_api_sources", + "signature": "", + "docstring": "Generate swagger-enabled Markdown sources and the spec copy.\n\nThe specification is written as ``openapi.json`` inside ``docs_dir`` and\nan ``index.md`` embedding the swagger UI is generated alongside it.\n\nArgs:\n spec: Parsed OpenAPI specification.\n docs_dir: Directory (for example ``docs/api``) where the swagger\n sources are written." + }, + "Any": { + "name": "Any", + "kind": "alias", + "path": "docforge.cli.commands.api_utils.Any", + "signature": "", + "docstring": null + } + } + }, "mcp_utils": { "name": "mcp_utils", "kind": "module", @@ -152,6 +254,13 @@ "signature": "", "docstring": null }, + "Iterable": { + "name": "Iterable", + "kind": "alias", + "path": "docforge.cli.commands.mkdocs_utils.Iterable", + "signature": "", + "docstring": null + }, "resources": { "name": "resources", "kind": "alias", @@ -282,7 +391,7 @@ "kind": "function", "path": "docforge.cli.commands.mkdocs_utils.generate_config", "signature": "", - "docstring": "Generate an `mkdocs.yml` configuration file.\n\nThe configuration is created by combining a template configuration\nwith a navigation structure derived from the docforge navigation\nspecification.\n\nArgs:\n docs_dir (Path):\n Directory containing generated documentation Markdown files.\n\n nav_file (Path):\n Path to the `docforge.nav.yml` navigation specification.\n\n template (Optional[Path]):\n Optional path to a custom MkDocs configuration template. If not\n provided, a built-in template will be used.\n\n out (Path):\n Destination path where the generated `mkdocs.yml` file will be written.\n\n site_name (str):\n Display name for the generated documentation site.\n\nRaises:\n click.FileError:\n If the navigation specification or template file cannot be found." + "docstring": "Generate an `mkdocs.yml` configuration file.\n\nThe configuration is created by combining a template configuration\nwith a navigation structure derived from the docforge navigation\nspecification.\n\nThe ``docs_dir`` is always written relative to the MkDocs root and is\nexpected to be the shared documentation parent (for example ``docs``),\nwith generated sources nested under ``lib/`` or ``api/`` subdirectories.\n\nArgs:\n docs_dir (Path):\n Shared documentation root used as the MkDocs ``docs_dir``.\n\n nav_file (Path):\n Path to the `docforge.nav.yml` navigation specification.\n\n template (Optional[Path]):\n Optional path to a fully custom MkDocs configuration template.\n If not provided, built-in templates are merged; the provided\n template replaces the built-in templates entirely.\n\n out (Path):\n Destination path where the generated `mkdocs.yml` file will be written.\n\n site_name (str):\n Display name for the generated documentation site.\n\n modes (Optional[Iterable[str]]):\n Documentation modes to enable. Each mode contributes its own\n built-in template fragment (for example ``lib`` or ``api``),\n merged on top of the shared ``mkdocs.common.yml`` template.\n\n site_description (Optional[str]):\n Optional site description written into the configuration.\n\n site_author (Optional[str]):\n Optional site author written into the configuration.\n\nRaises:\n click.FileError:\n If the navigation specification or template file cannot be found." }, "build": { "name": "build", @@ -334,21 +443,21 @@ "name": "build", "kind": "function", "path": "docforge.cli.commands.build", - "signature": "", - "docstring": "Build documentation artifacts.\n\nThis command performs the full documentation build pipeline:\n\n1. Introspects the Python project using Griffe\n2. Generates renderer-specific documentation sources\n3. Optionally builds the final documentation output\n\nDepending on the selected options, the build can target:\n\n- MkDocs static documentation sites\n- MCP structured documentation resources\n\nArgs:\n mcp (bool):\n Enable MCP documentation generation.\n\n mkdocs (bool):\n Enable MkDocs documentation generation.\n\n module_is_source (bool):\n Treat the specified module directory as the project root.\n\n module (Optional[str]):\n Python module import path to document.\n\n project_name (Optional[str]):\n Optional override for the project name.\n\n site_name (Optional[str]):\n Display name for the MkDocs site.\n\n docs_dir (Path):\n Directory where Markdown documentation sources will be generated.\n\n nav_file (Path):\n Path to the navigation specification file.\n\n template (Optional[Path]):\n Optional custom MkDocs configuration template.\n\n mkdocs_yml (Path):\n Output path for the generated MkDocs configuration.\n\n out_dir (Path):\n Output directory for generated MCP resources.\n\nRaises:\n click.UsageError:\n If required options are missing or conflicting." + "signature": "", + "docstring": "Build documentation artifacts.\n\nThis command performs the full documentation build pipeline:\nstyle of the selected platform, generates renderer-specific\ndocumentation sources, and optionally builds the final output.\n\nDepending on the selected options, the build can target:\n\n- MkDocs static documentation sites for library reference docs\n- Swagger-enabled API docs generated from an OpenAPI spec\n- MCP structured documentation resources\n\nArgs:\n mcp (bool):\n Enable MCP documentation generation.\n\n mkdocs (bool):\n Enable MkDocs library documentation generation.\n\n api (bool):\n Enable API documentation generation from an OpenAPI spec.\n\n module_is_source (bool):\n Treat the specified module directory as the project root.\n\n module (Optional[str]):\n Python module import path to document.\n\n openapi_spec (Optional[Path]):\n Path to the OpenAPI JSON specification used for API docs.\n\n project_name (Optional[str]):\n Optional override for the project name.\n\n site_name (Optional[str]):\n Display name for the MkDocs site.\n\n docs_dir (Path):\n Shared documentation root used as the MkDocs ``docs_dir``.\n\n nav_file (Path):\n Path to the navigation specification file.\n\n template (Optional[Path]):\n Optional custom MkDocs configuration template.\n\n mkdocs_yml (Path):\n Output path for the generated MkDocs configuration.\n\n out_dir (Path):\n Output directory for generated MCP resources.\n\nRaises:\n click.UsageError:\n If required options are missing or conflicting." }, "serve": { "name": "serve", "kind": "function", "path": "docforge.cli.commands.serve", - "signature": "", + "signature": "", "docstring": "Serve generated documentation locally.\n\nDepending on the selected mode, this command starts either:\n\n- A MkDocs development server for browsing documentation\n- An MCP server exposing structured documentation resources\n\nArgs:\n mcp (bool):\n Serve documentation using the MCP server.\n\n mkdocs (bool):\n Serve the MkDocs development site.\n\n module (Optional[str]):\n Python module import path to serve via MCP.\n\n mkdocs_yml (Path):\n Path to the MkDocs configuration file.\n\n out_dir (Path):\n Root directory containing MCP documentation resources.\n\nRaises:\n click.UsageError:\n If invalid or conflicting options are provided." }, "tree": { "name": "tree", "kind": "function", "path": "docforge.cli.commands.tree", - "signature": "", + "signature": "", "docstring": "Display the documentation object tree for a module.\n\nThis command introspects the specified module and prints a\nhierarchical representation of the discovered documentation\nobjects, including modules, classes, functions, and members.\n\nArgs:\n module (str):\n Python module import path to introspect.\n\n project_name (Optional[str]):\n Optional name to display as the project root." }, "Any": { diff --git a/docs/mcp/modules/docforge.cli.json b/docs/mcp/modules/docforge.cli.json index 95037a6..536047d 100644 --- a/docs/mcp/modules/docforge.cli.json +++ b/docs/mcp/modules/docforge.cli.json @@ -27,6 +27,108 @@ } } }, + "api_utils": { + "name": "api_utils", + "kind": "module", + "path": "docforge.cli.api_utils", + "signature": null, + "docstring": "# Summary\n\nUtilities for building API documentation from an OpenAPI specification.", + "members": { + "json": { + "name": "json", + "kind": "alias", + "path": "docforge.cli.api_utils.json", + "signature": "", + "docstring": null + }, + "dataclass": { + "name": "dataclass", + "kind": "alias", + "path": "docforge.cli.api_utils.dataclass", + "signature": "", + "docstring": null + }, + "Path": { + "name": "Path", + "kind": "alias", + "path": "docforge.cli.api_utils.Path", + "signature": "", + "docstring": null + }, + "click": { + "name": "click", + "kind": "alias", + "path": "docforge.cli.api_utils.click", + "signature": "", + "docstring": null + }, + "SWAGGER_SPEC_FILENAME": { + "name": "SWAGGER_SPEC_FILENAME", + "kind": "attribute", + "path": "docforge.cli.api_utils.SWAGGER_SPEC_FILENAME", + "signature": null, + "docstring": null + }, + "OpenAPIMetadata": { + "name": "OpenAPIMetadata", + "kind": "class", + "path": "docforge.cli.api_utils.OpenAPIMetadata", + "signature": "", + "docstring": "Metadata derived from the ``info`` block of an OpenAPI specification.\n\nAttributes:\n site_name: Spec title, used as the MkDocs site name.\n site_description: Spec description, used as the site description.\n site_author: Contact name (fallback: contact email), used as the\n site author.", + "members": { + "site_name": { + "name": "site_name", + "kind": "attribute", + "path": "docforge.cli.api_utils.OpenAPIMetadata.site_name", + "signature": null, + "docstring": null + }, + "site_description": { + "name": "site_description", + "kind": "attribute", + "path": "docforge.cli.api_utils.OpenAPIMetadata.site_description", + "signature": null, + "docstring": null + }, + "site_author": { + "name": "site_author", + "kind": "attribute", + "path": "docforge.cli.api_utils.OpenAPIMetadata.site_author", + "signature": null, + "docstring": null + } + } + }, + "load_openapi_spec": { + "name": "load_openapi_spec", + "kind": "function", + "path": "docforge.cli.api_utils.load_openapi_spec", + "signature": "", + "docstring": "Load and validate an OpenAPI specification from a JSON file.\n\nArgs:\n spec_path: Path to the OpenAPI JSON specification file.\n\nReturns:\n dict:\n The parsed OpenAPI specification.\n\nRaises:\n click.ClickException:\n If the file cannot be read or the ``info`` block is invalid." + }, + "derive_metadata": { + "name": "derive_metadata", + "kind": "function", + "path": "docforge.cli.api_utils.derive_metadata", + "signature": "", + "docstring": "Derive MkDocs site metadata from an OpenAPI spec ``info`` block.\n\nArgs:\n spec: Parsed OpenAPI specification.\n\nReturns:\n OpenAPIMetadata:\n Site name, description, and author derived from the spec." + }, + "generate_api_sources": { + "name": "generate_api_sources", + "kind": "function", + "path": "docforge.cli.api_utils.generate_api_sources", + "signature": "", + "docstring": "Generate swagger-enabled Markdown sources and the spec copy.\n\nThe specification is written as ``openapi.json`` inside ``docs_dir`` and\nan ``index.md`` embedding the swagger UI is generated alongside it.\n\nArgs:\n spec: Parsed OpenAPI specification.\n docs_dir: Directory (for example ``docs/api``) where the swagger\n sources are written." + }, + "Any": { + "name": "Any", + "kind": "alias", + "path": "docforge.cli.api_utils.Any", + "signature": "", + "docstring": null + } + } + }, "commands": { "name": "commands", "kind": "module", @@ -48,6 +150,108 @@ "signature": "", "docstring": null }, + "api_utils": { + "name": "api_utils", + "kind": "module", + "path": "docforge.cli.commands.api_utils", + "signature": "", + "docstring": "# Summary\n\nUtilities for building API documentation from an OpenAPI specification.", + "members": { + "json": { + "name": "json", + "kind": "alias", + "path": "docforge.cli.commands.api_utils.json", + "signature": "", + "docstring": null + }, + "dataclass": { + "name": "dataclass", + "kind": "alias", + "path": "docforge.cli.commands.api_utils.dataclass", + "signature": "", + "docstring": null + }, + "Path": { + "name": "Path", + "kind": "alias", + "path": "docforge.cli.commands.api_utils.Path", + "signature": "", + "docstring": null + }, + "click": { + "name": "click", + "kind": "alias", + "path": "docforge.cli.commands.api_utils.click", + "signature": "", + "docstring": null + }, + "SWAGGER_SPEC_FILENAME": { + "name": "SWAGGER_SPEC_FILENAME", + "kind": "attribute", + "path": "docforge.cli.commands.api_utils.SWAGGER_SPEC_FILENAME", + "signature": "", + "docstring": null + }, + "OpenAPIMetadata": { + "name": "OpenAPIMetadata", + "kind": "class", + "path": "docforge.cli.commands.api_utils.OpenAPIMetadata", + "signature": "", + "docstring": "Metadata derived from the ``info`` block of an OpenAPI specification.\n\nAttributes:\n site_name: Spec title, used as the MkDocs site name.\n site_description: Spec description, used as the site description.\n site_author: Contact name (fallback: contact email), used as the\n site author.", + "members": { + "site_name": { + "name": "site_name", + "kind": "attribute", + "path": "docforge.cli.commands.api_utils.OpenAPIMetadata.site_name", + "signature": "", + "docstring": null + }, + "site_description": { + "name": "site_description", + "kind": "attribute", + "path": "docforge.cli.commands.api_utils.OpenAPIMetadata.site_description", + "signature": "", + "docstring": null + }, + "site_author": { + "name": "site_author", + "kind": "attribute", + "path": "docforge.cli.commands.api_utils.OpenAPIMetadata.site_author", + "signature": "", + "docstring": null + } + } + }, + "load_openapi_spec": { + "name": "load_openapi_spec", + "kind": "function", + "path": "docforge.cli.commands.api_utils.load_openapi_spec", + "signature": "", + "docstring": "Load and validate an OpenAPI specification from a JSON file.\n\nArgs:\n spec_path: Path to the OpenAPI JSON specification file.\n\nReturns:\n dict:\n The parsed OpenAPI specification.\n\nRaises:\n click.ClickException:\n If the file cannot be read or the ``info`` block is invalid." + }, + "derive_metadata": { + "name": "derive_metadata", + "kind": "function", + "path": "docforge.cli.commands.api_utils.derive_metadata", + "signature": "", + "docstring": "Derive MkDocs site metadata from an OpenAPI spec ``info`` block.\n\nArgs:\n spec: Parsed OpenAPI specification.\n\nReturns:\n OpenAPIMetadata:\n Site name, description, and author derived from the spec." + }, + "generate_api_sources": { + "name": "generate_api_sources", + "kind": "function", + "path": "docforge.cli.commands.api_utils.generate_api_sources", + "signature": "", + "docstring": "Generate swagger-enabled Markdown sources and the spec copy.\n\nThe specification is written as ``openapi.json`` inside ``docs_dir`` and\nan ``index.md`` embedding the swagger UI is generated alongside it.\n\nArgs:\n spec: Parsed OpenAPI specification.\n docs_dir: Directory (for example ``docs/api``) where the swagger\n sources are written." + }, + "Any": { + "name": "Any", + "kind": "alias", + "path": "docforge.cli.commands.api_utils.Any", + "signature": "", + "docstring": null + } + } + }, "mcp_utils": { "name": "mcp_utils", "kind": "module", @@ -182,6 +386,13 @@ "signature": "", "docstring": null }, + "Iterable": { + "name": "Iterable", + "kind": "alias", + "path": "docforge.cli.commands.mkdocs_utils.Iterable", + "signature": "", + "docstring": null + }, "resources": { "name": "resources", "kind": "alias", @@ -312,7 +523,7 @@ "kind": "function", "path": "docforge.cli.commands.mkdocs_utils.generate_config", "signature": "", - "docstring": "Generate an `mkdocs.yml` configuration file.\n\nThe configuration is created by combining a template configuration\nwith a navigation structure derived from the docforge navigation\nspecification.\n\nArgs:\n docs_dir (Path):\n Directory containing generated documentation Markdown files.\n\n nav_file (Path):\n Path to the `docforge.nav.yml` navigation specification.\n\n template (Optional[Path]):\n Optional path to a custom MkDocs configuration template. If not\n provided, a built-in template will be used.\n\n out (Path):\n Destination path where the generated `mkdocs.yml` file will be written.\n\n site_name (str):\n Display name for the generated documentation site.\n\nRaises:\n click.FileError:\n If the navigation specification or template file cannot be found." + "docstring": "Generate an `mkdocs.yml` configuration file.\n\nThe configuration is created by combining a template configuration\nwith a navigation structure derived from the docforge navigation\nspecification.\n\nThe ``docs_dir`` is always written relative to the MkDocs root and is\nexpected to be the shared documentation parent (for example ``docs``),\nwith generated sources nested under ``lib/`` or ``api/`` subdirectories.\n\nArgs:\n docs_dir (Path):\n Shared documentation root used as the MkDocs ``docs_dir``.\n\n nav_file (Path):\n Path to the `docforge.nav.yml` navigation specification.\n\n template (Optional[Path]):\n Optional path to a fully custom MkDocs configuration template.\n If not provided, built-in templates are merged; the provided\n template replaces the built-in templates entirely.\n\n out (Path):\n Destination path where the generated `mkdocs.yml` file will be written.\n\n site_name (str):\n Display name for the generated documentation site.\n\n modes (Optional[Iterable[str]]):\n Documentation modes to enable. Each mode contributes its own\n built-in template fragment (for example ``lib`` or ``api``),\n merged on top of the shared ``mkdocs.common.yml`` template.\n\n site_description (Optional[str]):\n Optional site description written into the configuration.\n\n site_author (Optional[str]):\n Optional site author written into the configuration.\n\nRaises:\n click.FileError:\n If the navigation specification or template file cannot be found." }, "build": { "name": "build", @@ -364,21 +575,21 @@ "name": "build", "kind": "function", "path": "docforge.cli.commands.build", - "signature": "", - "docstring": "Build documentation artifacts.\n\nThis command performs the full documentation build pipeline:\n\n1. Introspects the Python project using Griffe\n2. Generates renderer-specific documentation sources\n3. Optionally builds the final documentation output\n\nDepending on the selected options, the build can target:\n\n- MkDocs static documentation sites\n- MCP structured documentation resources\n\nArgs:\n mcp (bool):\n Enable MCP documentation generation.\n\n mkdocs (bool):\n Enable MkDocs documentation generation.\n\n module_is_source (bool):\n Treat the specified module directory as the project root.\n\n module (Optional[str]):\n Python module import path to document.\n\n project_name (Optional[str]):\n Optional override for the project name.\n\n site_name (Optional[str]):\n Display name for the MkDocs site.\n\n docs_dir (Path):\n Directory where Markdown documentation sources will be generated.\n\n nav_file (Path):\n Path to the navigation specification file.\n\n template (Optional[Path]):\n Optional custom MkDocs configuration template.\n\n mkdocs_yml (Path):\n Output path for the generated MkDocs configuration.\n\n out_dir (Path):\n Output directory for generated MCP resources.\n\nRaises:\n click.UsageError:\n If required options are missing or conflicting." + "signature": "", + "docstring": "Build documentation artifacts.\n\nThis command performs the full documentation build pipeline:\nstyle of the selected platform, generates renderer-specific\ndocumentation sources, and optionally builds the final output.\n\nDepending on the selected options, the build can target:\n\n- MkDocs static documentation sites for library reference docs\n- Swagger-enabled API docs generated from an OpenAPI spec\n- MCP structured documentation resources\n\nArgs:\n mcp (bool):\n Enable MCP documentation generation.\n\n mkdocs (bool):\n Enable MkDocs library documentation generation.\n\n api (bool):\n Enable API documentation generation from an OpenAPI spec.\n\n module_is_source (bool):\n Treat the specified module directory as the project root.\n\n module (Optional[str]):\n Python module import path to document.\n\n openapi_spec (Optional[Path]):\n Path to the OpenAPI JSON specification used for API docs.\n\n project_name (Optional[str]):\n Optional override for the project name.\n\n site_name (Optional[str]):\n Display name for the MkDocs site.\n\n docs_dir (Path):\n Shared documentation root used as the MkDocs ``docs_dir``.\n\n nav_file (Path):\n Path to the navigation specification file.\n\n template (Optional[Path]):\n Optional custom MkDocs configuration template.\n\n mkdocs_yml (Path):\n Output path for the generated MkDocs configuration.\n\n out_dir (Path):\n Output directory for generated MCP resources.\n\nRaises:\n click.UsageError:\n If required options are missing or conflicting." }, "serve": { "name": "serve", "kind": "function", "path": "docforge.cli.commands.serve", - "signature": "", + "signature": "", "docstring": "Serve generated documentation locally.\n\nDepending on the selected mode, this command starts either:\n\n- A MkDocs development server for browsing documentation\n- An MCP server exposing structured documentation resources\n\nArgs:\n mcp (bool):\n Serve documentation using the MCP server.\n\n mkdocs (bool):\n Serve the MkDocs development site.\n\n module (Optional[str]):\n Python module import path to serve via MCP.\n\n mkdocs_yml (Path):\n Path to the MkDocs configuration file.\n\n out_dir (Path):\n Root directory containing MCP documentation resources.\n\nRaises:\n click.UsageError:\n If invalid or conflicting options are provided." }, "tree": { "name": "tree", "kind": "function", "path": "docforge.cli.commands.tree", - "signature": "", + "signature": "", "docstring": "Display the documentation object tree for a module.\n\nThis command introspects the specified module and prints a\nhierarchical representation of the discovered documentation\nobjects, including modules, classes, functions, and members.\n\nArgs:\n module (str):\n Python module import path to introspect.\n\n project_name (Optional[str]):\n Optional name to display as the project root." }, "Any": { @@ -531,6 +742,13 @@ "signature": "", "docstring": null }, + "Iterable": { + "name": "Iterable", + "kind": "alias", + "path": "docforge.cli.mkdocs_utils.Iterable", + "signature": "", + "docstring": null + }, "resources": { "name": "resources", "kind": "alias", @@ -653,28 +871,28 @@ "name": "generate_sources", "kind": "function", "path": "docforge.cli.mkdocs_utils.generate_sources", - "signature": "", + "signature": "", "docstring": "Generate MkDocs Markdown sources for a Python module.\n\nThis function introspects the specified module, builds the internal\ndocumentation model, and renders Markdown documentation files for\nuse with MkDocs.\n\nArgs:\n module (str):\n Python module import path used as the entry point for\n documentation generation.\n\n docs_dir (Path):\n Directory where the generated Markdown files will be written.\n\n project_name (Optional[str]):\n Optional override for the project name used in documentation metadata.\n\n module_is_source (Optional[bool]):\n If True, treat the specified module directory as the project root\n rather than a nested module.\n\n readme_dir (Optional[Path]):\n Directory where the generated README.md should be written. If not\n provided, defaults to the parent of ``docs_dir``." }, "generate_config": { "name": "generate_config", "kind": "function", "path": "docforge.cli.mkdocs_utils.generate_config", - "signature": "", - "docstring": "Generate an `mkdocs.yml` configuration file.\n\nThe configuration is created by combining a template configuration\nwith a navigation structure derived from the docforge navigation\nspecification.\n\nArgs:\n docs_dir (Path):\n Directory containing generated documentation Markdown files.\n\n nav_file (Path):\n Path to the `docforge.nav.yml` navigation specification.\n\n template (Optional[Path]):\n Optional path to a custom MkDocs configuration template. If not\n provided, a built-in template will be used.\n\n out (Path):\n Destination path where the generated `mkdocs.yml` file will be written.\n\n site_name (str):\n Display name for the generated documentation site.\n\nRaises:\n click.FileError:\n If the navigation specification or template file cannot be found." + "signature": "", + "docstring": "Generate an `mkdocs.yml` configuration file.\n\nThe configuration is created by combining a template configuration\nwith a navigation structure derived from the docforge navigation\nspecification.\n\nThe ``docs_dir`` is always written relative to the MkDocs root and is\nexpected to be the shared documentation parent (for example ``docs``),\nwith generated sources nested under ``lib/`` or ``api/`` subdirectories.\n\nArgs:\n docs_dir (Path):\n Shared documentation root used as the MkDocs ``docs_dir``.\n\n nav_file (Path):\n Path to the `docforge.nav.yml` navigation specification.\n\n template (Optional[Path]):\n Optional path to a fully custom MkDocs configuration template.\n If not provided, built-in templates are merged; the provided\n template replaces the built-in templates entirely.\n\n out (Path):\n Destination path where the generated `mkdocs.yml` file will be written.\n\n site_name (str):\n Display name for the generated documentation site.\n\n modes (Optional[Iterable[str]]):\n Documentation modes to enable. Each mode contributes its own\n built-in template fragment (for example ``lib`` or ``api``),\n merged on top of the shared ``mkdocs.common.yml`` template.\n\n site_description (Optional[str]):\n Optional site description written into the configuration.\n\n site_author (Optional[str]):\n Optional site author written into the configuration.\n\nRaises:\n click.FileError:\n If the navigation specification or template file cannot be found." }, "build": { "name": "build", "kind": "function", "path": "docforge.cli.mkdocs_utils.build", - "signature": "", + "signature": "", "docstring": "Build the MkDocs documentation site.\n\nThis function loads the MkDocs configuration and runs the MkDocs\nbuild command to generate the final static documentation site.\n\nArgs:\n mkdocs_yml (Path):\n Path to the `mkdocs.yml` configuration file.\n\nRaises:\n click.ClickException:\n If the configuration file does not exist." }, "serve": { "name": "serve", "kind": "function", "path": "docforge.cli.mkdocs_utils.serve", - "signature": "", + "signature": "", "docstring": "Start an MkDocs development server with live reload.\n\nThe server watches documentation files and automatically reloads\nthe site when changes are detected.\n\nArgs:\n mkdocs_yml (Path):\n Path to the `mkdocs.yml` configuration file.\n\nRaises:\n click.ClickException:\n If the configuration file does not exist." } } diff --git a/docs/mcp/modules/docforge.cli.mkdocs_utils.json b/docs/mcp/modules/docforge.cli.mkdocs_utils.json index d906397..6a260f5 100644 --- a/docs/mcp/modules/docforge.cli.mkdocs_utils.json +++ b/docs/mcp/modules/docforge.cli.mkdocs_utils.json @@ -11,6 +11,13 @@ "signature": "", "docstring": null }, + "Iterable": { + "name": "Iterable", + "kind": "alias", + "path": "docforge.cli.mkdocs_utils.Iterable", + "signature": "", + "docstring": null + }, "resources": { "name": "resources", "kind": "alias", @@ -133,28 +140,28 @@ "name": "generate_sources", "kind": "function", "path": "docforge.cli.mkdocs_utils.generate_sources", - "signature": "", + "signature": "", "docstring": "Generate MkDocs Markdown sources for a Python module.\n\nThis function introspects the specified module, builds the internal\ndocumentation model, and renders Markdown documentation files for\nuse with MkDocs.\n\nArgs:\n module (str):\n Python module import path used as the entry point for\n documentation generation.\n\n docs_dir (Path):\n Directory where the generated Markdown files will be written.\n\n project_name (Optional[str]):\n Optional override for the project name used in documentation metadata.\n\n module_is_source (Optional[bool]):\n If True, treat the specified module directory as the project root\n rather than a nested module.\n\n readme_dir (Optional[Path]):\n Directory where the generated README.md should be written. If not\n provided, defaults to the parent of ``docs_dir``." }, "generate_config": { "name": "generate_config", "kind": "function", "path": "docforge.cli.mkdocs_utils.generate_config", - "signature": "", - "docstring": "Generate an `mkdocs.yml` configuration file.\n\nThe configuration is created by combining a template configuration\nwith a navigation structure derived from the docforge navigation\nspecification.\n\nArgs:\n docs_dir (Path):\n Directory containing generated documentation Markdown files.\n\n nav_file (Path):\n Path to the `docforge.nav.yml` navigation specification.\n\n template (Optional[Path]):\n Optional path to a custom MkDocs configuration template. If not\n provided, a built-in template will be used.\n\n out (Path):\n Destination path where the generated `mkdocs.yml` file will be written.\n\n site_name (str):\n Display name for the generated documentation site.\n\nRaises:\n click.FileError:\n If the navigation specification or template file cannot be found." + "signature": "", + "docstring": "Generate an `mkdocs.yml` configuration file.\n\nThe configuration is created by combining a template configuration\nwith a navigation structure derived from the docforge navigation\nspecification.\n\nThe ``docs_dir`` is always written relative to the MkDocs root and is\nexpected to be the shared documentation parent (for example ``docs``),\nwith generated sources nested under ``lib/`` or ``api/`` subdirectories.\n\nArgs:\n docs_dir (Path):\n Shared documentation root used as the MkDocs ``docs_dir``.\n\n nav_file (Path):\n Path to the `docforge.nav.yml` navigation specification.\n\n template (Optional[Path]):\n Optional path to a fully custom MkDocs configuration template.\n If not provided, built-in templates are merged; the provided\n template replaces the built-in templates entirely.\n\n out (Path):\n Destination path where the generated `mkdocs.yml` file will be written.\n\n site_name (str):\n Display name for the generated documentation site.\n\n modes (Optional[Iterable[str]]):\n Documentation modes to enable. Each mode contributes its own\n built-in template fragment (for example ``lib`` or ``api``),\n merged on top of the shared ``mkdocs.common.yml`` template.\n\n site_description (Optional[str]):\n Optional site description written into the configuration.\n\n site_author (Optional[str]):\n Optional site author written into the configuration.\n\nRaises:\n click.FileError:\n If the navigation specification or template file cannot be found." }, "build": { "name": "build", "kind": "function", "path": "docforge.cli.mkdocs_utils.build", - "signature": "", + "signature": "", "docstring": "Build the MkDocs documentation site.\n\nThis function loads the MkDocs configuration and runs the MkDocs\nbuild command to generate the final static documentation site.\n\nArgs:\n mkdocs_yml (Path):\n Path to the `mkdocs.yml` configuration file.\n\nRaises:\n click.ClickException:\n If the configuration file does not exist." }, "serve": { "name": "serve", "kind": "function", "path": "docforge.cli.mkdocs_utils.serve", - "signature": "", + "signature": "", "docstring": "Start an MkDocs development server with live reload.\n\nThe server watches documentation files and automatically reloads\nthe site when changes are detected.\n\nArgs:\n mkdocs_yml (Path):\n Path to the `mkdocs.yml` configuration file.\n\nRaises:\n click.ClickException:\n If the configuration file does not exist." } } diff --git a/docs/mcp/modules/docforge.json b/docs/mcp/modules/docforge.json index 2f65a43..ae0cb51 100644 --- a/docs/mcp/modules/docforge.json +++ b/docs/mcp/modules/docforge.json @@ -140,6 +140,108 @@ } } }, + "api_utils": { + "name": "api_utils", + "kind": "module", + "path": "docforge.cli.api_utils", + "signature": null, + "docstring": "# Summary\n\nUtilities for building API documentation from an OpenAPI specification.", + "members": { + "json": { + "name": "json", + "kind": "alias", + "path": "docforge.cli.api_utils.json", + "signature": "", + "docstring": null + }, + "dataclass": { + "name": "dataclass", + "kind": "alias", + "path": "docforge.cli.api_utils.dataclass", + "signature": "", + "docstring": null + }, + "Path": { + "name": "Path", + "kind": "alias", + "path": "docforge.cli.api_utils.Path", + "signature": "", + "docstring": null + }, + "click": { + "name": "click", + "kind": "alias", + "path": "docforge.cli.api_utils.click", + "signature": "", + "docstring": null + }, + "SWAGGER_SPEC_FILENAME": { + "name": "SWAGGER_SPEC_FILENAME", + "kind": "attribute", + "path": "docforge.cli.api_utils.SWAGGER_SPEC_FILENAME", + "signature": null, + "docstring": null + }, + "OpenAPIMetadata": { + "name": "OpenAPIMetadata", + "kind": "class", + "path": "docforge.cli.api_utils.OpenAPIMetadata", + "signature": "", + "docstring": "Metadata derived from the ``info`` block of an OpenAPI specification.\n\nAttributes:\n site_name: Spec title, used as the MkDocs site name.\n site_description: Spec description, used as the site description.\n site_author: Contact name (fallback: contact email), used as the\n site author.", + "members": { + "site_name": { + "name": "site_name", + "kind": "attribute", + "path": "docforge.cli.api_utils.OpenAPIMetadata.site_name", + "signature": null, + "docstring": null + }, + "site_description": { + "name": "site_description", + "kind": "attribute", + "path": "docforge.cli.api_utils.OpenAPIMetadata.site_description", + "signature": null, + "docstring": null + }, + "site_author": { + "name": "site_author", + "kind": "attribute", + "path": "docforge.cli.api_utils.OpenAPIMetadata.site_author", + "signature": null, + "docstring": null + } + } + }, + "load_openapi_spec": { + "name": "load_openapi_spec", + "kind": "function", + "path": "docforge.cli.api_utils.load_openapi_spec", + "signature": "", + "docstring": "Load and validate an OpenAPI specification from a JSON file.\n\nArgs:\n spec_path: Path to the OpenAPI JSON specification file.\n\nReturns:\n dict:\n The parsed OpenAPI specification.\n\nRaises:\n click.ClickException:\n If the file cannot be read or the ``info`` block is invalid." + }, + "derive_metadata": { + "name": "derive_metadata", + "kind": "function", + "path": "docforge.cli.api_utils.derive_metadata", + "signature": "", + "docstring": "Derive MkDocs site metadata from an OpenAPI spec ``info`` block.\n\nArgs:\n spec: Parsed OpenAPI specification.\n\nReturns:\n OpenAPIMetadata:\n Site name, description, and author derived from the spec." + }, + "generate_api_sources": { + "name": "generate_api_sources", + "kind": "function", + "path": "docforge.cli.api_utils.generate_api_sources", + "signature": "", + "docstring": "Generate swagger-enabled Markdown sources and the spec copy.\n\nThe specification is written as ``openapi.json`` inside ``docs_dir`` and\nan ``index.md`` embedding the swagger UI is generated alongside it.\n\nArgs:\n spec: Parsed OpenAPI specification.\n docs_dir: Directory (for example ``docs/api``) where the swagger\n sources are written." + }, + "Any": { + "name": "Any", + "kind": "alias", + "path": "docforge.cli.api_utils.Any", + "signature": "", + "docstring": null + } + } + }, "commands": { "name": "commands", "kind": "module", @@ -161,6 +263,108 @@ "signature": "", "docstring": null }, + "api_utils": { + "name": "api_utils", + "kind": "module", + "path": "docforge.cli.commands.api_utils", + "signature": "", + "docstring": "# Summary\n\nUtilities for building API documentation from an OpenAPI specification.", + "members": { + "json": { + "name": "json", + "kind": "alias", + "path": "docforge.cli.commands.api_utils.json", + "signature": "", + "docstring": null + }, + "dataclass": { + "name": "dataclass", + "kind": "alias", + "path": "docforge.cli.commands.api_utils.dataclass", + "signature": "", + "docstring": null + }, + "Path": { + "name": "Path", + "kind": "alias", + "path": "docforge.cli.commands.api_utils.Path", + "signature": "", + "docstring": null + }, + "click": { + "name": "click", + "kind": "alias", + "path": "docforge.cli.commands.api_utils.click", + "signature": "", + "docstring": null + }, + "SWAGGER_SPEC_FILENAME": { + "name": "SWAGGER_SPEC_FILENAME", + "kind": "attribute", + "path": "docforge.cli.commands.api_utils.SWAGGER_SPEC_FILENAME", + "signature": "", + "docstring": null + }, + "OpenAPIMetadata": { + "name": "OpenAPIMetadata", + "kind": "class", + "path": "docforge.cli.commands.api_utils.OpenAPIMetadata", + "signature": "", + "docstring": "Metadata derived from the ``info`` block of an OpenAPI specification.\n\nAttributes:\n site_name: Spec title, used as the MkDocs site name.\n site_description: Spec description, used as the site description.\n site_author: Contact name (fallback: contact email), used as the\n site author.", + "members": { + "site_name": { + "name": "site_name", + "kind": "attribute", + "path": "docforge.cli.commands.api_utils.OpenAPIMetadata.site_name", + "signature": "", + "docstring": null + }, + "site_description": { + "name": "site_description", + "kind": "attribute", + "path": "docforge.cli.commands.api_utils.OpenAPIMetadata.site_description", + "signature": "", + "docstring": null + }, + "site_author": { + "name": "site_author", + "kind": "attribute", + "path": "docforge.cli.commands.api_utils.OpenAPIMetadata.site_author", + "signature": "", + "docstring": null + } + } + }, + "load_openapi_spec": { + "name": "load_openapi_spec", + "kind": "function", + "path": "docforge.cli.commands.api_utils.load_openapi_spec", + "signature": "", + "docstring": "Load and validate an OpenAPI specification from a JSON file.\n\nArgs:\n spec_path: Path to the OpenAPI JSON specification file.\n\nReturns:\n dict:\n The parsed OpenAPI specification.\n\nRaises:\n click.ClickException:\n If the file cannot be read or the ``info`` block is invalid." + }, + "derive_metadata": { + "name": "derive_metadata", + "kind": "function", + "path": "docforge.cli.commands.api_utils.derive_metadata", + "signature": "", + "docstring": "Derive MkDocs site metadata from an OpenAPI spec ``info`` block.\n\nArgs:\n spec: Parsed OpenAPI specification.\n\nReturns:\n OpenAPIMetadata:\n Site name, description, and author derived from the spec." + }, + "generate_api_sources": { + "name": "generate_api_sources", + "kind": "function", + "path": "docforge.cli.commands.api_utils.generate_api_sources", + "signature": "", + "docstring": "Generate swagger-enabled Markdown sources and the spec copy.\n\nThe specification is written as ``openapi.json`` inside ``docs_dir`` and\nan ``index.md`` embedding the swagger UI is generated alongside it.\n\nArgs:\n spec: Parsed OpenAPI specification.\n docs_dir: Directory (for example ``docs/api``) where the swagger\n sources are written." + }, + "Any": { + "name": "Any", + "kind": "alias", + "path": "docforge.cli.commands.api_utils.Any", + "signature": "", + "docstring": null + } + } + }, "mcp_utils": { "name": "mcp_utils", "kind": "module", @@ -295,6 +499,13 @@ "signature": "", "docstring": null }, + "Iterable": { + "name": "Iterable", + "kind": "alias", + "path": "docforge.cli.commands.mkdocs_utils.Iterable", + "signature": "", + "docstring": null + }, "resources": { "name": "resources", "kind": "alias", @@ -425,7 +636,7 @@ "kind": "function", "path": "docforge.cli.commands.mkdocs_utils.generate_config", "signature": "", - "docstring": "Generate an `mkdocs.yml` configuration file.\n\nThe configuration is created by combining a template configuration\nwith a navigation structure derived from the docforge navigation\nspecification.\n\nArgs:\n docs_dir (Path):\n Directory containing generated documentation Markdown files.\n\n nav_file (Path):\n Path to the `docforge.nav.yml` navigation specification.\n\n template (Optional[Path]):\n Optional path to a custom MkDocs configuration template. If not\n provided, a built-in template will be used.\n\n out (Path):\n Destination path where the generated `mkdocs.yml` file will be written.\n\n site_name (str):\n Display name for the generated documentation site.\n\nRaises:\n click.FileError:\n If the navigation specification or template file cannot be found." + "docstring": "Generate an `mkdocs.yml` configuration file.\n\nThe configuration is created by combining a template configuration\nwith a navigation structure derived from the docforge navigation\nspecification.\n\nThe ``docs_dir`` is always written relative to the MkDocs root and is\nexpected to be the shared documentation parent (for example ``docs``),\nwith generated sources nested under ``lib/`` or ``api/`` subdirectories.\n\nArgs:\n docs_dir (Path):\n Shared documentation root used as the MkDocs ``docs_dir``.\n\n nav_file (Path):\n Path to the `docforge.nav.yml` navigation specification.\n\n template (Optional[Path]):\n Optional path to a fully custom MkDocs configuration template.\n If not provided, built-in templates are merged; the provided\n template replaces the built-in templates entirely.\n\n out (Path):\n Destination path where the generated `mkdocs.yml` file will be written.\n\n site_name (str):\n Display name for the generated documentation site.\n\n modes (Optional[Iterable[str]]):\n Documentation modes to enable. Each mode contributes its own\n built-in template fragment (for example ``lib`` or ``api``),\n merged on top of the shared ``mkdocs.common.yml`` template.\n\n site_description (Optional[str]):\n Optional site description written into the configuration.\n\n site_author (Optional[str]):\n Optional site author written into the configuration.\n\nRaises:\n click.FileError:\n If the navigation specification or template file cannot be found." }, "build": { "name": "build", @@ -477,21 +688,21 @@ "name": "build", "kind": "function", "path": "docforge.cli.commands.build", - "signature": "", - "docstring": "Build documentation artifacts.\n\nThis command performs the full documentation build pipeline:\n\n1. Introspects the Python project using Griffe\n2. Generates renderer-specific documentation sources\n3. Optionally builds the final documentation output\n\nDepending on the selected options, the build can target:\n\n- MkDocs static documentation sites\n- MCP structured documentation resources\n\nArgs:\n mcp (bool):\n Enable MCP documentation generation.\n\n mkdocs (bool):\n Enable MkDocs documentation generation.\n\n module_is_source (bool):\n Treat the specified module directory as the project root.\n\n module (Optional[str]):\n Python module import path to document.\n\n project_name (Optional[str]):\n Optional override for the project name.\n\n site_name (Optional[str]):\n Display name for the MkDocs site.\n\n docs_dir (Path):\n Directory where Markdown documentation sources will be generated.\n\n nav_file (Path):\n Path to the navigation specification file.\n\n template (Optional[Path]):\n Optional custom MkDocs configuration template.\n\n mkdocs_yml (Path):\n Output path for the generated MkDocs configuration.\n\n out_dir (Path):\n Output directory for generated MCP resources.\n\nRaises:\n click.UsageError:\n If required options are missing or conflicting." + "signature": "", + "docstring": "Build documentation artifacts.\n\nThis command performs the full documentation build pipeline:\nstyle of the selected platform, generates renderer-specific\ndocumentation sources, and optionally builds the final output.\n\nDepending on the selected options, the build can target:\n\n- MkDocs static documentation sites for library reference docs\n- Swagger-enabled API docs generated from an OpenAPI spec\n- MCP structured documentation resources\n\nArgs:\n mcp (bool):\n Enable MCP documentation generation.\n\n mkdocs (bool):\n Enable MkDocs library documentation generation.\n\n api (bool):\n Enable API documentation generation from an OpenAPI spec.\n\n module_is_source (bool):\n Treat the specified module directory as the project root.\n\n module (Optional[str]):\n Python module import path to document.\n\n openapi_spec (Optional[Path]):\n Path to the OpenAPI JSON specification used for API docs.\n\n project_name (Optional[str]):\n Optional override for the project name.\n\n site_name (Optional[str]):\n Display name for the MkDocs site.\n\n docs_dir (Path):\n Shared documentation root used as the MkDocs ``docs_dir``.\n\n nav_file (Path):\n Path to the navigation specification file.\n\n template (Optional[Path]):\n Optional custom MkDocs configuration template.\n\n mkdocs_yml (Path):\n Output path for the generated MkDocs configuration.\n\n out_dir (Path):\n Output directory for generated MCP resources.\n\nRaises:\n click.UsageError:\n If required options are missing or conflicting." }, "serve": { "name": "serve", "kind": "function", "path": "docforge.cli.commands.serve", - "signature": "", + "signature": "", "docstring": "Serve generated documentation locally.\n\nDepending on the selected mode, this command starts either:\n\n- A MkDocs development server for browsing documentation\n- An MCP server exposing structured documentation resources\n\nArgs:\n mcp (bool):\n Serve documentation using the MCP server.\n\n mkdocs (bool):\n Serve the MkDocs development site.\n\n module (Optional[str]):\n Python module import path to serve via MCP.\n\n mkdocs_yml (Path):\n Path to the MkDocs configuration file.\n\n out_dir (Path):\n Root directory containing MCP documentation resources.\n\nRaises:\n click.UsageError:\n If invalid or conflicting options are provided." }, "tree": { "name": "tree", "kind": "function", "path": "docforge.cli.commands.tree", - "signature": "", + "signature": "", "docstring": "Display the documentation object tree for a module.\n\nThis command introspects the specified module and prints a\nhierarchical representation of the discovered documentation\nobjects, including modules, classes, functions, and members.\n\nArgs:\n module (str):\n Python module import path to introspect.\n\n project_name (Optional[str]):\n Optional name to display as the project root." }, "Any": { @@ -644,6 +855,13 @@ "signature": "", "docstring": null }, + "Iterable": { + "name": "Iterable", + "kind": "alias", + "path": "docforge.cli.mkdocs_utils.Iterable", + "signature": "", + "docstring": null + }, "resources": { "name": "resources", "kind": "alias", @@ -766,28 +984,28 @@ "name": "generate_sources", "kind": "function", "path": "docforge.cli.mkdocs_utils.generate_sources", - "signature": "", + "signature": "", "docstring": "Generate MkDocs Markdown sources for a Python module.\n\nThis function introspects the specified module, builds the internal\ndocumentation model, and renders Markdown documentation files for\nuse with MkDocs.\n\nArgs:\n module (str):\n Python module import path used as the entry point for\n documentation generation.\n\n docs_dir (Path):\n Directory where the generated Markdown files will be written.\n\n project_name (Optional[str]):\n Optional override for the project name used in documentation metadata.\n\n module_is_source (Optional[bool]):\n If True, treat the specified module directory as the project root\n rather than a nested module.\n\n readme_dir (Optional[Path]):\n Directory where the generated README.md should be written. If not\n provided, defaults to the parent of ``docs_dir``." }, "generate_config": { "name": "generate_config", "kind": "function", "path": "docforge.cli.mkdocs_utils.generate_config", - "signature": "", - "docstring": "Generate an `mkdocs.yml` configuration file.\n\nThe configuration is created by combining a template configuration\nwith a navigation structure derived from the docforge navigation\nspecification.\n\nArgs:\n docs_dir (Path):\n Directory containing generated documentation Markdown files.\n\n nav_file (Path):\n Path to the `docforge.nav.yml` navigation specification.\n\n template (Optional[Path]):\n Optional path to a custom MkDocs configuration template. If not\n provided, a built-in template will be used.\n\n out (Path):\n Destination path where the generated `mkdocs.yml` file will be written.\n\n site_name (str):\n Display name for the generated documentation site.\n\nRaises:\n click.FileError:\n If the navigation specification or template file cannot be found." + "signature": "", + "docstring": "Generate an `mkdocs.yml` configuration file.\n\nThe configuration is created by combining a template configuration\nwith a navigation structure derived from the docforge navigation\nspecification.\n\nThe ``docs_dir`` is always written relative to the MkDocs root and is\nexpected to be the shared documentation parent (for example ``docs``),\nwith generated sources nested under ``lib/`` or ``api/`` subdirectories.\n\nArgs:\n docs_dir (Path):\n Shared documentation root used as the MkDocs ``docs_dir``.\n\n nav_file (Path):\n Path to the `docforge.nav.yml` navigation specification.\n\n template (Optional[Path]):\n Optional path to a fully custom MkDocs configuration template.\n If not provided, built-in templates are merged; the provided\n template replaces the built-in templates entirely.\n\n out (Path):\n Destination path where the generated `mkdocs.yml` file will be written.\n\n site_name (str):\n Display name for the generated documentation site.\n\n modes (Optional[Iterable[str]]):\n Documentation modes to enable. Each mode contributes its own\n built-in template fragment (for example ``lib`` or ``api``),\n merged on top of the shared ``mkdocs.common.yml`` template.\n\n site_description (Optional[str]):\n Optional site description written into the configuration.\n\n site_author (Optional[str]):\n Optional site author written into the configuration.\n\nRaises:\n click.FileError:\n If the navigation specification or template file cannot be found." }, "build": { "name": "build", "kind": "function", "path": "docforge.cli.mkdocs_utils.build", - "signature": "", + "signature": "", "docstring": "Build the MkDocs documentation site.\n\nThis function loads the MkDocs configuration and runs the MkDocs\nbuild command to generate the final static documentation site.\n\nArgs:\n mkdocs_yml (Path):\n Path to the `mkdocs.yml` configuration file.\n\nRaises:\n click.ClickException:\n If the configuration file does not exist." }, "serve": { "name": "serve", "kind": "function", "path": "docforge.cli.mkdocs_utils.serve", - "signature": "", + "signature": "", "docstring": "Start an MkDocs development server with live reload.\n\nThe server watches documentation files and automatically reloads\nthe site when changes are detected.\n\nArgs:\n mkdocs_yml (Path):\n Path to the `mkdocs.yml` configuration file.\n\nRaises:\n click.ClickException:\n If the configuration file does not exist." } } @@ -1635,7 +1853,7 @@ "kind": "class", "path": "docforge.nav.NavSpec", "signature": "", - "docstring": "Parsed representation of a navigation specification.\n\nA ``NavSpec`` describes the intended documentation navigation layout before\nit is resolved against the filesystem.\n\nAttributes:\n home: Relative path to the documentation home page (for example\n ``index.md``).\n groups: Mapping of navigation group titles to lists of file patterns\n or glob expressions.", + "docstring": "Parsed representation of a navigation specification.\n\nA ``NavSpec`` describes the intended documentation navigation layout before\nit is resolved against the filesystem.\n\nAttributes:\n home: Relative path to the documentation home page (for example\n ``index.md``).\n groups: Mapping of navigation group titles to lists of file patterns\n or glob expressions.\n icon: Optional mapping of theme icon entries (for example\n ``{\"logo\": \"material/code-tags\"}``) injected into the MkDocs\n theme as ``theme.icon``.", "members": { "home": { "name": "home", @@ -1651,6 +1869,13 @@ "signature": "", "docstring": null }, + "icon": { + "name": "icon", + "kind": "attribute", + "path": "docforge.nav.NavSpec.icon", + "signature": "", + "docstring": null + }, "load": { "name": "load", "kind": "function", @@ -1829,7 +2054,7 @@ "kind": "class", "path": "docforge.nav.resolver.NavSpec", "signature": "", - "docstring": "Parsed representation of a navigation specification.\n\nA ``NavSpec`` describes the intended documentation navigation layout before\nit is resolved against the filesystem.\n\nAttributes:\n home: Relative path to the documentation home page (for example\n ``index.md``).\n groups: Mapping of navigation group titles to lists of file patterns\n or glob expressions.", + "docstring": "Parsed representation of a navigation specification.\n\nA ``NavSpec`` describes the intended documentation navigation layout before\nit is resolved against the filesystem.\n\nAttributes:\n home: Relative path to the documentation home page (for example\n ``index.md``).\n groups: Mapping of navigation group titles to lists of file patterns\n or glob expressions.\n icon: Optional mapping of theme icon entries (for example\n ``{\"logo\": \"material/code-tags\"}``) injected into the MkDocs\n theme as ``theme.icon``.", "members": { "home": { "name": "home", @@ -1845,6 +2070,13 @@ "signature": "", "docstring": null }, + "icon": { + "name": "icon", + "kind": "attribute", + "path": "docforge.nav.resolver.NavSpec.icon", + "signature": "", + "docstring": null + }, "load": { "name": "load", "kind": "function", @@ -1925,8 +2157,8 @@ "name": "NavSpec", "kind": "class", "path": "docforge.nav.spec.NavSpec", - "signature": "", - "docstring": "Parsed representation of a navigation specification.\n\nA ``NavSpec`` describes the intended documentation navigation layout before\nit is resolved against the filesystem.\n\nAttributes:\n home: Relative path to the documentation home page (for example\n ``index.md``).\n groups: Mapping of navigation group titles to lists of file patterns\n or glob expressions.", + "signature": "", + "docstring": "Parsed representation of a navigation specification.\n\nA ``NavSpec`` describes the intended documentation navigation layout before\nit is resolved against the filesystem.\n\nAttributes:\n home: Relative path to the documentation home page (for example\n ``index.md``).\n groups: Mapping of navigation group titles to lists of file patterns\n or glob expressions.\n icon: Optional mapping of theme icon entries (for example\n ``{\"logo\": \"material/code-tags\"}``) injected into the MkDocs\n theme as ``theme.icon``.", "members": { "home": { "name": "home", @@ -1942,18 +2174,25 @@ "signature": null, "docstring": null }, + "icon": { + "name": "icon", + "kind": "attribute", + "path": "docforge.nav.spec.NavSpec.icon", + "signature": null, + "docstring": null + }, "load": { "name": "load", "kind": "function", "path": "docforge.nav.spec.NavSpec.load", - "signature": "", + "signature": "", "docstring": "Load a navigation specification from a YAML file.\n\nArgs:\n path: Filesystem path to the navigation specification file.\n\nReturns:\n A ``NavSpec`` instance representing the parsed configuration.\n\nRaises:\n FileNotFoundError: If the specified file does not exist.\n ValueError: If the file contents are not a valid navigation\n specification." }, "all_patterns": { "name": "all_patterns", "kind": "function", "path": "docforge.nav.spec.NavSpec.all_patterns", - "signature": "", + "signature": "", "docstring": "Return all path patterns referenced by the specification.\n\nReturns:\n A list containing the home document (if defined) and all\n group pattern entries." } } @@ -1962,7 +2201,7 @@ "name": "load_nav_spec", "kind": "function", "path": "docforge.nav.spec.load_nav_spec", - "signature": "", + "signature": "", "docstring": "Load a navigation specification file.\n\nThis helper function reads a YAML navigation file and constructs a\ncorresponding ``NavSpec`` instance.\n\nArgs:\n path: Path to the navigation specification file.\n\nReturns:\n A ``NavSpec`` instance representing the parsed specification.\n\nRaises:\n FileNotFoundError: If the specification file does not exist.\n ValueError: If the YAML structure is invalid." } } diff --git a/docs/mcp/modules/docforge.nav.json b/docs/mcp/modules/docforge.nav.json index 9f2d149..85ef248 100644 --- a/docs/mcp/modules/docforge.nav.json +++ b/docs/mcp/modules/docforge.nav.json @@ -9,7 +9,7 @@ "kind": "class", "path": "docforge.nav.NavSpec", "signature": "", - "docstring": "Parsed representation of a navigation specification.\n\nA ``NavSpec`` describes the intended documentation navigation layout before\nit is resolved against the filesystem.\n\nAttributes:\n home: Relative path to the documentation home page (for example\n ``index.md``).\n groups: Mapping of navigation group titles to lists of file patterns\n or glob expressions.", + "docstring": "Parsed representation of a navigation specification.\n\nA ``NavSpec`` describes the intended documentation navigation layout before\nit is resolved against the filesystem.\n\nAttributes:\n home: Relative path to the documentation home page (for example\n ``index.md``).\n groups: Mapping of navigation group titles to lists of file patterns\n or glob expressions.\n icon: Optional mapping of theme icon entries (for example\n ``{\"logo\": \"material/code-tags\"}``) injected into the MkDocs\n theme as ``theme.icon``.", "members": { "home": { "name": "home", @@ -25,6 +25,13 @@ "signature": "", "docstring": null }, + "icon": { + "name": "icon", + "kind": "attribute", + "path": "docforge.nav.NavSpec.icon", + "signature": "", + "docstring": null + }, "load": { "name": "load", "kind": "function", @@ -203,7 +210,7 @@ "kind": "class", "path": "docforge.nav.resolver.NavSpec", "signature": "", - "docstring": "Parsed representation of a navigation specification.\n\nA ``NavSpec`` describes the intended documentation navigation layout before\nit is resolved against the filesystem.\n\nAttributes:\n home: Relative path to the documentation home page (for example\n ``index.md``).\n groups: Mapping of navigation group titles to lists of file patterns\n or glob expressions.", + "docstring": "Parsed representation of a navigation specification.\n\nA ``NavSpec`` describes the intended documentation navigation layout before\nit is resolved against the filesystem.\n\nAttributes:\n home: Relative path to the documentation home page (for example\n ``index.md``).\n groups: Mapping of navigation group titles to lists of file patterns\n or glob expressions.\n icon: Optional mapping of theme icon entries (for example\n ``{\"logo\": \"material/code-tags\"}``) injected into the MkDocs\n theme as ``theme.icon``.", "members": { "home": { "name": "home", @@ -219,6 +226,13 @@ "signature": "", "docstring": null }, + "icon": { + "name": "icon", + "kind": "attribute", + "path": "docforge.nav.resolver.NavSpec.icon", + "signature": "", + "docstring": null + }, "load": { "name": "load", "kind": "function", @@ -299,8 +313,8 @@ "name": "NavSpec", "kind": "class", "path": "docforge.nav.spec.NavSpec", - "signature": "", - "docstring": "Parsed representation of a navigation specification.\n\nA ``NavSpec`` describes the intended documentation navigation layout before\nit is resolved against the filesystem.\n\nAttributes:\n home: Relative path to the documentation home page (for example\n ``index.md``).\n groups: Mapping of navigation group titles to lists of file patterns\n or glob expressions.", + "signature": "", + "docstring": "Parsed representation of a navigation specification.\n\nA ``NavSpec`` describes the intended documentation navigation layout before\nit is resolved against the filesystem.\n\nAttributes:\n home: Relative path to the documentation home page (for example\n ``index.md``).\n groups: Mapping of navigation group titles to lists of file patterns\n or glob expressions.\n icon: Optional mapping of theme icon entries (for example\n ``{\"logo\": \"material/code-tags\"}``) injected into the MkDocs\n theme as ``theme.icon``.", "members": { "home": { "name": "home", @@ -316,18 +330,25 @@ "signature": null, "docstring": null }, + "icon": { + "name": "icon", + "kind": "attribute", + "path": "docforge.nav.spec.NavSpec.icon", + "signature": null, + "docstring": null + }, "load": { "name": "load", "kind": "function", "path": "docforge.nav.spec.NavSpec.load", - "signature": "", + "signature": "", "docstring": "Load a navigation specification from a YAML file.\n\nArgs:\n path: Filesystem path to the navigation specification file.\n\nReturns:\n A ``NavSpec`` instance representing the parsed configuration.\n\nRaises:\n FileNotFoundError: If the specified file does not exist.\n ValueError: If the file contents are not a valid navigation\n specification." }, "all_patterns": { "name": "all_patterns", "kind": "function", "path": "docforge.nav.spec.NavSpec.all_patterns", - "signature": "", + "signature": "", "docstring": "Return all path patterns referenced by the specification.\n\nReturns:\n A list containing the home document (if defined) and all\n group pattern entries." } } @@ -336,7 +357,7 @@ "name": "load_nav_spec", "kind": "function", "path": "docforge.nav.spec.load_nav_spec", - "signature": "", + "signature": "", "docstring": "Load a navigation specification file.\n\nThis helper function reads a YAML navigation file and constructs a\ncorresponding ``NavSpec`` instance.\n\nArgs:\n path: Path to the navigation specification file.\n\nReturns:\n A ``NavSpec`` instance representing the parsed specification.\n\nRaises:\n FileNotFoundError: If the specification file does not exist.\n ValueError: If the YAML structure is invalid." } } diff --git a/docs/mcp/modules/docforge.nav.resolver.json b/docs/mcp/modules/docforge.nav.resolver.json index 096f242..2df085f 100644 --- a/docs/mcp/modules/docforge.nav.resolver.json +++ b/docs/mcp/modules/docforge.nav.resolver.json @@ -30,7 +30,7 @@ "kind": "class", "path": "docforge.nav.resolver.NavSpec", "signature": "", - "docstring": "Parsed representation of a navigation specification.\n\nA ``NavSpec`` describes the intended documentation navigation layout before\nit is resolved against the filesystem.\n\nAttributes:\n home: Relative path to the documentation home page (for example\n ``index.md``).\n groups: Mapping of navigation group titles to lists of file patterns\n or glob expressions.", + "docstring": "Parsed representation of a navigation specification.\n\nA ``NavSpec`` describes the intended documentation navigation layout before\nit is resolved against the filesystem.\n\nAttributes:\n home: Relative path to the documentation home page (for example\n ``index.md``).\n groups: Mapping of navigation group titles to lists of file patterns\n or glob expressions.\n icon: Optional mapping of theme icon entries (for example\n ``{\"logo\": \"material/code-tags\"}``) injected into the MkDocs\n theme as ``theme.icon``.", "members": { "home": { "name": "home", @@ -46,6 +46,13 @@ "signature": "", "docstring": null }, + "icon": { + "name": "icon", + "kind": "attribute", + "path": "docforge.nav.resolver.NavSpec.icon", + "signature": "", + "docstring": null + }, "load": { "name": "load", "kind": "function", diff --git a/docs/mcp/modules/docforge.nav.spec.json b/docs/mcp/modules/docforge.nav.spec.json index 99a8855..ab0d693 100644 --- a/docs/mcp/modules/docforge.nav.spec.json +++ b/docs/mcp/modules/docforge.nav.spec.json @@ -22,8 +22,8 @@ "name": "NavSpec", "kind": "class", "path": "docforge.nav.spec.NavSpec", - "signature": "", - "docstring": "Parsed representation of a navigation specification.\n\nA ``NavSpec`` describes the intended documentation navigation layout before\nit is resolved against the filesystem.\n\nAttributes:\n home: Relative path to the documentation home page (for example\n ``index.md``).\n groups: Mapping of navigation group titles to lists of file patterns\n or glob expressions.", + "signature": "", + "docstring": "Parsed representation of a navigation specification.\n\nA ``NavSpec`` describes the intended documentation navigation layout before\nit is resolved against the filesystem.\n\nAttributes:\n home: Relative path to the documentation home page (for example\n ``index.md``).\n groups: Mapping of navigation group titles to lists of file patterns\n or glob expressions.\n icon: Optional mapping of theme icon entries (for example\n ``{\"logo\": \"material/code-tags\"}``) injected into the MkDocs\n theme as ``theme.icon``.", "members": { "home": { "name": "home", @@ -39,18 +39,25 @@ "signature": null, "docstring": null }, + "icon": { + "name": "icon", + "kind": "attribute", + "path": "docforge.nav.spec.NavSpec.icon", + "signature": null, + "docstring": null + }, "load": { "name": "load", "kind": "function", "path": "docforge.nav.spec.NavSpec.load", - "signature": "", + "signature": "", "docstring": "Load a navigation specification from a YAML file.\n\nArgs:\n path: Filesystem path to the navigation specification file.\n\nReturns:\n A ``NavSpec`` instance representing the parsed configuration.\n\nRaises:\n FileNotFoundError: If the specified file does not exist.\n ValueError: If the file contents are not a valid navigation\n specification." }, "all_patterns": { "name": "all_patterns", "kind": "function", "path": "docforge.nav.spec.NavSpec.all_patterns", - "signature": "", + "signature": "", "docstring": "Return all path patterns referenced by the specification.\n\nReturns:\n A list containing the home document (if defined) and all\n group pattern entries." } } @@ -59,7 +66,7 @@ "name": "load_nav_spec", "kind": "function", "path": "docforge.nav.spec.load_nav_spec", - "signature": "", + "signature": "", "docstring": "Load a navigation specification file.\n\nThis helper function reads a YAML navigation file and constructs a\ncorresponding ``NavSpec`` instance.\n\nArgs:\n path: Path to the navigation specification file.\n\nReturns:\n A ``NavSpec`` instance representing the parsed specification.\n\nRaises:\n FileNotFoundError: If the specification file does not exist.\n ValueError: If the YAML structure is invalid." } } diff --git a/docs/mcp/nav.json b/docs/mcp/nav.json index c3c9367..8f62362 100644 --- a/docs/mcp/nav.json +++ b/docs/mcp/nav.json @@ -7,6 +7,10 @@ "module": "docforge.cli", "resource": "doc://modules/docforge.cli" }, + { + "module": "docforge.cli.api_utils", + "resource": "doc://modules/docforge.cli.api_utils" + }, { "module": "docforge.cli.commands", "resource": "doc://modules/docforge.cli.commands" diff --git a/mkdocs.yml b/mkdocs.yml index 0c54747..87ef16b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -21,6 +21,31 @@ theme: - search.highlight - search.share - search.suggest + icon: + logo: material/file-document-multiple + repo: fontawesome/brands/github +markdown_extensions: +- pymdownx.superfences +- pymdownx.inlinehilite +- pymdownx.snippets +- admonition +- pymdownx.details +- pymdownx.highlight: + linenums: true + anchor_linenums: true + line_spans: __span + pygments_lang_class: true +- pymdownx.tabbed: + alternate_style: true +- pymdownx.tasklist: + custom_checkbox: true +- tables +- footnotes +- pymdownx.caret +- pymdownx.tilde +- pymdownx.mark +extra_css: +- https://unpkg.com/dracula-prism/dist/css/dracula-prism.css plugins: - search - mkdocstrings: @@ -41,52 +66,32 @@ plugins: show_category_heading: true show_object_full_path: false show_symbol_type_heading: true -markdown_extensions: -- pymdownx.superfences -- pymdownx.inlinehilite -- pymdownx.snippets -- admonition -- pymdownx.details -- pymdownx.superfences -- pymdownx.highlight: - linenums: true - anchor_linenums: true - line_spans: __span - pygments_lang_class: true -- pymdownx.tabbed: - alternate_style: true -- pymdownx.tasklist: - custom_checkbox: true -- tables -- footnotes -- pymdownx.caret -- pymdownx.tilde -- pymdownx.mark site_name: docforge -docs_dir: docs/lib +docs_dir: docs nav: -- Home: index.md +- Home: lib/index.md - Loaders: - - loaders/index.md - - loaders/griffe_loader.md + - lib/loaders/index.md + - lib/loaders/griffe_loader.md - Models: - - models/index.md - - models/module.md - - models/object.md - - models/project.md + - lib/models/index.md + - lib/models/module.md + - lib/models/object.md + - lib/models/project.md - Navigation: - - nav/index.md - - nav/spec.md - - nav/resolver.md - - nav/mkdocs.md + - lib/nav/index.md + - lib/nav/spec.md + - lib/nav/resolver.md + - lib/nav/mkdocs.md - Renderers: - - renderers/index.md - - renderers/base.md - - renderers/mkdocs_renderer.md - - renderers/mcp_renderer.md + - lib/renderers/index.md + - lib/renderers/base.md + - lib/renderers/mkdocs_renderer.md + - lib/renderers/mcp_renderer.md - CLI: - - cli/index.md - - cli/main.md - - cli/commands.md - - cli/mcp_utils.md - - cli/mkdocs_utils.md + - lib/cli/index.md + - lib/cli/main.md + - lib/cli/commands.md + - lib/cli/api_utils.md + - lib/cli/mcp_utils.md + - lib/cli/mkdocs_utils.md diff --git a/pyproject.toml b/pyproject.toml index 3979bc9..6e02ea3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -67,6 +67,7 @@ mkdocs = [ "pymdown-extensions==10.16.1", "neoteroi-mkdocs==1.1.3", + "mkdocs-swagger-ui-tag>=0.3.0", ] sphinx = [ "sphinx>=5.0.0", diff --git a/tests/cli/test_build_api.py b/tests/cli/test_build_api.py new file mode 100644 index 0000000..3489e31 --- /dev/null +++ b/tests/cli/test_build_api.py @@ -0,0 +1,134 @@ +import json +from pathlib import Path + +from docforge.cli.main import cli + + +def _write_spec(cwd, title="Aetoskia Auth Server", description="Auth docs"): + spec = { + "openapi": "3.1.0", + "info": { + "title": title, + "description": description, + "contact": { + "name": "Aetoskia Dev Team", + "email": "dev@aetoskia.com", + }, + "version": "0.0.5", + }, + "paths": {}, + } + path = cwd / "openapi.json" + path.write_text(json.dumps(spec), encoding="utf-8") + return path + + +def test_api_build_full_flow( + cli_runner, + mock_mkdocs_build, + mock_mkdocs_load_config, +): + with cli_runner.isolated_filesystem(): + cwd = Path.cwd() + + spec_path = _write_spec(cwd) + + nav_file = cwd / "docforge.nav.yml" + nav_file.write_text( + "home: api/index.md\ngroups: {}\n" + "icon:\n" + " logo: material/database\n" + " repo: fontawesome/brands/github\n", + encoding="utf-8", + ) + + result = cli_runner.invoke( + cli, + ["build", "--api", "--openapi-spec", str(spec_path)], + ) + + assert result.exit_code == 0, result.output + assert mock_mkdocs_build() is True + + api_dir = cwd / "docs" / "api" + assert (api_dir / "openapi.json").exists() + index = (api_dir / "index.md").read_text(encoding="utf-8") + assert '' in index + + config = (cwd / "mkdocs.yml").read_text(encoding="utf-8") + assert "docs_dir: docs" in config + assert "site_name: Aetoskia Auth Server" in config + assert "site_description: Auth docs" in config + assert "site_author: Aetoskia Dev Team" in config + assert "swagger-ui-tag" in config + assert "logo: material/database" in config + assert "repo: fontawesome/brands/github" in config + + +def test_api_build_missing_spec_fails(cli_runner): + result = cli_runner.invoke(cli, ["build", "--api"]) + assert result.exit_code != 0 + assert "--openapi-spec is required" in result.output + + +def test_api_build_spec_not_found(cli_runner): + result = cli_runner.invoke(cli, ["build", "--api", "--openapi-spec", "nope.json"]) + assert result.exit_code != 0 + assert "OpenAPI spec not found" in result.output + + +def test_api_build_rejects_site_name_override(cli_runner): + with cli_runner.isolated_filesystem(): + cwd = Path.cwd() + spec_path = _write_spec(cwd) + + result = cli_runner.invoke( + cli, + ["build", "--api", "--openapi-spec", str(spec_path), "--site-name", "X"], + ) + assert result.exit_code != 0 + assert "cannot be overridden" in result.output + + +def test_api_build_combined_with_mkdocs_allows_site_name_for_lib( + cli_runner, mock_mkdocs_build, mock_mkdocs_load_config +): + # site_name is accepted when --mkdocs is also present (lib mode owns it) + with cli_runner.isolated_filesystem(): + cwd = Path.cwd() + + pkg = cwd / "testpkg" + pkg.mkdir() + (pkg / "__init__.py").write_text("") + (pkg / "mod.py").write_text("def f(): ...\n") + + spec_path = _write_spec(cwd) + + nav_file = cwd / "docforge.nav.yml" + nav_file.write_text( + "home: lib/testpkg/index.md\n" + "groups:\n" + " API:\n" + " - api/index.md\n", + encoding="utf-8", + ) + + result = cli_runner.invoke( + cli, + [ + "build", + "--mkdocs", + "--api", + "--module", + "testpkg", + "--openapi-spec", + str(spec_path), + ], + ) + + assert result.exit_code == 0, result.output + + config = (cwd / "mkdocs.yml").read_text(encoding="utf-8") + assert "docs_dir: docs" in config + assert "swagger-ui-tag" in config + assert "mkdocstrings" in config diff --git a/tests/cli/test_build_mkdocs.py b/tests/cli/test_build_mkdocs.py index b44da95..501011b 100644 --- a/tests/cli/test_build_mkdocs.py +++ b/tests/cli/test_build_mkdocs.py @@ -18,7 +18,7 @@ def test_mkdocs_build_full_flow( (pkg / "mod.py").write_text("def f(): ...\n") nav_file = cwd / "docforge.nav.yml" - nav_file.write_text("home: testpkg/index.md\ngroups: {}\n") + nav_file.write_text("home: lib/testpkg/index.md\ngroups: {}\n") # We need to create a dummy testpkg/index.md for nav resolution if it's there # But generate_sources will create it. @@ -42,7 +42,7 @@ def test_mkdocs_build_full_flow( assert mock_mkdocs_build() is True assert (cwd / "mkdocs.yml").exists() assert (cwd / "docs" / "lib" / "testpkg" / "mod.md").exists() - assert "docs_dir: docs/lib" in (cwd / "mkdocs.yml").read_text() + assert "docs_dir: docs" in (cwd / "mkdocs.yml").read_text() def test_mkdocs_build_missing_module_fails(cli_runner): @@ -69,7 +69,7 @@ def test_mkdocs_build_without_site_name_uses_module_as_default_full_flow( # Create nav spec expected by generate_config nav_file = cwd / "docforge.nav.yml" nav_file.write_text( - "home: testpkg/index.md\ngroups: {}\n", + "home: lib/testpkg/index.md\ngroups: {}\n", encoding="utf-8", )