Query JSON with JMESPath in Python

JMESPath is a query language for JSON. JMESPath in Python allows you to obtain the data you need from a JSON document or dictionary easily. This library is available for Python, but also for many other programming languages, meaning that if you master the JMESPath query language, you can use it in many places.

The problem JMESPath solves

As we’ve seen on the previous page, it’s easy to get a nested value from a Python dictionary using Python’s own JSON library. For example: doc["person"]["age"] will get you the nested value for age in a document that looks like this:

{
  "persons": {
    "name": "erik",
    "age": "38"
  }
}

But what if you want to extract all the age-fields from an array of persons, in a document like the one below?

{
  "persons": [
    { "name": "erik", "age": 38 },
    { "name": "john", "age": 45 },
    { "name": "rob", "age": 14 }
  ]
}

We could write a for-loop and loop over all the persons. Easy peasy. But loops are slow and introduce complexity to your code. This is where JMESPath comes in!

JMESPath Python examples

Let’s start with some simple use-cases. We’ll first get the first person from the array, and then get the first peron’s age:

>>> jmespath.search('persons[0]', persons)
{'name': 'erik', 'age': 38}
>>> jmespath.search('persons[0].age', persons)
38

In the problem statement above, we wanted to extract all the age-fields from the array of persons in the JSON document. This JMESPath expression will get the job done:

>>> import jmespath
>>> persons = {
...   "persons": [
...     { "name": "erik", "age": 38 },
...     { "name": "john", "age": 45 },
...     { "name": "rob", "age": 14 }
...   ]
... }
>>> jmespath.search('persons[*].age', persons)
[38, 45, 14]

Suppose you want to filter the list, and only get the ages for people named ‘erik’. You can do so with a filter:

>>> jmespath.search("persons[?name=='erik'].age", persons)
[38]

Note that we’re now using double quotes, because we need to quote the name inside the filter expression.

Installing JMESPath for Python

JMESPath is not part of the Python standard library, meaning you’ll need to install it with pip or pipenv. The JMESPath package is hosted on PyPI, like most Python packages. It’s available under the unsurprising name jmespath.

For example, when using pip in a virtual environment, you can install it as follows:

$ pip3 install jmespath
$ python3
Python 3.8.2 (default, Jul 16 2020, 14:00:26)
>>> import jmespath
>>> j = { "people": [{ "name": "erik", "age": 38 }] }
>>> jmespath.search("people[*].age", j)
[38]
>>>

Futher JMESPath resources

You’re now ready to start experimenting! If you want to learn more, try these links: