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

Uploaded Python 3

File details

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

File metadata

  • Download URL: grabmonkey-1.0.0.tar.gz
  • Upload date:
  • Size: 26.2 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.0.tar.gz
Algorithm Hash digest
SHA256 05a5ccbe8f187c4a0c0e6b04c872206f136632105f8c3b212bb5751b1956970b
MD5 a10b8ee8a63ef305b8c9873c4cd26b80
BLAKE2b-256 33b3804cf4168667978befb80905e304792936977e9246e94033a896163014a0

See more details on using hashes here.

File details

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

File metadata

  • Download URL: grabmonkey-1.0.0-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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7a4ec00f9fca273145217fa634db0ded40a91c6f787a2f1e71d0bd464c257bb7
MD5 3f3d40771dea9142484f91a08d811543
BLAKE2b-256 760dfde62fcf23a1059bb7032c69ef1636e0021e9101db7d68c678798495311f

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