Skip to content

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.

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.

The canonical source identifier (e.g. "iem.live", "awc.live", "noaa_bdp"). Mirrors the v0.1.0 df.attrs["source"] contract.

UTC timestamp of the fetch. MUST be tz-aware.

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) when the caller requested QC. Mirrors df.attrs["quality_control"].

Optional DataVersion token for reproducibility.

>>> 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"]
42

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

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

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.