Skip to main content

Dot-path access, mutation, and flattening for deeply nested dict/JSON data, with clear error messages.

Project description

grabmonkey

Dot-path access, mutation, and flattening for deeply nested dict/JSON data — with error messages that tell you exactly which level failed.

Stop writing this:

data.get("response", {}).get("results", [{}])[0].get("metadata", {}).get("created_at", "")

Write this:

from grabmonkey import grab

grab(data, "response.results[0].metadata.created_at", default="")

Install

pip install grabmonkey

Requires Python 3.11+. No runtime dependencies.

Quick start

from grabmonkey import grab, grab_many, put, delete, flatten, unflatten

data = {"response": {"results": [{"metadata": {"id": 1, "created_at": "2026"}}]}}

# Read, any depth
grab(data, "response.results[0].metadata.created_at")   # "2026"

# Safe default instead of an exception
grab(data, "response.results[0].missing", default="")   # ""

# Type coercion on access
grab({"count": "42"}, "count", as_type=int)             # 42

# Wildcards over lists
grab({"items": [{"n": 1}, {"n": 2}]}, "items[*].n")     # [1, 2]

# Batch access
grab_many(data, {"id": "response.results[0].metadata.id"})   # {"id": 1}

# Set and delete (mutates in place, creates intermediate containers)
d = {}
put(d, "a.b[2].c", 9)              # {"a": {"b": [None, None, {"c": 9}]}}
delete(d, "a.b[2].c")              # {"a": {"b": [None, None, {}]}}
delete(d, "a.b[2]", prune=True)    # {"a": {"b": [None, None]}}  (prune drops empties)

# Flatten / unflatten
flatten({"a": {"b": [1, 2]}})           # {"a.b[0]": 1, "a.b[1]": 2}
unflatten({"a.b[0]": 1, "a.b[1]": 2})   # {"a": {"b": [1, 2]}}

Clear errors

grab(data, "response.results[0].nope")
# grabmonkey.errors.PathError:
# Path 'response.results[0].nope' failed at 'nope':
# key not found in dict with keys ['metadata']

PathError (a LookupError) means a structural miss — the case default= absorbs. PathSyntaxError means a malformed path string. CoercionError means the value was found but as_type could not convert it. The last two are not absorbed by default=, on purpose.

Path syntax

Syntax Meaning
a.b.c dict key or object attribute
items[0], items[-1] sequence index
items[*] every element of a sequence / value of a mapping
data['weird.key'] quoted key for keys with dots/brackets/spaces

Works on dicts, lists, dataclasses, named tuples, and any object with attribute access. Strings and bytes are treated as leaf values, not navigable containers (see LIMITATIONS.md).

CLI

Reads JSON from a file (--input) or stdin, prints JSON:

echo '{"user":{"name":"Alice"}}' | grabmonkey grab user.name   # "Alice"
echo '{"a":{"b":1}}'             | grabmonkey flatten          # {"a.b": 1}
grabmonkey grab metadata.id --input response.json

Using with AI assistants

See SKILL.md for an LLM-consumable reference (decision table, worked examples, anti-patterns). See LIMITATIONS.md for deliberate design tradeoffs.

Development & review

grabmonkey is tested and reviewed under a portable review kit:

  • CONTRIBUTING.md — testing philosophy and the competitive multi-model review-panel process.
  • LIMITATIONS.md — deliberate tradeoffs reviewers should not re-litigate (read before "fixing" surprising behaviour).
  • RELEASE_READINESS.md — the release rubric; run python scripts/readiness.py for the score and convergence verdict.
  • REVIEW_HISTORY.md — the panel-by-panel trajectory.
  • review-kit/ — the pristine, project-agnostic templates the above were derived from (inert to the project's own checks).
pip install -e ".[dev]"
pytest -q && ruff check src tests && mypy
python scripts/readiness.py

License

MIT

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

grabmonkey-1.1.0.tar.gz (33.0 kB view details)

Uploaded Source

Built Distribution

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

grabmonkey-1.1.0-py3-none-any.whl (22.9 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for grabmonkey-1.1.0.tar.gz
Algorithm Hash digest
SHA256 26640fc4d778c3a8994377c5d818ad4fe541501c157f6aa648dede2d8482fcfd
MD5 7912c022945f537b21699098d14dbbb7
BLAKE2b-256 457023e535ba0ba4fda8f68b91116b187a81c588ec9a66a1dffce2ea3a2bf28f

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for grabmonkey-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 01eda7b32bf02fb05751e306d4211858e4e30d1669283126587d95bf65c4cf36
MD5 3940af1f627a4d49a2778803e87cb18c
BLAKE2b-256 c34756ff0408ba078667862797d975b01a6173b35bd8861d5d2b80255c8bc3f6

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