diff --git a/docs/core/logger.md b/docs/core/logger.md index dc5e0c0d64..6fb4fa2801 100644 --- a/docs/core/logger.md +++ b/docs/core/logger.md @@ -143,6 +143,89 @@ When debugging in non-production environments, you can instruct Logger to log th ... ``` +#### Setting a Correlation ID + +> New in 1.12.0 + +You can set a Correlation ID using `correlation_id_path` param by passing a [JMESPath expression](https://jmespath.org/tutorial.html){target="_blank"}. + +=== "collect.py" + + ```python hl_lines="6" + from aws_lambda_powertools import Logger + + logger = Logger() + + @logger.inject_lambda_context(correlation_id_path="headers.my_request_id_header") + def handler(event, context): + logger.info("Collecting payment") + ... + ``` + +=== "Example Event" + + ```json hl_lines="3" + { + "headers": { + "my_request_id_header": "correlation_id_value" + } + } + ``` + +=== "Example CloudWatch Logs excerpt" + + ```json hl_lines="7" + { + "timestamp": "2020-05-24 18:17:33,774", + "level": "INFO", + "location": "collect.handler:1", + "service": "payment", + "sampling_rate": 0.0, + "correlation_id": "correlation_id_value", + "message": "Collecting payment" + } + ``` + +We provide [built-in JMESPath expressions](#built-in-correlation-id-expressions) for known event sources, where either a request ID or X-Ray Trace ID are present. + +=== "collect.py" + + ```python hl_lines="2" + from aws_lambda_powertools import Logger + from aws_lambda_powertools.logging import correlation_paths + + logger = Logger() + + @logger.inject_lambda_context(correlation_id_path=correlation_paths.API_GATEWAY_REST) + def handler(event, context): + logger.info("Collecting payment") + ... + ``` + +=== "Example Event" + + ```json hl_lines="3" + { + "requestContext": { + "requestId": "correlation_id_value" + } + } + ``` + +=== "Example CloudWatch Logs excerpt" + + ```json hl_lines="7" + { + "timestamp": "2020-05-24 18:17:33,774", + "level": "INFO", + "location": "collect.handler:1", + "service": "payment", + "sampling_rate": 0.0, + "correlation_id": "correlation_id_value", + "message": "Collecting payment" + } + ``` + ### Appending additional keys You can append additional keys using either mechanism: @@ -188,24 +271,58 @@ You can append your own keys to your existing Logger via `structure_logs(append= This example will add `order_id` if its value is not empty, and in subsequent invocations where `order_id` might not be present it'll remove it from the logger. -#### Setting correlation ID +#### extra parameter -You can set a correlation_id to your existing Logger via `set_correlation_id(value)` method. +> New in 1.10.0 + +Extra parameter is available for all log levels' methods, as implemented in the standard logging library - e.g. `logger.info, logger.warning`. + +It accepts any dictionary, and all keyword arguments will be added as part of the root structure of the logs for that log statement. + +!!! info "Any keyword argument added using `extra` will not be persisted for subsequent messages." + +=== "extra_parameter.py" + + ```python hl_lines="6" + logger = Logger(service="payment") + + fields = { "request_id": "1123" } + + logger.info("Hello", extra=fields) + ``` +=== "Example CloudWatch Logs excerpt" + + ```json hl_lines="7" + { + "timestamp": "2021-01-12 14:08:12,357", + "level": "INFO", + "location": "collect.handler:1", + "service": "payment", + "sampling_rate": 0.0, + "request_id": "1123", + "message": "Collecting payment" + } + ``` + +#### set_correlation_id method + +> New in 1.12.0 + +You can set a correlation_id to your existing Logger via `set_correlation_id(value)` method by passing any string value. === "collect.py" - ```python hl_lines="8" + ```python hl_lines="6" from aws_lambda_powertools import Logger - from aws_lambda_powertools.utilities.data_classes import APIGatewayProxyEvent logger = Logger() def handler(event, context): - event = APIGatewayProxyEvent(event) - logger.set_correlation_id(event.request_context.request_id) + logger.set_correlation_id(event["requestContext"]["requestId"]) logger.info("Collecting payment") ... ``` + === "Example Event" ```json hl_lines="3" @@ -215,6 +332,7 @@ You can set a correlation_id to your existing Logger via `set_correlation_id(val } } ``` + === "Example CloudWatch Logs excerpt" ```json hl_lines="7" @@ -229,37 +347,82 @@ You can set a correlation_id to your existing Logger via `set_correlation_id(val } ``` -#### extra parameter - -Extra parameter is available for all log levels' methods, as implemented in the standard logging library - e.g. `logger.info, logger.warning`. +Alternatively, you can combine [Data Classes utility](../utilities/data_classes.md) with Logger to use dot notation object: -It accepts any dictionary, and all keyword arguments will be added as part of the root structure of the logs for that log statement. +=== "collect.py" -!!! info "Any keyword argument added using `extra` will not be persisted for subsequent messages." + ```python hl_lines="2 7-8" + from aws_lambda_powertools import Logger + from aws_lambda_powertools.utilities.data_classes import APIGatewayProxyEvent -=== "extra_parameter.py" + logger = Logger() - ```python hl_lines="6" - logger = Logger(service="payment") + def handler(event, context): + event = APIGatewayProxyEvent(event) + logger.set_correlation_id(event.request_context.request_id) + logger.info("Collecting payment") + ... + ``` +=== "Example Event" - fields = { "request_id": "1123" } + ```json hl_lines="3" + { + "requestContext": { + "requestId": "correlation_id_value" + } + } + ``` - logger.info("Hello", extra=fields) - ``` === "Example CloudWatch Logs excerpt" ```json hl_lines="7" { - "timestamp": "2021-01-12 14:08:12,357", + "timestamp": "2020-05-24 18:17:33,774", "level": "INFO", "location": "collect.handler:1", "service": "payment", "sampling_rate": 0.0, - "request_id": "1123", + "correlation_id": "correlation_id_value", "message": "Collecting payment" } ``` +### Logging exceptions + +When logging exceptions, Logger will add new keys named `exception_name` and `exception` with the full traceback as a string. + +!!! tip + > New in 1.12.0 + + You can use your preferred Log Analytics tool to enumerate exceptions across all your services using `exception_name` key. + +=== "logging_an_exception.py" + + ```python hl_lines="7" + from aws_lambda_powertools import Logger + logger = Logger() + + try: + raise ValueError("something went wrong") + except Exception: + logger.exception("Received an exception") + ``` + +=== "Example CloudWatch Logs excerpt" + + ```json + { + "level": "ERROR", + "location": ":4", + "message": "Received an exception", + "timestamp": "2020-08-28 18:11:38,886", + "service": "service_undefined", + "sampling_rate": 0.0, + "exception_name": "ValueError", + "exception": "Traceback (most recent call last):\n File \"\", line 2, in \nValueError: something went wrong" + } + ``` + ## Advanced ### Reusing Logger across your code @@ -490,37 +653,6 @@ You can also change the order of the following log record keys via the `log_reco } ``` -#### Logging exceptions - -When logging exceptions, Logger will add new keys named `exception_name` and `exception` with the full traceback as a string. - -=== "logging_an_exception.py" - - ```python hl_lines="7" - from aws_lambda_powertools import Logger - logger = Logger() - - try: - raise ValueError("something went wrong") - except Exception: - logger.exception("Received an exception") - ``` - -=== "Example CloudWatch Logs excerpt" - - ```json - { - "level": "ERROR", - "location": ":4", - "message": "Received an exception", - "timestamp": "2020-08-28 18:11:38,886", - "service": "service_undefined", - "sampling_rate": 0.0, - "exception_name": "ValueError", - "exception": "Traceback (most recent call last):\n File \"\", line 2, in \nValueError: something went wrong" - } - ``` - ## Testing your code When unit testing your code that makes use of `inject_lambda_context` decorator, you need to pass a dummy Lambda Context, or else Logger will fail. @@ -585,6 +717,23 @@ POWERTOOLS_LOG_DEDUPLICATION_DISABLED="1" pytest -o log_cli=1 !!! warning This feature should be used with care, as it explicitly disables our ability to filter propagated messages to the root logger (if configured). +## Built-in Correlation ID expressions + +> New in 1.12.0 + +You can use any of the following built-in JMESPath expressions as part of [inject_lambda_context decorator](#setting-a-correlation-id). + +!!! note "Escaping necessary for the `-` character" + Any object key named with `-` must be escaped, for example **`request.headers."x-amzn-trace-id"`**. + +Name | Expression | Description +------------------------------------------------- | ------------------------------------------------- | --------------------------------------------------------------------------------- +**API_GATEWAY_REST** | `"requestContext.requestId"` | API Gateway REST API request ID +**API_GATEWAY_HTTP** | `"requestContext.requestId"` | API Gateway HTTP API request ID +**APPSYNC_RESOLVER** | `'request.headers."x-amzn-trace-id"'` | AppSync X-Ray Trace ID +**APPLICATION_LOAD_BALANCER** | `'headers."x-amzn-trace-id"'` | ALB X-Ray Trace ID +**EVENT_BRIDGE** | `"id"` | EventBridge Event ID + ## FAQ **How can I enable boto3 and botocore library logging?** diff --git a/docs/utilities/data_classes.md b/docs/utilities/data_classes.md index 3e79a4db72..b834390cc1 100644 --- a/docs/utilities/data_classes.md +++ b/docs/utilities/data_classes.md @@ -106,8 +106,12 @@ It is used for either API Gateway REST API or HTTP API using v1 proxy event. ### AppSync Resolver -Used when building a Lambda GraphQL Resolvers with [Amplify GraphQL Transform Library](https://docs.amplify.aws/cli/graphql-transformer/function){target="_blank"} -and can also be used for [AppSync Direct Lambda Resolvers](https://aws.amazon.com/blogs/mobile/appsync-direct-lambda/){target="_blank"}. +> New in 1.12.0 + +Used when building Lambda GraphQL Resolvers with [Amplify GraphQL Transform Library](https://docs.amplify.aws/cli/graphql-transformer/function){target="_blank"} (`@function`), +and [AppSync Direct Lambda Resolvers](https://aws.amazon.com/blogs/mobile/appsync-direct-lambda/){target="_blank"}. + +In this example, we also use the new Logger `correlation_id` and built-in `correlation_paths` to extract, if available, X-Ray Trace ID in AppSync request headers: === "app.py" @@ -252,11 +256,10 @@ Verify Auth Challenge | `data_classes.cognito_user_pool_event.VerifyAuthChalleng #### Define Auth Challenge Example -!!! warning "NOTE " +!!! warning "NOTE" In this example we are modifying the wrapped dict response fields, so we need to return the json serializable wrapped event in `event.raw_event` -!!! info "NOTE " - This example is based on the AWS Cognito docs for [Define Auth Challenge Lambda Trigger](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-define-auth-challenge.html){target="_blank"} +This example is based on the AWS Cognito docs for [Define Auth Challenge Lambda Trigger](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-define-auth-challenge.html){target="_blank"}. === "app.py" @@ -410,8 +413,7 @@ Verify Auth Challenge | `data_classes.cognito_user_pool_event.VerifyAuthChalleng #### Create Auth Challenge Example -!!! info "NOTE " - This example is based on the AWS Cognito docs for [Create Auth Challenge Lambda Trigger](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-create-auth-challenge.html){target="_blank"} +This example is based on the AWS Cognito docs for [Create Auth Challenge Lambda Trigger](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-create-auth-challenge.html){target="_blank"}. === "app.py" @@ -429,8 +431,7 @@ Verify Auth Challenge | `data_classes.cognito_user_pool_event.VerifyAuthChalleng #### Verify Auth Challenge Response Example -!!! info "NOTE " - This example is based on the AWS Cognito docs for [Verify Auth Challenge Response Lambda Trigger](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-verify-auth-challenge-response.html){target="_blank"} +This example is based on the AWS Cognito docs for [Verify Auth Challenge Response Lambda Trigger](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-verify-auth-challenge-response.html){target="_blank"}. === "app.py" @@ -447,6 +448,8 @@ Verify Auth Challenge | `data_classes.cognito_user_pool_event.VerifyAuthChalleng ### Connect Contact Flow +> New in 1.11.0 + === "app.py" ```python diff --git a/docs/utilities/idempotency.md b/docs/utilities/idempotency.md index 6e74bd2b16..09e8567344 100644 --- a/docs/utilities/idempotency.md +++ b/docs/utilities/idempotency.md @@ -39,6 +39,11 @@ As of now, Amazon DynamoDB is the only supported persistent storage layer, so yo === "template.yml" + !!! tip "You can share a single state table for all functions" + > New in 1.12.0 + + You can reuse the same DynamoDB table to store idempotency state. We add your function_name in addition to the idempotency key as a hash key. + ```yaml hl_lines="5-13 21-23" Resources: IdempotencyTable: diff --git a/docs/utilities/parameters.md b/docs/utilities/parameters.md index 9eab97105e..e50f3f85b8 100644 --- a/docs/utilities/parameters.md +++ b/docs/utilities/parameters.md @@ -4,17 +4,24 @@ description: Utility --- -The parameters utility provides a way to retrieve parameter values from [AWS Systems Manager Parameter Store](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html), [AWS Secrets Manager](https://aws.amazon.com/secrets-manager/) or [Amazon DynamoDB](https://aws.amazon.com/dynamodb/). It also provides a base class to create your parameter provider implementation. +The parameters utility provides high-level functions to retrieve one or multiple parameter values from [AWS Systems Manager Parameter Store](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html){target="_blank"}, [AWS Secrets Manager](https://aws.amazon.com/secrets-manager/), [AWS AppConfig](https://aws.amazon.com/appconfig/){target="_blank"}, [Amazon DynamoDB](https://aws.amazon.com/dynamodb/){target="_blank"}, or bring your own. -**Key features** +## Key features * Retrieve one or multiple parameters from the underlying provider * Cache parameter values for a given amount of time (defaults to 5 seconds) * Transform parameter values from JSON or base 64 encoded strings +* Bring Your Own Parameter Store Provider -**IAM Permissions** +## Getting started -This utility requires additional permissions to work as expected. See the table below: +By default, we fetch parameters from System Manager Parameter Store, secrets from Secrets Manager, and application configuration from AppConfig. + +### IAM Permissions + +This utility requires additional permissions to work as expected. + +!!! note "Different parameter providers require different permissions" Provider | Function/Method | IAM Permission ------------------------------------------------- | ------------------------------------------------- | --------------------------------------------------------------------------------- @@ -25,13 +32,15 @@ DynamoDB | `DynamoDBProvider.get` | `dynamodb:GetItem` DynamoDB | `DynamoDBProvider.get_multiple` | `dynamodb:Query` App Config | `AppConfigProvider.get_app_config`, `get_app_config` | `appconfig:GetConfiguration` -## SSM Parameter Store +### Fetching parameters + +You can retrieve a single parameter using `get_parameter` high-level function. -You can retrieve a single parameter using `get_parameter` high-level function. For multiple parameters, you can use `get_parameters` and pass a path to retrieve them recursively. +For multiple parameters, you can use `get_parameters` and pass a path to retrieve them recursively. === "ssm_parameter_store.py" - ```python + ```python hl_lines="1 5 9" from aws_lambda_powertools.utilities import parameters def handler(event, context): @@ -45,15 +54,49 @@ You can retrieve a single parameter using `get_parameter` high-level function. F print(f"{k}: {v}") ``` -### SSMProvider class +### Fetching secrets -Alternatively, you can use the `SSMProvider` class, which gives more flexibility, such as the ability to configure the underlying SDK client. +You can fetch secrets stored in Secrets Manager using `get_secrets`. -This can be used to retrieve values from other regions, change the retry behavior, etc. +=== "secrets_manager.py" -=== "ssm_parameter_store.py" + ```python hl_lines="1 5" + from aws_lambda_powertools.utilities import parameters + + def handler(event, context): + # Retrieve a single secret + value = parameters.get_secret("my-secret") + ``` + +### Fetching app configurations + +> New in 1.10.0 + +You can fetch application configurations in AWS AppConfig using `get_app_config`. + +The following will retrieve the latest version and store it in the cache. + +=== "appconfig.py" + + ```python hl_lines="1 5" + from aws_lambda_powertools.utilities import parameters + + def handler(event, context): + # Retrieve a single configuration, latest version + value: bytes = parameters.get_app_config(name="my_configuration", environment="my_env", application="my_app") + ``` + +## Advanced - ```python +### Adjusting cache TTL + +By default, we cache parameters retrieved in-memory for 5 seconds. + +You can adjust how long we should keep values in cache by using the param `max_age`, when using `get()` or `get_multiple()` methods across all providers. + +=== "app.py" + + ```python hl_lines="9" from aws_lambda_powertools.utilities import parameters from botocore.config import Config @@ -62,7 +105,7 @@ This can be used to retrieve values from other regions, change the retry behavio def handler(event, context): # Retrieve a single parameter - value = ssm_provider.get("/my/parameter") + value = ssm_provider.get("/my/parameter", max_age=60) # 1 minute # Retrieve multiple parameters from a path prefix values = ssm_provider.get_multiple("/my/path/prefix") @@ -70,53 +113,74 @@ This can be used to retrieve values from other regions, change the retry behavio print(f"{k}: {v}") ``` -**Additional arguments** +### Always fetching the latest -The AWS Systems Manager Parameter Store provider supports two additional arguments for the `get()` and `get_multiple()` methods: +If you'd like to always ensure you fetch the latest parameter from the store regardless if already available in cache, use `force_fetch` param. -| Parameter | Default | Description | -|---------------|---------|-------------| -| **decrypt** | `False` | Will automatically decrypt the parameter. | -| **recursive** | `True` | For `get_multiple()` only, will fetch all parameter values recursively based on a path prefix. | +=== "app.py" + + ```python hl_lines="5" + from aws_lambda_powertools.utilities import parameters + + def handler(event, context): + # Retrieve a single parameter + value = parameters.get_parameter("/my/parameter", force_fetch=True) + ``` + +### Built-in provider class + +For greater flexibility such as configuring the underlying SDK client used by built-in providers, you can use their respective Provider Classes directly. + +!!! tip "This can be used to retrieve values from other regions, change the retry behavior, etc." -**Example:** +#### SSMProvider === "ssm_parameter_store.py" - ```python + ```python hl_lines="5 9 12" from aws_lambda_powertools.utilities import parameters + from botocore.config import Config - ssm_provider = parameters.SSMProvider() + config = Config(region_name="us-west-1") + ssm_provider = parameters.SSMProvider(config=config) def handler(event, context): - decrypted_value = ssm_provider.get("/my/encrypted/parameter", decrypt=True) + # Retrieve a single parameter + value = ssm_provider.get("/my/parameter") - no_recursive_values = ssm_provider.get_multiple("/my/path/prefix", recursive=False) + # Retrieve multiple parameters from a path prefix + values = ssm_provider.get_multiple("/my/path/prefix") + for k, v in values.items(): + print(f"{k}: {v}") ``` -## Secrets Manager +The AWS Systems Manager Parameter Store provider supports two additional arguments for the `get()` and `get_multiple()` methods: -For secrets stored in Secrets Manager, use `get_secret`. +| Parameter | Default | Description | +|---------------|---------|-------------| +| **decrypt** | `False` | Will automatically decrypt the parameter. +| **recursive** | `True` | For `get_multiple()` only, will fetch all parameter values recursively based on a path prefix. -=== "secrets_manager.py" +> **Example** + +=== "ssm_parameter_store.py" - ```python + ```python hl_lines="6 8" from aws_lambda_powertools.utilities import parameters - def handler(event, context): - # Retrieve a single secret - value = parameters.get_secret("my-secret") - ``` + ssm_provider = parameters.SSMProvider() -### SecretsProvider class + def handler(event, context): + decrypted_value = ssm_provider.get("/my/encrypted/parameter", decrypt=True) -Alternatively, you can use the `SecretsProvider` class, which give more flexibility, such as the ability to configure the underlying SDK client. + no_recursive_values = ssm_provider.get_multiple("/my/path/prefix", recursive=False) + ``` -This can be used to retrieve values from other regions, change the retry behavior, etc. +#### SecretsProvider === "secrets_manager.py" - ```python + ```python hl_lines="5 9" from aws_lambda_powertools.utilities import parameters from botocore.config import Config @@ -128,25 +192,24 @@ This can be used to retrieve values from other regions, change the retry behavio value = secrets_provider.get("my-secret") ``` -## DynamoDB - -To use the DynamoDB provider, you need to import and instantiate the `DynamoDBProvider` class. +#### DynamoDBProvider The DynamoDB Provider does not have any high-level functions, as it needs to know the name of the DynamoDB table containing the parameters. -**DynamoDB table structure** +**DynamoDB table structure for single parameters** -When using the default options, if you want to retrieve only single parameters, your table should be structured as such, assuming a parameter named **my-parameter** with a value of **my-value**. The `id` attribute should be the [partition key](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.PrimaryKey) for that table. +For single parameters, you must use `id` as the [partition key](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.PrimaryKey) for that table. | id | value | |--------------|----------| | my-parameter | my-value | -With this table, when you do a `dynamodb_provider.get("my-param")` call, this will return `my-value`. +> **Example** -=== "dynamodb.py" +=== "app.py" + With this table, the return value of `dynamodb_provider.get("my-param")` call will be `my-value`. - ```python + ```python hl_lines="3 7" from aws_lambda_powertools.utilities import parameters dynamodb_provider = parameters.DynamoDBProvider(table_name="my-table") @@ -156,9 +219,11 @@ With this table, when you do a `dynamodb_provider.get("my-param")` call, this wi value = dynamodb_provider.get("my-parameter") ``` -**Retrieve multiple values** +**DynamoDB table structure for multiple values parameters** -If you want to be able to retrieve multiple parameters at once sharing the same `id`, your table needs to contain a sort key name `sk`. For example, if you want to retrieve multiple parameters having `my-hash-key` as ID: +If you want to be able to retrieve multiple parameters at once sharing the same `id`, your table needs to contain a sort key name `sk`. + +For example, if you want to retrieve multiple parameters having `my-hash-key` as ID: | id | sk | value | |-------------|---------|------------| @@ -166,9 +231,10 @@ If you want to be able to retrieve multiple parameters at once sharing the same | my-hash-key | param-b | my-value-b | | my-hash-key | param-c | my-value-c | -With this table, when you do a `dynamodb_provider.get_multiple("my-hash-key")` call, you will receive the following dict as a response: -``` +With this table, the return of `dynamodb_provider.get_multiple("my-hash-key")` call will be a dictionary like: + +```json { "param-a": "my-value-a", "param-b": "my-value-b", @@ -176,11 +242,11 @@ With this table, when you do a `dynamodb_provider.get_multiple("my-hash-key")` c } ``` -**Example:** +> **Example** -=== "dynamodb_multiple.py" +=== "app_multiple_parameters.py" - ```python + ```python hl_lines="3 8" from aws_lambda_powertools.utilities import parameters dynamodb_provider = parameters.DynamoDBProvider(table_name="my-table") @@ -195,7 +261,7 @@ With this table, when you do a `dynamodb_provider.get_multiple("my-hash-key")` c **Additional arguments** -The Amazon DynamoDB provider supports four additional arguments at initialization: +The DynamoDB provider supports four additional arguments at initialization. These can be used if you require a custom table structure: | Parameter | Mandatory | Default | Description | |----------------|-----------|---------|-------------| @@ -204,9 +270,11 @@ The Amazon DynamoDB provider supports four additional arguments at initializatio | **sort_attr** | No | `sk` | Range key for the DynamoDB table. You don't need to set this if you don't use the `get_multiple()` method. | **value_attr** | No | `value` | Name of the attribute containing the parameter value. -=== "dynamodb.py" +> **Example** - ```python +=== "app.py" + + ```python hl_lines="3-8" from aws_lambda_powertools.utilities import parameters dynamodb_provider = parameters.DynamoDBProvider( @@ -220,32 +288,11 @@ The Amazon DynamoDB provider supports four additional arguments at initializatio value = dynamodb_provider.get("my-parameter") ``` -## App Config - -> New in 1.10.0 +#### AppConfigProvider -For configurations stored in App Config, use `get_app_config`. -The following will retrieve the latest version and store it in the cache. +=== "app.py" -=== "appconfig.py" - - ```python - from aws_lambda_powertools.utilities import parameters - - def handler(event, context): - # Retrieve a single configuration, latest version - value: bytes = parameters.get_app_config(name="my_configuration", environment="my_env", application="my_app") - ``` - -### AppConfigProvider class - -Alternatively, you can use the `AppConfigProvider` class, which give more flexibility, such as the ability to configure the underlying SDK client. - -This can be used to retrieve values from other regions, change the retry behavior, etc. - -=== "appconfig.py" - - ```python + ```python hl_lines="5 9" from aws_lambda_powertools.utilities import parameters from botocore.config import Config @@ -257,7 +304,7 @@ This can be used to retrieve values from other regions, change the retry behavio value: bytes = appconf_provider.get("my_conf") ``` -## Create your own provider +### Create your own provider You can create your own custom parameter store provider by inheriting the `BaseProvider` class, and implementing both `_get()` and `_get_multiple()` methods to retrieve a single, or multiple parameters from your custom store. @@ -267,7 +314,7 @@ Here is an example implementation using S3 as a custom parameter store: === "custom_provider.py" - ```python + ```python hl_lines="3 6 17 27" import copy from aws_lambda_powertools.utilities import BaseProvider @@ -321,13 +368,24 @@ Here is an example implementation using S3 as a custom parameter store: ``` -## Transform values +### Deserializing values with transform parameter -For parameters stored in JSON or Base64 format, you can use the `transform` argument for deserialization - The `transform` argument is available across all providers, including the high level functions. +For parameters stored in JSON or Base64 format, you can use the `transform` argument for deserialization. -=== "transform.py" +!!! info "The `transform` argument is available across all providers, including the high level functions" - ```python +=== "High level functions" + + ```python hl_lines="4" + from aws_lambda_powertools.utilities import parameters + + def handler(event, context): + value_from_json = parameters.get_parameter("/my/json/parameter", transform="json") + ``` + +=== "Providers" + + ```python hl_lines="7 10" from aws_lambda_powertools.utilities import parameters ssm_provider = parameters.SSMProvider() @@ -340,28 +398,17 @@ For parameters stored in JSON or Base64 format, you can use the `transform` argu value_from_binary = ssm_provider.get("/my/binary/parameter", transform="binary") ``` -You can also use the `transform` argument with high-level functions: - -=== "transform.py" - - ```python - from aws_lambda_powertools.utilities import parameters - - def handler(event, context): - value_from_json = parameters.get_parameter("/my/json/parameter", transform="json") - ``` - -### Partial transform failures with `get_multiple()` +#### Partial transform failures with `get_multiple()` If you use `transform` with `get_multiple()`, you can have a single malformed parameter value. To prevent failing the entire request, the method will return a `None` value for the parameters that failed to transform. -You can override this by setting the `raise_on_transform_error` argument to `True`. If you do so, a single transform error will raise a `TransformParameterError` exception. +You can override this by setting the `raise_on_transform_error` argument to `True`. If you do so, a single transform error will raise a **`TransformParameterError`** exception. -For example, if you have three parameters (*/param/a*, */param/b* and */param/c*) but */param/c* is malformed: +For example, if you have three parameters, */param/a*, */param/b* and */param/c*, but */param/c* is malformed: === "partial_failures.py" - ```python + ```python hl_lines="9 14-15" from aws_lambda_powertools.utilities import parameters ssm_provider = parameters.SSMProvider() @@ -379,13 +426,13 @@ For example, if you have three parameters (*/param/a*, */param/b* and */param/c* values = ssm_provider.get_multiple("/param", transform="json", raise_on_transform_error=True) ``` -## Additional SDK arguments +### Passing additional SDK arguments You can use arbitrary keyword arguments to pass it directly to the underlying SDK method. === "ssm_parameter_store.py" - ```python + ```python hl_lines="7" from aws_lambda_powertools.utilities import parameters secrets_provider = parameters.SecretsProvider()