|
| 1 | +--- |
| 2 | +title: JMESPath Functions |
| 3 | +description: Utility |
| 4 | +--- |
| 5 | + |
| 6 | +You might have events or responses that contain non-encoded JSON, where you need to decode so that you can access portions of the object or ensure the Powertools utility receives a JSON object. This is a common use case when using the [validation](/utilities/validation) or [idempotency](/utilities/idempotency) utilities. |
| 7 | + |
| 8 | +## Built-in JMESPath functions |
| 9 | +You can use our built-in JMESPath functions within your expressions to do exactly that to decode JSON Strings, base64, and uncompress gzip data. |
| 10 | + |
| 11 | +!!! info |
| 12 | + We use these for built-in envelopes to easily decode and unwrap events from sources like API Gateway, Kinesis, CloudWatch Logs, etc. |
| 13 | + |
| 14 | +#### powertools_json function |
| 15 | + |
| 16 | +Use `powertools_json` function to decode any JSON String anywhere a JMESPath expression is allowed. |
| 17 | + |
| 18 | +> **Validation scenario** |
| 19 | +
|
| 20 | +This sample will decode the value within the `data` key into a valid JSON before we can validate it. |
| 21 | + |
| 22 | +=== "powertools_json_jmespath_function.py" |
| 23 | + |
| 24 | + ```python hl_lines="9" |
| 25 | + from aws_lambda_powertools.utilities.validation import validate |
| 26 | + |
| 27 | + import schemas |
| 28 | + |
| 29 | + sample_event = { |
| 30 | + 'data': '{"payload": {"message": "hello hello", "username": "blah blah"}}' |
| 31 | + } |
| 32 | + |
| 33 | + validate(event=sample_event, schema=schemas.INPUT, envelope="powertools_json(data)") |
| 34 | + ``` |
| 35 | + |
| 36 | +=== "schemas.py" |
| 37 | + |
| 38 | + ```python hl_lines="7 14 16 23 39 45 47 52" |
| 39 | + --8<-- "docs/shared/validation_basic_jsonschema.py" |
| 40 | + ``` |
| 41 | + |
| 42 | +> **Idempotency scenario** |
| 43 | +
|
| 44 | +This sample will decode the value within the `body` key of an API Gateway event into a valid JSON object to ensure the Idempotency utility processes a JSON object instead of a string. |
| 45 | + |
| 46 | +=== "powertools_json_jmespath_function.py" |
| 47 | + |
| 48 | + ```python hl_lines="8" |
| 49 | + import json |
| 50 | + from aws_lambda_powertools.utilities.idempotency import ( |
| 51 | + IdempotencyConfig, DynamoDBPersistenceLayer, idempotent |
| 52 | + ) |
| 53 | + |
| 54 | + persistence_layer = DynamoDBPersistenceLayer(table_name="IdempotencyTable") |
| 55 | + |
| 56 | + config = IdempotencyConfig(event_key_jmespath="powertools_json(body)") |
| 57 | + @idempotent(config=config, persistence_store=persistence_layer) |
| 58 | + def handler(event:APIGatewayProxyEvent, context): |
| 59 | + body = json.loads(event['body']) |
| 60 | + payment = create_subscription_payment( |
| 61 | + user=body['user'], |
| 62 | + product=body['product_id'] |
| 63 | + ) |
| 64 | + ... |
| 65 | + return { |
| 66 | + "payment_id": payment.id, |
| 67 | + "message": "success", |
| 68 | + "statusCode": 200 |
| 69 | + } |
| 70 | + ``` |
| 71 | + |
| 72 | +#### powertools_base64 function |
| 73 | + |
| 74 | +Use `powertools_base64` function to decode any base64 data. |
| 75 | + |
| 76 | +This sample will decode the base64 value within the `data` key, and decode the JSON string into a valid JSON before we can validate it. |
| 77 | + |
| 78 | +=== "powertools_json_jmespath_function.py" |
| 79 | + |
| 80 | + ```python hl_lines="12" |
| 81 | + from aws_lambda_powertools.utilities.validation import validate |
| 82 | + |
| 83 | + import schemas |
| 84 | + |
| 85 | + sample_event = { |
| 86 | + "data": "eyJtZXNzYWdlIjogImhlbGxvIGhlbGxvIiwgInVzZXJuYW1lIjogImJsYWggYmxhaCJ9=" |
| 87 | + } |
| 88 | + |
| 89 | + validate( |
| 90 | + event=sample_event, |
| 91 | + schema=schemas.INPUT, |
| 92 | + envelope="powertools_json(powertools_base64(data))" |
| 93 | + ) |
| 94 | + ``` |
| 95 | + |
| 96 | +=== "schemas.py" |
| 97 | + |
| 98 | + ```python hl_lines="7 14 16 23 39 45 47 52" |
| 99 | + --8<-- "docs/shared/validation_basic_jsonschema.py" |
| 100 | + ``` |
| 101 | + |
| 102 | +#### powertools_base64_gzip function |
| 103 | + |
| 104 | +Use `powertools_base64_gzip` function to decompress and decode base64 data. |
| 105 | + |
| 106 | +This sample will decompress and decode base64 data, then use JMESPath pipeline expression to pass the result for decoding its JSON string. |
| 107 | + |
| 108 | +=== "powertools_json_jmespath_function.py" |
| 109 | + |
| 110 | + ```python hl_lines="12" |
| 111 | + from aws_lambda_powertools.utilities.validation import validate |
| 112 | + |
| 113 | + import schemas |
| 114 | + |
| 115 | + sample_event = { |
| 116 | + "data": "H4sIACZAXl8C/52PzUrEMBhFX2UILpX8tPbHXWHqIOiq3Q1F0ubrWEiakqTWofTdTYYB0YWL2d5zvnuTFellBIOedoiyKH5M0iwnlKH7HZL6dDB6ngLDfLFYctUKjie9gHFaS/sAX1xNEq525QxwFXRGGMEkx4Th491rUZdV3YiIZ6Ljfd+lfSyAtZloacQgAkqSJCGhxM6t7cwwuUGPz4N0YKyvO6I9WDeMPMSo8Z4Ca/kJ6vMEYW5f1MX7W1lVxaG8vqX8hNFdjlc0iCBBSF4ERT/3Pl7RbMGMXF2KZMh/C+gDpNS7RRsp0OaRGzx0/t8e0jgmcczyLCWEePhni/23JWalzjdu0a3ZvgEaNLXeugEAAA==" |
| 117 | + } |
| 118 | + |
| 119 | + validate( |
| 120 | + event=sample_event, |
| 121 | + schema=schemas.INPUT, |
| 122 | + envelope="powertools_base64_gzip(data) | powertools_json(@)" |
| 123 | + ) |
| 124 | + ``` |
| 125 | + |
| 126 | +=== "schemas.py" |
| 127 | + |
| 128 | + ```python hl_lines="7 14 16 23 39 45 47 52" |
| 129 | + --8<-- "docs/shared/validation_basic_jsonschema.py" |
| 130 | + ``` |
| 131 | + |
| 132 | +### Bring your own JMESPath function |
| 133 | + |
| 134 | +!!! warning |
| 135 | + This should only be used for advanced use cases where you have special formats not covered by the built-in functions. |
| 136 | + |
| 137 | + This will **replace all provided built-in functions such as `powertools_json`, so you will no longer be able to use them**. |
| 138 | + |
| 139 | +For special binary formats that you want to decode before applying JSON Schema validation, you can bring your own [JMESPath function](https://github.com/jmespath/jmespath.py#custom-functions){target="_blank"} and any additional option via `jmespath_options` param. |
| 140 | + |
| 141 | +=== "custom_jmespath_function.py" |
| 142 | + |
| 143 | + ```python hl_lines="2 6-10 14" |
| 144 | + from aws_lambda_powertools.utilities.validation import validator |
| 145 | + from jmespath import functions |
| 146 | + |
| 147 | + import schemas |
| 148 | + |
| 149 | + class CustomFunctions(functions.Functions): |
| 150 | + |
| 151 | + @functions.signature({'types': ['string']}) |
| 152 | + def _func_special_decoder(self, s): |
| 153 | + return my_custom_decoder_logic(s) |
| 154 | + |
| 155 | + custom_jmespath_options = {"custom_functions": CustomFunctions()} |
| 156 | + |
| 157 | + @validator(schema=schemas.INPUT, jmespath_options=**custom_jmespath_options) |
| 158 | + def handler(event, context): |
| 159 | + return event |
| 160 | + ``` |
| 161 | + |
| 162 | +=== "schemas.py" |
| 163 | + |
| 164 | + ```python hl_lines="7 14 16 23 39 45 47 52" |
| 165 | + --8<-- "docs/shared/validation_basic_jsonschema.py" |
| 166 | + ``` |
0 commit comments