exlab_wizard.tray#
Tray application package. Backend Spec §4.3.2.
Public API:
AutostartManager– per-platform autostart register / unregister / is_registered.NotificationBus– coalesced OS notifications via plyer.QuitCoordinator– §4.3.2 graceful-shutdown protocol.ServerRunner– in-process uvicorn host with atomicserver.jsonwrites.StatusTicker– 5-second status submenu refresh.TrayApp– the long-lived wiring assembly used byexlab_wizard.tray.main().WindowLauncher– spawns / focusesexlab-wizard-windowsubprocess.build_icon()– pystray icon factory.
- class exlab_wizard.tray.AutostartManager(*, executable_path=None, filesystem_root=None, platform=None)[source]#
Bases:
objectPer-platform autostart register / unregister / is_registered.
Construction-time parameters:
executable_path– absolute path toExLab-Wizard-Tray. The production launcher resolvessys.executable(PyInstaller bundles setsys.executableto the launcher binary).filesystem_root– root directory for per-user files. Defaults toPath.home()in production; tests injecttmp_path. The env-var overrideEXLAB_AUTOSTART_ROOTwins over the constructor default.platform– override the OS dispatch, used by tests to exercise every branch on a single host.
- Parameters:
- property platform: Platform#
Return the platform dispatch this manager is configured for.
- class exlab_wizard.tray.NotificationBus(*, notifier=None, is_window_foregrounded=None, coalescing_window=5.0)[source]#
Bases:
objectCoalescing layer over
notify().The launcher constructs one bus and threads it through to the components that emit notification-eligible events (plugin host, NAS-sync). Components call
emit(); the bus handles coalescing, foreground suppression, and the actual plyer call.- Parameters:
- class exlab_wizard.tray.QuitCoordinator(*, server_runner, window_launcher, session_store, nas_sync, on_force_quit_prompt=None, timeout_seconds=30.0, sigterm_timeout_seconds=5.0, poll_interval_seconds=0.1)[source]#
Bases:
objectDrive the §4.3.2 graceful-shutdown protocol.
Construction-time dependencies are kept loosely typed so the coordinator can integrate with whatever stub fixtures unit tests pass. The runtime contract is documented per parameter.
- Parameters:
- class exlab_wizard.tray.ServerRunner(*, app, state_dir)[source]#
Bases:
objectStarts uvicorn on a free localhost port and tracks its state file.
Backend Spec §4.3.2 + §15.3.1.
- property port: int#
Return the port the server is bound to.
Raises
RuntimeErrorwhen called beforestart().
- class exlab_wizard.tray.StatusSnapshot(active_sessions=0, sync_queue_depth=0, input_required_count=0)[source]#
Bases:
objectImmutable view over the §4.3.2 status inputs.
- class exlab_wizard.tray.StatusTicker(*, session_store=None, nas_sync=None, on_update=None, interval_seconds=5.0)[source]#
Bases:
objectPolls
snapshot_status()on a fixed cadence.On every tick the formatted string is computed; if it differs from the previous label the
on_updatecallback is invoked with the new label. The callback is the tray menu’s “set status text” hook; tests pass a recording callable.- Parameters:
- class exlab_wizard.tray.TrayApp(server_runner, window_launcher, quit_coordinator, status_ticker, notification_bus, autostart, icon=None, update_checker=None)[source]#
Bases:
objectBundle of long-lived tray components.
The launcher constructs one and calls
run(); tests build one with stub components and exerciseshutdown()/open()individually.- Parameters:
server_runner (
ServerRunner)window_launcher (
WindowLauncher)quit_coordinator (
QuitCoordinator)status_ticker (
StatusTicker)notification_bus (
NotificationBus)autostart (
AutostartManager)icon (
Any)update_checker (
Any)
- autostart: AutostartManager#
- notification_bus: NotificationBus#
- open_releases_page()[source]#
Open the GitHub releases page in the operator’s browser.
Wired to the “Check for updates…” tray item (Design Spec §15.6 / §15.8 item 3). Any browser-launch failure is logged and swallowed so the tray menu callback never crashes the icon thread.
- Return type:
- quit_coordinator: QuitCoordinator#
- run(*, run_loop=None)[source]#
Start the server, build the icon, run the pystray loop.
run_loopis injected by tests so they don’t actually callIcon.run(which would block on a real backend). Returns the exit code.
- server_runner: ServerRunner#
- status_ticker: StatusTicker#
- window_launcher: WindowLauncher#
- class exlab_wizard.tray.WindowLauncher(*, window_executable=None, state_dir)[source]#
Bases:
objectSpawn
exlab-wizard-windowas a subprocess, track its PID.On a re-open request with an existing live child, focuses the existing window (best-effort) rather than spawning a duplicate (Backend §4.1: “single-instance window”).
- exlab_wizard.tray.build_icon(*, on_open, on_quit, status_provider, pystray_module=None, icon_image=None, icon_name='exlab-wizard', title='ExLab-Wizard', on_check_update=None)[source]#
Build the pystray icon with the §4.1 menu.
status_provideris invoked every time pystray re-renders the menu (pystray supports lazily-evaluated text via callable labels) so the operator sees live status without a separate refresh notification.When
on_check_updateis supplied (Design Spec §15.6 / §15.8 item 3) a “Check for updates…” item is inserted between the separator and Quit, giving the order Open, Status, —, Check for updates…, Quit. When it is None the menu is exactly as before.
- exlab_wizard.tray.format_status(snapshot)[source]#
Return the menu-label string for the §4.3.2 formatter.
- Parameters:
snapshot (
StatusSnapshot)- Return type:
- exlab_wizard.tray.notify(*, title, message, notifier=None)[source]#
Fire a plyer notification (or an injected stub).
notifierdefaults toplyer.notification.notifywhich the plyer wheel auto-resolves to the platform-appropriate backend (UNUserNotificationCenter / ToastNotificationManager / libnotify). Tests pass a recording callable.
- exlab_wizard.tray.snapshot_status(*, session_store=None, nas_sync=None)[source]#
Build a
StatusSnapshotfrom live component references.Each component is read defensively so the launcher can pass
None(setup-incomplete state) without the formatter crashing. The function readsactive_sessionsandinput_required-style counts fromsession_storeandin_flight_jobs/queue_depthfromnas_sync.- Parameters:
- Return type:
Modules
Per-platform autostart registration. |
|
Production |
|
pystray icon construction. |
|
|
|
OS notifications via plyer with 5-second coalescing. |
|
Graceful tray shutdown coordinator. |
|
Programmatic uvicorn launcher with atomic |
|
Status-submenu rendering. |
|
Per-installation NiceGUI |
|
Spawn / focus the on-demand window subprocess. |