Skill Tracer
Skills › Scientific Agent Skills › pylabrobot › visualization.md

visualization.md

187 lines · skills/pylabrobot/references/visualization.md at 5f2bc03

Open on GitHub

Most marks come from matching words in the file, so treat them as pointers.

1# Visualization and software-only simulation
2
3Verified against **PyLabRobot 0.2.2** on **2026-10-01**.
4

Visualization and software-only simulation

Verified against PyLabRobot 0.2.2 on 2026-10-01.

Raw lines 1 to 4
5## Three different layers
6
7Do not conflate:
8
91. **Manifest/ledger planning** — the bundled dependency-free CLIs validate
10 bounded JSON/CSV and produce non-executable JSON.
112. **Chatterbox backend** — PyLabRobot validates frontend/tracker operations and
12 prints them instead of sending hardware commands.
133. **Visualizer** — a browser renderer that receives resource and tracker events
14 over localhost HTTP/WebSocket services.
16None is a robot physics simulator, collision-motion planner, liquid-dynamics
17model, or physical sensor.

Three different layers

Do not conflate:

  1. Manifest/ledger planning — the bundled dependency-free CLIs validate bounded JSON/CSV and produce non-executable JSON.
  2. Chatterbox backend — PyLabRobot validates frontend/tracker operations and prints them instead of sending hardware commands.
  3. Visualizer — a browser renderer that receives resource and tracker events over localhost HTTP/WebSocket services.

None is a robot physics simulator, collision-motion planner, liquid-dynamics model, or physical sensor.

Raw lines 5 to 18
19## Chatterbox backend
21The verified stable import is:
23```python
24from pylabrobot.liquid_handling import LiquidHandler
25from pylabrobot.liquid_handling.backends import LiquidHandlerChatterboxBackend
26from pylabrobot.resources.hamilton import STARLetDeck
28lh = LiquidHandler(
29 backend=LiquidHandlerChatterboxBackend(num_channels=8),
30 deck=STARLetDeck(),
32await lh.setup()
33try:
34 # Assign resources, seed tracker state, and execute planned calls.
35 ...
36finally:
37 await lh.stop()
38```
40`setup()` above is offline only because the backend is constructed literally as
41`LiquidHandlerChatterboxBackend`. Never replace it from a config string,
42environment variable, plugin, or auto-detected device.
44The stable docs sometimes use the generic phrase `ChatterboxBackend`, but the
45verified liquid-handler class/import is `LiquidHandlerChatterboxBackend`.
46`ChatterBoxBackend` (capital `B`) is a distinct exported legacy-named class.

Chatterbox backend

The verified stable import is:

from pylabrobot.liquid_handling import LiquidHandler
from pylabrobot.liquid_handling.backends import LiquidHandlerChatterboxBackend
from pylabrobot.resources.hamilton import STARLetDeck

lh = LiquidHandler(
    backend=LiquidHandlerChatterboxBackend(num_channels=8),
    deck=STARLetDeck(),
)
await lh.setup()
try:
    # Assign resources, seed tracker state, and execute planned calls.
    ...
finally:
    await lh.stop()

setup() above is offline only because the backend is constructed literally as LiquidHandlerChatterboxBackend. Never replace it from a config string, environment variable, plugin, or auto-detected device.

The stable docs sometimes use the generic phrase ChatterboxBackend, but the verified liquid-handler class/import is LiquidHandlerChatterboxBackend. ChatterBoxBackend (capital B) is a distinct exported legacy-named class.

Raw lines 19 to 47
48## Visualizer API
50Source-verified illustrative usage; server startup/browser rendering was not
51run during this refresh:
53```python
54from pylabrobot.visualizer import Visualizer
56vis = Visualizer(
57 resource=lh,
58 host="127.0.0.1",
59 ws_port=2121,
60 fs_port=1337,
61 open_browser=False,
63await vis.setup()
64try:
65 # Exercise the software-only liquid handler.
66 ...
67finally:
68 await vis.stop()
69```
71Corrections to stale examples:
73- `Visualizer` requires a root `resource`; `Visualizer()` alone is incomplete.
74- Use `setup()` / `stop()`, not `start()`.
75- Do not assign `lh.visualizer = vis`; pass `lh` as the Visualizer resource.
76- Stable defaults are WebSocket port 2121 and file-server port 1337, not 1234.
78The Visualizer starts two local servers and can open a browser. It therefore
79uses localhost networking even when the liquid handler is software-only.
80Do not use it where the requirement is "no network." Bind only to loopback,
81keep `open_browser=False` for controlled tests, avoid shared/untrusted hosts,
82and stop both services reliably.
84The bundled CLIs and tests do **not** start the Visualizer or any socket.

Visualizer API

Source-verified illustrative usage; server startup/browser rendering was not run during this refresh:

from pylabrobot.visualizer import Visualizer

vis = Visualizer(
    resource=lh,
    host="127.0.0.1",
    ws_port=2121,
    fs_port=1337,
    open_browser=False,
)
await vis.setup()
try:
    # Exercise the software-only liquid handler.
    ...
finally:
    await vis.stop()

Corrections to stale examples:

  • Visualizer requires a root resource; Visualizer() alone is incomplete.
  • Use setup() / stop(), not start().
  • Do not assign lh.visualizer = vis; pass lh as the Visualizer resource.
  • Stable defaults are WebSocket port 2121 and file-server port 1337, not 1234.

The Visualizer starts two local servers and can open a browser. It therefore uses localhost networking even when the liquid handler is software-only. Do not use it where the requirement is "no network." Bind only to loopback, keep open_browser=False for controlled tests, avoid shared/untrusted hosts, and stop both services reliably.

The bundled CLIs and tests do not start the Visualizer or any socket.

Raw lines 48 to 85
86## What the Visualizer does
88It:
90- renders a `Resource` tree;
91- receives assignment/unassignment callbacks;
92- renders tracker state such as planned tips and volumes;
93- updates as frontend operations change state.
95It does not:
97- calculate physical trajectories or clearances;
98- detect an incorrect/missing physical resource, tip, or liquid;
99- model meniscus, viscosity, foam, pressure, carryover, or pipetting error;
100- emulate firmware timing, sensors, interlocks, doors, arms, or failures;
101- validate liquid classes or calibrations;
102- authorize a live run.
104Upstream's contributor guide explicitly describes the browser as passive: it
105renders messages and does not perform simulation logic.

What the Visualizer does

It:

  • renders a Resource tree;
  • receives assignment/unassignment callbacks;
  • renders tracker state such as planned tips and volumes;
  • updates as frontend operations change state.

It does not:

  • calculate physical trajectories or clearances;
  • detect an incorrect/missing physical resource, tip, or liquid;
  • model meniscus, viscosity, foam, pressure, carryover, or pipetting error;
  • emulate firmware timing, sensors, interlocks, doors, arms, or failures;
  • validate liquid classes or calibrations;
  • authorize a live run.

Upstream's contributor guide explicitly describes the browser as passive: it renders messages and does not perform simulation logic.

Raw lines 86 to 106
107## Tracker setup
109```python
110from pylabrobot.resources import set_tip_tracking, set_volume_tracking
112set_tip_tracking(True)
113set_volume_tracking(True)
114source.get_well("A1").tracker.set_volume(100.0)
115```
117Set initial state from a synthetic fixture for tests. For later live work,
118reconcile planned state with the physical deck; do not infer physical presence
119from what the browser draws.

Tracker setup

from pylabrobot.resources import set_tip_tracking, set_volume_tracking

set_tip_tracking(True)
set_volume_tracking(True)
source.get_well("A1").tracker.set_volume(100.0)

Set initial state from a synthetic fixture for tests. For later live work, reconcile planned state with the physical deck; do not infer physical presence from what the browser draws.

Raw lines 107 to 120
121## Deterministic no-network plan
123Generate a JSON plan without importing PyLabRobot:
125```bash
126python3 skills/pylabrobot/scripts/generate_simulation_plan.py \
127 --manifest tests/pylabrobot/fixtures/protocol_manifest.json \
128 --transfers tests/pylabrobot/fixtures/transfers.csv
129```
131The output:
133- fixes the target at `PyLabRobot==0.2.2`;
134- names only `LiquidHandlerChatterboxBackend`;
135- marks live backends as forbidden;
136- records zero connection attempts and no serial/USB/network access;
137- expands each transfer into tip pickup, aspirate, dispense, and tip disposal;
138- includes final planned volumes, tip counts, limitations, and a mandatory human
139 review checklist.
141It intentionally produces data, not executable Python.

Deterministic no-network plan

Generate a JSON plan without importing PyLabRobot:

python3 skills/pylabrobot/scripts/generate_simulation_plan.py \
  --manifest tests/pylabrobot/fixtures/protocol_manifest.json \
  --transfers tests/pylabrobot/fixtures/transfers.csv

The output:

  • fixes the target at PyLabRobot==0.2.2;
  • names only LiquidHandlerChatterboxBackend;
  • marks live backends as forbidden;
  • records zero connection attempts and no serial/USB/network access;
  • expands each transfer into tip pickup, aspirate, dispense, and tip disposal;
  • includes final planned volumes, tip counts, limitations, and a mandatory human review checklist.

It intentionally produces data, not executable Python.

Raw lines 121 to 142
Runs code python3 skills/pylabrobot/scripts/generate_simulation_plan.py :126
143## Test strategy
145Use layers of evidence:
1471. Strict manifest schema validation.
1482. Static deck bounds and axis-aligned overlap screen.
1493. Transfer/dead-volume/destination/tip/channel/rate/height ledger.
1504. Non-executable simulation plan review.
1515. Pinned 0.2.2 import/signature inspection with zero backend instances.
1526. Chatterbox-only protocol smoke with synthetic resources.
1537. Optional Visualizer review on an approved loopback host.
1548. Independent physical commissioning only after explicit operator approval.
156Test failures should be deterministic. Do not catch broad errors and continue;
157do not disable trackers; do not mutate expected state to make a failed
158assertion pass.
160Run the skill's tests without bytecode:
162```bash
163PYTHONDONTWRITEBYTECODE=1 python tests/run_all.py --isolated pylabrobot
164```

Test strategy

Use layers of evidence:

  1. Strict manifest schema validation.
  2. Static deck bounds and axis-aligned overlap screen.
  3. Transfer/dead-volume/destination/tip/channel/rate/height ledger.
  4. Non-executable simulation plan review.
  5. Pinned 0.2.2 import/signature inspection with zero backend instances.
  6. Chatterbox-only protocol smoke with synthetic resources.
  7. Optional Visualizer review on an approved loopback host.
  8. Independent physical commissioning only after explicit operator approval.

Test failures should be deterministic. Do not catch broad errors and continue; do not disable trackers; do not mutate expected state to make a failed assertion pass.

Run the skill's tests without bytecode:

PYTHONDONTWRITEBYTECODE=1 python tests/run_all.py --isolated pylabrobot
Raw lines 143 to 165
Runs code python tests/run_all.py :163
166## Stable versus development
168Use the released wheel/source for pinned 0.2.2 behavior. Hosted `/stable/` now
169mixes older API pages with development pages; `/dev/` and repository `main` may
170change event payloads, serialization or the UI. See [review](review.md).
171Do not copy development examples without checking the installed release.

Stable versus development

Use the released wheel/source for pinned 0.2.2 behavior. Hosted /stable/ now mixes older API pages with development pages; /dev/ and repository main may change event payloads, serialization or the UI. See review. Do not copy development examples without checking the installed release.

Raw lines 166 to 172
173## Sources
175Checked **2026-10-01**:
177- [Hosted Visualizer guide](https://docs.pylabrobot.org/stable/user_guide/machine-agnostic-features/using-the-visualizer.html)
178 — development guide; released constructor and ports checked in source.
179- [Visualizer contributor architecture](https://docs.pylabrobot.org/stable/contributor_guide/visualizer.html)
180 — passive rendering, file server, WebSocket server, and callbacks.
181- [Hosted tracker guide](https://docs.pylabrobot.org/stable/user_guide/machine-agnostic-features/using-trackers.html)
182 — planned tip/volume state.
183- [Hosted liquid-handling API](https://docs.pylabrobot.org/stable/api/pylabrobot.liquid_handling.html)
184 — `LiquidHandlerChatterboxBackend`.
185- [released 0.2.2 Visualizer source](https://pypi.org/project/PyLabRobot/0.2.2/#files)
186 and [chatterbox source](https://pypi.org/project/PyLabRobot/0.2.2/#files)
187 — exact constructor/method verification; released 2026-07-30.

Sources

Checked 2026-10-01:

Raw lines 173 to 187