Kontra
Fast data quality validation for files, databases, and DataFrames.
Kontra validates data against declarative rules. It stays fast on large datasets by resolving checks from metadata when possible, then running the rest via batched SQL pushdown (DuckDB / PostgreSQL / SQL Server / ClickHouse).
pip install kontra
Quick Start
import kontra
from kontra import rules
result = kontra.validate("users.parquet", rules=[
rules.not_null("user_id"),
rules.unique("email"),
rules.range("age", min=0, max=120),
])
result.passed # True
result.to_dict() # Structured output for CI/services
result.to_llm() # Token-optimized summary for agents
DataFrames work too:
result = kontra.validate(df, rules=[...]) # Polars or pandas
CLI
kontra profile users.parquet --draft > contract.yml
kontra validate contract.yml
✅ users — PASSED (4 of 4 rules)
✅ COL:user_id:not_null [metadata]
✅ COL:age:range [metadata]
✅ COL:email:unique [sql]
✅ COL:status:allowed_values [sql]
Execution
Metadata (preplan) resolves what it can prove. Remaining rules run via SQL pushdown when available, or locally (Polars). Preplan and pushdown are configurable.
Contracts
Rules can also be defined in YAML:
name: users
datasource: users.parquet
rules:
- name: not_null
params: { column: user_id }
- name: unique
params: { column: email }
severity: warning
- name: allowed_values
params:
column: status
values: [active, inactive, pending]
- name: range
params: { column: age, min: 0, max: 120 }
What You Get
- 18 built-in rules for nulls, uniqueness, ranges, regex, freshness, and more (reference)
- Fast execution: metadata analysis + batched SQL pushdown
- Multiple sources: Parquet, CSV, PostgreSQL, SQL Server, ClickHouse, S3, Azure ADLS Gen2
- Agent-friendly: structured, token-optimized summaries via
.to_llm() - Official MCP server: expose validation, profiling, and history to Claude, Codex, Cursor, or any MCP client —
pip install "kontra[mcp-postgres]"(docs) - Debuggable failures: collect failing rows during validation, fetch more later on demand
- Track drift: save runs and compare over time with
kontra diff
Fail Fast vs Exact Counts
By default, Kontra runs in fail-fast mode: it stops at the first violation per rule and reports failed_count: 1 as a lower bound. This enables early termination and metadata-only resolution — large Parquet tables can validate in milliseconds when Parquet statistics are sufficient to prove a rule passes.
When you need exact counts, enable tally:
result = kontra.validate("users.parquet", rules=[...], tally=True)
Or per-rule in YAML:
rules:
- name: not_null
params: { column: user_id }
tally: true # scan all rows, count all violations
Results:
- default (fail fast) →
failed_count: 1(≥1 violation exists) tally: true→failed_count: 23741(exact)
Failure Samples
# Collect samples during validation
result = kontra.validate("users.parquet", rules=[...], sample=5)
# Access what was collected
for rule in result.rules:
if not rule.passed and rule.samples:
print(rule.rule_id, rule.samples)
# Need more? Fetch on demand
result.sample_failures("COL:user_id:not_null", n=20)
Install Extras
pip install "kontra[postgres]" # PostgreSQL
pip install "kontra[sqlserver]" # SQL Server
pip install "kontra[clickhouse]" # ClickHouse
pip install "kontra[s3]" # S3 / MinIO
Documentation
| Doc | Audience |
|---|---|
| Getting Started | New users |
| Python API | Library users |
| Rules Reference | All 18 rules |
| Configuration | Project setup |
| Agents and MCP | Agent integrations |
| Architecture | Contributors |
License
Apache License 2.0
Metadata
Release files for kontra 0.15.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| kontra-0.15.0.tar.gz | 535.3 kB | Without provenance | Details for kontra-0.15.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| kontra-0.15.0-py3-none-any.whl | Python 3 | none | any | Details for kontra-0.15.0-py3-none-any.whl |
Total release size: 987.4 kB
Release files / kontra-0.15.0.tar.gz
| Download URL | kontra-0.15.0.tar.gz |
|---|---|
| Size | 535.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cb9dcd0a6c53392158b1f120d7c3953fa7983b66f4003842efb950d67affa0e4
|
|
BLAKE2b-256 checksum How to use checksums |
2f6e25bf8cf9205cafcbb7a6f27f6486812c46d5ecf3b7538fed28a6a151ead1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Release files / kontra-0.15.0-py3-none-any.whl
| Download URL | kontra-0.15.0-py3-none-any.whl |
|---|---|
| Size | 452.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
18a71b3be6fc57f9e8d1f56cd47f3ce56c700f0a4ef553a80f7320f3db274724
|
|
BLAKE2b-256 checksum How to use checksums |
97ea074d9e299a05e1e8e845b3e0e06e2a405e5dfe1812524d5c46f378bec2f2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Security for kontra 0.15.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.