The device registry#
Every machine listed on the Supported Machines page comes from a single JSON file,
docs/_static/devices.json. Two directives read it: device-table renders a searchable table of
devices, device-card renders a single device as a card. Adding a machine to the docs means adding
one object to that file.
Adding a device#
Append an object to docs/_static/devices.json:
{
"id": "curiox-ht2000",
"vendor": "Curiox",
"name": "HT2000",
"kind": "plate washer",
"capabilities": ["plate washing"],
"status": "mostly",
"api": "pylabrobot.curiox.CurioxHT2000",
"api_version": "v1",
"code_slug": "curiox",
"doc_slug": "curiox/curiox-ht2000/hello-world",
"manager": "https://discuss.pylabrobot.org/u/rickwierenga",
"oem": "https://curiox.com/"
}
Field |
Required |
Meaning |
|---|---|---|
|
yes |
Unique kebab-case identifier. Used by |
|
yes |
Manufacturer, as users would search for it. |
|
yes |
Model name, without the vendor. |
|
yes |
Device type, e.g. |
|
yes |
One of |
|
no |
Core functions, e.g. |
|
no |
Import path of the driver class, e.g. |
|
no |
|
|
no |
The machine’s own page, relative to |
|
no |
The driver’s module or package, relative to |
|
no |
Forum profile of whoever looks after this driver, e.g. |
|
no |
Manufacturer product page. |
|
no |
One line about which models the entry covers, or what is missing. |
The registry is validated when the docs build starts: unknown fields, duplicate ids and unknown
statuses fail the build, as do doc_slug and code_slug values that do not point at a real page
or a real module.
kind and capabilities are controlled vocabularies, listed as KINDS and CAPABILITIES in
docs/_exts/plr_devices/data.py. A machine that needs a genuinely new term gets it added there in
the same change — the point is that “sealer” and “heat sealer” cannot quietly become two different
filter chips. Terms that nothing uses are removed, and a test enforces both directions.
The two slugs exist so entries stay short and the prefixes stay in one place. doc_slug is
resolved against plr_devices_doc_prefix, and code_slug against plr_devices_code_root and the
repository and branch in html_context — the same ones the theme’s “edit this page” links use.
Adding a guide to an existing device#
If a device already has a registry object, update that object rather than appending another one:
Set
doc_slugto the guide’s path relative todocs/user_guide/, without.mdor.ipynb.Add the guide to its manufacturer’s
{toctree}.Put a
{device-card}directive in the guide using the registry object’sid.
For example, a notebook at docs/user_guide/agilent/vspin/hello-world.ipynb uses:
"doc_slug": "agilent/vspin/hello-world"
and its card is:
```{device-card} agilent-vspin
```
Validate registry changes with:
python -m pytest docs/_exts/plr_devices/registry_tests.py
Rendering a table#
A bare device-table renders every device, with a search box and filter chips:
```{device-table}
```
Options narrow it down:
```{device-table}
:vendor: QInstruments
:search: false
:filters: false
```
capabilities, vendor, kind and status each take one value and filter the rows. search and
filters take false to hide the search box or the chips, which is useful for a short,
pre-filtered list on a vendor page.
Rendering a card#
device-card renders one device. It works anywhere MyST is parsed, including markdown cells in the
notebooks under docs/user_guide — put one at the top of a machine’s hello-world notebook so the
page carries the same vendor, support level, capabilities and links as the table.
```{device-card} curiox-ht2000
```
A directive is rendered when Sphinx builds the docs. In a notebook opened in an editor it shows as a literal code block instead, so a card on a notebook page only appears on the published version.
Styling#
The markup is generated by docs/_exts/plr_devices, and styled by docs/_static/plr_devices.css.
Search and filtering are handled by docs/_static/plr_devices.js. Capability badge colors are
derived from a hash of the capability name, so a new capability gets a stable color without a CSS
change.