Add optional remote scripting server (Tools -> Remote Scripting...)#105
Open
thomdehoog wants to merge 2 commits into
Open
Add optional remote scripting server (Tools -> Remote Scripting...)#105thomdehoog wants to merge 2 commits into
thomdehoog wants to merge 2 commits into
Conversation
mesoSPIM-control has no external control interface: everything runs in-process inside the Qt event loop. The Script Window already runs Python in the live Core context (self == Core); this makes that reachable from another process over a socket, so external tools can script the microscope with the full mesoSPIM Python API. Text in, console text out -- no command vocabulary, no data format. - mesoSPIM_RemoteScripting.py (new): a signal-driven QTcpServer that, for each received script, runs the EXISTING Core.execute_script and returns its captured console output. Length-framed UTF-8. Optional shared token (first frame, constant-time compare over UTF-8 bytes) gates access. A script's console is captured PER-THREAD, so its output is returned without swapping the process-wide stdout/stderr out from under the other threads. A dropped/crashed client cannot crash mesoSPIM (the disconnect teardown is guarded against an already-reclaimed socket). - mesoSPIM_Core: start_remote_scripting(host, port, token) / stop slots, invoked via a queued connection so the server lives on the Core's thread (where execute_script runs), plus a sig_remote_scripting_started(ok, message) signal so a bind failure is reported rather than shown as a false "running". - mesoSPIM_MainWindow: a "Tools -> Remote Scripting..." menu entry (added in code, no .ui change) with a Start/Stop dialog (host/port/token + generator); reflects the real start outcome; stops on app close. OFF BY DEFAULT and secure-by-default: the server never runs until an operator starts it from Tools -> Remote Scripting...; the dialog binds 127.0.0.1, pre-fills a fresh token, and warns before any network bind without a token. A script is arbitrary Python on the acquisition PC; this is plain TCP, so the token gates casual LAN access, it is not sniffer-proof (tunnel it for untrusted networks). Validated against -D demo mode (both v1.20.0 and release/candidate-py312): started from the GUI signal path, a client authenticates, reads state, drives the demo stage, gets structured output via print(json), runs an acquisition, and sees a raising script's traceback as text (no crash). execute_script is reused unmodified.
thomdehoog
force-pushed
the
remote-scripting-py312
branch
from
July 3, 2026 12:13
8d931c1 to
b8eff6c
Compare
thomdehoog
added a commit
to thomdehoog/ZMART-microscopy
that referenced
this pull request
Jul 6, 2026
PR #105 (mesoSPIM/mesoSPIM-control) picked up a second, purely additive commit after this branch last touched pull_request/: Add remote scripting full demo test, adding mesoSPIM/scripts/remote_scripting_full_test.py (1121 lines). It does not change the 3 core files from the first commit. - Add 0002-Add-remote-scripting-full-demo-test.patch alongside the existing 0001 patch (same git format-patch convention). - README/TODO: the PR is open at mesoSPIM/mesoSPIM-control#105 -- drop the stale not-yet-submitted wording and note the second patch is optional.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this adds
mesoSPIM-control has no external control interface — everything runs in-process in the Qt event loop. The Script Window already runs Python in the live Core (
self == Core); this PR makes that reachable from another process over a localhost socket, so external tools can script the microscope with the full mesoSPIM Python API. Text in, console text out — no command vocabulary, no data format.Why it's this small
It reuses the existing, unmodified
Core.execute_script. Everything opinionated (a command set, structured results) lives in the client, injected as a script — so there's nothing new for mesoSPIM to maintain.Files (3 files, +480)
mesoSPIM_RemoteScripting.py(new): a signal-drivenQTcpServer. For each received script it runsCore.execute_scriptand returns its console output, captured per-thread so it never swaps the process-widestdout/stderrout from under other threads. Length-framed UTF-8; framing + the token gate are socket-free helpers (frame/FrameDecoder/AuthGate) with Qt-free unit tests; constant-time token compare over UTF-8 bytes. A new client preempts a stale one, and a dropped/crashed client's teardown is guarded, so a misbehaving client can neither wedge nor crash the server.mesoSPIM_Core.py(+37):start_remote_scripting(host, port, token)/stop_remote_scripting()slots, invoked via a queued connection so the server lives on the Core thread (whereexecute_scriptruns), plus asig_remote_scripting_started(ok, message)signal so a bind failure is reported instead of shown as a false "running".mesoSPIM_MainWindow.py(+131): a Tools → Remote Scripting… menu entry with a Start/Stop dialog (host / port / token + generator); reflects the real start outcome; stops on app close.Security — this is remote code execution, handled deliberately
enable_remote_scripting = True— an unmodified install cannot start it.127.0.0.1, the dialog pre-fills a fresh token, and warns before any network bind without a token.Validation
Ran the real app in
-Ddemo mode (all Demo backends, offscreen Qt on Windows) on both v1.20.0 and thisrelease/candidate-py312branch: a client authenticates (incl. a non-ASCII token), reads state, drives the demo stage (self.move_absolute), runs an acquisition that writes a file, gets structured output viaprint(json.dumps(...)), and sees a raising script's traceback returned as text (no crash).execute_scriptis unchanged, so there's no behavior change for existing users.Happy to adjust the naming, add a config-file defaults block, or a CHANGELOG / docs entry as you prefer.