JMESPath
raw JSON → 1.1.0 verified Tue May 12 auth: no python install: verified quickstart: verified
JMESPath (pronounced 'james path') is a query language for JSON that allows you to declaratively extract, filter, and transform elements from JSON documents or Python dictionaries. Current stable version is 1.0.0 (1.1.0 on PyPI as of 2026). The project is mature and low-churn — it reached 1.0 in 2022 with no breaking API changes, and releases are infrequent. It is a foundational dependency of boto3/botocore and is used by the AWS CLI --query flag.
pip install jmespath Common errors
error ModuleNotFoundError: No module named 'jmespath' ↓
cause The 'jmespath' package is not installed or not accessible in the current Python environment. This often occurs if it was not installed, or installed in a different Python interpreter/virtual environment than the one being used.
fix
Run
pip install jmespath to install the library. error AttributeError: module 'jmespath' has no attribute 'search' ↓
cause This error typically occurs when a local Python file named `jmespath.py` exists in the same directory or an earlier directory in the Python path, shadowing the installed `jmespath` library.
fix
Rename the conflicting local
jmespath.py file to something else to avoid the name collision, or ensure the correct jmespath library is being imported. error jmespath.exceptions.ParseError: Expecting: ..., got: ... ↓
cause The JMESPath expression provided contains a syntax error, such as incorrect quoting, missing operators, or malformed function calls. The '...' in the error message indicates what was expected versus what was found.
fix
Review and correct the JMESPath expression syntax, paying close attention to proper quoting (e.g., single quotes for string literals, backticks for numbers/booleans in some contexts, double quotes for identifiers with special characters), correct use of operators, and valid function argument structures.
error TypeError: <function_name>() expected argument 1 to be type <expected_type> but received type <received_type> instead ↓
cause A JMESPath function was invoked with an argument of an incorrect data type, which does not match the function's expected signature. JMESPath functions have strict type requirements for their arguments.
fix
Ensure that the arguments passed to JMESPath functions are of the correct type as specified in the function's documentation. Use type conversion functions like
to_string(), to_number(), etc., within the JMESPath expression if necessary to match the expected argument types. Warnings
breaking jmespath.search() requires a parsed Python dict/list, NOT a raw JSON string. Passing a JSON string silently returns None or wrong results. ↓
fix Parse first: jmespath.search(expr, json.loads(raw_string)) or response.json().
breaking Python 2 and Python <3.7 support was dropped in 1.0.0. The PyPI package requires Python >=3.9 as of 1.1.0. ↓
fix Upgrade to Python >=3.9 and pin jmespath>=1.0.0.
gotcha Indexing into a wildcard projection (e.g. people[*].name[0]) does NOT return the first element of the projected list — it attempts to index each string, returning []. ↓
fix Use a pipe to stop the projection first: people[*].name | [0]
gotcha [] (flatten) and [*] (wildcard) are NOT equivalent. [] flattens one level of nested arrays; [*] keeps the original list structure intact. ↓
fix Use [*] to project over a list without flattening; use [] only when you explicitly need one-level flattening.
deprecated Custom function support is explicitly marked experimental by the authors; the API (signature decorator, _func_ naming) may change without a major version bump. ↓
fix Pin your jmespath version if you rely on custom functions, and audit after any upgrade.
gotcha Calling jmespath.search() with the same expression string in a hot loop re-parses the expression on every call, causing significant overhead. ↓
fix Use jmespath.compile(expr) once and call compiled_expr.search(data) in the loop.
gotcha Numeric literals in filter expressions must be wrapped in backticks, not quotes. people[?age > '18'] compares against a string; people[?age > `18`] compares against a number. ↓
fix Always use backtick-delimited literals for numbers and booleans in filter expressions: [?count > `0`].
Install compatibility verified last tested: 2026-05-12
python os / libc status wheel install import disk
3.10 alpine (musl) - - 0.04s 17.9M
3.10 slim (glibc) - - 0.02s 18M
3.11 alpine (musl) - - 0.05s 19.8M
3.11 slim (glibc) - - 0.04s 20M
3.12 alpine (musl) - - 0.05s 11.7M
3.12 slim (glibc) - - 0.06s 12M
3.13 alpine (musl) - - 0.06s 11.3M
3.13 slim (glibc) - - 0.06s 12M
3.9 alpine (musl) - - 0.03s 17.4M
3.9 slim (glibc) - - 0.03s 18M
Imports
- jmespath
import jmespath - functions.Functions
from jmespath import functions - functions.signature
from jmespath.functions import signature - Options
jmespath.Options(dict_cls=..., custom_functions=...)
Quickstart verified last tested: 2026-04-23
import jmespath
from jmespath import functions
# 1. One-shot search
data = {
"people": [
{"name": "Alice", "age": 30},
{"name": "Bob", "age": 17},
{"name": "Carol", "age": 25},
]
}
# Returns all names
names = jmespath.search("people[*].name", data)
print(names) # ['Alice', 'Bob', 'Carol']
# Filter: only adults
adults = jmespath.search("people[?age >= `18`].name", data)
print(adults) # ['Alice', 'Carol']
# 2. Compile once, search many times (avoids re-parsing)
expr = jmespath.compile("people[*].age")
print(expr.search(data)) # [30, 17, 25]
# 3. Pipe to index into a projection result (not people[*].name[0]!)
first_name = jmespath.search("people[*].name | [0]", data)
print(first_name) # 'Alice'
# 4. Custom function via Options
class MyFunctions(functions.Functions):
@functions.signature({"types": ["string"]})
def _func_upper(self, s):
return s.upper()
opts = jmespath.Options(custom_functions=MyFunctions())
result = jmespath.search("people[0].name | upper(@)", data, opts)
print(result) # 'ALICE'