We follow RFC 9535 strictly and test against the JSONPath Compliance Test Suite.
Table of Contents
Install Python JSONPath RFC 9535 using pip:
pip install jsonpath-rfc9535
Or Pipenv:
pipenv install -u jsonpath-rfc9535
import jsonpath_rfc9535 as jsonpath
data = {
"users": [
{"name": "Sue", "score": 100},
{"name": "Sally", "score": 84, "admin": False},
{"name": "John", "score": 86, "admin": True},
{"name": "Jane", "score": 55},
],
"moderator": "John",
}
for node in jsonpath.find("$.users[?@.score > 85]", data):
print(node.value)
# {'name': 'Sue', 'score': 100}
# {'name': 'John', 'score': 86, 'admin': True}
Or, reading JSON data from a file:
import json
import jsonpath_rfc9535 as jsonpath
with open("/path/to/some.json", encoding="utf-8") as fd:
data = json.load(fd)
nodes = jsonpath.find("$.some.query", data)
values = nodes.values()
# ...
You could read data from a YAML formatted file too. If you have PyYaml installed:
import jsonpath_rfc9535 as jsonpath
import yaml
with open("some.yaml") as fd:
data = yaml.safe_load(fd)
products = jsonpath.find("$..products.*", data).values()
# ...
- Change log: https://github.com/jg-rp/python-jsonpath-rfc9535/blob/main/CHANGELOG.md
- PyPi: https://pypi.org/project/jsonpath-rfc9535
- Source code: https://github.com/jg-rp/python-jsonpath-rfc9535
- Issue tracker: https://github.com/jg-rp/python-jsonpath-rfc9535/issues
- Python JSONPath - Another Python package implementing JSONPath, but with additional features and customization options.
- JSON P3 - RFC 9535 implemented in TypeScript.
find(query: str, value: JSONValue) -> JSONPathNodeList
Apply JSONPath expression query to value. value should arbitrary, possible nested, Python dictionaries, lists, strings, integers, floats, Booleans or None
, as you would get from json.load()
.
A list of JSONPathNode
instances is returned, one node for each value matched by query. The returned list will be empty if there were no matches.
Each JSONPathNode
has:
- a
value
property, which is the JSON-like value associated with the node. - a
location
property, which is a tuple of property names and array/list indexes that were required to reach the node's value in the target JSON document. - a
path()
method, which returns the normalized path to the node in the target JSON document.
import jsonpath_rfc9535 as jsonpath
value = {
"users": [
{"name": "Sue", "score": 100},
{"name": "John", "score": 86, "admin": True},
{"name": "Sally", "score": 84, "admin": False},
{"name": "Jane", "score": 55},
],
"moderator": "John",
}
for node in jsonpath.find("$.users[?@.score > 85]", value):
print(f"{node.value} at '{node.path()}'")
# {'name': 'Sue', 'score': 100} at '$['users'][0]'
# {'name': 'John', 'score': 86, 'admin': True} at '$['users'][1]'
JSONPathNodeList
is a subclass of list
with some helper methods.
values()
returns a list of values, one for each node.items()
returns a list of(normalized path, value)
tuples.
find_one(query: str, value: JSONValue) -> Optional[JSONPathNode]
find_one()
accepts the same arguments as find()
, but returns the first available JSONPathNode
, or None
if there were no matches.
find_one()
is equivalent to:
def find_one(query, value):
try:
return next(iter(jsonpath.finditer(query, value)))
except StopIteration:
return None
finditer(query: str, value: JSONValue) -> Iterable[JSONPathNode]
finditer()
accepts the same arguments as find()
, but returns an iterator over JSONPathNode
instances rather than a list. This could be useful if you're expecting a large number of results that you don't want to load into memory all at once.
compile(query: str) -> JSONPathQuery
find(query, value)
is a convenience function for JSONPathEnvironment().compile(query).apply(value)
. Use compile(query)
to obtain a JSONPathQuery
instance which can be applied to difference JSON-like values repeatedly.
import jsonpath_rfc9535 as jsonpath
value = {
"users": [
{"name": "Sue", "score": 100},
{"name": "John", "score": 86, "admin": True},
{"name": "Sally", "score": 84, "admin": False},
{"name": "Jane", "score": 55},
],
"moderator": "John",
}
query = jsonpath.compile("$.users[?@.score > 85]")
for node in query.apply(value):
print(f"{node.value} at '{node.path()}'")
# {'name': 'Sue', 'score': 100} at '$['users'][0]'
# {'name': 'John', 'score': 86, 'admin': True} at '$['users'][1]'
A JSONPathQuery
has a finditer(value)
method too, and find(value)
is an alias for apply(value)
.
python-jsonpath-rfc9535
is distributed under the terms of the MIT license.