Skip to main content

BDD-style metric definitions with built-in data trust checks

Project description

Litmus

BDD-style metric definitions with built-in data trust checks.

PyPI version Python versions License: Apache 2.0 CI Downloads


Install

pip install litmus-data
litmus init           # scaffold litmus.yml + metrics/ folder
litmus check metrics/ # run trust checks

The problem

Your CEO asks: "What was our revenue last month?"

The data analyst says $4.2M. Finance says $3.8M. Engineering says $4.5M.

Three teams, three numbers, zero trust — because metric definitions live in SQL files, dbt models, and spreadsheet formulas that business users can't read or approve. Nobody agrees on what "revenue" means, and nobody knows if the underlying data is trustworthy.

The solution

Litmus lets you define metrics in plain English that business stakeholders can review and sign off on, then validates the data continuously. A .metric file is a Gherkin-inspired contract — Given / When / Then for the business logic, plus a Trust: block with executable data-quality rules.

Quickstart

Write metrics/revenue.metric:

Metric: Monthly Revenue
Description: Total revenue from completed orders in the current calendar month
Owner: finance-team
Tags: finance, reporting

Source: orders

Given all records from orders table
  And status is "completed"
  And order_date is within current calendar month

When we calculate
  Then sum the amount column

The result is "Monthly Revenue"

Trust:
  Freshness must be less than 6 hours
  Null rate on amount must be less than 1%
  Row count must not drop more than 20% day over day
  Value must be between 100000 and 50000000
  Value must not change more than 30% month over month

Run the checks:

$ litmus check metrics/revenue.metric

Monthly Revenue
   Owner: finance-team

   Trust Checks:
   PASS  Freshness: 2 hours (threshold: < 6 hours)
   PASS  Null rate on amount: 0.3% (threshold: < 1%)
   WARN  Row count: -18% day-over-day (threshold: < 20%)
   PASS  Value: $4,200,000 (range: $100,000 – $50,000,000)
   PASS  Change month-over-month: +12% (threshold: < 30%)

   Trust Score: 4.5 / 5

Generate a stakeholder-friendly explanation:

litmus explain metrics/revenue.metric

What you get

Command What it does
litmus init Scaffold litmus.yml and a starter metrics/example.metric.
litmus check <path> Parse every .metric under <path> and run its trust rules against the warehouse. Exits non-zero on failure.
litmus parse <file> Dump the parsed MetricSpec — useful when debugging DSL changes.
litmus explain <file> Render a plain-English description from a spec (non-engineer friendly).
litmus import-dbt <manifest.json> Seed .metric files from an existing dbt manifest.json.
litmus export --to dbt <path> Emit dbt schema.yml plus singular tests from a .metric file, so Litmus rules run inside a dbt project.
litmus share <path> Render a self-contained HTML card (with check results) you can paste into Slack or Notion.
litmus report <dir> Produce an HTML, Markdown, or JSON report across a whole metrics folder.

Run litmus <cmd> --help for the full flag list.

Trust checks

Nine built-in check types, all declarable inside the Trust: block:

  • Freshness — maximum age of the most recent row (Freshness must be less than 6 hours).
  • Null rate — share of nulls in a column (Null rate on amount must be less than 1%).
  • Volume — row-count drop vs the previous period (Row count must not drop more than 20% day over day).
  • Range — inclusive bounds on the metric's value (Value must be between 100000 and 50000000).
  • Change — period-over-period movement on the value (Value must not change more than 30% month over month).
  • Duplicate rate — uniqueness guard on a column (Duplicate rate on invoice_id must be 0%).
  • Schema drift — fail if the source table's columns change (Schema must not drift).
  • Distribution shift — flag when a column's distribution moves beyond a threshold (Mean of net_amount must not change more than 25% month over month).
  • Custom SQL — pluggable hook in litmus/checks/custom.py for rules the DSL doesn't express yet.

Change / distribution / volume rules compare against a SQLite history store (~/.litmus/history.db by default, overridable via LITMUS_HISTORY_DB or --history-db).

Supported warehouses

Warehouse Status Install
DuckDB Built-in, zero config included
SQLite Built-in included
PostgreSQL Supported pip install 'litmus-data[postgres]'
Snowflake Supported pip install 'litmus-data[snowflake]'
BigQuery Supported pip install 'litmus-data[bigquery]'
All of the above pip install 'litmus-data[all]'

Warehouse credentials are read from the LITMUS_WAREHOUSE_USER and LITMUS_WAREHOUSE_PASSWORD environment variables — never from litmus.yml.

Run it on every PR

Drop this into .github/workflows/litmus-check.yml:

name: Litmus trust check
on:
  pull_request:
    paths: ["metrics/**/*.metric", "litmus.yml"]

permissions:
  pull-requests: write
  contents: read

jobs:
  litmus:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - id: litmus
        uses: zinnoberHaus/litmus@v0
        with:
          path: metrics/
      - if: always() && github.event.pull_request
        uses: marocchino/sticky-pull-request-comment@v2
        with:
          header: litmus
          message: ${{ steps.litmus.outputs.summary-markdown }}

The composite action is defined in action.yml. Inputs: path (required), config, extras (e.g. postgres,snowflake), fail-on-warning, litmus-version. Outputs: report-json, trust-score, summary-markdown. An annotated copy of this workflow lives at .github/workflows/litmus-check.example.yml.

How it fits with dbt and semantic layers

Litmus is a trust / contract layer, not a replacement for your transformation or semantic tools. dbt and Cube / LookML / MetricFlow answer "how is this metric computed?" — Litmus answers "is the metric currently trustworthy, and did the business sign off on its definition?" litmus import-dbt seeds specs from an existing dbt project, and litmus export --to dbt emits dbt singular tests so the same rules can run inside a dbt CI pipeline. The two stacks are designed to sit side by side.

Documentation

License

Apache 2.0 — see LICENSE.

Project details


Download files

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

Source Distribution

litmus_data-0.1.1.tar.gz (67.6 kB view details)

Uploaded Source

Built Distribution

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

litmus_data-0.1.1-py3-none-any.whl (78.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: litmus_data-0.1.1.tar.gz
  • Upload date:
  • Size: 67.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for litmus_data-0.1.1.tar.gz
Algorithm Hash digest
SHA256 76ddbed8b31dcc4217bfdfb11b42481f8f214d55f706195543496ded4718dc56
MD5 362cdf5504c2ad96b52b6da6ffe299cc
BLAKE2b-256 c7b275eee951cd28fc51ca1445c13b0e7e8adcdaeded1b3face74f85e04e4586

See more details on using hashes here.

Provenance

The following attestation bundles were made for litmus_data-0.1.1.tar.gz:

Publisher: release.yml on zinnoberHaus/litmus

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

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

File metadata

  • Download URL: litmus_data-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 78.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for litmus_data-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 12c8c7c0523c87760968bc861992a1cdd39dc9b76aab3758d2354853b95c9c3b
MD5 7f723ce21f7811f54e17887905da27ea
BLAKE2b-256 768c17998edb3314f8ffe92689b7fe1e32d28b125815075272fcbd4e21219cad

See more details on using hashes here.

Provenance

The following attestation bundles were made for litmus_data-0.1.1-py3-none-any.whl:

Publisher: release.yml on zinnoberHaus/litmus

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page