JSONPath-NG

raw JSON →
1.8.0 verified Tue May 12 auth: no python install: verified quickstart: stale

jsonpath-ng is a robust and significantly extended implementation of JSONPath for Python. It aims to be standard compliant, including arithmetic and binary comparison operators, and provides a clear Abstract Syntax Tree (AST) for metaprogramming. As of version 1.8.0, it is actively maintained with a regular release cadence, merging functionalities from older libraries like jsonpath-rw and jsonpath-rw-ext.

pip install jsonpath-ng
error ModuleNotFoundError: No module named 'jsonpath_ng'
cause The `jsonpath-ng` library is not installed or is not accessible in the current Python environment.
fix
Ensure the library is installed using pip: pip install jsonpath-ng
error jsonpath_ng.exceptions.JsonPathLexerError: Error on line 1, col X: Unexpected character: ?
cause This error often occurs when using filter expressions `[?()]` with the default `jsonpath_ng.parse` function, which might not fully support advanced filter syntax from other JSONPath implementations.
fix
For extended filter syntax and other advanced features, import parse from jsonpath_ng.ext instead: from jsonpath_ng.ext import parse
error jsonpath_ng.exceptions.JsonPathParserError: Parse error at X:Y near token Z (NUMBER)
cause This error typically occurs when attempting to access a dictionary key that is a string containing only digits using dot notation (e.g., `$.data.1`), as `jsonpath-ng` interprets it as a numerical index.
fix
Access string keys that look like numbers using bracket notation with quotes: jsonpath_expr = parse('$.data["1"]')
error AttributeError: 'DatumInContext' object has no attribute 'key'
cause The `DatumInContext` object returned by `find()` in `jsonpath-ng` does not have a direct `key` attribute to retrieve the key of the matched element; it primarily provides `value`, `path`, and `context`.
fix
To get the key, you need to access it from the path attribute of the DatumInContext object, typically by checking if the path is a Child or Fields instance and extracting its field_name: [match.path.field_name for match in jsonpath_expr.find(data) if isinstance(match.path, (jsonpath_ng.jsonpath.Child, jsonpath_ng.jsonpath.Fields))]
breaking Python 3.7 support was removed in v1.7.0. Python 3.8 and 3.9 support were removed in v1.8.0. Users on these Python versions must upgrade to Python 3.10 or newer to use jsonpath-ng >= 1.8.0.
fix Upgrade your Python environment to 3.10 or newer.
gotcha The `find()` method returns a list of `DatumInContext` objects, even if only one or no matches are found. Users commonly forget to check if the list is empty before accessing `[0].value`, leading to an `IndexError`.
fix Always check if the `matches` list is not empty (e.g., `if matches: value = matches[0].value`) or use a list comprehension if expecting multiple results.
gotcha In older versions, updating a JSON object using `jsonpath_expr.update()` could fail with `TypeError` if the target value was `None` or a boolean. While fixes have been implemented (e.g., for boolean values in v1.7.0, and null values in earlier patches), ensure you are on a recent version if experiencing such issues.
fix Upgrade to the latest version of `jsonpath-ng` to benefit from these fixes, especially if performing `update` operations on data that might contain `None` or boolean values.
gotcha The library internally uses `this` to refer to the 'current object' within a filter expression, rather than the `@` symbol often seen in other JSONPath implementations. While `@` might work in simple cases due to parsing ambiguities, `this` is the explicit and recommended syntax for clarity and correctness.
fix Use `this` (e.g., `[?(this.price < 10)]`) instead of `@` when referencing the current object within filter expressions.
python os / libc status wheel install import disk
3.10 alpine (musl) - - 0.04s 18.3M
3.10 slim (glibc) - - 0.04s 19M
3.11 alpine (musl) - - 0.13s 20.2M
3.11 slim (glibc) - - 0.10s 21M
3.12 alpine (musl) - - 0.10s 12.1M
3.12 slim (glibc) - - 0.08s 13M
3.13 alpine (musl) - - 0.07s 11.7M
3.13 slim (glibc) - - 0.07s 12M
3.9 alpine (musl) - - 0.06s 17.8M
3.9 slim (glibc) - - 0.04s 18M

This quickstart demonstrates how to parse JSON data, extract specific elements using JSONPath expressions, filter results, and update values within a JSON structure. It covers the core `parse` and `find` methods, as well as a basic `update` operation.

from jsonpath_ng import jsonpath, parse
import json

data = {
    "store": {
        "book": [
            {"category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95},
            {"category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99},
            {"category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99},
            {"category": "fiction", "author": "J.R.R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8", "price": 22.99}
        ],
        "bicycle": {"color": "red", "price": 19.95}
    },
    "expensive": 10
}

# Find all book titles
jsonpath_expr = parse('$.store.book[*].title')
matches = jsonpath_expr.find(data)
book_titles = [match.value for match in matches]
print(f"Book Titles: {book_titles}")

# Find books cheaper than $10
jsonpath_expr = parse('$.store.book[?(@.price < 10)].title')
matches = jsonpath_expr.find(data)
cheap_books = [match.value for match in matches]
print(f"Cheap Books (titles): {cheap_books}")

# Update a value (e.g., change bicycle color)
update_expr = parse('$.store.bicycle.color')
updated_data = update_expr.update(data, 'blue')
print(f"Updated Bicycle Color: {updated_data['store']['bicycle']['color']}")