DiamondLightSource / DiamondLightSource/fastcs
Documentation improvements: new tutorials, explanations, and docstrings
- Dominant language
- Python
- Stars
- 6
- Forks
- 8
- Avg merge
- 2d 12h
- Merged PRs (30d)
- 3
Description
## Summary
After analyzing the FastCS source code, I've identified several documentation gaps that would improve the developer experience. The recommendations are organized following the existing Diataxis framework (tutorials, how-to guides, explanations, reference).
---
## 1. Recommended New Tutorials
### 1.1 "Your First FastCS Controller" (HIGH PRIORITY)
**Gap:** The existing static-drivers tutorial is excellent but comprehensive. New users need a gentler 5-minute introduction.
**Should cover:**
- Minimal Controller with one `AttrR` attribute
- Running with `FastCS` class and empty transports
- Verifying in the interactive shell
### 1.2 "Understanding Transports" (HIGH PRIORITY)
**Gap:** No dedicated tutorial on configuring transports. Users from different control system backgrounds need specific guidance.
**Should cover:**
- Installing transport-specific extras (`pip install 'fastcs[epics-ca]'`)
- Transport options classes (`EpicsIOCOptions`, `RestOptions`)
- Running multiple transports simultaneously
- GUI generation for EPICS, REST endpoints, GraphQL queries
### 1.3 "Working with DataTypes" (MEDIUM PRIORITY)
**Gap:** DataType fields like `prec`, `min_alarm`, `max_alarm`, `units` are undocumented.
**Should cover:**
- Scalar types: `Int`, `Float`, `Bool`, `String` with metadata fields
- `Enum` with Python's `StrEnum`/`IntEnum`
- Array types: `Waveform` with `array_dtype` and `shape`
- Structured data: `Table` with `structured_dtype`
### 1.4 "Using the launch() CLI" (MEDIUM PRIORITY)
**Gap:** The `launch()` function is well-documented in code but no tutorial shows production usage.
**Should cover:**
- Creating entry points with `launch(MyController)`
- YAML configuration files
- Using `schema` subcommand for JSON schema generation
- Logging configuration and Graylog integration
---
## 2. Recommended New How-to Guides
### 2.1 "How to Create Custom AttributeIO Patterns" (HIGH PRIORITY)
**Gap:** Core pattern for device communication only learned through tutorial examples.
**Should cover:**
- Subclassing `AttributeIORef` with device-specific fields
- Implementing `AttributeIO.update()` and `send()`
- Registering IOs with Controllers via `ios` parameter
- Type conversion between device protocol and Python
### 2.2 "How to Wait for Attribute Values" (MEDIUM PRIORITY)
**Gap:** `wait_for_value()` and `wait_for_predicate()` methods exist but are undocumented.
**Should cover:**
- Using `attr.wait_for_value(target, timeout=...)`
- Using `attr.wait_for_predicate(predicate, timeout=...)`
- Handling `TimeoutError`
- Patterns for coordinating multiple attributes
### 2.3 "How to Use Tracing for Debugging" (MEDIUM PRIORITY)
**Gap:** The `Tracer` class is powerful but only briefly mentioned in static-drivers tutorial.
**Should cover:**
- Enabling tracing on attributes (`attr.enable_tracing()`)
- Setting log level to `TRACE` with `configure_logging()`
- Interpreting trace output across the stack
### 2.4 "How to Configure EPICS GUI Generation" (LOW PRIORITY)
**Should cover:** `EpicsGUIOptions` fields, PVI integration, customizing layouts
---
## 3. Recommended New Explanations
### 3.1 "FastCS Architecture Overview" (HIGH PRIORITY)
**Gap:** No high-level architectural document exists.
**Should cover:**
- Controller-Attribute-Transport layered architecture
- How `FastCS` class orchestrates the application lifecycle
- The role of `ControllerAPI` as the transport abstraction layer
- Event loop management and async patterns
### 3.2 "The Attribute System" (HIGH PRIORITY)
**Gap:** The callback architecture is complex and affects driver behavior.
**Should cover:**
- `AttrR`, `AttrW`, `AttrRW` inheritance hierarchy
- The callback system (`_update_callback`, `_on_update_callbacks`, `_on_put_callback`)
- Value flow: device -> AttributeIO -> Attribute -> Transport
- `DataType` validation
### 3.3 "The AttributeIO Pattern" (HIGH PRIORITY)
**Gap:** ADR-0009 explains the "why" but not the "how it works".
**Should cover:**
- Why the pattern exists (breaking circular dependencies)
- Relationship between `AttributeIO`, `AttributeIORef`, and `Attribute`
- Type parameterization and runtime matching
- Connection vs. reference separation
### 3.4 "Controller Lifecycle" (MEDIUM PRIORITY)
**Should cover:** `__init__()` -> `initialise()` -> `post_initialise()` -> `connect()` -> `disconnect()` flow
### 3.5 "Scan and Update Loops" (MEDIUM PRIORITY)
**Should cover:** How `@scan` methods become periodic tasks, `update_period`, the `ONCE` sentinel
---
## 4. Docstring Improvements
### Priority 1 - Critical (Core Public API)
| Class/Function | File | Issue |
|---|---|---|
| `FastCS` class | `control_system.py:20` | Has docstring but missing method docs for `run()`, `serve()` |
| `Controller.connect()` | `controllers/controller.py` | No docstring - key lifecycle method |
| `Controller.disconnect()` | `controllers/controller.py` | No docstring - key lifecycle method |
| `@scan` decorator | `methods/scan.py:87` | Minimal - needs Args for `period`, explain `ONCE` sentinel, example |
| `Scan` class | `methods/scan.py:19` | Good class doc but `period` parameter undocumented |
### Priority 2 - High (Undocumented Fields)
| Item | File | Issue |
|---|---|---|
| `Float.prec` | `datatypes/float.py` | No doc - controls decimal precision |
| `_Numeric` fields | `datatypes/_numeric.py` | `units`, `min`, `max`, `min_alarm`, `max_alarm` undocumented |
| `Waveform.array_dtype/shape` | `datatypes/waveform.py` | No field docs |
| `Table.structured_dtype` | `datatypes/table.py` | No field docs - needs numpy dtype example |
| `AttributeIORef.update_period` | `attributes/attribute_io_ref.py` | No doc - critical for polling frequency |
### Priority 3 - Medium (Protocol Methods)
| Item | File | Issue |
|---|---|---|
| `AttributeIO.update()` | `attributes/attribute_io.py` | No docstring - core interface |
| `AttributeIO.send()` | `attributes/attribute_io.py` | No docstring - core interface |
| `Transport.connect()` | `transports/transport.py` | No docstring |
| `Transport.serve()` | `transports/transport.py` | No docstring |
### Priority 4 - Lower (Transport Implementations)
- `EpicsCATransport`, `EpicsIOCOptions`, `RestTransport`, `GraphQLTransport` - minimal docs
---
## Good Examples to Follow
These existing docstrings demonstrate the quality standard:
1. **`launch()` function** (`launch.py`) - Excellent: full Args, Raises, Example sections
2. **`@command` decorator** - Good: Args section with `group` parameter
3. **`Scan` class** - Good class-level description of purpose
4. **`Tracer` class** - Well documented with usage context
---
## Suggested Priority Order
**Do First (Highest Impact):**
1. Explanation: "FastCS Architecture Overview"
2. Explanation: "The Attribute System"
3. Tutorial: "Understanding Transports"
4. How-to: "Create Custom AttributeIO Patterns"
5. Docstrings: `@scan`, `Controller.connect/disconnect`, `AttributeIO` methods
**Do Next:**
1. Tutorial: "Your First FastCS Controller"
2. Explanation: "The AttributeIO Pattern"
3. Tutorial: "Working with DataTypes"
4. Docstrings: DataType fields (`prec`, `units`, `min`, `max`)
5. How-to: "Wait for Attribute Values"
Contributor guide
Assessment
This issue has not been assessed yet.