JMESPath Python: JSON Query Language

JMESPath is a JSON query language. 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 Python 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!

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 with pip, and import the module 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]
>>>

JMESPath Python examples

Let’s start with some simple use-cases. We’ll fetch the first person from the array, and then get the first person’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.

Keep learning

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

Get certified with our courses

Learn Python properly through small, easy-to-digest lessons, progress tracking, quizzes to test your knowledge, and practice sessions. Each course will earn you a downloadable course certificate.

Related articles

Leave a Comment