exlab_wizard.api.app#
FastAPI app + lifespan + dependency wiring. Backend Spec §4.6.
The create_app() factory builds the app with the §4.6 versioned
prefix (/api/v1/...), mounts every router, registers exception
handlers (§4.6.3 envelope), and binds an AppDependencies
instance onto app.state.dependencies so per-request handlers can
look up the live controller / validator / cache writers / etc.
Lifespan responsibilities (§4.5):
Load (or accept the supplied)
config.yaml.Build the plugin registry (best-effort; failure logs WARN).
Refresh the LIMS project cache (best-effort).
Start the background audit task (every 30 s; pub-sub publishes deltas on the
/problems/eventschannel).On shutdown, drain in-flight sessions, stop the audit task, and close the cache writers.
The launcher (in production) constructs a full AppDependencies
with real components; tests can pass a custom dependencies object whose
fields are stubs / mocks.
Functions
|
Build the FastAPI app. |
Classes
|
Bundle of live components the API surface dispatches to. |
Multi-subscriber pub-sub for the Problems WebSocket. |
- class exlab_wizard.api.app.AppDependencies(config=None, save_config=None, lims_reachable=True, keyring_password_present=True, lims_reason=None, controller=None, validator=None, plugin_host=None, cache_creation=None, lims_client=None, nas_sync=None, session_store=None, ingest_writer=None, staging_watcher=None, audit_channel=None, last_audit_at=None, nas_sync_snapshot=None, session_store_snapshot=None, registered_plugin_count=0, plugin_host_status='ok', lims_probe=None, equipment_probe=None, autostart_toggle=None, audit_task=None)[source]#
Bases:
objectBundle of live components the API surface dispatches to.
Production wiring (the launcher) constructs everything; tests can pass mocks. Attributes are typed loosely (
Any) so the API code does not impose imports on the caller – the runtime contract is documented per attribute.- Parameters:
save_config (
Callable[[Config],Awaitable[None] |None] |None)lims_reachable (
bool)keyring_password_present (
bool)controller (
Any)validator (
Any)plugin_host (
Any)cache_creation (
Any)lims_client (
Any)nas_sync (
Any)session_store (
Any)ingest_writer (
Any)staging_watcher (
Any)audit_channel (
AuditChannel|None)session_store_snapshot (
Callable[[],dict[str,Any]] |None)registered_plugin_count (
int)plugin_host_status (
str)
- audit_channel: AuditChannel | None = None#
- class exlab_wizard.api.app.AuditChannel[source]#
Bases:
objectMulti-subscriber pub-sub for the Problems WebSocket. Backend Spec §4.6.2.
Subscribers receive every published frame (snapshot or delta). The channel keeps the most recent snapshot so late subscribers do not have to wait for the next 30-second tick.
- exlab_wizard.api.app.create_app(*, config=None, dependencies=None, audit_interval_seconds=30.0, start_audit_task=False)[source]#
Build the FastAPI app. Backend Spec §4.6.
config: optional pre-loadedconfig.yaml; ifdependenciesis supplied this is ignored.dependencies: a fully-configuredAppDependencies(production launcher uses this).audit_interval_seconds: how often the background audit task runs; tests can pass a small value to exercise the loop.start_audit_task: if True the lifespan handler launches the audit task; defaults to False so tests don’t accumulate tasks.