mostlyright.core
mostlyright.core
Section titled “mostlyright.core”mostlyright.core — temporal safety + schema + format primitives.
The architectural spine of the mostlyright SDK. Originally ported from
the mostlyright-mcp wave-1-core branch (lift provenance preserved in
per-module docstrings); promoted from the _v02 reference into the
canonical namespace in Phase 2 of the v0.1.0 plan.
Sub-modules:
mostlyright.core.exceptions— structured exception hierarchy (MostlyRightErrorbase + 6 subclasses + JSON-safeto_dict).MostlyRightMCPErrorremains importable as a deprecation alias.mostlyright.core.temporal— UTC-awareTimePointwrapper;KnowledgeView+LeakageDetector(Phase 2 Wave 2).mostlyright.core.schema— declarativeSchemaframework with audit-log seam used by the source-identityValidator.mostlyright.core.schemas— three canonical schema instances (observation, forecast, settlement).mostlyright.core.formats— five lossless format serializers (dataframe/json/parquet/toon/csv).
class mostlyright.core.ColumnSpec(name, dtype, units, nullable, enum_values=None, notes=”)
Section titled “class mostlyright.core.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.KnowledgeView(df, as_of)
Section titled “class mostlyright.core.KnowledgeView(df, as_of)”Bases: object
A filtered, knowledge-time-bounded view over a DataFrame.
Construction validates the shape of the input DataFrame. After
construction, dataframe() returns a defensive copy of the rows
where knowledge_time <= as_of.
Examples
Section titled “Examples”Build a 3-row DataFrame with a tz-aware UTC knowledge_time column
and view only the rows knowable as of 2025-01-02T12:00:00Z:
>>> import pandas as pd>>> from mostlyright.core import KnowledgeView, TimePoint>>> df = pd.DataFrame({... "knowledge_time": pd.to_datetime([... "2025-01-01T00:00:00Z",... "2025-01-02T00:00:00Z",... "2025-01-03T00:00:00Z",... ], utc=True),... "value": [10, 20, 30],... })>>> view = KnowledgeView(df, TimePoint("2025-01-02T12:00:00Z"))>>> len(view.dataframe())2- Parameters:
- df (pd.DataFrame | MostlyRightResult)
- as_of (TimePoint)
property as_of : TimePoint
Section titled “property as_of : TimePoint”The as-of cutoff supplied at construction.
dataframe()
Section titled “dataframe()”Return a defensive copy of the rows where knowledge_time <= as_of.
- Return type:
DataFrame
class mostlyright.core.LeakageDetector(as_of)
Section titled “class mostlyright.core.LeakageDetector(as_of)”Bases: object
Convenience wrapper for repeated detection against a fixed as_of.
- Parameters: as_of (TimePoint)
property as_of : TimePoint
Section titled “property as_of : TimePoint”check(df)
Section titled “check(df)”Run assert_no_leakage() against the bound as_of.
Accepts either a raw DataFrame or a MostlyRightResult
wrapper (unwrapped inside assert_no_leakage()).
- Return type:
None - Parameters: df (DataFrame | MostlyRightResult)
check_issued_at(df)
Section titled “check_issued_at(df)”Raise IssuedAtMissingError if any row has null issued_at.
Phase 20 OM-04 extension. Independent of as_of — the bound
cutoff is irrelevant when the row carries no model-run time at
all.
- Return type:
None - Parameters: df (DataFrame | MostlyRightResult)
exception mostlyright.core.LeakageError(message=”, , as_of, violating_count, sample_violations=None, source=None, request_id=None, error_code=None)
Section titled “exception mostlyright.core.LeakageError(message=”, , as_of, violating_count, sample_violations=None, source=None, request_id=None, error_code=None)”Bases: MostlyRightError
Temporal leakage detected — at least one row has knowledge_time
greater than the asserted as_of cutoff. Carries the count and a small
sample of violating rows for actionable surfacing.
- Parameters:
- Return type: None
default_error_code : str = ‘LEAKAGE_DETECTED’
Section titled “default_error_code : str = ‘LEAKAGE_DETECTED’”Subclass override — the stable string enum surfaced via error_code.
exception mostlyright.core.MostlyRightError(message=”, , error_code=None, source=None, request_id=None)
Section titled “exception mostlyright.core.MostlyRightError(message=”, , error_code=None, source=None, request_id=None)”Bases: Exception
Base class for all mostlyright structured errors.
error_code is a stable enum (e.g. "SOURCE_UNAVAILABLE") used by
callers / agents to branch on without parsing message text. source is
the source ID involved ("iem.archive" etc.) when applicable, and
request_id correlates an MCP JSON-RPC request when applicable.
- Parameters:
- Return type: None
default_error_code : str = ‘MOSTLYRIGHT_ERROR’
Section titled “default_error_code : str = ‘MOSTLYRIGHT_ERROR’”Subclass override — the stable string enum surfaced via error_code.
to_dict()
Section titled “to_dict()”Return a JSON-safe dict suitable for MCP error.data.
class mostlyright.core.MostlyRightResult(frame, source, retrieved_at, schema_id=None, qc=None, data_version=None)
Section titled “class mostlyright.core.MostlyRightResult(frame, source, retrieved_at, schema_id=None, qc=None, data_version=None)”Bases: object
Backend-neutral provenance wrapper for a DataFrame-returning call.
Both pandas-backend and polars-backend adapters return the same
wrapper shape. frame holds the native frame; the remaining fields
carry the provenance that v0.1.0 used to stamp on df.attrs.
- Parameters:
- frame (FrameLike)
- source (str)
- retrieved_at (datetime)
- schema_id (str | None)
- qc (dict [str , Any ] | None)
- data_version (DataVersion | None)
The underlying DataFrame (pandas OR polars). Optional polars
type is type-hinted via TYPE_CHECKING so default install
does not require polars.
source
Section titled “source”The canonical source identifier (e.g. "iem.live",
"awc.live", "noaa_bdp"). Mirrors the v0.1.0
df.attrs["source"] contract.
retrieved_at
Section titled “retrieved_at”UTC timestamp of the fetch. MUST be tz-aware.
schema_id
Section titled “schema_id”Optional canonical schema ID (e.g.
"schema.observation.v1"). None if the call returns
heterogeneous rows (e.g. research() pairs).
Optional QC summary (rules_fired counts, sidecar_paths) if the
caller invoked qc=True. Mirrors df.attrs["qc"].
data_version
Section titled “data_version”Optional DataVersion token for reproducibility.
Examples
Section titled “Examples”>>> import pandas as pd>>> from datetime import datetime, timezone>>> from mostlyright.core.result import MostlyRightResult>>> df = pd.DataFrame({"date": ["2025-01-01"], "value": [42]})>>> result = MostlyRightResult(... frame=df,... source="iem.live",... retrieved_at=datetime(2025, 1, 1, tzinfo=timezone.utc),... )>>> result.source'iem.live'>>> result.frame_as_pandas().iloc[0]["value"]42data_version : DataVersion | None = None
Section titled “data_version : DataVersion | None = None”frame : DataFrame | DataFrame
Section titled “frame : DataFrame | DataFrame”frame_as_pandas()
Section titled “frame_as_pandas()”Return the underlying frame as a pandas DataFrame.
Pandas frames pass through unchanged. Polars frames are converted
via pl.DataFrame.to_pandas(). Parity-locked modules call this
before running their pandas-only pipelines (Phase 6 PLAN.md W4-T1).
Polars→pandas conversion may shift datetime resolution (us → ns
on the v0.1.0 contract path) and may change nullable-int storage.
Callers that need byte-equivalent round-trip across backends MUST
consult the documented coercion rules in
tests/fixtures/parity/coerce_pd3.py.
- Return type:
DataFrame
legacy_df_with_attrs()
Section titled “legacy_df_with_attrs()”Return the wrapped pandas DataFrame with df.attrs populated.
Mirrors the v0.1.0 df.attrs-stamped shape that catalog adapters
produced: attrs["source"], attrs["retrieved_at"] (ISO
string), and attrs["qc"] / attrs["data_version"] when set.
For callers that still consume df.attrs["source"] directly
instead of the wrapper, this method bridges the legacy expectation
for one release cycle (strict deprecation lands in v0.3).
- Raises: TypeError – if the wrapped frame is polars — the legacy shape was pandas-only by definition.
- Return type:
DataFrame
qc : dict[str, Any] | None = None
Section titled “qc : dict[str, Any] | None = None”retrieved_at : datetime
Section titled “retrieved_at : datetime”schema_id : str | None = None
Section titled “schema_id : str | None = None”source : str
Section titled “source : str”to_dict()
Section titled “to_dict()”JSON-safe dict representation for v0.2 MCP JSON-RPC serialization.
Excludes the frame body — callers that need to ship rows over MCP
should serialize the frame via mostlyright.core.formats.* writers
and attach the provenance via this method’s output.
exception mostlyright.core.PayloadTooLargeError(message=”, , declared_size, limit, accepted_modes=None, source=None, request_id=None, error_code=None)
Section titled “exception mostlyright.core.PayloadTooLargeError(message=”, , declared_size, limit, accepted_modes=None, source=None, request_id=None, error_code=None)”Bases: MostlyRightError
The MCP server rejected an inline payload whose declared size exceeded
the cap. accepted_modes advertises the alternatives (e.g. file-path
mode per design.md §Q).
- Parameters:
- Return type: None
default_error_code : str = ‘PAYLOAD_TOO_LARGE’
Section titled “default_error_code : str = ‘PAYLOAD_TOO_LARGE’”Subclass override — the stable string enum surfaced via error_code.
class mostlyright.core.Schema
Section titled “class mostlyright.core.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.SchemaRegistration(schema, source, retrieved_at_min, retrieved_at_max, rows, _audit=)
Section titled “class mostlyright.core.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.
retrieved_at_max : datetime
Section titled “retrieved_at_max : datetime”retrieved_at_min : datetime
Section titled “retrieved_at_min : datetime”source : str
Section titled “source : str”exception mostlyright.core.SchemaValidationError(message=”, , schema_id, violations=None, quarantine_count=0, sample_violations=None, source=None, request_id=None, error_code=None)
Section titled “exception mostlyright.core.SchemaValidationError(message=”, , schema_id, violations=None, quarantine_count=0, sample_violations=None, source=None, request_id=None, error_code=None)”Bases: MostlyRightError
A DataFrame failed schema validation. Carries the full violation list (capped at 10,000 — surplus written to file via §Q file-path mode by the SDK) and a small inline sample for MCP wire serialization (≤10 entries).
- Parameters:
- Return type: None
default_error_code : str = ‘SCHEMA_VALIDATION_FAILED’
Section titled “default_error_code : str = ‘SCHEMA_VALIDATION_FAILED’”Subclass override — the stable string enum surfaced via error_code.
exception mostlyright.core.SourceMismatchError(message=”, , schema_source, data_source, role=None, catalog_warning=None, source=None, request_id=None, error_code=None)
Section titled “exception mostlyright.core.SourceMismatchError(message=”, , schema_source, data_source, role=None, catalog_warning=None, source=None, request_id=None, error_code=None)”Bases: MostlyRightError
The data’s source does not match the schema’s registered source, and
the caller did not opt out via allow_source_drift. role (if set)
identifies which leg of a pull_pairs request mismatched and uses the
canonical long form: "observations" / "forecasts" / "settlement".
- Parameters:
- Return type: None
VALID_ROLES = frozenset({‘forecasts’, ‘observations’, ‘settlement’})
Section titled “VALID_ROLES = frozenset({‘forecasts’, ‘observations’, ‘settlement’})”Canonical role-name vocabulary (design.md §R).
default_error_code : str = ‘SOURCE_MISMATCH’
Section titled “default_error_code : str = ‘SOURCE_MISMATCH’”Subclass override — the stable string enum surfaced via error_code.
exception mostlyright.core.SourceUnavailableError(message=”, , source=None, http_status=None, retryable=False, retry_after_s=None, underlying=”, url=None, request_id=None, error_code=None)
Section titled “exception mostlyright.core.SourceUnavailableError(message=”, , source=None, http_status=None, retryable=False, retry_after_s=None, underlying=”, url=None, request_id=None, error_code=None)”Bases: MostlyRightError
A source (HTTP endpoint, vendored parser, etc.) returned an error or was otherwise unreachable. Carries enough metadata for callers to decide whether to retry and after how long.
- Parameters:
- Return type: None
default_error_code : str = ‘SOURCE_UNAVAILABLE’
Section titled “default_error_code : str = ‘SOURCE_UNAVAILABLE’”Subclass override — the stable string enum surfaced via error_code.
exception mostlyright.core.TemporalDriftError(message=”, , schema_id, asserted_range, violating_rows, sample_violations=None, source=None, request_id=None, error_code=None)
Section titled “exception mostlyright.core.TemporalDriftError(message=”, , schema_id, asserted_range, violating_rows, sample_violations=None, source=None, request_id=None, error_code=None)”Bases: MostlyRightError
Raised by the reproducibility audit (design.md §P) when one or more
rows have retrieved_at outside the asserted range AND fall within the
volatile window of now. Indicates the source materially re-amended
historical rows since the schema’s registered capture.
- Parameters:
- Return type: None
default_error_code : str = ‘TEMPORAL_DRIFT’
Section titled “default_error_code : str = ‘TEMPORAL_DRIFT’”Subclass override — the stable string enum surfaced via error_code.
class mostlyright.core.TimePoint(value)
Section titled “class mostlyright.core.TimePoint(value)”Bases: object
A UTC-aware timestamp normalized to UTC for storage.
Construction accepts:
datetime.datetimewithtzinfoset (converted to UTC)pandas.Timestampwithtzset (converted to UTC)- ISO 8601 string with a timezone (parsed and converted to UTC)
Rejects:
- naive
datetime/pd.Timestamp(tzinfo/tzisNone) - date-only ISO strings (no time component, e.g.
"2026-05-21")
Storage is a datetime with tzinfo=timezone.utc and microsecond
precision preserved.
- Parameters: value (TimePointInput)
as_zone(tz)
Section titled “as_zone(tz)”Convert to a different IANA zone via zoneinfo.ZoneInfo.
Display helper only — the canonical storage stays UTC. Raises
zoneinfo.ZoneInfoNotFoundError if tz is not a known IANA
timezone.
classmethod from_pandas(ts)
Section titled “classmethod from_pandas(ts)”Construct from a tz-aware pandas.Timestamp.
Explicit alternative to passing a Timestamp to TimePoint(...)
— useful when the caller wants the pandas-specific dispatch path
to be unambiguous.
Raises ValueError if ts is pd.NaT (missing-data sentinel).
- Return type:
TimePoint - Parameters: ts (Timestamp)
Return an ISO 8601 UTC string.
Includes microseconds only when non-zero, matching standard
datetime.isoformat() behavior (e.g.
"2026-05-21T14:30:00+00:00" or
"2026-05-21T14:30:00.123456+00:00").
- Return type:
str
classmethod now()
Section titled “classmethod now()”Return a TimePoint for the current UTC time.
- Return type:
TimePoint
to_utc()
Section titled “to_utc()”Return the underlying UTC datetime (microseconds preserved).
- Return type:
datetime
mostlyright.core.assert_no_leakage(df, as_of)
Section titled “mostlyright.core.assert_no_leakage(df, as_of)”Raise LeakageError if any row’s knowledge_time > as_of.
Phase 6 W0-T6: accepts either a raw DataFrame or a
MostlyRightResult; wrapped polars frames are converted to
pandas via MostlyRightResult.frame_as_pandas() because the body
of this function uses pd.Timestamp + iterrows semantics.
- Parameters:
- df (
DataFrame|MostlyRightResult) – DataFrame with a tz-aware UTCknowledge_timecolumn, OR aMostlyRightResultwrapping such a frame. - as_of (
TimePoint) – The as-of cutoff. Rows with strictly greaterknowledge_timecount as leakage.
- df (
- Raises:
- SchemaValidationError – if
knowledge_timeis missing or not tz-aware UTC. - TypeError – if
as_ofis not aTimePoint. - LeakageError – if ≥1 rows have
knowledge_time > as_of. Payload carriesviolating_countand a sample (≤10) of violations.
- SchemaValidationError – if
- Return type: None
Examples
Section titled “Examples”- Return type:
None - Parameters:
- df (DataFrame | MostlyRightResult)
- as_of (TimePoint)
A leak-free frame passes silently:
>>> import pandas as pd>>> from mostlyright.core import TimePoint, assert_no_leakage>>> df = pd.DataFrame({... "knowledge_time": pd.to_datetime(["2025-01-01T00:00:00Z"], utc=True),... "value": [10],... })>>> assert_no_leakage(df, TimePoint("2025-01-02T00:00:00Z"))A row past the cutoff raises LeakageError:
>>> from mostlyright.core import LeakageError>>> leaky = pd.DataFrame({... "knowledge_time": pd.to_datetime(["2025-01-03T00:00:00Z"], utc=True),... "value": [99],... })>>> try:... assert_no_leakage(leaky, TimePoint("2025-01-02T00:00:00Z"))... except LeakageError as err:... print(err.violating_count)1mostlyright.core.assert_source_identity(df, expected_source, , role=‘observations’)
Section titled “mostlyright.core.assert_source_identity(df, expected_source, , role=‘observations’)”Raise SourceMismatchError if any row’s source != expected.
A defense-in-depth per-row gate: mirrors the per-row check in
mostlyright.core.validator.validate_dataframe() but at the
source-pinned dispatch layer so callers get a role-flavored error
message when a pinned single-source frame carries a foreign row.
- Parameters:
- Raises:
SourceMismatchError – when one or more rows carry a
sourceother thanexpected_source. - Return type:
None
mostlyright.core.validate_dataframe(df, schema_id, , allow_source_drift=None)
Section titled “mostlyright.core.validate_dataframe(df, schema_id, , allow_source_drift=None)”Validate a DataFrame against the named canonical schema.
Phase 6 W0-T4: accepts either a raw pd.DataFrame (legacy v0.1.0
contract — must carry df.attrs["source"] / df.attrs["retrieved_at"])
or a MostlyRightResult wrapper (v0.2+ contract — provenance
travels on the wrapper). When passed a wrapper, the validator
unwraps to pandas via MostlyRightResult.legacy_df_with_attrs()
and proceeds with the same logic so the four checks below run
byte-identically for both shapes.
The Validator runs four checks, in order:
- Source-identity invariant. Reads
df.attrs["source"]and compares againstschema_cls._registered_source. If they differ andallow_source_driftis None, raisesSourceMismatchError. Ifallow_source_driftis supplied, the drift is permitted and the audit log records the reason. - Required-column presence. Non-nullable columns must be present
in
df.columns. - Per-column dtype. Dispatched on
ColumnSpec.dtype. - Enum value membership.
dtype="enum"columns must have values inColumnSpec.enum_values. Sample of violating values capped at 10.
- Parameters:
- df (
DataFrame|MostlyRightResult) – The DataFrame to validate. Must carrydf.attrs["source"], OR aMostlyRightResultwrapper whosesource/retrieved_atpopulate the equivalent attrs on unwrap. - schema_id (
str) – Canonical schema ID (e.g."schema.observation.v1"). - allow_source_drift (
str|None) – Reason string. If supplied, source mismatch is allowed; audit log records the reason.
- df (
- Return type:
SchemaRegistration - Returns:
A
SchemaRegistrationrecording the validation. Carries the full audit log (registeredevent always;source_drift_allowedevent whenallow_source_driftis supplied). - Raises:
- SchemaValidationError – column / dtype / enum / null-sentinel violations.
- SourceMismatchError – source identity violated without opt-out.
Examples
Section titled “Examples”The source-identity invariant fires when df.attrs["source"] differs
from the schema’s registered canonical source (here
schema.observation.v1 is registered to iem.archive):
>>> import pandas as pd>>> from mostlyright.core import SourceMismatchError, validate_dataframe>>> df = pd.DataFrame({"date": pd.to_datetime(["2025-01-06"])})>>> df.attrs["source"] = "awc.live">>> try:... validate_dataframe(df, "schema.observation.v1")... except SourceMismatchError as err:... print(err.data_source, "!=", err.schema_source)awc.live != iem.archiveA full passing example requires the canonical column set; see
packages/core/tests/core/test_validator.py for end-to-end fixtures.
Modules
Section titled “Modules”exceptions | Structured exception hierarchy for the mostlyright SDK and MCP server. |
|---|---|
formats | Format converters for DataFrame interchange. |
merge | Phase 2.1 — read-time merge policy for silver-tier observation ledgers. |
result | MostlyRightResult — backend-neutral provenance wrapper. |
schema | Declarative schema framework for mostlyright. |
schemas | Canonical schemas shipped with mostlyright v0.1. |
source_identity | Canonical home for the assert_source_identity source-pinning gate. |
temporal | mostlyright.core.temporal — temporal-safety primitives. |
validator | DataFrame validator with source-identity enforcement. |