Skip to main content

Type-aware, key-based structural diffing of tabular datasets with human- and machine-readable reports.

Project description

diffmonkey

Type-aware, key-based structural diffing of tabular datasets — answer "what changed between last month's export and this month's?" in one call, with human- and machine-readable reports.

diffmonkey matches rows by a key column (or composite key), compares the remaining columns with type awareness (numbers by value, dates by calendar date, booleans by truth, strings whitespace-normalised, nulls unified), and buckets the result into added / removed / changed / unchanged with summary statistics. It is built on the rexbytes ecosystem — typemonkey for type inference and number parsing, datemonkey for date parsing, cleanmonkey for whitespace and invisible-character normalisation — so it does not re-derive those wheels.

In scope: structural comparison, change detection, change reporting. Out of scope: merge/reconciliation, text diffing, schema migration, version control.

Install

pip install diffmonkey            # CSV/TSV/pipe input built in
pip install "diffmonkey[excel]"   # add .xlsx reading (openpyxl)

Requires Python 3.11+.

Quick start

from diffmonkey import compare

old = [{"id": "1", "name": "Widget", "price": "1,234"},
       {"id": "2", "name": "Gadget", "price": "50"}]
new = [{"id": "1", "name": "Widget", "price": "1234"},   # price reformatted, not changed
       {"id": "3", "name": "Gizmo",  "price": "9"}]       # id 2 removed, id 3 added

result = compare(old, new, key="id")

print(result.summary.one_line())
# 1 added, 1 removed, 0 changed (of 2 current), 0 unchanged

print(result.to_markdown())   # human report
result.to_dict()              # machine-readable
result.write_csv("changes.csv")

"1,234" vs "1234" is not reported as a change — type-aware numeric comparison sees one number. The same applies to "01/02/2025" vs "2025-01-02" (dates, with a locale hint), " foo " vs "foo" (whitespace), and None/""/"NA" (nulls).

CLI

diffmonkey compare old.csv new.csv --key id
diffmonkey compare old.csv new.csv --key region,sku --ignore updated_at --format markdown
diffmonkey compare old.xlsx new.xlsx --key id --format json -o diff.json

Exit code is 0 when the datasets are identical and 1 when they differ — handy in CI and scripts.

Key options

Option Purpose
key Identity column, or list for a composite key
columns / ignore Restrict / exclude columns from comparison
column_map={"old":"new"} Handle renamed columns (avoids false add+remove)
rel_tol / abs_tol Floating-point tolerance for numeric columns
locale="us" / "eu" Disambiguate slash dates and number separators
null_equivalent Treat all null spellings as one value (default on)
type_aware / date_aware Toggle type/date-aware comparison
include_unchanged Retain unchanged rows in the result
on_duplicate / on_missing_key Policies for messy keys

Output formats

  • result.to_dict() — JSON-serialisable structure
  • result.to_markdown() — report for PRs, chat, email
  • result.to_html() — standalone HTML diff report
  • result.to_csv() / result.write_csv(path) — one row per field change

Using with AI assistants

See SKILL.md for LLM-oriented usage (decision tree, worked examples, anti-patterns). See LIMITATIONS.md for the deliberate design tradeoffs (date/locale ambiguity, null vocabulary, duplicate handling) so behaviour that looks surprising is not mistaken for a bug.

Contributing & quality

diffmonkey is tested and reviewed against an explicit quality contract. See CONTRIBUTING.md for the testing philosophy and the competitive multi-model review process, REVIEW_HISTORY.md for the review trajectory, and RELEASE_READINESS.md for the release rubric (python scripts/readiness.py).

License

MIT — 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

diffmonkey-1.1.0.tar.gz (53.4 kB view details)

Uploaded Source

Built Distribution

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

diffmonkey-1.1.0-py3-none-any.whl (29.6 kB view details)

Uploaded Python 3

File details

Details for the file diffmonkey-1.1.0.tar.gz.

File metadata

  • Download URL: diffmonkey-1.1.0.tar.gz
  • Upload date:
  • Size: 53.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for diffmonkey-1.1.0.tar.gz
Algorithm Hash digest
SHA256 e030995156a0ea3fe9022197bbdc9e55aab4b457a4d82b14a94aa6c292a70b80
MD5 1737c847b858247ffff277908d5b2c12
BLAKE2b-256 453240871dff5b2cdd2899ebc2550be8915b47a588017014720941b720af49b9

See more details on using hashes here.

File details

Details for the file diffmonkey-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: diffmonkey-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 29.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for diffmonkey-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 827b5342a47a89aeab5f55313ad9daab1adbef5804511937daaacc046aa29548
MD5 d71b137422cd058b32eff50af3ad3980
BLAKE2b-256 62963f625e1d1063ce221a6e42c1b89761e0ad1455c08c1acdc05ebc5fb1920c

See more details on using hashes here.

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