Skip to main content
sma terminal demo

tests python license demo

sma — Sports Model Integrity Auditor

A model can look great in a notebook — high accuracy, clean metrics — and still fall over in production, because the number was never the problem. sma audits a fitted model plus its dataset for five of the most common ways that happens, and returns a plain-language report card instead of a wall of statistics.

Built framework-agnostic: works with anything exposing .predict — scikit-learn, XGBoost, LightGBM, or a hand-rolled class. See sma/core/checks/base.py.

Live demo → (free-tier hosting — first request after inactivity takes ~30–50s to wake up)


What it checks

Check Catches
class_imbalance A skewed target that makes accuracy alone misleading
small_sample_instability Too little data — overall, or in a minority class — for the reported metric to be trustworthy. Bootstraps the metric to quantify how noisy it actually is
target_leakage A feature suspiciously correlated with the label — often a sign it encodes the answer (a "cancellation_notice_sent" column when predicting churn)
temporal_leakage A non-chronological train/test split, or a feature that predicts tomorrow's label better than today's — the classic look-ahead bug in feature engineering
data_drift The current data's distribution has shifted from what the model was trained on (PSI + KS-test), so its assumptions may no longer hold

Every check returns PASS / WARN / FAIL / NOT_APPLICABLE with structured evidence — never a bare pass/fail with no explanation.

Real-world validation

Built and tested against synthetic failure cases (a deliberate 9:1 class imbalance, a leaky churn feature, a genuine look-ahead bug, a simulated "price increase" distribution shift) — all five checks fired exactly as designed, with 32 passing unit tests.

Then dogfooded against PulseConnect, an F1 telemetry and driver-compatibility ML platform, using its real GradientBoostingRegressor and 8 seasons of real race data (2019–2026):

  • Leakage checks came back cleantarget_leakage and temporal_leakage both passed, which is itself evidence the leakage fix already documented in PulseConnect's own code comments (recency-windowed features, season-indexed constructor form) actually worked.
  • data_drift caught something real: comparing early seasons (2019–2022) against recent ones (2023–2026), driver pace and tyre-degradation features showed major distribution shift (PSI 1.3–1.4) — a legitimate signal of F1's 2022 regulation overhaul, not a bug. It's concrete evidence that pooling all seasons as one training set treats different regulation eras as statistically the same when they aren't.

Architecture

architecture diagram
sma/
├── sma/
│   ├── core/
│   │   ├── checks/           # one file per check, all sharing base.py's contract
│   │   │   ├── base.py       # CheckResult, Status, ModelAdapter
│   │   │   ├── class_imbalance.py
│   │   │   ├── small_sample.py
│   │   │   ├── target_leakage.py
│   │   │   ├── temporal_leakage.py
│   │   │   └── data_drift.py
│   │   ├── auditor.py        # orchestrates: run(model, X, y, ...) -> Report
│   │   └── report.py         # aggregates CheckResults, computes overall status
│   ├── report_renderers/     # Report -> markdown / html
│   └── cli.py
├── api/
│   ├── main.py                # FastAPI wrapper — imports sma.core directly
│   └── static/index.html      # terminal-styled demo frontend
└── tests/                      # 32 tests, one file per check

Every check shares one contract:

def run(model, X, y, **kwargs) -> CheckResult:
    ...

registered in sma/core/auditor.py::DEFAULT_CHECKS. The CLI, the API, and both report renderers all consume the same Auditor.run() — nothing is duplicated between them, so what a pip installer gets is exactly what the hosted demo runs. A check that fails to run (missing optional input, not-yet-implemented) is isolated and reported as NOT_APPLICABLE, never crashes the whole audit.

Install

pip install sma-audit          # once published — see below
# or, for local development:
git clone https://github.com/kopommops/sma-audit
cd sma-audit
pip install -e ".[dev,api]"

Use as a package

from sma import Auditor

report = Auditor().run(model, X, y)
print(report.overall_status)      # Status.PASS / WARN / FAIL
print(report.to_dict())

With the optional inputs each check can use:

report = Auditor().run(
    model, X, y,
    timestamps=df["date"],           # enables temporal_leakage
    reference_X=training_data,       # enables data_drift
)

Use as a CLI

sma audit model.pkl --data train.csv --target churned --format html --out report.html

# with timestamps + a chronological split check:
sma audit model.pkl --data train.csv --target churned \
  --timestamp-col date --split-date 2026-01-01

# with a reference dataset for drift detection:
sma audit model.pkl --data current.csv --target churned \
  --reference-data training_data.csv

Run the API + demo frontend locally

uvicorn api.main:app --reload
# visit http://127.0.0.1:8000 for the terminal UI,
# or POST directly to /audit (JSON) or /audit/html (rendered report)

Run tests

pytest -q
# 32 passed

Design notes

  • Framework-agnostic by constructionModelAdapter (sma/core/checks/base.py) wraps any object exposing .predict; checks never call the model directly, so swapping in a future model type (a raw PyTorch wrapper, say) means changing one adapter, not five checks.
  • Isolated check failures — the orchestrator catches exceptions per-check and reports them as a FAIL with the error message, rather than letting one broken check take down the whole audit.
  • Evidence over verdicts — every result carries structured evidence (counts, scores, thresholds), not just a status label, so a report card is something you can actually investigate, not just trust.

Roadmap

  • All 5 v1 checks implemented and tested
  • CLI, package API, and FastAPI demo, all sharing one core
  • Dogfooded against a real production model (PulseConnect)
  • Hosted demo deployed
  • Publish to PyPI
  • Config object for per-check thresholds (currently hardcoded per-module constants)
  • Additional checks (e.g. feature importance stability, calibration)

License

MIT — see LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sma_audit-0.1.1.tar.gz (37.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sma_audit-0.1.1-py3-none-any.whl (41.8 kB view details)

Uploaded Python 3

File details

Details for the file sma_audit-0.1.1.tar.gz.

File metadata

  • Download URL: sma_audit-0.1.1.tar.gz
  • Upload date:
  • Size: 37.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.0

File hashes

Hashes for sma_audit-0.1.1.tar.gz
Algorithm Hash digest
SHA256 60be372dbd786f1b4604de59cfe160041d875fa741de39752b514d52b4b74c3a
MD5 f3ddef4b379475cc259f898229100374
BLAKE2b-256 cca27d88710ea4dca60b75352888d9d101be8c0667a1c86ac3ce79e5308189a4

See more details on using hashes here.

File details

Details for the file sma_audit-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: sma_audit-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 41.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.0

File hashes

Hashes for sma_audit-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 9487db739ce5424855d8aec280a40959286de78e27272a251a3ce4c51213d1d8
MD5 045a9e35974337918b3b08cb863ff548
BLAKE2b-256 97846ff74289449d34fd6d7abf6ecbbe8da49dd3999bd3eb2038f6416dcda1de

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page