# Documentation Writing

> Use when writing or editing documentation under docs/ — page layout, docs_src snippet embedding, snippet tests, link conventions, and FastStream example-code rules.

- Skill: `ag2ai/documentation-writing` (Agent Skill)
- Install (CLI): `npx skillmds@latest add ag2ai/documentation-writing`
- Raw SKILL.md: https://api.skillmd.com/api/skills/ag2ai/documentation-writing/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: ag2ai (https://skillmd.com/u/ag2ai)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/ag2ai/documentation-writing

---


# FastStream Documentation Writing

## Layout

- Pages: `docs/docs/en/...` (markdown; mkdocs-material with the i18n plugin — English is the source language).
- Runnable code snippets: `docs/docs_src/<topic>/...` (fully excluded from ruff — see `exclude` in `ruff.toml`).
- Navigation: `docs/docs/SUMMARY.md` (literate-nav) — new pages need an entry there.
- API reference pages are generated by `docs/create_api_docs.py` — never hand-edit them.

## Code snippets

Never inline non-trivial code in markdown. Put a runnable Python file in `docs/docs_src/` and embed it with `mdx_include`:

```python linenums="1" hl_lines="10"
{!> docs_src/getting_started/publishing/kafka/broker.py !}
```

New `docs_src` snippets should get a test under `tests/docs/<topic>/test_<feature>.py` — one test file covers all broker variants via require marks (e.g. `@require_aiokafka`), not one file per broker subdir (see the **testing-patterns** skill). Some examples are intentionally untested; the exemptions are listed in the coverage `omit` list in `pyproject.toml`.

A snippet test imports the runnable objects from the module and exercises them in-memory — never a bare `import module` (it tests nothing and trips ruff `F401`):

```python
import pytest

from faststream.nats import TestApp, TestNatsBroker


@pytest.mark.nats()
@pytest.mark.asyncio()
async def test_basic() -> None:
    from docs.docs_src.nats.js.pull_sub import app, broker, handle

    async with TestNatsBroker(broker), TestApp(app):
        await broker.publish("Hi!", "test")
        handle.mock.assert_called_once_with("Hi!")
```

The test imports via the `docs.docs_src.…` package path, while the markdown embeds it via the `docs_src/…` path (mdx_include `base_path` is `docs/`). Either way the snippet MUST live under `docs/docs_src/`, not repo-root `docs_src/` — otherwise the embed silently resolves to nothing and the import fails.

## Markdown conventions

- External links: `[text](https://...){.external-link target="_blank"}`; internal links: `{.internal-link}`.
- Multi-broker pages use pymdownx tabs with one snippet per broker:

  ```markdown
  === "AIOKafka"
      ...embedded kafka snippet...

  === "Confluent"
      ...embedded confluent snippet...

  === "RabbitMQ"
      ...embedded rabbit snippet...
  ```

- Admonitions (`!!! note`, `!!! tip`, `!!! warning`) are available and encouraged for caveats.

## Example-code rules (FastStream usage)

All example code must follow idiomatic FastStream usage:

- Create the broker outside the app and pass it positionally: `app = FastStream(broker)`. Don't use `app.broker`.
- Prefer the `faststream.Logger` annotation in broker handlers over `print()` (some HTTP-integration examples use `print()` for brevity).
- Register subscribers/publishers only via `@broker.subscriber(...)` / `@broker.publisher(...)` (or the router equivalents).
- Fully annotate handler parameters; handlers return `None` unless their return value is published.
- Don't add decorator options the example doesn't need.
- Use `Annotated[str, Path()]` for subject path params and `Annotated[..., Context()]` for context access (built-ins: `broker`, `context`, `logger`, `message`).
- Import only from public packages — never `faststream._internal`.

## Build & serve

- `just docs-serve` — live dev server on port 8000.
- `just docs-build` — build the static site.
- `just docs-build-api` — regenerate the API reference.

## Related skills

- **testing-patterns** — how to mark and run the snippet tests in `tests/docs/`.
- **code-architecture** — source conventions example code must follow (public API only, no `_internal` imports).
- **dev-workflow** — environment setup for the docs toolchain.

