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 structureresult.to_markdown()— report for PRs, chat, emailresult.to_html()— standalone HTML diff reportresult.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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e030995156a0ea3fe9022197bbdc9e55aab4b457a4d82b14a94aa6c292a70b80
|
|
| MD5 |
1737c847b858247ffff277908d5b2c12
|
|
| BLAKE2b-256 |
453240871dff5b2cdd2899ebc2550be8915b47a588017014720941b720af49b9
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
827b5342a47a89aeab5f55313ad9daab1adbef5804511937daaacc046aa29548
|
|
| MD5 |
d71b137422cd058b32eff50af3ad3980
|
|
| BLAKE2b-256 |
62963f625e1d1063ce221a6e42c1b89761e0ad1455c08c1acdc05ebc5fb1920c
|