Skip to main content

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.

Metadata

Release files for diffmonkey 1.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for diffmonkey 1.1.1
File Size Uploaded Provenance
diffmonkey-1.1.1.tar.gz 54.2 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for diffmonkey 1.1.1
File Interpreter ABI Platform
diffmonkey-1.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 84.0 kB

Release files / diffmonkey-1.1.1.tar.gz

Download URL diffmonkey-1.1.1.tar.gz
Size 54.2 kB
Tags Source
SHA-256 checksum
How to use checksums
874b5b8038ab882103cd277f2ddce70d3b7e11f5c81b344e618ee2359dd22d9f
BLAKE2b-256 checksum
How to use checksums
986fcca24e38ad89a52032f1b063b42a0aa2b6a0c3b0e2708879198fe3ab0197
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release files / diffmonkey-1.1.1-py3-none-any.whl

Download URL diffmonkey-1.1.1-py3-none-any.whl
Size 29.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7342a661d4e96b52044146bf04ea91cadb50b07c76d86dae5b3c5a21036babc6
BLAKE2b-256 checksum
How to use checksums
99c009c286b44f379da07926a338af708eb24149846df19a2f1e581b2eb6454d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Security for diffmonkey 1.1.1

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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page