This is a Python implementation of JSON Query, a small, flexible, and expandable JSON query language.
Try it out on the online playground: https://jsonquerylang.org
Install via PyPi: https://pypi.org/project/jsonquerylang/
pip install jsonquerylang
from jsonquerylang import jsonquery
from pprint import pprint
data = {
"friends": [
{"name": "Chris", "age": 23, "city": "New York"},
{"name": "Emily", "age": 19, "city": "Atlanta"},
{"name": "Joe", "age": 32, "city": "New York"},
{"name": "Kevin", "age": 19, "city": "Atlanta"},
{"name": "Michelle", "age": 27, "city": "Los Angeles"},
{"name": "Robert", "age": 45, "city": "Manhattan"},
{"name": "Sarah", "age": 31, "city": "New York"}
]
}
# Get the array containing the friends from the object, filter the friends that live in New York,
# sort them by age, and pick just the name and age out of the objects.
output = jsonquery(data, """
.friends
| filter(.city == "New York")
| sort(.age)
| pick(.name, .age)
""")
pprint(output)
# [{'age': 23, 'name': 'Chris'},
# {'age': 31, 'name': 'Sarah'},
# {'age': 32, 'name': 'Joe'}]
# The same query can be written using the JSON format instead of the text format.
# Note that the functions `parse` and `stringify` can be used
# to convert from text format to JSON format and vice versa.
pprint(jsonquery(data, [
"pipe",
["get", "friends"],
["filter", ["eq", ["get", "city"], "New York"]],
["sort", ["get", "age"]],
["pick", ["get", "name"], ["get", "age"]]
]))
# [{'age': 23, 'name': 'Chris'},
# {'age': 31, 'name': 'Sarah'},
# {'age': 32, 'name': 'Joe'}]The JSON Query syntax is described on the following page: https://github.com/jsonquerylang/jsonquery?tab=readme-ov-file#syntax.
Compile and evaluate a JSON query.
Syntax:
jsonquery(data, query [, options])
Where:
datais a JSON object or arrayqueryis a JSON query or string containing a text queryoptionsis an optional object which can have the following options:functionsan object with custom functions
Example:
from pprint import pprint
from jsonquerylang import jsonquery
input = [
{"name": "Chris", "age": 23, "scores": [7.2, 5, 8.0]},
{"name": "Joe", "age": 32, "scores": [6.1, 8.1]},
{"name": "Emily", "age": 19},
]
query = ["sort", ["get", "age"], "desc"]
output = jsonquery(input, query)
pprint(output)
# [{'age': 32, 'name': 'Joe', 'scores': [6.1, 8.1]},
# {'age': 23, 'name': 'Chris', 'scores': [7.2, 5, 8.0]},
# {'age': 19, 'name': 'Emily'}]Compile a JSON Query. Returns a function which can execute the query repeatedly for different inputs.
Syntax:
compile(query [, options])
Where:
queryis a JSON query or string containing a text queryoptionsis an optional object which can have the following options:functionsan object with custom functions
The function returns a lambda function which can be executed by passing JSON data as first argument.
Example:
from pprint import pprint
from jsonquerylang import compile
input = [
{"name": "Chris", "age": 23, "scores": [7.2, 5, 8.0]},
{"name": "Joe", "age": 32, "scores": [6.1, 8.1]},
{"name": "Emily", "age": 19},
]
query = ["sort", ["get", "age"], "desc"]
queryMe = compile(query)
output = queryMe(input)
pprint(output)
# [{'age': 32, 'name': 'Joe', 'scores': [6.1, 8.1]},
# {'age': 23, 'name': 'Chris', 'scores': [7.2, 5, 8.0]},
# {'age': 19, 'name': 'Emily'}]Parse a string containing a JSON Query into JSON.
Syntax:
parse(textQuery, [, options])
Where:
textQuery: A query in text formatoptions: An optional object which can have the following properties:functionsan object with custom functionsoperatorsan object with the names of custom operators both as key and value
Example:
from pprint import pprint
from jsonquerylang import parse
text_query = '.friends | filter(.city == "new York") | sort(.age) | pick(.name, .age)'
json_query = parse(text_query)
pprint(json_query)
# ['pipe',
# ['get', 'friends'],
# ['filter', ['eq', ['get', 'city'], 'New York']],
# ['sort', ['get', 'age']],
# ['pick', ['get', 'name'], ['get', 'age']]]Stringify a JSON Query into a readable, human friendly text format.
Syntax:
stringify(query [, options])
Where:
queryis a JSON Queryoptionsis an optional object that can have the following properties:operatorsan object with the names of custom operators both as key and valueindentationa string containing the desired indentation, defaults to two spaces:" "max_line_lengtha number with the maximum line length, used for wrapping contents. Default value:40.
Example:
from jsonquerylang import stringify
jsonQuery = [
"pipe",
["get", "friends"],
["filter", ["eq", ["get", "city"], "New York"]],
["sort", ["get", "age"]],
["pick", ["get", "name"], ["get", "age"]],
]
textQuery = stringify(jsonQuery)
print(textQuery)
# '.friends | filter(.city == "new York") | sort(.age) | pick(.name, .age)'Released under the ISC license.
