mrkeyoor.com_
Tue 22 Sept 22:33 UTC
PyPIUtilsupdated 22 Sept 2026

glom review

glom 25.12.0 is a Python mini-language for reading, reshaping, validating, and sometimes mutating nested objects. A dotted string follows a path, a dictionary describes output fields, a one-item list maps over input, and a tuple pipes one transformation into the next. Named specifiers such as `Coalesce`, `Match`, `Iter`, `Assign`, and `Delete` add fallback, validation, streaming, and mutation. The current release is maintenance-only, adding Python 3.13 and 3.14 tests and test fixes. Our Python 3.12 install was pure Python and small, but the distribution has no `py.typed` marker and does not declare a Python requirement in its metadata.

Verdict

glom 25.12.0 installed in 0.5 seconds, used 2 MB, imported in 0.51 seconds, and produced 0 pip-audit findings in our sandbox. It earns its place when nested transformations repeat across a codebase; direct Python remains clearer for short, local lookups.

We installed it

Lab card: what happened when we installed glomScreenshot of glom documentation
Install✓ · 0.5s4 packages on disk · 2 MB
Importimport glom in 0.51s · pure Python
Known vulns0(pip-audit)

Answers from our run

Does glom install cleanly?

Yes. In a fresh container with an empty cache, pip install glom finished in 0.5s, leaving 4 packages and 2 MB on disk. pip-audit reported no known vulnerabilities.

What does glom need to run?

Python 3.x, and nothing compiled: it is pure Python. In our run import glom succeeded in 0.51s.

glom or jmespath: which should you use?

jmespath: Use it for read-only JSON queries expressed in a language with implementations beyond Python. glom 25.12.0 installed in 0.5 seconds, used 2 MB, imported in 0.51 seconds, and produced 0 pip-audit findings in our sandbox.

When should you not use glom?

A couple of subscripts and one comprehension already tell the story. glom's container rules and specifier classes add a language that maintainers must learn.

API stability4/5The changelog states a backward-compatibility goal, and the central `glom(target, spec)` call still interprets paths, mappings, one-item lists, tuples, and `T` as long-standing building blocks. New work has generally added specifier classes such as matching and streaming rather than replacing the entry point. CalVer numbers describe release date instead of compatibility, and wildcard behavior has changed before, so large specs still need regression fixtures around exact input and output.
Docs5/5Read the Docs separates the tutorial, API, CLI, matching, streaming, grouping, mutation, modes, debugging, and FAQ. Examples explain `SKIP`, `STOP`, recursive `Ref`, scope values, and the mutation helpers, while error documentation shows the target and spec trace that glom adds. The FAQ also names a boundary: general recursive tree traversal belongs elsewhere. The remaining difficulty comes from the DSL itself because Python container syntax changes meaning by position.
Maintenance4/5PyPI serves 25.12.0 without a yanked flag, GitHub showed a July 17, 2026 push, 2,163 stars, 128 open issues and pull requests, and an unarchived repository. The current release is deliberately modest: tests and fixes for Python 3.13 and 3.14. That is useful compatibility maintenance, though the absent `requires-python`, missing `py.typed`, and unknown package license metadata leave three packaging details less precise than the source documentation.
Ecosystem3/5glom records 5,822,889 weekly downloads and operates on ordinary mappings, sequences, objects, iterators, and callables. Custom registration can adapt object types, while the CLI handles JSON and documented optional formats. Specs do not travel cleanly across languages because they can contain Python functions, classes, target expressions, and mutations. That makes the ecosystem useful inside Python services but weak as a shared query or validation contract.

Use it if

  • Several endpoints need the same nested payload reshaped into a stable output dictionary.
  • Deep lookup failures should identify the exact path segment instead of ending as a generic KeyError or TypeError.
  • A transformation combines mapping, filtering, fallback, reduction, or validation and a named spec is easier to test than repeated loops.
  • Developers want to prototype short JSON transformations with a command-line tool before placing the spec in Python code.
Skip it if

Setup reality

We installed glom 25.12.0 in 0.5 seconds inside a fresh Python 3.12 Bookworm sandbox. The environment ended with 4 packages taking 2 MB. The distribution reports 5 direct dependencies, is pure Python, and has no py.typed marker. Its metadata does not specify a Python floor or a usable license value. import glom worked in 0.51 seconds, and pip-audit found 0 known vulnerabilities.

There are no credentials, services, or configuration files. Installation adds both the Python module and a glom command. The CLI consumes JSON by default; TOML and YAML depend on the documented format support and extras. A path query is pleasant at the shell, but nested tuple and dictionary specs quickly become a quoting exercise. Put longer transformations in a Python module where they can be named and tested.

The learning cost appears on the first real spec. Strings with dots mean traversal, one-item lists map, dictionaries construct output, tuples form a pipeline, and callables run on the current target. To read a literal key containing a dot, use T['a.b'] or Path. Wildcards also carry glom meaning. A broad default or Coalesce can quietly convert a malformed required field into an ordinary-looking result, so attach fallbacks only to optional data.

Most glom() calls create a new result, but assign() and delete() modify the supplied object. Copy shared input before mutation. Call, Invoke, arbitrary callables, attribute access, and custom spec types make trusted-code ownership a security boundary. The 25.12.0 changelog lists test coverage work for Python 3.13 and 3.14, while package metadata still leaves requires-python blank. Test the exact interpreter versions in your own build rather than inferring support from metadata.

Patterns

Read a nested field read-deep-path

from glom import glom

payload = {'customer': {'address': {'city': 'Pune'}}}
city = glom(payload, 'customer.address.city')

A missing segment raises `PathAccessError` with its position in the 3-part path, which is more specific than a later TypeError.

Try two email locations fallback-between-paths

from glom import Coalesce, glom

email = glom(
    payload,
    Coalesce('contact.work_email', 'contact.personal_email', default=None),
)

`Coalesce` checks candidates in order. Its default should represent an optional field, since it also hides path failures.

Build a smaller output dictionary reshape-record

from glom import Coalesce, glom

spec = {
    'customer_id': 'customer.id',
    'name': 'customer.profile.name',
    'postcode': Coalesce('customer.address.postcode', default=None),
}
summary = glom(payload, spec)

Every value spec runs against the original payload. Dictionary keys become the output field names.

Convert nested invoice rows map-and-convert-list

from glom import glom

spec = ('invoices', [{
    'id': 'number',
    'amount': ('amount_paise', lambda value: value / 100),
}])
rows = glom(payload, spec)

A list containing 1 spec maps it over each item. Tuple elements execute as sequential stages.

Read a literal key containing a dot access-dotted-key

from glom import T, glom

data = {'invoice.total': 1250, 'tax_rate': 0.18}
result = glom(data, {
    'subtotal': T['invoice.total'],
    'gross': T['invoice.total'] * (1 + T['tax_rate']),
})

The string `'invoice.total'` would mean a 2-segment path. `T[...]` treats it as one literal mapping key.

Drop inactive records with SKIP filter-mapped-values

from glom import SKIP, glom

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

`SKIP` removes the list element. Returning `None` would preserve an element whose value is null.

Match required field types validate-record-list

from glom import Match, glom

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

The `object: object` pair allows extra fields. A mismatch raises a `MatchError` subtype rather than returning false.

Change a value in place assign-nested-field

from glom import assign

customer = {'profile': {'status': 'trial'}}
assign(customer, 'profile.status', 'paid')

`assign()` mutates `customer`. Make a copy first when another caller relies on the original object.

Remove temporary data delete-nested-field

from glom import delete

customer = {'profile': {'name': 'Asha', 'debug': True}}
delete(customer, 'profile.debug')

Deletion happens in place. A failed traversal or removal raises `PathDeleteError`.

Combine child lists flatten-one-level

from glom import Flatten, glom

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

`Flatten()` removes 1 iterable layer. It is not a recursive walk over an unknown tree.

Process an iterator lazily stream-filter-results

from glom import Iter, T, glom

spec = Iter().filter(T['active']).map(T['id'])
active_ids = list(glom(users, spec))

`Iter` defers work until iteration. Converting to `list` consumes the full source and materializes every result.

Check a path from the shell query-json-cli

glom --scalar 'customer.address.city' '{"customer":{"address":{"city":"Pune"}}}'

The `--scalar` flag prints a single value without JSON string quoting. It was added in 24.11.0 and remains in 25.12.0.

Alternatives

PackageRegistryPick it when
jmespathPyPIUse it for read-only JSON queries expressed in a language with implementations beyond Python.
dpathPyPIUse it for glob-like get, search, set, and merge operations over dictionaries without glom's full spec model.
BeneDictPyPIUse it when attribute and key-path access on dictionary-like objects is the main need rather than declarative reshaping.

More utils guides

lru-cache · ajv · type-fest · p-limit · find-up · js-yaml · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.