You could create a CustomFunctions
class to do this, similar to the examples given in the GitHub page.
from jmespath import search
from jmespath import functions
from jmespath import Options
from json import loads
class CustomFunctions(functions.Functions):
# Method that selects 'bigImage' key value if it exists
# Otherwise return 'normalImage' value
# dict.get() is perfect for this, since it returns a default value if a key doesn't exist
# Use type 'object' since thats the equivalant type to a Python dictionary in JSON
# Make sure to decorate function signature as well to indicate types
# Make sure to also put _func_ before your function name
@functions.signature({'types': ['object']})
def _func_choose_key(self, d):
return d.get('bigImage', d['normalImage'])
if __name__ == "__main__":
# Get custom function options
options = Options(custom_functions=CustomFunctions())
# Test method which runs JMESPath query with custom function
def test(json):
json_dict = loads(json)
return search('product.images | choose_key(@)', json_dict, options=options)
# TEST 1 - bigImage key exists
json1 = """{
"sku": 123,
"product": {
"name": "Some name",
"images": {
"normalImage": "http://somelink.com/1.jpg",
"bigImage": "http://somelink.com/1b.jpg"
}
}
}"""
print("Test1: %s" % test(json1))
# TEST 2 - bigImage key doesn't exist
json2 = """{
"sku": 123,
"product": {
"name": "Some name",
"images": {
"normalImage": "http://somelink.com/1.jpg"
}
}
}"""
print("Test2: %s" % test(json2))
Which prints out the following results:
Test1: http://somelink.com/1b.jpg # When bigImage key exists
Test2: http://somelink.com/1.jpg # When bigImage key doesn't exist
If JMESPath gets too complicated, we can always use the good old standard dictionary approach:
def test2(json):
json_dict = loads(json)
images = json_dict["product"]["images"]
return images.get("bigImage", images["normalImage"])
# TEST 1 - bigImage key exists
json1 = """{
"sku": 123,
"product": {
"name": "Some name",
"images": {
"normalImage": "http://somelink.com/1.jpg",
"bigImage": "http://somelink.com/1b.jpg"
}
}
}"""
print("Test1: %s" % test2(json1))
# TEST 2 - bigImage key doesn't exist
json2 = """{
"sku": 123,
"product": {
"name": "Some name",
"images": {
"normalImage": "http://somelink.com/1.jpg"
}
}
}"""
print("Test2: %s" % test2(json2))
Which also prints the same results:
Test1: http://somelink.com/1b.jpg # When bigImage key exists
Test2: http://somelink.com/1.jpg # When bigImage key doesn't exist