448 lines
6.8 KiB
Python
448 lines
6.8 KiB
Python
"""
|
|
Renderer-agnostic Python documentation compiler that converts Python docstrings
|
|
into structured documentation for both humans (MkDocs) and machines (MCP / AI agents).
|
|
|
|
`doc-forge` statically analyzes source code, builds a semantic model of modules,
|
|
classes, functions, and attributes, and renders that model into documentation
|
|
outputs without executing user code.
|
|
|
|
---
|
|
|
|
## Installation
|
|
|
|
Install using pip:
|
|
|
|
pip install doc-forge
|
|
|
|
---
|
|
|
|
## Quick start
|
|
|
|
Generate a MkDocs site from a Python package:
|
|
|
|
doc-forge build --mkdocs --module my_package
|
|
|
|
Generate MCP JSON documentation:
|
|
|
|
doc-forge build --mcp --module my_package
|
|
|
|
Serve documentation locally:
|
|
|
|
doc-forge serve --mkdocs --module my_package
|
|
|
|
---
|
|
|
|
## Core concepts
|
|
|
|
**Loader**
|
|
|
|
Extracts symbols, signatures, and docstrings using static analysis.
|
|
|
|
**Semantic model**
|
|
|
|
Structured, renderer-agnostic representation of the API.
|
|
|
|
**Renderer**
|
|
|
|
Converts the semantic model into output formats such as MkDocs or MCP JSON.
|
|
|
|
**Symbol**
|
|
|
|
Any documentable object:
|
|
|
|
- module
|
|
- class
|
|
- function
|
|
- method
|
|
- property
|
|
- attribute
|
|
|
|
---
|
|
|
|
## Architecture
|
|
|
|
`doc-forge` follows a compiler architecture:
|
|
|
|
Front-end:
|
|
|
|
Static analysis of modules, classes, functions, type hints, and docstrings.
|
|
|
|
Middle-end:
|
|
|
|
Builds a semantic model describing symbols and relationships.
|
|
|
|
Back-end:
|
|
|
|
Renders documentation using interchangeable renderers.
|
|
|
|
This architecture ensures deterministic documentation generation.
|
|
|
|
---
|
|
|
|
## Rendering pipeline
|
|
|
|
Typical flow:
|
|
|
|
Python package
|
|
↓
|
|
Loader (static analysis)
|
|
↓
|
|
Semantic model
|
|
↓
|
|
Renderer
|
|
↓
|
|
MkDocs site or MCP JSON
|
|
|
|
---
|
|
|
|
## CLI usage
|
|
|
|
Build MkDocs documentation:
|
|
|
|
doc-forge build --mkdocs --module my_package
|
|
|
|
Build MCP documentation:
|
|
|
|
doc-forge build --mcp --module my_package
|
|
|
|
Serve MkDocs locally:
|
|
|
|
doc-forge serve --module my_package
|
|
|
|
---
|
|
|
|
## Public API
|
|
|
|
Loaders:
|
|
|
|
GriffeLoader
|
|
discover_module_paths
|
|
|
|
Renderers:
|
|
|
|
MkDocsRenderer
|
|
MCPRenderer
|
|
|
|
CLI:
|
|
|
|
main
|
|
|
|
Models:
|
|
|
|
models
|
|
|
|
---
|
|
|
|
## Google-Styled Doc-Forge Convention (GSDFC)
|
|
|
|
GSDFC defines how docstrings must be written so they render correctly in MkDocs
|
|
and remain machine-parsable.
|
|
|
|
Docstrings are the single source of truth. doc-forge compiles docstrings but does
|
|
not generate documentation content.
|
|
|
|
Documentation follows the Python import hierarchy.
|
|
|
|
---
|
|
|
|
### General rules
|
|
|
|
Use Markdown headings at package and module level.
|
|
|
|
Use Google-style sections at class and function level.
|
|
|
|
Supported structured sections:
|
|
|
|
Args:
|
|
Returns:
|
|
Raises:
|
|
Yields:
|
|
Attributes:
|
|
Notes:
|
|
Example:
|
|
Examples:
|
|
See Also:
|
|
|
|
Indent section contents using four spaces.
|
|
|
|
Type information must come from function signatures, not duplicated prose.
|
|
|
|
Avoid NumPy-style sections such as:
|
|
|
|
Parameters
|
|
Returns tables
|
|
|
|
Avoid pseudo-fields such as:
|
|
|
|
required:
|
|
default:
|
|
|
|
---
|
|
|
|
### Package docstrings
|
|
|
|
Package docstrings act as the documentation home page.
|
|
|
|
They should include:
|
|
|
|
Summary
|
|
---
|
|
Installation
|
|
Quick start
|
|
Core concepts
|
|
Architecture
|
|
Rendering pipeline
|
|
CLI usage
|
|
Public API
|
|
Examples
|
|
Notes
|
|
|
|
Example:
|
|
|
|
'''
|
|
My package summary.
|
|
|
|
---
|
|
|
|
## Installation
|
|
|
|
pip install my-package
|
|
|
|
## Quick start
|
|
|
|
from my_package import Foo
|
|
|
|
foo = Foo()
|
|
foo.run()
|
|
'''
|
|
|
|
---
|
|
|
|
### Module docstrings
|
|
|
|
Module docstrings describe subsystems.
|
|
|
|
Recommended sections:
|
|
|
|
Summary
|
|
---
|
|
Examples
|
|
Notes
|
|
Public API
|
|
|
|
Example:
|
|
|
|
'''
|
|
Execution subsystem.
|
|
|
|
---
|
|
|
|
Example:
|
|
|
|
from my_package.engine import Engine
|
|
|
|
engine = Engine(nodes)
|
|
'''
|
|
|
|
---
|
|
|
|
### Class docstrings
|
|
|
|
Class docstrings define object responsibility and lifecycle.
|
|
|
|
Supported sections:
|
|
|
|
Attributes:
|
|
Notes:
|
|
Example:
|
|
Raises:
|
|
|
|
Example:
|
|
|
|
class Engine:
|
|
'''
|
|
Executes pipelines.
|
|
|
|
Attributes:
|
|
nodes (tuple[Node, ...]):
|
|
Execution nodes.
|
|
|
|
Notes:
|
|
Guarantees:
|
|
|
|
- deterministic execution
|
|
- immutable state propagation
|
|
|
|
Lifecycle:
|
|
|
|
- reusable across executions
|
|
|
|
Example:
|
|
Basic usage:
|
|
|
|
engine = Engine(nodes)
|
|
engine.run(state)
|
|
'''
|
|
|
|
---
|
|
|
|
### Function and method docstrings
|
|
|
|
Function docstrings define API contracts.
|
|
|
|
Supported sections:
|
|
|
|
Args:
|
|
Returns:
|
|
Raises:
|
|
Yields:
|
|
Notes:
|
|
Example:
|
|
|
|
Example:
|
|
|
|
def run(state: State) -> list[State]:
|
|
'''
|
|
Execute pipeline.
|
|
|
|
Args:
|
|
state (State):
|
|
Initial execution state.
|
|
|
|
Returns:
|
|
list[State]:
|
|
Resulting execution states.
|
|
|
|
Notes:
|
|
Guarantees:
|
|
|
|
- state is not modified
|
|
'''
|
|
|
|
---
|
|
|
|
### Property docstrings
|
|
|
|
Properties must document return values.
|
|
|
|
Example:
|
|
|
|
@property
|
|
def nodes(self) -> tuple[Node, ...]:
|
|
'''
|
|
Return execution nodes.
|
|
|
|
Returns:
|
|
tuple[Node, ...]:
|
|
Configured nodes.
|
|
'''
|
|
|
|
---
|
|
|
|
### Attribute documentation
|
|
|
|
Attributes must be documented in the class docstring using Attributes:.
|
|
|
|
Example:
|
|
|
|
class State:
|
|
'''
|
|
Execution state.
|
|
|
|
Attributes:
|
|
payload (dict):
|
|
Immutable execution data.
|
|
|
|
depth (int):
|
|
Distance from root state.
|
|
'''
|
|
|
|
---
|
|
|
|
### Notes subsection grouping
|
|
|
|
Subsections may be grouped using labeled blocks:
|
|
|
|
Notes:
|
|
Guarantees:
|
|
|
|
- deterministic execution
|
|
|
|
Lifecycle:
|
|
|
|
- reusable instance
|
|
|
|
Thread safety:
|
|
|
|
- safe for concurrent use
|
|
|
|
Do not use horizontal separators inside structured sections.
|
|
|
|
---
|
|
|
|
### Example formatting
|
|
|
|
Use indentation for examples:
|
|
|
|
Example:
|
|
Basic usage:
|
|
|
|
engine = Engine(nodes)
|
|
engine.run(state)
|
|
|
|
Multiple examples may be grouped using labels.
|
|
|
|
---
|
|
|
|
### Separator rules
|
|
|
|
Use horizontal separators only at docstring root level:
|
|
|
|
---
|
|
|
|
Do not use separators inside:
|
|
|
|
Args:
|
|
Returns:
|
|
Notes:
|
|
Attributes:
|
|
|
|
---
|
|
|
|
### Parsing guarantees
|
|
|
|
GSDFC ensures doc-forge can deterministically extract:
|
|
|
|
symbol type
|
|
symbol name
|
|
parameters
|
|
return types
|
|
attributes
|
|
examples
|
|
structured notes
|
|
|
|
This enables reliable MkDocs rendering and MCP export.
|
|
|
|
---
|
|
|
|
## Notes
|
|
|
|
doc-forge never executes analyzed modules.
|
|
|
|
Documentation is generated entirely through static analysis.
|
|
"""
|
|
|
|
from .loaders import GriffeLoader, discover_module_paths
|
|
from .renderers import MkDocsRenderer, MCPRenderer
|
|
from .cli import main
|
|
from . import models
|
|
|
|
__all__ = [
|
|
"GriffeLoader",
|
|
"discover_module_paths",
|
|
"MkDocsRenderer",
|
|
"MCPRenderer",
|
|
"models",
|
|
"main",
|
|
]
|