Skip to content

Releases: Saevarl/Kontra

Kontra 0.14.2

Choose a tag to compare

@Saevarl Saevarl released this 17 Jul 23:00

Bugfix release: SQL Server query-vs-table and table-vs-query compares now use set-based SQL pushdown, including cross-database table references. Mixed pairs execute through the query-side connection while cross-database query pairs continue to fall back safely.

v0.12.2

Choose a tag to compare

@Saevarl Saevarl released this 13 Jul 21:43

Performance: faster PostgreSQL validation.

  • A validate() against a PostgreSQL URI now opens one connection instead of three (shared across preplan, execution, and introspection).
  • Redundant SQL round-trips removed: COUNT(*) is folded into the tally aggregate (the whole contract becomes a single query), the compiled plan supplies required columns instead of an information_schema lookup, and preplan catalog queries are skipped when no rule can be resolved from metadata.
  • Small-table validation is substantially faster locally (exact-count path ~40ms → ~8ms).

Behavior note: in the default fail-fast mode, total_rows and derived rates are now taken from the PostgreSQL reltuples estimate rather than a separate exact COUNT(*). Rule pass/fail and failed_count are unchanged; only fail-fast totals/rates may now be estimates (fail-fast results are already lower bounds). Use tally=True for exact totals.

v0.12.1

Choose a tag to compare

@Saevarl Saevarl released this 13 Jul 18:53

Fix: probe key alignment no longer fails when a side carries a non-key column named like the join key (compare / profile_relationship, and the MCP compare_datasets/profile_relationship tools). Both sides are aligned onto collision-safe internal aliases; original key names are preserved in all output.

Metadata: project URLs now point to https://kontrakit.io and https://kontrakit.dev.

v0.10.0

Choose a tag to compare

@Saevarl Saevarl released this 09 Jul 16:48

Kontra 0.10.0

Transformation probes gain FK→PK key support, profile history becomes a first‑class Python API, and a batch of database‑path fixes land for SQL Server and Entra ID auth.

✨ New features

  • Different‑named join keys for transformation probes. compare() accepts before_key=/after_key= and profile_relationship() accepts left_on=/right_on= (pandas‑merge naming) for the common FK→PK case. The symmetric key=/on= forms still work; composite keys pair positionally.
    kontra.compare(tickets, orgs, before_key="organization_id", after_key="id")
    kontra.profile_relationship(tickets, orgs, left_on="organization_id", right_on="id")
  • Profile history in the Python API. kontra.profile(..., save=True), get_profile(), list_profiles(), and profile_diff() are now fully wired to the same store the CLI uses — profiles saved from Python and from kontra profile --save-profile are interchangeable.
  • PostgreSQL profile store. get_profile_store("postgres", uri=...) persists profiles to a shared kontra_profiles table for multi‑host setups (local .kontra/profiles/ remains the default).
  • Open annotation vocabulary. Any non‑empty annotation_type is accepted; two new documented types — diagnosis (first‑responder assessment) and expected (owner adjudication verdict).

🐛 Fixes

  • SQL Server Entra ID on Windows. msodbcsql18 rejects the Authentication=ActiveDirectory* keywords for token modes on Windows; Kontra now acquires the token via azure-identity and passes it through pyodbc attrs_before. entra_password remains the azure‑identity‑free fallback on all platforms.
  • Entra entra_password now correctly retains URI userinfo (UID/PWD).
  • Transformation‑probe materialization on SQL Server (pyodbc). Fixed a ShapeError (Row→tuple) and truncated dtype inference (columns NULL in the first 100 rows now infer correctly).
  • SQL Server scan profiling overflow. Numeric aggregates are widened (AVG/SUM args cast) so wide‑range integer columns no longer raise "Arithmetic overflow converting expression to data type int".
  • Trustworthy uniqueness on identifier columns. Estimated distinct counts for id‑like columns on tables ≤ 1M rows are refined with an exact COUNT(DISTINCT) — no more phantom duplicates (uniqueness_ratio < 1.0 on a genuinely unique key).
  • Constant columns surface their value. A distinct_count == 1 column now reports its single value in top_values/values on every backend.
  • kontra.set_config() is honored everywhere. Config‑path overrides now apply across validate(), datasource resolution, and state — previously only health() respected them.

⚠️ Notable changes

  • kontra.profile(save=...) now defaults to False. The kwarg was previously accepted but never acted on; it now works, and defaults to off to avoid surprise writes. Pass save=True to persist. Inline DataFrame profiles have no stable identity and are not saved.
  • The sqlserver-entra extra now also installs azure-identity (for the Windows token path).

📚 Docs

Updated across transformation probes, the Python API, profile history & store backends, SQL Server Entra config, and profiling‑estimate semantics.

Install

pip install --upgrade kontra # or: pip install kontra==0.10.0

Full changeset: everything above shipped under a single squashed commit gated by the full suite (1585 tests, 0 failures) across live PostgreSQL, SQL Server, and DuckDB.

v0.6.2

Choose a tag to compare

@Saevarl Saevarl released this 01 Feb 21:58

Glob Pattern Validation - Validate multiple files with s3://bucket/*.parquet

Cloud Sampling - sample_failures() now works with S3 and Azure parquet files

Simpler API

  • validate("contract.yml") extracts datasource automatically
  • draft("data.parquet") profiles internally
  • Dict-of-lists columnar input format supported

Bug Fixes

  • unique rule NULL handling consistency between SQL and Polars
  • dry_run=True and health() now properly load builtin rules
  • Empty DataFrame compare() no longer crashes
  • allowed_values("active") gives helpful error (expects list)
  • freshness suggestions default to severity: warning

v0.6.0

Choose a tag to compare

@Saevarl Saevarl released this 29 Jan 19:20

Highlights

🚀 Tally Mode - Control the trade-off between speed and precision

  • --tally for exact violation counts
  • --no-tally for fast early-stop
  • Per-rule tally: setting in contracts

2x Faster Cold Start - Lazy loading of heavy dependencies

  • import kontra now <200ms (was 500ms+)
  • Polars, DuckDB, database drivers loaded on-demand

UX Improvements - Better outputs everywhere

  • JSON validation output is now pretty-printed
  • Helpful hints: ≥1 failure (use --tally for exact count)
  • Cleaner profile displays

📚 Documentation Overhaul - Completely rewritten and restructured

Other Changes

  • EXISTS optimization for fast violation detection
  • rules.dtype() accepts dtype= parameter alias
  • Interrogate preset shows percentiles (p25, p75, p99)
  • DatasetProfile.to_json() method
  • MSSQL named datasource resolution
  • Config displays profile: instead of scout:
  • to_llm() suppresses top values for unique columns