Claude Code for jmespath: JSON Query Language in Python — Claude Skills 360 Blog
Blog / AI / Claude Code for jmespath: JSON Query Language in Python
AI

Claude Code for jmespath: JSON Query Language in Python

Published: April 20, 2028
Read time: 5 min read
By: Claude Skills 360

jmespath implements the JMESPath query language for JSON — extract and transform nested data with a single expression. pip install jmespath. Basic: import jmespath; jmespath.search("a.b.c", {"a": {"b": {"c": 42}}}) → 42. Array: jmespath.search("people[0].name", data). Wildcard: jmespath.search("people[*].name", data) → list. Filter: jmespath.search("people[?age > \30`].name”, data). Multi-select list: jmespath.search(“people[].[name, age]”, data). Multi-select hash: jmespath.search(“people[].{n: name, a: age}”, data). Pipe: jmespath.search(“locations[].state | sort(@)”, data). Functions: length(people), keys(obj), values(obj), sort_by(people, &age), min_by(people, &age), max_by(people, &age), sum(scores), avg(scores), contains(arr, val), starts_with(str, prefix), ends_with, reverse(arr), to_string(n), to_number(s), type(val). Flatten: data[].items[]. Literal: `` jmespath.search("hello", {}) `` → ”hello”. Compile: expr = jmespath.compile(“people[].name”); expr.search(data). Or/And: a || b, a && b. Not: !bool. Custom: from jmespath import functions; class CF(functions.Functions): @functions.signature(…) def _func_myname(self, val): …`. Claude Code generates jmespath extractors, AWS response parsers, and JSON query utilities.

CLAUDE.md for jmespath

## jmespath Stack
- Version: jmespath >= 1.0 | pip install jmespath
- Search: jmespath.search("expr", data) → extracted value or None
- Compile: jmespath.compile("expr").search(data) — reuse parsed expr
- Wildcard: people[*].name — extract field from all items
- Filter: people[?age > `18`].name — filter by condition
- Functions: sort_by(@, &field) | min_by | max_by | keys | values | length
- Reshape: [*].{id: id, label: name} — multi-select hash remapping

jmespath JSON Query Pipeline

# app/jmespath_utils.py — jmespath search, compile, reshape, filter, and AWS helpers
from __future__ import annotations

from typing import Any

import jmespath
from jmespath import functions as jf


# ─────────────────────────────────────────────────────────────────────────────
# 1. Core helpers
# ─────────────────────────────────────────────────────────────────────────────

def search(expr: str, data: Any, default: Any = None) -> Any:
    """
    Execute a JMESPath expression against data.
    Returns default when the result is None.
    """
    result = jmespath.search(expr, data)
    return result if result is not None else default


def compile_expr(expr: str) -> jmespath.parser.ParsedResult:
    """
    Pre-compile a JMESPath expression for repeated use.
    Avoids re-parsing the same expression on every call.
    """
    return jmespath.compile(expr)


def multi_search(data: Any, **named_exprs: str) -> dict[str, Any]:
    """
    Run multiple JMESPath expressions against the same data object.
    Returns {name: result} for each expression.

    Example:
        multi_search(response,
            total="meta.total",
            items="data[*].id",
            first_name="data[0].name",
        )
    """
    return {name: search(expr, data) for name, expr in named_exprs.items()}


def pluck(data: Any, path: str, default: Any = None) -> Any:
    """Alias for search with a default — one-line field extraction."""
    return search(path, data, default=default)


def reshape(items: list[dict], mapping: dict[str, str]) -> list[dict]:
    """
    Reshape a list of dicts by extracting fields via JMESPath.
    mapping: {new_key: jmespath_expr_applied_to_each_item}

    Example:
        reshape(users, {"id": "user_id", "label": "profile.display_name"})
    """
    return [
        {new_key: search(expr, item) for new_key, expr in mapping.items()}
        for item in items
    ]


# ─────────────────────────────────────────────────────────────────────────────
# 2. List / collection operations
# ─────────────────────────────────────────────────────────────────────────────

def extract_field(data: Any, items_path: str, field_path: str) -> list[Any]:
    """
    Extract a field from every item in a nested list.

    Example:
        extract_field(response, "data.users", "email")
        → same as: jmespath.search("data.users[*].email", response)
    """
    return search(f"{items_path}[*].{field_path}", data, default=[])


def filter_items(data: Any, items_path: str, condition: str) -> list[dict]:
    """
    Filter a nested list by a JMESPath condition expression.

    Example:
        filter_items(data, "users", "role == `admin`")
        → jmespath.search("users[? role == `admin`]", data)
    """
    return search(f"{items_path}[?{condition}]", data, default=[])


def sort_items(data: Any, items_path: str, sort_key: str, reverse: bool = False) -> list[dict]:
    """
    Sort a nested list by sort_key using sort_by().

    Example:
        sort_items(data, "products", "price")
        sort_items(data, "products", "price", reverse=True)
    """
    expr = f"sort_by({items_path}, &{sort_key})"
    result = search(expr, data, default=[])
    if reverse:
        return list(reversed(result))
    return result


def top_n(data: Any, items_path: str, sort_key: str, n: int) -> list[dict]:
    """Return the top n items sorted by sort_key descending."""
    sorted_items = sort_items(data, items_path, sort_key, reverse=True)
    return sorted_items[:n]


def aggregate(data: Any, items_path: str, field: str) -> dict[str, Any]:
    """
    Compute min, max, sum, avg, count for a numeric field in a nested list.

    Example:
        aggregate(data, "orders", "total")
        → {"min": ..., "max": ..., "sum": ..., "avg": ..., "count": ...}
    """
    arr_expr = f"{items_path}[*].{field}"
    values = search(arr_expr, data, default=[])
    if not values:
        return {"min": None, "max": None, "sum": 0, "avg": None, "count": 0}
    return {
        "min":   min(values),
        "max":   max(values),
        "sum":   sum(values),
        "avg":   sum(values) / len(values),
        "count": len(values),
    }


# ─────────────────────────────────────────────────────────────────────────────
# 3. AWS / paginated response helpers
# ─────────────────────────────────────────────────────────────────────────────

def extract_aws_resources(response: dict, resource_key: str) -> list[dict]:
    """
    Extract a resource list from a standard AWS SDK response.
    Handles both direct lists and paginated NextToken responses.

    Example:
        instances = extract_aws_resources(ec2.describe_instances(), "Reservations[*].Instances[]")
    """
    return search(resource_key, response, default=[])


def aws_tags_to_dict(tags: list[dict]) -> dict[str, str]:
    """
    Convert AWS tags [{"Key": "Name", "Value": "prod"}] to {"Name": "prod"}.
    """
    if not tags:
        return {}
    return {t["Key"]: t["Value"] for t in tags if "Key" in t and "Value" in t}


def filter_aws_by_tag(resources: list[dict], tag_key: str, tag_value: str) -> list[dict]:
    """Filter AWS resources by a tag Key+Value pair."""
    return [
        r for r in resources
        if tag_value in [
            t.get("Value", "")
            for t in r.get("Tags", [])
            if t.get("Key") == tag_key
        ]
    ]


# ─────────────────────────────────────────────────────────────────────────────
# 4. API response normalizer
# ─────────────────────────────────────────────────────────────────────────────

class ResponseExtractor:
    """
    Reusable extractor for a fixed API response schema.
    Compiles expressions once for efficient repeated use.

    Usage:
        extractor = ResponseExtractor({
            "items":       "data.results[*]",
            "total":       "meta.total",
            "page":        "meta.page",
            "item_ids":    "data.results[*].id",
            "first_name":  "data.results[0].name",
        })
        info = extractor.extract(api_response)
    """

    def __init__(self, schema: dict[str, str]):
        self._compiled = {
            name: compile_expr(expr)
            for name, expr in schema.items()
        }

    def extract(self, data: Any) -> dict[str, Any]:
        """Run all compiled expressions and return {name: result}."""
        return {name: expr.search(data) for name, expr in self._compiled.items()}

    def get(self, name: str, data: Any) -> Any:
        """Run a single named expression."""
        if name not in self._compiled:
            raise KeyError(f"Unknown expression name: {name!r}")
        return self._compiled[name].search(data)


# ─────────────────────────────────────────────────────────────────────────────
# Demo
# ─────────────────────────────────────────────────────────────────────────────

if __name__ == "__main__":
    data = {
        "meta": {"total": 100, "page": 1, "per_page": 10},
        "data": {
            "users": [
                {"id": 1, "name": "Alice", "age": 30, "role": "admin",     "score": 95},
                {"id": 2, "name": "Bob",   "age": 25, "role": "user",      "score": 72},
                {"id": 3, "name": "Carol", "age": 28, "role": "moderator", "score": 88},
                {"id": 4, "name": "Dave",  "age": 22, "role": "user",      "score": 65},
                {"id": 5, "name": "Eve",   "age": 35, "role": "admin",     "score": 91},
            ]
        }
    }

    print("=== Basic search ===")
    print("total:", search("meta.total", data))
    print("first user:", search("data.users[0].name", data))
    print("all names:", search("data.users[*].name", data))

    print("\n=== Filter ===")
    admins = filter_items(data, "data.users", "role == `admin`")
    print("Admins:", [u["name"] for u in admins])

    seniors = filter_items(data, "data.users", "age > `27`")
    print("Age > 27:", [u["name"] for u in seniors])

    print("\n=== Sort + Top N ===")
    by_score = sort_items(data, "data.users", "score", reverse=True)
    print("By score desc:", [(u["name"], u["score"]) for u in by_score])
    top2 = top_n(data, "data.users", "score", 2)
    print("Top 2:", [(u["name"], u["score"]) for u in top2])

    print("\n=== Aggregate ===")
    stats = aggregate(data, "data.users", "score")
    print("Score stats:", {k: round(v, 1) if isinstance(v, float) else v for k, v in stats.items()})

    print("\n=== Multi-select hash (reshape) ===")
    reshaped = reshape(data["data"]["users"], {"user_id": "id", "label": "name", "score": "score"})
    for r in reshaped:
        print(" ", r)

    print("\n=== multi_search ===")
    info = multi_search(
        data,
        total="meta.total",
        page="meta.page",
        admin_names="data.users[?role == `admin`].name",
        min_age="min(data.users[*].age)",
    )
    print(info)

    print("\n=== ResponseExtractor ===")
    extractor = ResponseExtractor({
        "user_ids":   "data.users[*].id",
        "top_scorer": "max_by(data.users, &score).name",
        "total":      "meta.total",
    })
    result = extractor.extract(data)
    print(result)

    print("\n=== Compile (reuse) ===")
    age_expr = compile_expr("data.users[*].age")
    ages = age_expr.search(data)
    print("ages:", ages)
    print("avg age:", sum(ages)/len(ages))

For the glom alternative — glom is Python-native and works on any Python object (dataclasses, custom classes, etc.) with assignment and method chaining; jmespath implements the JMESPath RFC standard so expressions are portable across languages (Python, JavaScript, Go, Java) — use jmespath when the expression must be stored in config, shared across services, or applied to AWS API responses. For the jsonpath-ng alternative — jsonpath-ng implements RFC JSONPath (dollar-sign $..key syntax) and has recursive descent (..) expressions; jmespath uses a different syntax with filter projections and built-in aggregate functions like sort_by, min_by, max_by that JSONPath lacks — jmespath is the de facto standard for AWS CLI and SDKs. The Claude Skills 360 bundle includes jmespath skill sets covering search()/compile()/multi_search() core API, pluck()/reshape()/extract_field() helpers, filter_items()/sort_items()/top_n(), aggregate() min/max/sum/avg, extract_aws_resources()/aws_tags_to_dict()/filter_aws_by_tag() AWS helpers, and ResponseExtractor with pre-compiled expressions. Start with the free tier to try JMESPath query code generation.

Keep Reading

AI

Claude Code for email.contentmanager: Python Email Content Accessors

Read and write EmailMessage body content with Python's email.contentmanager module and Claude Code — email contentmanager ContentManager for the class that maps content types to get and set handler functions allowing EmailMessage to support get_content and set_content with type-specific behaviour, email contentmanager raw_data_manager for the ContentManager instance that handles raw bytes and str payloads without any conversion, email contentmanager content_manager for the standard ContentManager instance used by email.policy.default that intelligently handles text plain text html multipart and binary content types, email contentmanager get_content_text for the handler that returns the decoded text payload of a text-star message part as a str, email contentmanager get_content_binary for the handler that returns the raw decoded bytes payload of a non-text message part, email contentmanager get_data_manager for the get-handler lookup used by EmailMessage get_content to find the right reader function for the content type, email contentmanager set_content text for the handler that creates and sets a text part correctly choosing charset and transfer encoding, email contentmanager set_content bytes for the handler that creates and sets a binary part with base64 encoding and optional filename Content-Disposition, email contentmanager EmailMessage get_content for the method that reads the message body using the registered content manager handlers, email contentmanager EmailMessage set_content for the method that sets the message body and MIME headers in one call, email contentmanager EmailMessage make_alternative make_mixed make_related for the methods that convert a simple message into a multipart container, email contentmanager EmailMessage add_attachment for the method that attaches a file or bytes to a multipart message, and email contentmanager integration with email.message and email.policy and email.mime and io for building high-level email readers attachment extractors text body accessors HTML readers and policy-aware MIME construction pipelines.

5 min read Feb 12, 2029
AI

Claude Code for email.charset: Python Email Charset Encoding

Control header and body encoding for international email with Python's email.charset module and Claude Code — email charset Charset for the class that wraps a character set name with the encoding rules for header encoding and body encoding describing how to encode text for that charset in email messages, email charset Charset header_encoding for the attribute specifying whether headers using this charset should use QP quoted-printable encoding BASE64 encoding or no encoding, email charset Charset body_encoding for the attribute specifying the Content-Transfer-Encoding to use for message bodies in this charset such as QP or BASE64, email charset Charset output_codec for the attribute giving the Python codec name used to encode the string to bytes for the wire format, email charset Charset input_codec for the attribute giving the Python codec name used to decode incoming bytes to str, email charset Charset get_output_charset for returning the output charset name, email charset Charset header_encode for encoding a header string using the charset's header_encoding method, email charset Charset body_encode for encoding body content using the charset's body_encoding, email charset Charset convert for converting a string from the input_codec to the output_codec, email charset add_charset for registering a new charset with custom encoding rules in the global charset registry, email charset add_alias for adding an alias name that maps to an existing registered charset, email charset add_codec for registering a codec name mapping for use by the charset machinery, and email charset integration with email.message and email.mime and email.policy and email.encoders for building international email senders non-ASCII header encoders Content-Transfer-Encoding selectors charset-aware message constructors and MIME encoding pipelines.

5 min read Feb 11, 2029
AI

Claude Code for email.utils: Python Email Address and Header Utilities

Parse and format RFC 2822 email addresses and dates with Python's email.utils module and Claude Code — email utils parseaddr for splitting a display-name plus angle-bracket address string into a realname and email address tuple, email utils formataddr for combining a realname and address string into a properly quoted RFC 2822 address with angle brackets, email utils getaddresses for parsing a list of raw address header strings each potentially containing multiple comma-separated addresses into a list of realname address tuples, email utils parsedate for parsing an RFC 2822 date string into a nine-tuple compatible with time.mktime, email utils parsedate_tz for parsing an RFC 2822 date string into a ten-tuple that includes the UTC offset timezone in seconds, email utils parsedate_to_datetime for parsing an RFC 2822 date string into an aware datetime object with timezone, email utils formatdate for formatting a POSIX timestamp or the current time as an RFC 2822 date string with optional usegmt and localtime flags, email utils format_datetime for formatting a datetime object as an RFC 2822 date string, email utils make_msgid for generating a globally unique Message-ID string with optional idstring and domain components, email utils decode_rfc2231 for decoding an RFC 2231 encoded parameter value into a tuple of charset language and value, email utils encode_rfc2231 for encoding a string as an RFC 2231 encoded parameter value, email utils collapse_rfc2231_value for collapsing a decoded RFC 2231 tuple to a Unicode string, and email utils integration with email.message and email.headerregistry and datetime and time for building address parsers date formatters message-id generators header extractors and RFC-compliant email construction utilities.

5 min read Feb 10, 2029

Put these ideas into practice

Claude Skills 360 gives you production-ready skills for everything in this article — and 2,350+ more. Start free or go all-in.

Back to Blog

Get 360 skills free