mostlyright.core.result
ProvenancedFrame — backend-neutral provenance wrapper.
Polars frames have no .attrs, so stamping df.attrs["source"] /
df.attrs["retrieved_at"] cannot survive the polars backend.
ProvenancedFrame carries the provenance separately from the frame so
both pandas and polars callers preserve source-identity invariants without
.attrs writes.
Validator, KnowledgeView, and LeakageDetector accept either a raw
DataFrame OR a ProvenancedFrame; the wrapper-aware dispatch unwraps via
frame_as_pandas() and the validation logic runs unchanged.
Classes
Section titled “Classes”ProvenancedFrame(frame, source, retrieved_at) | Backend-neutral provenance wrapper for a DataFrame-returning call. |
|---|
class mostlyright.core.result.ProvenancedFrame(frame, source, retrieved_at, schema_id=None, quality_control=None, data_version=None)
Section titled “class mostlyright.core.result.ProvenancedFrame(frame, source, retrieved_at, schema_id=None, quality_control=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:
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).
quality_control
Section titled “quality_control”Optional QC summary (rules_fired counts,
sidecar_paths) when the caller requested QC. Mirrors
df.attrs["quality_control"].
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 ProvenancedFrame>>> df = pd.DataFrame({"date": ["2025-01-01"], "value": [42]})>>> result = ProvenancedFrame(... 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
Section titled “data_version: DataVersion | 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 (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
quality_control: dict[str, Any] | None
Section titled “quality_control: dict[str, Any] | None”retrieved_at: datetime
Section titled “retrieved_at: datetime”schema_id: str | None
Section titled “schema_id: str | None”source: str
Section titled “source: str”to_dataframe()
Section titled “to_dataframe()”Return the underlying frame as a pandas DataFrame, schema-stamped.
Routes through the SAME shared finalizer the default DataFrame/bypass
paths use (mostlyright._internal._finalize), so the wrapper path and
the return_type="dataframe" bypass emit identical
mostlyright_schema_id / mostlyright_schema_version attrs (A13 —
one implementation, no drift). When schema_id is None (a
heterogeneous-row wrapper) the stamp is skipped — there is no single
schema to name.
- Return type:
DataFrame
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.