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.

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.0.1.tar.gz (26.3 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.0.1-py3-none-any.whl (20.3 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for grabmonkey-1.0.1.tar.gz
Algorithm Hash digest
SHA256 41b7bfe48792c4a083a18b7119079501d0bc3c2c5948abb36d595fede0b47ef4
MD5 72df0b89a114f9348625e5abc4104175
BLAKE2b-256 d54e24689a628626f2e7683b8168512d62628e54202a26fc5fd8a7c7271d4f8f

See more details on using hashes here.

File details

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

File metadata

  • Download URL: grabmonkey-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 20.3 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.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 f664b51016e227af3a1be9cb80dc6e5bd0da939ae9280270040d45288f405ea6
MD5 01e321fc99e8b9892d69b73c34378a95
BLAKE2b-256 61bb57ff2934bd82bdae89f7ca3058de5495bb11decd336d36597dffdefd30eb

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