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; they unwrap the wrapper via frame_as_pandas() and the validation logic runs unchanged.

ClassDescription
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 pandas callers also find on df.attrs.

  • Parameters:

The underlying DataFrame (pandas or polars). The polars type is type-hinted via TYPE_CHECKING so the default install does not require polars.

The canonical source identifier (e.g. "iem.live", "awc.live", "noaa_bdp"). Mirrors the 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(). Modules whose output is pinned by the parity fixtures call this before running their pandas-only pipelines.

Polars→pandas conversion may shift datetime resolution (us → ns) and may change nullable-int storage. Callers that need a byte-equivalent round-trip across backends should consult the 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 finalizer the direct DataFrame path uses (mostlyright._internal._finalize), so the wrapper path and the return_type="dataframe" path emit identical mostlyright_schema_id / mostlyright_schema_version attrs. 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.