← All extensions
MLOps Data Contracts banner

MLOps Data Contracts

ivyx

Adds data contracts to the MLOps extension, stopping the pipeline when your data stops matching

MLOps Data Contracts

The pandera engine for the MLOps hub: draft a data contract from a dataset you already have, then stop the pipeline when the data stops matching it.

pandera is the real upstream tool — this extension manages it, it does not imitate it. The contract is a pandera schema in your repository, it is code you edit, and git is its history.

What you can do

  • Draft a data contract from a dataset you already have, instead of writing one from a blank file
  • Keep that contract as code in your repository, edited by you and versioned in git
  • Stop an MLOps pipeline the moment your data stops matching the contract, with the offending column named
  • Check a dataset against its contract before anything downstream sees it

Requirements

The MLOps extension, the desktop app, and pandera in the Python environment your workspace already uses.

Getting started

This is step 5 of the walkthrough in the MLOps extension's README, which starts from an empty folder and ends with a run that this gate stops. Install this alongside MLOps and draft a contract from one of your datasets.

What a contract is here

A file the pipeline points at. Either a Python module that exports schema (a DataFrameSchema) or defines a DataFrameModel class, or a pandera YAML schema:

import pandera.pandas as pa

schema = pa.DataFrameSchema(
    {
        "id": pa.Column("int64", nullable=False),
        "age": pa.Column("float64", nullable=True, checks=[pa.Check.in_range(18, 92)]),
        "city": pa.Column(nullable=False, checks=[pa.Check.isin(["ankara", "izmir"])]),
    },
    strict=False,
    coerce=False,
)

Wire it into .punica/mlops.yaml as a gate and the hub runs it in order:

stages:
  - id: data-contract
    kind: gate
    capability: mlops.pandera.validate
    input:
      contract: contracts/data_contract.py
      data: data/prepared.csv
    onFailure: stop
  - id: train
    kind: pipeline
    onFailure: stop

A failing gate marked stop ends the run, and train is recorded as skipped.

Drafting one from a dataset

mlops.pandera.contractFromProfile profiles a file through Data Profiler and writes a contract from what the profile measured. The draft is conservative on purpose — a generated contract that fails on the next perfectly good file teaches people to ignore the gate:

  • Column presence and nullability, from the observed null ratio.
  • Numeric dtype, and the observed numeric range (turn this off with ranges: false).
  • An isin list only when the profile proves the list is complete — top-K carries an (other) remainder whenever it does not cover every row, so its absence is exact evidence.
  • No coerce, because coercion turns one missing value into three failures and hides real type drift.
  • No dtype on text or dates. Measured: pandas 2.3.3 reads a string column as object and pandas 3.0.5 reads it as str, so a hardcoded string dtype breaks on whichever version the profile did not come from.
  • No unique, because the profiler's distinct count is approximate and an approximation must not mint a hard constraint.

Everything it could not prove is written into the file's docstring rather than guessed.

How it runs

The interpreter comes from Python Environments (python.env.resolve) and the validation driver is handed to it with -c. There is deliberately no bare python3, no PATH lookup, and no scratch file written into your workspace to run a gate.

The range this provider is written against is pandera[pandas]>=0.32,<0.34, measured on pandera 0.32.1 with pandas 3.0.5. The pandas extra is not optional: pandera installs without pandas, and the panel reports that state separately because the fix is different.

Capabilities

Capability Policy What it does
mlops.pandera.validate low / none Checks a dataset against a contract; reports which column failed which check, how often, and with what values
mlops.pandera.contractFromProfile medium / none Drafts a contract from a dataset profile and writes it into the workspace
mlops.pandera.engine low / none The installed pandera and pandas versions
mlops.pandera.reveal low / none Reveal the Data Contracts panel

mlops.pandera.validate answers pass: false with a reason when the data violates the contract — that is the verdict the MLOps hub records as a failed stage. An unusable environment (no interpreter, no pandera, no pandas, a contract that does not import) throws instead, with a different sentence for each, because each has a different fix.

Limits worth knowing

  • Electron-only: running processes is not something a browser host does.
  • Whole-file validation. A dataset larger than memory needs a limit, and the gate then states what it checked.
  • The panel reads its gate list from the hub's mlops.pipeline.describe. With no MLOps hub installed it says so rather than showing an empty list.

Verification

  • npm run check:pandera replays measured driver envelopes (pandera 0.32.1 / pandas 3.0.5, plus two deliberately broken environments) through the shipped parsers, generator and panel logic. 78 checks.
  • npm run probe:pandera -- /path/to/python builds a throwaway dataset, drafts a contract with the shipped generator, and drives the shipped engine against a live pandera: the draft accepts the data it came from, a raised null ratio fails the gate and names the column, every generated check fires, and a missing column is named. Re-run this after a pandera or pandas upgrade — a renamed check passes the harness and fails in the app.