ursa.register.api¶
Implementations of the four ursa.register.* write functions.
Each function:
Builds the corresponding
*Rowfrom keyword args (Pydantic validates types, ranges, andMetadataDictshape on construction).For :func:
modality, additionally validates thatstorage_urimatches the bucket tier implied byformat(raw →RAW_BUCKET; canonical →ASSETS_BUCKET) via :func:ursa.layout.validate_storage_uri.Inserts the row through the supplied :class:
CatalogWriter.
Phase 1a (M2) is non-idempotent: a re-register with an existing primary
key raises :class:ursa.catalog.CatalogRowExists. Idempotent re-register
is tracked in ENG-1074 <https://linear.app/constellationlab/issue/ENG-1074>_.
Module Contents¶
Functions¶
Register a new participant. |
|
Register a recording session. |
|
Register a data stream within a recording. |
|
Register a time-stamped event within a recording. |
Data¶
API¶
- ursa.register.api.__all__¶
[‘participant’, ‘recording’, ‘modality’, ‘event’]
- ursa.register.api.participant(*, participant_id: str, enrolled_at: datetime.datetime, metadata: dict[str, Any] | None = None, catalog: ursa.register._writer.CatalogWriter) ursa.catalog.ParticipantRow[source]¶
Register a new participant.
Not called by data-engine on every recording — the intended caller is a separate Constellation enrollment surface (admin script or dashboard). Data-engine’s recording flow only calls
- Func:
recordingwith an existingparticipant_id.
.. note:: Phase 1a (M2): non-idempotent. Re-register with the same
participant_idraises- Class:
ursa.catalog.CatalogRowExists. Idempotency is tracked inENG-1074 <https://linear.app/constellationlab/issue/ENG-1074>_.
- ursa.register.api.recording(*, recording_hash: str, participant_ids: list[str], start_time: datetime.datetime, duration: datetime.timedelta, device_info: dict[str, Any] | None = None, metadata: dict[str, Any] | None = None, catalog: ursa.register._writer.CatalogWriter) ursa.catalog.RecordingRow[source]¶
Register a recording session.
.. note:: Phase 1a (M2):
recording_hashMUST conform to^[A-Za-z0-9_-]+$(validated byCatalogID). Data-engine passes its nativerecording_idverbatim (e.g.rec_20260507_143022_a7f3), which already conforms. Phase 1b will introduce content-addressed hashing underENG-1070 <https://linear.app/constellationlab/issue/ENG-1070>_; the change is purely additive — the pattern relaxes, no caller change required.participant_idsis a non-empty list (architecture v0.4): a recording can cover multiple participants (multi-subject experiments, dyad sessions, crowd recordings). Single-participant recordings pass a one-element list. FK enforcement against theparticipantstable at write time is a Phase 1b concern.device_infois the rig hardware manifest. data-engine populates it from itsnodes/<node_id>.jsonregistry entry. Encode per-channel structures as parallel lists ({"channel_names": [...], "polarity": [...]}), not list-of-dicts — that’s theMetadataDictshape required by Lance MapType.Non-idempotent: re-register raises
- Class:
ursa.catalog.CatalogRowExists(ENG-1074 <https://linear.app/constellationlab/issue/ENG-1074>_).
- ursa.register.api.modality(*, recording_hash: str, modality: str, raw_storage_uri: str, storage_uri: str | None = None, ingestion_status: ursa.catalog.IngestionStatus = IngestionStatus.RAW, format: ursa.catalog.StorageFormat | None = None, domain_intervals: list[tuple[float, float]] | None = None, sampling_rate: float | None = None, channel_spec: dict[str, Any] | None = None, metadata: dict[str, Any] | None = None, catalog: ursa.register._writer.CatalogWriter) ursa.catalog.ModalityRow[source]¶
Register a data stream within a recording.
Phase 1a (M2) is catalog-only: the blob at
raw_storage_uriis assumed to already exist (data-engine uploads raw segments before calling). Existence is not verified — a missing blob surfaces at first read, not at register.Architecture v0.4 splits a modality’s lifecycle into two states:
Default (
ingestion_status="raw") — register against a cold-bucket raw file.raw_storage_uriis required;storage_uridefaults to mirror it.formatmay be aRAW_*value (when known at registration) or null.domain_intervalsandchannel_specare typically null — Virgo’s ingestion node populates them.After Virgo ingestion (
ingestion_status="processed") — the caller is Virgo’s ingestion node, which converted the raw file to a canonical format.storage_uripoints at the processed object;formatis canonical (non-RAW_*);domain_intervalsandchannel_specare populated.raw_storage_uristays as the cold-bucket pointer for re-ingestion.
.. note:: Phase 1a (M2): URIs must match the bucket tier implied by
format:Raw formats (
RAW_*) →r2://constellation-data/...Canonical formats (
ZARR,LANCE,MP4_INDEX,PARQUET) →r2://constellation-assets/...
Mismatch raises
ValueErrorbefore any catalog write.The canonical-write surface (
data=parameter that uploads the blob and registers the row in one call) is deferred toENG-1072 <https://linear.app/constellationlab/issue/ENG-1072>_. Virgo (M3) is the first real consumer of that path.Non-idempotent: re-register raises
- Class:
ursa.catalog.CatalogRowExists(ENG-1074 <https://linear.app/constellationlab/issue/ENG-1074>_).
- ursa.register.api.event(*, event_id: str, recording_hash: str, event_time: float, event_type: str, prompt: str | None = None, response: str | None = None, metadata: dict[str, Any] | None = None, catalog: ursa.register._writer.CatalogWriter) ursa.catalog.EventRow[source]¶
Register a time-stamped event within a recording.
.. note:: Phase 1a (M2):
EventRow’s primary key is currently(event_id,)— a single global namespace across every recording.event_idis caller-generated and must be globally unique. Recommended format:f"{recording_hash}_{seq:08d}"whereseqis a per-recording monotonic counter. Therecording_hashprefix guarantees cross-recording uniqueness.ENG-1073 <https://linear.app/constellationlab/issue/ENG-1073>_ will scope the PK to(recording_hash, event_id)so callers can use simple per-recording sequences.Auto-generation in Ursa is intentionally not provided: data-engine already has a per-modality sequence counter for ZMQ message ordering and is the right place to mint IDs.
Non-idempotent: re-register with the same
event_idraises- Class:
ursa.catalog.CatalogRowExists(ENG-1074 <https://linear.app/constellationlab/issue/ENG-1074>_).