mrkeyoor.com_
Sat 08 Aug 20:59 UTC
PyPIUtilsupdated 08 Aug 2026

glom

glom is a declarative nested-data toolkit for Python. A spec can retrieve a deep path, reshape dictionaries and lists, call transformations, provide fallbacks, filter or reduce collections, validate structures, mutate paths, and recurse through known tree shapes. Its main promise is that a reusable spec describes what output should look like while PathAccessError and related exceptions show where a nested lookup failed.

Verdict

glom earns its dependency when nested transformations recur and deserve named, tested specifications. For a handful of direct lookups, plain Python stays easier to read, type-check, profile, and debug.

API stability4/5The central `glom(target, spec)` contract and foundational string, dict, list, tuple, callable, T, and Coalesce forms have remained recognizable while newer releases add specifier types. The project uses calendar versioning, which makes release order clear but does not promise semantic-major signaling. Complex specs still bind to Python behavior and exact spec classes.
Docs5/5The documentation includes a tutorial, full API, CLI guide, debugging tools, FAQ, matching, mutation, grouping, streaming, modes, custom spec types, and a large snippets collection. Examples explain subtle features such as SKIP, recursive Ref specs, scope storage, Django registration, and the explicit lack of general arbitrary-tree traversal.
Maintenance4/5Version 25.12.0 was uploaded on December 29, 2025 and the repository was pushed on July 17, 2026. It tests across CPython 3.7 through 3.14 and PyPy according to the README. GitHub shows 128 open issues and pull requests, a meaningful backlog, but active pushes and a recent calendar-versioned release indicate ongoing maintenance.
Ecosystem3/5glom has 2,158 GitHub stars, works with ordinary dicts, lists, tuples, objects, iterators, and callables, and offers hooks for custom types such as Django managers. The CLI handles common data formats with extras. It is mature within Python, but its specs are Python-specific and cannot replace cross-language JSON query or schema standards.

Use it if

  • You repeatedly reshape nested API payloads into a stable application-facing structure
  • You want deep-path errors that identify the failed segment instead of a generic KeyError or TypeError
  • You need reusable transformations combining access, mapping, filtering, defaults, validation, and construction
  • You want to prototype a transformation at the command line and move the same spec into Python
Skip it if

Setup reality

`pip install glom` installs a pure-Python package plus boltons, attrs, and face; there are no native builds or service credentials. The same install exposes a `glom` command that reads JSON by default and accepts Python, TOML, or YAML formats, but TOML on older Python and YAML require the documented optional extras. The real setup cost is teaching the spec language. Strings such as `a.b.c` are parsed as paths, dictionaries build output dictionaries, one-item lists map over an iterable, tuples run stages in series, callables execute against the current target, and `T`, `S`, `A`, `M`, `Coalesce`, `Iter`, `Match`, `Check`, `Call`, and `Ref` each alter evaluation. Literal keys containing dots need an explicit `Path` or `T[...]` expression. Missing data raises detailed exceptions unless the spec supplies a default or fallback; broad defaults can hide malformed upstream payloads, so catch only expected absence. Ordinary transformation is non-mutating, while `assign()` and `delete()` deliberately change the target unless you copy it first. A spec can call arbitrary Python and custom classes can implement `glomit`, so do not deserialize and run specs from an untrusted boundary. For a team, keep named specs close to representative input and output tests, and stop expanding the DSL when a normal function is clearer. The CLI is useful for experiments, but shell quoting complex Python specs becomes brittle quickly.

Patterns

Read a nested path with a useful errorget-nested-value

from glom import glom

data = {'account': {'profile': {'name': 'Ada'}}}
name = glom(data, 'account.profile.name')

A missing segment raises PathAccessError identifying its location. Use a default only when absence is expected rather than malformed input.

Use a fallback for missing alternativesprovide-default

from glom import Coalesce, glom

email = glom(
    user,
    Coalesce('contact.primary_email', 'contact.backup_email', default=None),
)

Coalesce tries specs in order. A final default suppresses missing-path errors, so distinguish optional fields from required ones.

Reshape a nested recordreshape-object

from glom import Coalesce, glom

spec = {
    'id': 'user.id',
    'display_name': 'user.profile.name',
    'city': Coalesce('user.address.city', default='Unknown'),
}
result = glom(payload, spec)

Dictionary keys in a spec are output keys; dictionary values are evaluated against the same current target.

Transform every item in a nested listmap-nested-list

from glom import glom

spec = ('orders', [{
    'number': 'id',
    'total': ('amount_cents', lambda cents: cents / 100),
}])
orders = glom(payload, spec)

A one-item list maps its inner spec across the iterable. A tuple runs stages from left to right.

Handle literal keys and computed values with Tuse-target-expression

from glom import T, glom

data = {'a.b': 4, 'tax': 0.2}
result = glom(data, {
    'raw': T['a.b'],
    'with_tax': T['a.b'] * (1 + T['tax']),
})

A string containing dots is treated as a path. Use `T['a.b']` when the dot is part of the literal key.

Filter mapped items with SKIPfilter-items

from glom import SKIP, glom

active_ids = glom(
    users,
    [lambda user: user['id'] if user.get('active') else SKIP],
)

Returning SKIP removes the current item from list output. A regular `None` would remain in the result.

Validate record shapes with Matchvalidate-structure

from glom import Match, glom

spec = Match([{'id': int, 'email': str, object: object}])
validated = glom(records, spec)

Literal dictionary keys are required by default here, while `object: object` permits additional keys. A mismatch raises a MatchError family exception.

Assign a value at a deep pathassign-deep-value

from glom import assign

record = {'profile': {'name': 'Old'}}
assign(record, 'profile.name', 'Ada')
assert record['profile']['name'] == 'Ada'

`assign` mutates its target. Copy shared input first when callers expect transformation without side effects.

Delete a nested keydelete-deep-value

from glom import delete

record = {'user': {'name': 'Ada', 'temporary': True}}
delete(record, 'user.temporary')

Deletion is in place and raises PathDeleteError when traversal or deletion fails.

Flatten one level of nested iterablesflatten-results

from glom import Flatten, glom

values = glom([[1, 2], [3], [], [4, 5]], Flatten())
assert values == [1, 2, 3, 4, 5]

Flatten is a reduction specifier, not an arbitrary recursive tree walker. Repeated or recursive flattening needs an explicit design.

Construct an object with Callcall-constructor

from collections import deque
from glom import Call, T, glom

queue = glom([1, 2, 3], Call(deque, args=[T, 10]))
assert queue.maxlen == 10

Call executes Python code and can accept positional and keyword specs. Never treat arbitrary Call-bearing specs as untrusted data.

Prototype a path query at the command linequery-from-cli

glom 'users.0.profile.name' '{"users":[{"profile":{"name":"Ada"}}]}'

The CLI defaults to JSON input and Python-like specs. Complex specs are usually easier to keep in files than to quote through a shell.

Alternatives

PackageRegistryPick it when
jmespathPyPIYou need a portable, read-only JSON query language with implementations in several languages
jsonpath-ngPyPIYou specifically want JSONPath selection and updates rather than Python-shaped restructuring specs
dpathPyPIYou mainly need glob-like search, get, set, and merge operations on nested dictionaries