DiamondLightSource / DiamondLightSource/fastcs
DOCS: Rewrite tutorials around the examples/ controllers (one per example, single-sourced)
- Dominant language
- Python
- Stars
- 6
- Forks
- 8
- Avg merge
- 2d 12h
- Merged PRs (30d)
- 3
Description
Rewrite the tutorials as a single pass once the `fastcs.demo` example controllers exist, sourcing all tutorial code directly from those living modules. Implements #388 §6.
## Decisions (settled with Tom, 2026-07-22)
1. **Single source of truth = `fastcs.demo`.** Tutorials `literalinclude` the finished example modules (consolidated into `src/fastcs/demo/`, mirroring ophyd-async); CI (`tox -e docs`) keeps them green so docs can't drift.
2. **Four tutorials** — a hello-world → complicated-device ladder (five example modules; the old "reusable `io=` object" rung is gone, because `io=` objects were replaced by getter/setter callables):
| # | Tutorial | Teaches | Backend | Module(s) |
|---|----------|---------|---------|-----------|
| 1 | hello world | pure-soft `@attr` decorator | none | `hello_world.py` (#398) |
| 2 | getter/setter | `getter`/`setter` callables in `__init__`; closes with "for a real family, go declarative →" | temperature | `temperature_attr.py` (#404) |
| 3 | declarative | annotated `SCPIParam` + filler (static metadata) **plus** composition — sub-controllers/vector + `@scan` + `@command` on the full temp controller | temperature | `temperature_scpi.py` + `scpi.py` (#405), drawing on `controllers.py` (#390) |
| 4 | introspectable | bare hints filled from a **runtime** REST parameter tree | Eiger REST | `eiger.py` (#391) |
3. **Finished-example walkthrough** pedagogy (not the old 15-diff "Code N" build). Retire `docs/snippets/static01–15.py` and `docs/snippets/dynamic.py`.
4. **One umbrella docs pass**, after the examples land (see `Blocked by:`).
## Scope
- Four tutorial pages replacing the current `static-drivers` / `dynamic-drivers` split; update `tutorials.md` nav; keep `installation.md`.
- All code blocks come from the `fastcs.demo` modules via `literalinclude` with region markers (`:start-after:` / `:end-before:`). **Add the markers to each module as part of writing its tutorial here.**
- **State the declarative (class-body) / procedural (instance-scope) rule up front**, mirroring ophyd-async's `declarative-vs-procedural` page.
- Teach the **post-refactor** API only: `getter`/`setter` callables and `@attr` (no `io=` objects, no `AttributeIORef`, no `DataType`, no hand-rolled pydantic filler).
- Framing to reinforce: the io= tutorial is replaced by a **recommendation** in tut 2 to use declarative for families; tut 3's SCPI is **not** introspectable (static `SCPIParam`; `SCPIController`/`SCPIParam` in the demo layer, not core); tut 4's **backend switch is the lesson**.
## Key files
`docs/tutorials/*`, `docs/tutorials.md`, `docs/snippets/*` (removed), `docs/explanations/`, `src/fastcs/demo/*` (+ its README), `docs/conf.py`.
## Acceptance
`uv run --locked tox -e docs` green (real CI — docs env doesn't run in the nightly sandbox); every tutorial renders code pulled live from `fastcs.demo`; no `docs/snippets/static*.py` remain.
## Labels / process
`documentation`. **Deliberately NOT `api-convergence`** — human pedagogy pass, can't verify in the nightly sandbox, depends on the examples; the autonomous nightly job ignores it.
ADR: #388 §6 (0013 declarative/procedural rule)
Parent: #388
Blocked by: #398, #404, #390, #405, #391
Contributor guide
Research direction
First check the blocked example modules in src/fastcs/demo/ and the current pages under docs/tutorials/, then review docs/tutorials.md and docs/conf.py. Add the four tutorial pages with live literalincludes and markers, remove docs/snippets/static*.py and dynamic.py, and run uv run --locked tox -e docs; done means the docs build is green and every tutorial renders code from fastcs.demo.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- documentation
- Issue type
- Documentation
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 45/100