Installation
From PyPI
pip install jmespath-extensions
From Source
# Clone the repository
git clone https://github.com/joshrotenberg/jmespath-extensions
cd jmespath-extensions/crates/jmespath-extensions-py
# Install maturin if needed
pip install maturin
# Build and install
maturin develop --release
Verify Installation
import jmespath_extensions
# Check it works
result = jmespath_extensions.search("length(@)", [1, 2, 3])
print(result) # 3
# List available functions
functions = jmespath_extensions.list_functions()
print(f"Available functions: {len(functions)}")
Requirements
- Python 3.8+
- No runtime dependencies (Rust extensions are statically linked)
Usage
Basic Searching
The primary function is search(), which evaluates a JMESPath expression against data:
import jmespath_extensions as jpx
data = {
"users": [
{"name": "alice", "age": 30, "active": True},
{"name": "bob", "age": 25, "active": False},
{"name": "carol", "age": 35, "active": True}
]
}
# Extract active users
active = jpx.search("users[?active].name", data)
print(active) # ['alice', 'carol']
# Use extended functions
result = jpx.search("users | sort_by(@, &age) | [*].name", data)
print(result) # ['bob', 'alice', 'carol']
Compiled Expressions
For repeated use, compile the expression once:
import jmespath_extensions as jpx
# Compile once
expr = jpx.compile_expr("users[?age > `30`].name")
# Use many times
for dataset in datasets:
result = expr.search(dataset)
print(result)
Exploring Functions
List All Functions
import jmespath_extensions as jpx
# All functions
all_funcs = jpx.list_functions()
print(f"Total: {len(all_funcs)} functions")
# Filter by category
string_funcs = jpx.list_functions("string")
print(f"String functions: {string_funcs}")
List Categories
categories = jpx.list_categories()
print(categories)
# ['standard', 'string', 'array', 'object', 'math', 'datetime', ...]
Get Function Details
info = jpx.describe("split")
print(info)
# {
# 'name': 'split',
# 'category': 'String',
# 'signature': 'string, string -> array',
# 'description': 'Split string by delimiter...',
# 'example': 'split(`"a,b,c"`, `","`) -> ["a", "b", "c"]'
# }
Query Libraries
Parse and use .jpx query library files:
import jmespath_extensions as jpx
# Parse a query library
content = '''
-- :name active-users
-- :desc Get active users
users[?active]
-- :name user-count
length(users)
'''
library = jpx.parse_query_library(content)
# List queries
for query in library.list():
print(f"{query.name}: {query.description}")
# Get a specific query
query = library.get("active-users")
if query:
result = jpx.search(query.expression, data)
# Get all query names
names = library.names()
Check if Content is a Query Library
# Detect format
if jpx.is_query_library(content):
library = jpx.parse_query_library(content)
else:
# Plain expression
result = jpx.search(content.strip(), data)
Extended Functions Examples
String Functions
# Split and join
jpx.search('split(`"a,b,c"`, `","`)', {}) # ['a', 'b', 'c']
jpx.search('join(`"-"`, `["a","b","c"]`)', {}) # 'a-b-c'
# Case conversion
jpx.search('upper(`"hello"`)', {}) # 'HELLO'
jpx.search('snake_case(`"helloWorld"`)', {}) # 'hello_world'
Date/Time Functions
# Current time
jpx.search('now()', {}) # 1699900000 (Unix timestamp)
jpx.search('now_iso()', {}) # '2024-01-15T10:30:00Z'
# Parse and format dates
jpx.search('parse_datetime(`"2024-01-15"`, `"%Y-%m-%d"`)', {})
Math Functions
data = {"values": [1, 2, 3, 4, 5]}
jpx.search('mean(values)', data) # 3.0
jpx.search('std_dev(values)', data) # 1.414...
jpx.search('percentile(values, `50`)', data) # 3
Fuzzy Matching
tools = [
{"name": "create_user", "description": "Create a new user"},
{"name": "delete_user", "description": "Delete an existing user"},
{"name": "list_users", "description": "List all users"}
]
# Fuzzy search
results = jpx.search(
'fuzzy_search(@, `"name,description"`, `"user create"`)',
tools
)
Error Handling
import jmespath_extensions as jpx
try:
# Invalid expression
jpx.search("invalid[", {})
except ValueError as e:
print(f"Parse error: {e}")
try:
# Runtime error
jpx.search("length(@)", "not an array")
except Exception as e:
print(f"Evaluation error: {e}")
API Reference
Functions
search
def search(expression: str, data: Any) -> Any
Evaluate a JMESPath expression against data.
Parameters:
expression: JMESPath expression stringdata: Python data (dict, list, str, int, float, bool, None)
Returns: The result of the expression evaluation
Raises: ValueError for parse errors, Exception for runtime errors
Example:
result = jpx.search("users[0].name", {"users": [{"name": "alice"}]})
# Returns: "alice"
compile_expr
def compile_expr(expression: str) -> CompiledExpression
Compile a JMESPath expression for repeated use.
Parameters:
expression: JMESPath expression string
Returns: CompiledExpression object
Raises: ValueError for parse errors
Example:
expr = jpx.compile_expr("length(@)")
result = expr.search([1, 2, 3]) # 3
list_functions
def list_functions(category: Optional[str] = None) -> List[str]
List available function names.
Parameters:
category: Optional category filter (e.g., “string”, “math”, “datetime”)
Returns: List of function names
Example:
all_funcs = jpx.list_functions()
string_funcs = jpx.list_functions("string")
list_categories
def list_categories() -> List[str]
List all function categories.
Returns: List of category names
Example:
categories = jpx.list_categories()
# ['standard', 'string', 'array', 'object', 'math', ...]
describe
def describe(name: str) -> Optional[Dict]
Get detailed information about a function.
Parameters:
name: Function name or alias
Returns: Dictionary with function info, or None if not found
Return fields:
name: Function namecategory: Category namesignature: Type signaturedescription: Description textexample: Example usage
Example:
info = jpx.describe("split")
print(info["signature"]) # "string, string -> array"
parse_query_library
def parse_query_library(content: str) -> QueryLibrary
Parse a query library from string content.
Parameters:
content: Query library content in.jpxformat
Returns: QueryLibrary object
Raises: ValueError for parse errors
Example:
library = jpx.parse_query_library('''
-- :name my-query
-- :desc A sample query
users[?active]
''')
is_query_library
def is_query_library(content: str) -> bool
Check if content appears to be a query library format.
Parameters:
content: String content to check
Returns: True if content starts with query library directives
Example:
if jpx.is_query_library(content):
library = jpx.parse_query_library(content)
Classes
CompiledExpression
A compiled JMESPath expression for efficient repeated evaluation.
Methods
search
def search(self, data: Any) -> Any
Evaluate this expression against data.
Parameters:
data: Python data to evaluate against
Returns: Evaluation result
QueryLibrary
A collection of named queries parsed from a .jpx file.
Methods
get
def get(self, name: str) -> Optional[NamedQuery]
Get a query by name.
Parameters:
name: Query name
Returns: NamedQuery or None
list
def list(self) -> List[NamedQuery]
Get all queries in the library.
Returns: List of NamedQuery objects
names
def names(self) -> List[str]
Get all query names.
Returns: List of query names
NamedQuery
A single named query from a query library.
Properties
name: str- Query namedescription: Optional[str]- Query descriptionexpression: str- JMESPath expressionline_number: int- Line number in source file
Example:
query = library.get("my-query")
if query:
print(f"{query.name}: {query.description}")
result = jpx.search(query.expression, data)