codex/files-formats/jmespath_query.cat
# Requêtage JSON avec JMESPath
# JMESPath est un langage de requête pour JSON (utilisé par AWS CLI)
#
# Exécuter: catnip -m jmespath jmespath_query.cat
jmespath = import("jmespath")
# Données de test (réponse API d'exemple)
data = dict(
users=list(
dict(
id=1,
name="Alice",
email="alice@example.com",
role="admin",
active=True,
projects=list("alpha", "beta"),
),
dict(
id=2,
name="Bob",
email="bob@example.com",
role="developer",
active=True,
projects=list("beta", "gamma"),
),
dict(
id=3,
name="Charlie",
email="charlie@example.com",
role="developer",
active=False,
projects=list("alpha"),
)
),
metadata=dict(
total=3,
page=1,
per_page=10,
)
)
# Accès simple
print("⇒ Accès simple")
print(" metadata.total:", jmespath.search("metadata.total", data))
print(" metadata.page:", jmespath.search("metadata.page", data))
# Accès aux listes
print("\n⇒ Accès aux listes")
print(" Premier user:", jmespath.search("users[0].name", data))
print(" Dernier user:", jmespath.search("users[-1].name", data))
# Projection (extraire un champ de chaque élément)
print("\n⇒ Projection")
names = jmespath.search("users[*].name", data)
print(" Tous les noms:", names)
emails = jmespath.search("users[*].email", data)
print(" Tous les emails:", emails)
# Filtrage
print("\n⇒ Filtrage")
admins = jmespath.search("users[?role=='admin'].name", data)
print(" Admins:", admins)
active = jmespath.search("users[?active==`true`].name", data)
print(" Users actifs:", active)
devs = jmespath.search("users[?role=='developer']", data)
print(" Developers:", len(devs))
# Projection multiple (dict construit à la volée)
print("\n⇒ Projection multiple (sélection de champs)")
subset = jmespath.search("users[*].{nom: name, mail: email}", data)
print(" Subset:")
for u in subset {
print(" ", u)
}
print(" Exemple premier élément:")
print(" nom:", subset[0]["nom"])
print(" mail:", subset[0]["mail"])
# Flatten (aplatir les listes)
print("\n⇒ Flatten")
all_projects = jmespath.search("users[*].projects[]", data)
print(" Tous les projets (avec doublons):", all_projects)
# Fonctions
print("\n⇒ Fonctions JMESPath")
print(" Nombre d'users:", jmespath.search("length(users)", data))
print(" Premier nom (sort):", jmespath.search("sort(users[*].name)[0]", data))
print(" Dernier nom (sort):", jmespath.search("sort(users[*].name)[-1]", data))
# Conditions complexes
print("\n⇒ Conditions complexes")
beta_users = jmespath.search("users[?contains(projects, 'beta')].name", data)
print(" Users sur projet beta:", beta_users)
# Dict imbriqué dans le résultat
print("\n⇒ Dict imbriqué (retour structuré)")
summary = jmespath.search("{meta: metadata, admins: users[?role=='admin'].name, total_users: length(users)}", data)
print(" Résumé:", summary)
# Exemple: réponse API paginée
api_response = dict(
items=list(
dict(sku="A001", price=29.99, stock=100),
dict(sku="A002", price=49.99, stock=0),
dict(sku="B001", price=19.99, stock=50),
dict(sku="B002", price=99.99, stock=25),
),
pagination=dict(
next="/api/items?page=2",
total_pages=5,
)
)
print("\n⇒ Exemple API e-commerce")
in_stock = jmespath.search("items[?stock > `0`].sku", api_response)
print(" SKUs en stock:", in_stock)
expensive = jmespath.search("items[?price > `50`].{sku: sku, prix: price}", api_response)
print(" Produits > 50€:", expensive)
# Max/min avec sort
print("\n⇒ Min/Max")
cheapest = jmespath.search("sort_by(items, &price)[0]", api_response)
print(" Moins cher:", cheapest["sku"], "-", cheapest["price"], "€")
most_expensive = jmespath.search("sort_by(items, &price)[-1]", api_response)
print(" Plus cher:", most_expensive["sku"], "-", most_expensive["price"], "€")
# Compilation pour performance
print("\n⇒ Expression compilée")
expr = jmespath.compile("users[?active].name")
result = expr.search(data)
print(" Résultat:", result)