STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
documents.py
Go to the documentation of this file.
1"""Per-user engine designs with sharing, microversion history and named releases.
2
3A thin binding of :mod:`stardesign.documents` -- the router shared by all three
4design tools -- to this app's payload shape and route prefix. Everything of
5substance, including ``_resolve_doc`` (the one place cross-user access is
6granted), lives there.
7
8The payload here is ``{"config": <dict>, "ui": <dict>}``; pid-designer's is
9``{nodes, edges}``. That, the prefix, and the noun are the whole difference.
10
11``ui`` carries the authored state that is not in ``PintleEngineConfig`` -- the
12controller commands, the time-series pressure profiles, Layer 4's vehicle
13definition, the layer run settings, the plot definition. It is opaque here, as
14the config is: the frontend owns its shape (see frontend/src/lib/designState.ts).
15It defaults to ``{}`` so every design stored before it existed still loads.
16"""
17
18from __future__ import annotations
19
20import os
21
22from pydantic import BaseModel
23
24from stardesign.documents import ( # noqa: F401 (re-exported for callers)
25 CopyPayload,
26 DesignStore,
27 NamePayload,
28 SharePayload,
29 make_router,
30)
31
32from backend import storage, userdata
33
34
35class ConfigPayload(BaseModel):
36 config: dict
37 ui: dict = {}
38
39
40class CreatePayload(BaseModel):
41 name: str
42 config: dict | None = None # seed the working copy; {} if omitted
43 ui: dict | None = None
44
45
46class ReleasePayload(BaseModel):
47 label: str
48 config: dict | None = None # snapshot this; else the current working copy
49 ui: dict | None = None
50
51
52store = DesignStore(
53 ud=userdata.store,
54 backend=storage.backend,
55 body_model=ConfigPayload,
56 create_model=CreatePayload,
57 release_model=ReleasePayload,
58 to_data=lambda p: {
59 "config": getattr(p, "config", None) or {},
60 "ui": getattr(p, "ui", None) or {},
61 },
62 release_body=lambda p: (
63 None if p.config is None else {"config": p.config, "ui": p.ui or {}}
64 ),
65 noun="design",
66 default_slug="design",
67 # Seconds between automatic microversion snapshots for one design while it
68 # is being actively autosaved. The on-close /flush ignores this.
69 micro_interval=int(os.environ.get("ENGINE_MICRO_INTERVAL", "300")),
70 empty_payload=lambda: {"config": {}, "ui": {}},
71)
72
73router = make_router(store, prefix="/api/engine/documents")
74
75# Deliberately no module-level MICRO_INTERVAL / _last_micro aliases: an int copy
76# would look patchable in a test and silently not be, since the router reads
77# `store.micro_interval`. Tests patch the store.