Skip to main content

jsonpath-python

CI codecov PyPI version Python versions License

A lightweight and powerful JSONPath implementation for Python.

Why jsonpath-python?

There are already several JSONPath libraries in Python, so why choose this one?

  1. Lightweight & Zero Dependency: Unlike jsonpath-ng which relies on complex AST parsing frameworks like ply, jsonpath-python is implemented with pure Python string parsing. It has zero third-party dependencies, making it incredibly easy to integrate into any environment.
  2. Simple & Pythonic: The implementation is straightforward and linear. If you encounter a bug or need to extend it, the code is easy to read and modify. You can even copy the core file directly into your project as a utility.
  3. Powerful Features: It supports advanced features like sorting, filtering, and updating JSON data. If you require strict adherence to the JSONPath standard (RFC 9535), other libraries might be more suitable, but for practical data manipulation, this library offers more power.

Features

  • Light. (No need to install third-party dependencies.)
  • Support filter operator, including multi-selection, inverse-selection filtering.
  • Support sorter operator, including sorting by multiple fields, ascending and descending order.
  • Support updating JSON data using JSONPath expressions.
  • Support basic semantics of JSONPath.
  • Support output modes: VALUE, PATH.
  • Support regex filter (=~).

Installation

pip install jsonpath-python

# import
>>> from jsonpath import JSONPath

JSONPath Syntax

The JSONPath syntax in this project borrows from JSONPath - XPath for JSON and is modified and extended on it.

Operators

Operator Description
$ the root object/element
@ the current object/element
. or [] child operator
.. recursive descent
* wildcard
'' (Experimental) wrap field with special character: dots(.) and space ( ).
start:end:step array slice operator (It's same as the slice in python)
?() applies a filter expression
/() applies a sorter expression
() applies a field-extractor expression
=~ regex match operator (used in filter expressions)
in membership test operator (used in filter expressions)

Examples

Before running the following example, please import this module and the example data:

>>> from jsonpath import JSONPath

# For the data used in the following example, please refer to the Appendix part.

Select Fields

Select a field:

>>> JSONPath("$.book").parse(data)
[[{'category': 'reference', 'author': 'Nigel Rees', 'title': 'Sayings of the Century', 'price': 8.95, 'brand': {'version': 'v1.0.0'}}, {'category': 'fiction', 'author': 'Evelyn Waugh', 'title': 'Sword of Honour', 'price': 12.99, 'brand': {'version': 'v0.0.1'}}, {'category': 'fiction', 'author': 'Herman Melville', 'title': 'Moby Dick', 'isbn': '0-553-21311-3', 'price': 8.99, 'brand': {'version': 'v1.0.2'}}, {'category': 'fiction', 'author': 'J. R. R. Tolkien', 'title': 'The Lord of the Rings', 'isbn': '0-395-19395-8', 'price': 22.99, 'brand': {'version': 'v1.0.3'}}]]
>>> JSONPath("$[book]").parse(data)
[[{'category': 'reference', 'author': 'Nigel Rees', 'title': 'Sayings of the Century', 'price': 8.95, 'brand': {'version': 'v1.0.0'}}, {'category': 'fiction', 'author': 'Evelyn Waugh', 'title': 'Sword of Honour', 'price': 12.99, 'brand': {'version': 'v0.0.1'}}, {'category': 'fiction', 'author': 'Herman Melville', 'title': 'Moby Dick', 'isbn': '0-553-21311-3', 'price': 8.99, 'brand': {'version': 'v1.0.2'}}, {'category': 'fiction', 'author': 'J. R. R. Tolkien', 'title': 'The Lord of the Rings', 'isbn': '0-395-19395-8', 'price': 22.99, 'brand': {'version': 'v1.0.3'}}]]

(Experimental) Select a field with special character: dots(.) and space ( ).

>>> JSONPath("$.'a.b c'").parse(data)
['a.b c']
>>> JSONPath("$['a.b c']").parse(data)
['a.b c']

Select multiple fields:

>>> JSONPath("$[bicycle,scores]").parse(data)
[{'color': 'red', 'price': 19.95}, {'math': {'score': 100, 'avg': 60}, 'english': {'score': 95, 'avg': 80}, 'physic': {'score': 90, 'avg': 70}, 'chemistry': {'score': 85, 'avg': 80}, 'chinese': {'score': 60, 'avg': 75}}]

Select all fields using wildcard *:

>>> JSONPath("$.*").parse(data)
['a.b c', [{'category': 'reference', 'author': 'Nigel Rees', 'title': 'Sayings of the Century', 'price': 8.95, 'brand': {'version': 'v1.0.0'}}, {'category': 'fiction', 'author': 'Evelyn Waugh', 'title': 'Sword of Honour', 'price': 12.99, 'brand': {'version': 'v0.0.1'}}, {'category': 'fiction', 'author': 'Herman Melville', 'title': 'Moby Dick', 'isbn': '0-553-21311-3', 'price': 8.99, 'brand': {'version': 'v1.0.2'}}, {'category': 'fiction', 'author': 'J. R. R. Tolkien', 'title': 'The Lord of the Rings', 'isbn': '0-395-19395-8', 'price': 22.99, 'brand': {'version': 'v1.0.3'}}], {'color': 'red', 'price': 19.95}, {'math': {'score': 100, 'avg': 60}, 'english': {'score': 95, 'avg': 80}, 'physic': {'score': 90, 'avg': 70}, 'chemistry': {'score': 85, 'avg': 80}, 'chinese': {'score': 60, 'avg': 75}}]

Recursive Descent

>>> JSONPath("$..price").parse(data)
[8.95, 12.99, 8.99, 22.99, 19.95]

Slice

Support python-like slice.

>>> JSONPath("$.book[1:3]").parse(data)
[{'category': 'fiction', 'author': 'Evelyn Waugh', 'title': 'Sword of Honour', 'price': 12.99, 'brand': {'version': 'v0.0.1'}}, {'category': 'fiction', 'author': 'Herman Melville', 'title': 'Moby Dick', 'isbn': '0-553-21311-3', 'price': 8.99, 'brand': {'version': 'v1.0.2'}}]
>>> JSONPath("$.book[1:-1]").parse(data)
[{'category': 'fiction', 'author': 'Evelyn Waugh', 'title': 'Sword of Honour', 'price': 12.99, 'brand': {'version': 'v0.0.1'}}, {'category': 'fiction', 'author': 'Herman Melville', 'title': 'Moby Dick', 'isbn': '0-553-21311-3', 'price': 8.99, 'brand': {'version': 'v1.0.2'}}]
>>> JSONPath("$.book[0:-1:2]").parse(data)
[{'category': 'reference', 'author': 'Nigel Rees', 'title': 'Sayings of the Century', 'price': 8.95, 'brand': {'version': 'v1.0.0'}}, {'category': 'fiction', 'author': 'Herman Melville', 'title': 'Moby Dick', 'isbn': '0-553-21311-3', 'price': 8.99, 'brand': {'version': 'v1.0.2'}}]
>>> JSONPath("$.book[-1:1]").parse(data)
[]
>>> JSONPath("$.book[-1:-11:3]").parse(data)
[]
>>> JSONPath("$.book[:]").parse(data)
[{'category': 'reference', 'author': 'Nigel Rees', 'title': 'Sayings of the Century', 'price': 8.95, 'brand': {'version': 'v1.0.0'}}, {'category': 'fiction', 'author': 'Evelyn Waugh', 'title': 'Sword of Honour', 'price': 12.99, 'brand': {'version': 'v0.0.1'}}, {'category': 'fiction', 'author': 'Herman Melville', 'title': 'Moby Dick', 'isbn': '0-553-21311-3', 'price': 8.99, 'brand': {'version': 'v1.0.2'}}, {'category': 'fiction', 'author': 'J. R. R. Tolkien', 'title': 'The Lord of the Rings', 'isbn': '0-395-19395-8', 'price': 22.99, 'brand': {'version': 'v1.0.3'}}]
>>> JSONPath("$.book[::-1]").parse(data)
[{'category': 'fiction', 'author': 'J. R. R. Tolkien', 'title': 'The Lord of the Rings', 'isbn': '0-395-19395-8', 'price': 22.99, 'brand': {'version': 'v1.0.3'}}, {'category': 'fiction', 'author': 'Herman Melville', 'title': 'Moby Dick', 'isbn': '0-553-21311-3', 'price': 8.99, 'brand': {'version': 'v1.0.2'}}, {'category': 'fiction', 'author': 'Evelyn Waugh', 'title': 'Sword of Honour', 'price': 12.99, 'brand': {'version': 'v0.0.1'}}, {'category': 'reference', 'author': 'Nigel Rees', 'title': 'Sayings of the Century', 'price': 8.95, 'brand': {'version': 'v1.0.0'}}]

Filter Expression

Support all python comparison operators (==, !=, <, >, >=, <=), python membership operators (in, not in), python logical operators (and, or, not).

>>> JSONPath("$.book[?(@.price>8 and @.price<9)].price").parse(data)
[8.95, 8.99]
>>> JSONPath('$.book[?(@.category=="reference")].category').parse(data)
['reference']
>>> JSONPath('$.book[?(@.category!="reference" and @.price<9)].title').parse(data)
['Moby Dick']
>>> JSONPath('$.book[?(@.author=="Herman Melville" or @.author=="Evelyn Waugh")].author').parse(data)
['Evelyn Waugh', 'Herman Melville']
>>> JSONPath('$.book[?(@.title =~ /.*Century/)]').parse(data)
[{'category': 'reference', 'author': 'Nigel Rees', 'title': 'Sayings of the Century', 'price': 8.95, 'brand': {'version': 'v1.0.0'}}]

The in operator can be used to check membership in lists or substrings in strings:

# Check if a value exists in a list
>>> data = {"items": [{"tags": ["fruit", "red"]}, {"tags": ["vegetable"]}]}
>>> JSONPath("$.items[?('fruit' in @.tags)]").parse(data)
[{'tags': ['fruit', 'red']}]

# Check if a substring exists in a string
>>> data = {"items": [{"name": "apple"}, {"name": "banana"}]}
>>> JSONPath("$.items[?('app' in @.name)].name").parse(data)
['apple']

Note: You must use double quote("") instead of single quote('') to wrap the compared string, because single quote('') has another usage in this JSONPath syntax.

Sorter Expression

Support sorting by multiple fields (using operator ,) and reverse sort (using operator ~).

>>> JSONPath("$.book[/(price)].price").parse(data)
[8.95, 8.99, 12.99, 22.99]
>>> JSONPath("$.book[/(~price)].price").parse(data)
[22.99, 12.99, 8.99, 8.95]
>>> JSONPath("$.book[/(category,price)].price").parse(data)
[8.99, 12.99, 22.99, 8.95]
>>> JSONPath("$.book[/(brand.version)].brand.version").parse(data)
['v0.0.1', 'v1.0.0', 'v1.0.2', 'v1.0.3']
>>> JSONPath("$.scores[/(score)].score").parse(data)
[60, 85, 90, 95, 100]

Field-Extractor Expression

Using (field1,field2,…,filedn) after a dict object to extract its fields.

>>> JSONPath("$.scores[/(score)].(score)").parse(data)
[{'score': 60}, {'score': 85}, {'score': 90}, {'score': 95}, {'score': 100}]
>>> JSONPath("$.book[/(category,price)].(title,price)").parse(data)
[{'title': 'Moby Dick', 'price': 8.99}, {'title': 'Sword of Honour', 'price': 12.99}, {'title': 'The Lord of the Rings', 'price': 22.99}, {'title': 'Sayings of the Century', 'price': 8.95}]

Update Data

Update values in the JSON object using the update method.

# Update with a static value
>>> JSONPath("$.book[*].price").update(data, 100)
# Result: All book prices are set to 100

# Update with a function (e.g., apply a discount)
>>> JSONPath("$.book[*].price").update(data, lambda x: x * 0.9)
# Result: All book prices are multiplied by 0.9

API Reference

Functions

  • search(expr, data): Search JSON data using a JSONPath expression. This function uses LRU caching internally for better performance when the same expression is used multiple times.
>>> from jsonpath import search
>>> search("$..price", data)
[8.95, 12.99, 8.99, 22.99, 19.95]
  • compile(expr): Pre-compile a JSONPath expression for reuse. Equivalent to JSONPath(expr).
>>> from jsonpath import compile
>>> jp = compile("$.book[*].title")
>>> jp.parse(data)
['Sayings of the Century', 'Sword of Honour', 'Moby Dick', 'The Lord of the Rings']

Exceptions

  • ExprSyntaxError: Raised when a JSONPath expression has invalid syntax (e.g., using sorter on non-collection types).
  • JSONPathTypeError: Raised when type-related errors occur (e.g., comparing incompatible types during sorting).

Appendix: Example JSON data:

data = {
    "a.b c": "a.b c",
    "book": [
        {
            "category": "reference",
            "author": "Nigel Rees",
            "title": "Sayings of the Century",
            "price": 8.95,
            "brand": {
                "version": "v1.0.0"
            }
        },
        {
            "category": "fiction",
            "author": "Evelyn Waugh",
            "title": "Sword of Honour",
            "price": 12.99,
            "brand": {
                "version": "v0.0.1"
            }
        },
        {
            "category": "fiction",
            "author": "Herman Melville",
            "title": "Moby Dick",
            "isbn": "0-553-21311-3",
            "price": 8.99,
            "brand": {
                "version": "v1.0.2"
            }
        },
        {
            "category": "fiction",
            "author": "J. R. R. Tolkien",
            "title": "The Lord of the Rings",
            "isbn": "0-395-19395-8",
            "price": 22.99,
            "brand": {
                "version": "v1.0.3"
            }
        }
    ],
    "bicycle": {
        "color": "red",
        "price": 19.95
    },
    "scores": {
        "math": {
            "score": 100,
            "avg": 60
        },
        "english": {
            "score": 95,
            "avg": 80
        },
        "physic": {
            "score": 90,
            "avg": 70
        },
        "chemistry": {
            "score": 85,
            "avg": 80
        },
        "chinese": {
            "score": 60,
            "avg": 75
        }
    }
}

Release files for jsonpath-python 1.1.6

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for jsonpath-python 1.1.6
File Size Uploaded
jsonpath_python-1.1.6.tar.gz 88.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for jsonpath-python 1.1.6
File Interpreter ABI Platform
jsonpath_python-1.1.6-py3-none-any.whl Python 3 none any Details

Total release size: 102.6 kB

Release files / jsonpath_python-1.1.6.tar.gz

Download URL jsonpath_python-1.1.6.tar.gz
Size 88.2 kB
Tags Source
SHA-256 checksum
How to use checksums
dded9932b4ec41fb8726e09c83afa4e6be618f938c2db287cc2a81723c639671
BLAKE2b-256 checksum
How to use checksums
98184ca8742534a5993ff383f7602e325ce2d5d7cc93d72ac5e1cdedbea8a458
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 7, 2026.

Transparency log

Release files / jsonpath_python-1.1.6-py3-none-any.whl

Download URL jsonpath_python-1.1.6-py3-none-any.whl
Size 14.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a1c50afd8d3fbbaf47a4873bc890dcb3c15da96f5c020327977d844d8731a2d4
BLAKE2b-256 checksum
How to use checksums
558a1270a6803bd821cbfcdda387eaa13cb41a7b1f7b9bd145979b3bfb9d6cb7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 7, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.1.6 This release

2 release files

1.1.5

2 release files

1.1.4

2 release files

1.1.3

2 release files

1.1.2

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.6

2 release files

1.0.5

2 release files

1.0.4

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page