annotated-doc
Document parameters, class attributes, return types, and variables inline using typing.Annotated.
Repository Health
Technical Analysis
annotated-doc provides a single Doc class that lets Python developers attach documentation strings directly to parameters, class attributes, return types, and variables using the standard typing.Annotated construct, instead of writing separate docstring blocks in Sphinx, Google, or NumPy style. It began life as PEP 727, proposed for the Python standard library by FastAPI creator Sebastián Ramírez, and was published as a lightweight third-party package after the PEP was withdrawn.
Because the documentation lives inline next to the symbol it describes, editors get full syntax support for free, static tools can extract docs straight from the AST, and there is no risk of a parameter being renamed or removed while its docstring entry is forgotten. It has zero runtime dependencies, works back to Python 3.8, and already underpins reference documentation generation for FastAPI, Typer, SQLModel, and Asyncer via the griffe-typingdoc tool.
What You Get
- A single
Docclass for attaching a documentation string to any type-annotated symbol viaAnnotated[T, Doc("...")] - Zero runtime dependencies and support for Python 3.8 through 3.14
- Documentation strings accessible at runtime, not just statically, since they live in the type annotation itself
- Compatibility with static analysis and documentation-rendering tools that read the AST, including
griffe-typingdoc
Common Use Cases
- Documenting FastAPI, Typer, or SQLModel-style function parameters and model fields inline for auto-generated API reference docs
- Library authors who want parameter docs to stay perfectly in sync with the signature, eliminating docstring/signature drift
- Teams that prefer avoiding a separate docstring micro-syntax (Sphinx/Google/NumPy) in favor of plain Python typing constructs
- AI coding tools and IDEs that benefit from documentation being co-located with the exact symbol it describes
Under The Hood
Architecture - The library is deliberately minimal: a single Doc class defined in src/annotated_doc/main.py and re-exported from src/annotated_doc/__init__.py, with no internal module graph to speak of. Its entire behavior is to be an inert marker object placed as the second argument to typing.Annotated, which downstream tools (editors, griffe-typingdoc, static analyzers) introspect via typing.get_type_hints or AST inspection rather than through any runtime logic the library itself provides.
Tech Stack - Pure Python, managed with uv (uv.lock, .python-version), packaged via a standard pyproject.toml with dynamic versioning and zero declared dependencies, targeting Python 3.8+ per its classifiers. A scripts/ directory wraps lint, format, test, and coverage workflows, and scripts/prepare_release.py automates release-note generation, mirroring the tooling conventions of tiangolo’s other projects (FastAPI, Typer).
Code Quality - The tests/ directory covers both the core Doc behavior (test_main.py) and the release-automation script itself (test_prepare_release.py), with a coverage-badge workflow wired into CI (.github/workflows/test.yml referenced from the README) and a .pre-commit-config.yaml enforcing lint/format checks before commits land, consistent with the polish expected from a project maintained by the FastAPI author.
API Design - The public surface is a single class with a one-argument constructor, so there is effectively no learning curve; the README documents the tradeoffs honestly, listing both reasons to use and reasons not to use the library, which is unusually transparent API guidance for a Python package.
Used by 3 apps in this directory
Agno
Devops · AI Development · Automation
Build, run, and manage agent platforms with a full production stack — SDK, runtime, and control plane included.
knowhere
AI Development · Developer Tools
Transform messy, unstructured documents into persistent, navigable memory that AI agents can actually use.
SWIRL
Search · Databases · Data Engineering
Federated AI search and RAG across 100+ enterprise sources—no data extraction, no vector database required.