feat(client): the Python client — a GEM tool in plain Python (Phase C)
clients/python: pip-installable "secsgem-client", pure Python (stubs
pre-generated from equipment.proto, import made package-relative; no
compiled extension, no SEMI knowledge, no C++ toolchain). The API the whole
effort aimed at:
eq = Equipment("localhost:50051")
eq.set(ChamberPressure=2.5); eq["WaferCounter"] = 7
eq.fire("ProcessStarted", ChamberPressure=2.75)
eq.alarm("chiller_temp_high"); eq.clear("chiller_temp_high")
@eq.on("START")
def start(cmd): ... # auto-CompleteCommand after return
eq.listen(background=True)
eq.control_state; eq.request_control_state("HOST_OFFLINE"); eq.health()
Errors raise SecsGemError carrying the daemon's message ("no variable named
..."). bool checked before int in conversion (isinstance(True, int)).
examples/mini_tool.py is a complete GEM tool in ~25 lines.
PROOF — interop/pyclient_interop.py drives the PUBLISHED package (not raw
stubs) against a live secs_gemd with secsgem-py as the fab host: 13 checks
all green on first run — set/get round-trips, item syntax, SecsGemError on
unknown names, control state, health, fire->S6F11 on the host's wire,
alarm/clear->S5F1 with correct set bit, the full command loop (host S2F41 ->
HCACK=4 -> @eq.on handler -> completion event back at the host), operator
offline. Conversion layer unit-tested standalone; both wired into
tools/run_interop.sh as the pyclient step.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+16
-7
@@ -30,7 +30,7 @@ host and stays conformant while the tool software restarts/upgrades/crashes.
|
||||
| Daemon interop vs **secs4j** (Java) | ⬜ | mirror the secsgem-py harness against `interop/secs4j` |
|
||||
| `Subscribe` host→tool command stream + `CompleteCommand` | ✅ | HCACK-4 contract implemented + tested in-process AND live vs secsgem-py (full loop: S2F41 → stream → complete → S6F11) |
|
||||
| Universal RPC surface complete (vars/events/alarms/control-state/health) | ✅ | Phase A done; daemon tests 101 assertions, interop 15 checks |
|
||||
| Python client package (the "beautiful API") | ⬜ | thin wrapper over generated stubs |
|
||||
| Python client package (the "beautiful API") | ✅ | `clients/python` (`secsgem-client`); 13-check interop green via the published API |
|
||||
|
||||
## Known issues (found in the 2026-06-10 audit; honest list)
|
||||
|
||||
@@ -173,12 +173,21 @@ debts tax every later phase, and the most valuable tests aren't automated.
|
||||
7. ⬜ Java interop: `secs4j` host variant of the same scenario.
|
||||
|
||||
### Phase C — the beautiful Python client
|
||||
8. ⬜ `clients/python/` package (`pip install secsgem-client`): wraps generated
|
||||
stubs in the agreed API — `eq.set(chamber_pressure=2.5)`, `eq.fire("wafer_complete", thickness=1.2)`,
|
||||
`eq.alarm("pressure_high")`, `@eq.on("START")` consuming the stream,
|
||||
`eq.health()`. Pure Python (no compiled ext). Ship stubs pre-generated.
|
||||
9. ⬜ Example: rewrite a minimal `pvd_tool`-equivalent in ~40 lines of Python
|
||||
against the daemon; also migrate the C++ `pvd_tool` to `set_handler`.
|
||||
8. ✅ `clients/python/` — pip-installable `secsgem-client`, pure Python,
|
||||
stubs pre-generated (relative-import fixed). The full agreed API:
|
||||
`eq.set(ChamberPressure=2.5)` kwargs + `eq["..."]` item syntax, `eq.get`,
|
||||
`eq.fire(event, **data)`, `eq.alarm`/`eq.clear`, `eq.control_state`,
|
||||
`eq.request_control_state`, `eq.health()`/`watch_health()`, and
|
||||
`@eq.on("START")` + `eq.listen(background=...)` with auto-CompleteCommand.
|
||||
Errors raise `SecsGemError` carrying the daemon's explanation.
|
||||
PROOF: `interop/pyclient_interop.py` drives the PUBLISHED package against
|
||||
a live daemon with secsgem-py as the host — 13 checks all green (S6F11/
|
||||
S5F1 set+clear on the wire, HCACK-4 command loop through the decorator,
|
||||
operator offline). Conversion layer unit-tested (bool-before-int etc).
|
||||
Wired into tools/run_interop.sh as the `pyclient` step.
|
||||
9. 🚧 `clients/python/examples/mini_tool.py` — a complete GEM tool in ~25
|
||||
lines ✅. Migrating the C++ `pvd_tool` to EquipmentRuntime + capability
|
||||
registration + `set_handler` ⬜.
|
||||
|
||||
### Phase D — GEM300 in-the-loop (process/carrier tools)
|
||||
10. ⬜ Settle job/carrier semantics (who acks S16F5/S3F17, gate vs observe —
|
||||
|
||||
Reference in New Issue
Block a user