mostlyright.core.schema
mostlyright.core.schema
Section titled “mostlyright.core.schema”Declarative schema framework for mostlyright.
Defines the Schema base class, ColumnSpec description records, and
SchemaRegistration audit-trail container. These are the shape contracts
that the Validator, KnowledgeView, and adapter layers consume.
See docs/design.md §A (canonical schemas), §BB.3 (settlement schema),
§BB.4 (audit log API), and §J (allow_source_drift reason-string semantics).
TimePoint will eventually wrap timestamp handling; this module accepts raw
datetime objects for now and validates that they are timezone-aware.
Classes
Section titled “Classes”ColumnSpec(name, dtype, units, nullable[, …]) | Description of a single column in a Schema. |
|---|---|
Schema() | Declarative schema base class. |
SchemaRegistration(schema, source, …[, _audit]) | Audit-trail container produced by Schema.register(...). |
class mostlyright.core.schema.ColumnSpec(name, dtype, units, nullable, enum_values=None, notes=”)
Section titled “class mostlyright.core.schema.ColumnSpec(name, dtype, units, nullable, enum_values=None, notes=”)”Bases: object
Description of a single column in a Schema.
- Parameters:
Column name as it appears in the canonical (metric) projection.
One of the canonical dtype tags. "enum" requires
enum_values to be populated.
Free-form unit label ("celsius", "meters", "kt")
or None for dimensionless columns.
nullable
Section titled “nullable”Whether the column may contain NaN/NULL values.
enum_values
Section titled “enum_values”Allowed values when dtype == "enum". Must be None
for non-enum columns.
Free-form documentation surfaced in catalog metadata.
dtype : str
Section titled “dtype : str”enum_values : tuple[str, ...] | None = None
Section titled “enum_values : tuple[str, ...] | None = None”notes : str = ”
Section titled “notes : str = ””nullable : bool
Section titled “nullable : bool”units : str | None
Section titled “units : str | None”class mostlyright.core.schema.Schema
Section titled “class mostlyright.core.schema.Schema”Bases: object
Declarative schema base class.
Subclasses declare:
schema_id— stable identifier ("schema.observation.v1").COLUMNS— ordered list ofColumnSpec.IMPERIAL_RENAMES(optional) — metric → imperial column-name map; columns not mentioned keep their metric name.
The base class is intentionally light: no I/O, no DataFrame coupling.
Validator and adapter layers consume COLUMNS to perform their
work; Schema itself only holds the contract.
IMPERIAL_RENAMES : ClassVar[dict[str, str]] = {}
Section titled “IMPERIAL_RENAMES : ClassVar[dict[str, str]] = {}”classmethod column(name)
Section titled “classmethod column(name)”Look up a ColumnSpec by its (metric) name.
- Raises:
KeyError – if
namedoes not name a declared column. - Return type:
ColumnSpec - Parameters: name (str)
classmethod column_names(mode=‘metric’)
Section titled “classmethod column_names(mode=‘metric’)”Return the column names in declaration order for the given mode.
mode="metric" returns the canonical names declared in
COLUMNS. mode="imperial" applies IMPERIAL_RENAMES
(columns absent from the rename map keep their metric name).
- Raises:
ValueError – if
modeis not"metric"or"imperial". - Return type:
list[str] - Parameters: mode (str)
classmethod from_dataframe(df, source, retrieved_at)
Section titled “classmethod from_dataframe(df, source, retrieved_at)”Infer a schema from a DataFrame (BYO data path). Deferred to v0.1.1.
Per docs/design.md Premise 5 (and §”Layer responsibilities”):
schemas can be constructed declaratively (subclasses of Schema)
OR inferred from a sample DataFrame. The declarative path ships in
v0.1.0; the inference path (this method) ships in v0.1.1.
Track at:
classmethod register(source, retrieved_at, rows)
Section titled “classmethod register(source, retrieved_at, rows)”Register this schema against a concrete pull.
Records the source and retrieved_at provenance and produces
a fresh SchemaRegistration carrying the audit log. The
registered event is appended automatically.
v0.1.0 is a per-call factory. Every call returns a brand-new
SchemaRegistration with an independent audit log; there
is no cross-call registry that deduplicates by
(schema_id, source) or merges audit events across pulls.
Design §BB.4 describes an audit log that persists with the schema across calls; that persistence model lands in v0.1.1 alongside the catalog adapter, which owns the (schema, source) keying and on-disk storage decisions (parquet metadata, JSON sidecar). Callers in v0.1.0 that need a long-lived registration must hold onto the returned object themselves.
Track at:
- Parameters:
- Raises:
- TypeError – if
sourceis notstr,retrieved_atis not adatetime, orrowsis notint. - ValueError – if
sourceis empty,retrieved_atis naive, orrowsis negative.
- TypeError – if
- Return type:
SchemaRegistration
schema_id : ClassVar[str] = ”
Section titled “schema_id : ClassVar[str] = ””class mostlyright.core.schema.SchemaRegistration(schema, source, retrieved_at_min, retrieved_at_max, rows, _audit=)
Section titled “class mostlyright.core.schema.SchemaRegistration(schema, source, retrieved_at_min, retrieved_at_max, rows, _audit=)”Bases: object
Audit-trail container produced by Schema.register(...).
Records the (source, retrieved_at range, row count) provenance of a
training-time pull and accumulates an append-only audit log. The audit
log captures source-drift opt-outs and reproducibility-audit outcomes
per docs/design.md §BB.4.
Validator wires audit events in via _append_audit(); this module
intentionally does not import Validator (it is implemented elsewhere).
Audit-log seam (contract — read this). The single-underscore prefix
on _audit and _append_audit() denotes module-private with
one cross-module writer: the Validator (a sibling module) calls
_append_audit to record source_drift_allowed and
temporal_drift_audit events. Any caller OTHER than
Schema.register() or the Validator that invokes _append_audit
— or any direct mutation of _audit — is a contract violation: the
audit log is meant to be append-only and stamped by trusted writers
only. The list is intentionally not frozen so the Validator can append
without indirection; this is the explicit seam, documented here so
code review can catch unauthorised callers.
Deferred to v0.1.1: volatility_warning (per design §B/§P,
surfaced by catalog_search and flagged on schemas whose registered
rows fall within the 30-day volatile window of iem.archive) will
land as an attribute on this dataclass populated by the catalog
adapter at registration time. v0.1.0 carries no such attribute.
- Parameters:
audit_log()
Section titled “audit_log()”Return a defensive copy of the chronologically-ordered audit log.
Both the outer list and each inner entry are shallow-copied so
callers cannot mutate stored entries (e.g.
reg.audit_log()[0]["event"] = "tampered" is a no-op against
the underlying log). The list contains dict entries with at
minimum event and ts (ISO-8601 UTC) keys. See
_append_audit() for the supported event vocabulary.