aws-lambda-powertools 2.14.0__tar.gz → 2.15.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/PKG-INFO +28 -2
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/README.md +26 -1
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/logging/formatter.py +2 -2
- aws_lambda_powertools-2.15.0/aws_lambda_powertools/logging/formatters/__init__.py +5 -0
- aws_lambda_powertools-2.15.0/aws_lambda_powertools/logging/formatters/datadog.py +77 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/metrics/base.py +23 -10
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/batch/base.py +18 -7
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/batch/exceptions.py +5 -3
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/data_classes/api_gateway_authorizer_event.py +9 -2
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/data_classes/code_pipeline_job_event.py +2 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/data_classes/common.py +56 -3
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/data_classes/kafka_event.py +2 -3
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py +2 -3
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/data_classes/sqs_event.py +43 -2
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/jmespath_utils/envelopes.py +5 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/models/__init__.py +6 -0
- aws_lambda_powertools-2.15.0/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py +14 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/models/sqs.py +2 -2
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/pyproject.toml +11 -10
- aws_lambda_powertools-2.15.0/setup.py +64 -0
- aws_lambda_powertools-2.14.0/setup.py +0 -63
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/LICENSE +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/THIRD-PARTY-LICENSES +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/__init__.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/event_handler/__init__.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/event_handler/api_gateway.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/event_handler/appsync.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/event_handler/content_types.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/event_handler/exceptions.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/event_handler/lambda_function_url.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/event_handler/router.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/exceptions/__init__.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/logging/__init__.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/logging/correlation_paths.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/logging/exceptions.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/logging/filters.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/logging/lambda_context.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/logging/logger.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/logging/utils.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/metrics/__init__.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/metrics/exceptions.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/metrics/metric.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/metrics/metrics.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/metrics/types.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/middleware_factory/__init__.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/middleware_factory/exceptions.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/middleware_factory/factory.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/package_logger.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/py.typed +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/shared/__init__.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/shared/cache_dict.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/shared/constants.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/shared/cookies.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/shared/functions.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/shared/headers_serializer.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/shared/json_encoder.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/shared/lazy_import.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/shared/types.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/tracing/__init__.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/tracing/base.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/tracing/extensions.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/tracing/tracer.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/__init__.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/batch/__init__.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/batch/decorators.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/batch/sqs_fifo_partial_processor.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/batch/types.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/data_classes/__init__.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/data_classes/active_mq_event.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/data_classes/alb_event.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/data_classes/appsync/__init__.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/data_classes/appsync/scalar_types_utils.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/data_classes/appsync_authorizer_event.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/data_classes/appsync_resolver_event.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/data_classes/cloud_watch_custom_widget_event.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/data_classes/cloud_watch_logs_event.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/data_classes/cognito_user_pool_event.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/data_classes/connect_contact_flow_event.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/data_classes/dynamo_db_stream_event.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/data_classes/event_bridge_event.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/data_classes/event_source.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/data_classes/kinesis_stream_event.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/data_classes/lambda_function_url_event.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/data_classes/rabbit_mq_event.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/data_classes/s3_event.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/data_classes/s3_object_event.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/data_classes/ses_event.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/data_classes/sns_event.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/feature_flags/__init__.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/feature_flags/appconfig.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/feature_flags/base.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/feature_flags/exceptions.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/feature_flags/feature_flags.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/feature_flags/schema.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/feature_flags/time_conditions.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/idempotency/__init__.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/idempotency/base.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/idempotency/config.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/idempotency/exceptions.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/idempotency/idempotency.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/idempotency/persistence/__init__.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/idempotency/persistence/base.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/jmespath_utils/__init__.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parameters/__init__.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parameters/appconfig.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parameters/base.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parameters/dynamodb.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parameters/exceptions.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parameters/secrets.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parameters/ssm.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parameters/types.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/__init__.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/envelopes/__init__.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/envelopes/apigw.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/envelopes/apigwv2.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/envelopes/base.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/envelopes/cloudwatch.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/envelopes/dynamodb.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/envelopes/event_bridge.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/envelopes/kafka.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/envelopes/kinesis.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/envelopes/kinesis_firehose.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/envelopes/lambda_function_url.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/envelopes/sns.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/envelopes/sqs.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/exceptions.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/models/alb.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/models/apigw.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/models/apigwv2.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/models/cloudwatch.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/models/dynamodb.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/models/event_bridge.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/models/kafka.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/models/kinesis.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/models/kinesis_firehose.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/models/lambda_function_url.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/models/s3.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/models/s3_object_event.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/models/ses.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/models/sns.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/parser.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/pydantic.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/parser/types.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/streaming/__init__.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/streaming/_s3_seekable_io.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/streaming/compat.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/streaming/s3_object.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/streaming/transformations/__init__.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/streaming/transformations/base.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/streaming/transformations/csv.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/streaming/transformations/gzip.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/streaming/transformations/zip.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/typing/__init__.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/typing/lambda_client_context.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/typing/lambda_client_context_mobile_client.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/typing/lambda_cognito_identity.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/typing/lambda_context.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/validation/__init__.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/validation/base.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/validation/envelopes.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/validation/exceptions.py +0 -0
- {aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/utilities/validation/validator.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: aws-lambda-powertools
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.15.0
|
|
4
4
|
Summary: AWS Lambda Powertools is a developer toolkit to implement Serverless best practices and increase developer velocity.
|
|
5
5
|
Home-page: https://github.com/awslabs/aws-lambda-powertools-python
|
|
6
6
|
License: MIT
|
|
@@ -17,6 +17,7 @@ Classifier: Programming Language :: Python :: 3.8
|
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.9
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.10
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
21
|
Classifier: Programming Language :: Python :: 3.7
|
|
21
22
|
Classifier: Programming Language :: Python :: 3.8
|
|
22
23
|
Classifier: Programming Language :: Python :: 3.9
|
|
@@ -41,7 +42,7 @@ Description-Content-Type: text/markdown
|
|
|
41
42
|
|
|
42
43
|
[](https://github.com/awslabs/aws-lambda-powertools-python/actions/workflows/python_build.yml)
|
|
43
44
|
[](https://app.codecov.io/gh/awslabs/aws-lambda-powertools-python)
|
|
44
|
-
   [](https://discord.gg/B8zZKbbyET)
|
|
45
|
+
   [](https://discord.gg/B8zZKbbyET)
|
|
45
46
|
|
|
46
47
|
Powertools is a developer toolkit to implement Serverless [best practices and increase developer velocity](https://awslabs.github.io/aws-lambda-powertools-python/latest/#features).
|
|
47
48
|
|
|
@@ -83,6 +84,31 @@ With [pip](https://pip.pypa.io/en/latest/index.html) installed, run: ``pip insta
|
|
|
83
84
|
* [Serverless E-commerce platform](https://github.com/aws-samples/aws-serverless-ecommerce-platform)
|
|
84
85
|
* [Serverless GraphQL Nanny Booking Api](https://github.com/trey-rosius/babysitter_api)
|
|
85
86
|
|
|
87
|
+
## How to support AWS Lambda Powertools for Python?
|
|
88
|
+
|
|
89
|
+
### Becoming a reference customer
|
|
90
|
+
|
|
91
|
+
Knowing which companies are using this library is important to help prioritize the project internally. If your company is using AWS Lambda Powertools for Python, you can request to have your name and logo added to the README file by raising a [Support Lambda Powertools (become a reference)](https://github.com/awslabs/aws-lambda-powertools-python/issues/new?assignees=&labels=customer-reference&template=support_powertools.yml&title=%5BSupport+Lambda+Powertools%5D%3A+%3Cyour+organization+name%3E) issue.
|
|
92
|
+
|
|
93
|
+
The following companies, among others, use Powertools:
|
|
94
|
+
|
|
95
|
+
* [CPQi (Exadel Financial Services)](https://cpqi.com/)
|
|
96
|
+
* [CloudZero](https://www.cloudzero.com/)
|
|
97
|
+
* [CyberArk](https://www.cyberark.com/)
|
|
98
|
+
* [globaldatanet](https://globaldatanet.com/)
|
|
99
|
+
* [IMS](https://ims.tech/)
|
|
100
|
+
* [Propellor.ai](https://www.propellor.ai/)
|
|
101
|
+
* [TopSport](https://www.topsport.com.au/)
|
|
102
|
+
* [Trek10](https://www.trek10.com/)
|
|
103
|
+
|
|
104
|
+
### Sharing your work
|
|
105
|
+
|
|
106
|
+
Share what you did with Powertools 💞💞. Blog post, workshops, presentation, sample apps and others. Check out what the community has already shared about Powertools [here](https://awslabs.github.io/aws-lambda-powertools-python/latest/we_made_this/).
|
|
107
|
+
|
|
108
|
+
### Using Lambda Layer or SAR
|
|
109
|
+
|
|
110
|
+
This helps us understand who uses Powertools in a non-intrusive way, and helps us gain future investments for other Powertools languages. When [using Layers](https://awslabs.github.io/aws-lambda-powertools-python/latest/#lambda-layer), you can add Powertools as a dev dependency (or as part of your virtual env) to not impact the development process.
|
|
111
|
+
|
|
86
112
|
## Credits
|
|
87
113
|
|
|
88
114
|
* Structured logging initial implementation from [aws-lambda-logging](https://gitlab.com/hadrien/aws_lambda_logging)
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
[](https://github.com/awslabs/aws-lambda-powertools-python/actions/workflows/python_build.yml)
|
|
5
5
|
[](https://app.codecov.io/gh/awslabs/aws-lambda-powertools-python)
|
|
6
|
-
   [](https://discord.gg/B8zZKbbyET)
|
|
6
|
+
   [](https://discord.gg/B8zZKbbyET)
|
|
7
7
|
|
|
8
8
|
Powertools is a developer toolkit to implement Serverless [best practices and increase developer velocity](https://awslabs.github.io/aws-lambda-powertools-python/latest/#features).
|
|
9
9
|
|
|
@@ -45,6 +45,31 @@ With [pip](https://pip.pypa.io/en/latest/index.html) installed, run: ``pip insta
|
|
|
45
45
|
* [Serverless E-commerce platform](https://github.com/aws-samples/aws-serverless-ecommerce-platform)
|
|
46
46
|
* [Serverless GraphQL Nanny Booking Api](https://github.com/trey-rosius/babysitter_api)
|
|
47
47
|
|
|
48
|
+
## How to support AWS Lambda Powertools for Python?
|
|
49
|
+
|
|
50
|
+
### Becoming a reference customer
|
|
51
|
+
|
|
52
|
+
Knowing which companies are using this library is important to help prioritize the project internally. If your company is using AWS Lambda Powertools for Python, you can request to have your name and logo added to the README file by raising a [Support Lambda Powertools (become a reference)](https://github.com/awslabs/aws-lambda-powertools-python/issues/new?assignees=&labels=customer-reference&template=support_powertools.yml&title=%5BSupport+Lambda+Powertools%5D%3A+%3Cyour+organization+name%3E) issue.
|
|
53
|
+
|
|
54
|
+
The following companies, among others, use Powertools:
|
|
55
|
+
|
|
56
|
+
* [CPQi (Exadel Financial Services)](https://cpqi.com/)
|
|
57
|
+
* [CloudZero](https://www.cloudzero.com/)
|
|
58
|
+
* [CyberArk](https://www.cyberark.com/)
|
|
59
|
+
* [globaldatanet](https://globaldatanet.com/)
|
|
60
|
+
* [IMS](https://ims.tech/)
|
|
61
|
+
* [Propellor.ai](https://www.propellor.ai/)
|
|
62
|
+
* [TopSport](https://www.topsport.com.au/)
|
|
63
|
+
* [Trek10](https://www.trek10.com/)
|
|
64
|
+
|
|
65
|
+
### Sharing your work
|
|
66
|
+
|
|
67
|
+
Share what you did with Powertools 💞💞. Blog post, workshops, presentation, sample apps and others. Check out what the community has already shared about Powertools [here](https://awslabs.github.io/aws-lambda-powertools-python/latest/we_made_this/).
|
|
68
|
+
|
|
69
|
+
### Using Lambda Layer or SAR
|
|
70
|
+
|
|
71
|
+
This helps us understand who uses Powertools in a non-intrusive way, and helps us gain future investments for other Powertools languages. When [using Layers](https://awslabs.github.io/aws-lambda-powertools-python/latest/#lambda-layer), you can add Powertools as a dev dependency (or as part of your virtual env) to not impact the development process.
|
|
72
|
+
|
|
48
73
|
## Credits
|
|
49
74
|
|
|
50
75
|
* Structured logging initial implementation from [aws-lambda-logging](https://gitlab.com/hadrien/aws_lambda_logging)
|
|
@@ -139,11 +139,11 @@ class LambdaPowertoolsFormatter(BasePowertoolsFormatter):
|
|
|
139
139
|
if self.utc:
|
|
140
140
|
self.converter = time.gmtime
|
|
141
141
|
|
|
142
|
-
super(LambdaPowertoolsFormatter, self).__init__(datefmt=self.datefmt)
|
|
143
|
-
|
|
144
142
|
self.keys_combined = {**self._build_default_keys(), **kwargs}
|
|
145
143
|
self.log_format.update(**self.keys_combined)
|
|
146
144
|
|
|
145
|
+
super().__init__(datefmt=self.datefmt)
|
|
146
|
+
|
|
147
147
|
def serialize(self, log: Dict) -> str:
|
|
148
148
|
"""Serialize structured log dict to JSON str"""
|
|
149
149
|
return self.json_serializer(log)
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"""Built-in Logger formatters for Observability Providers that require custom config."""
|
|
2
|
+
|
|
3
|
+
# NOTE: we don't expose formatters directly (barrel import)
|
|
4
|
+
# as we cannot know if they'll need additional dependencies in the future
|
|
5
|
+
# so we isolate to avoid a performance hit and workarounds like lazy imports
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any, Callable
|
|
4
|
+
|
|
5
|
+
from aws_lambda_powertools.logging.formatter import LambdaPowertoolsFormatter
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class DatadogLogFormatter(LambdaPowertoolsFormatter):
|
|
9
|
+
def __init__(
|
|
10
|
+
self,
|
|
11
|
+
json_serializer: Callable[[dict], str] | None = None,
|
|
12
|
+
json_deserializer: Callable[[dict | str | bool | int | float], str] | None = None,
|
|
13
|
+
json_default: Callable[[Any], Any] | None = None,
|
|
14
|
+
datefmt: str | None = None,
|
|
15
|
+
use_datetime_directive: bool = False,
|
|
16
|
+
log_record_order: list[str] | None = None,
|
|
17
|
+
utc: bool = False,
|
|
18
|
+
use_rfc3339: bool = True, # NOTE: The only change from our base formatter
|
|
19
|
+
**kwargs,
|
|
20
|
+
):
|
|
21
|
+
"""Datadog formatter to comply with Datadog log parsing
|
|
22
|
+
|
|
23
|
+
Changes compared to the default Logger Formatter:
|
|
24
|
+
|
|
25
|
+
- timestamp format to use RFC3339 e.g., "2023-05-01T15:34:26.841+0200"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
Parameters
|
|
29
|
+
----------
|
|
30
|
+
log_record_order : list[str] | None, optional
|
|
31
|
+
_description_, by default None
|
|
32
|
+
|
|
33
|
+
Parameters
|
|
34
|
+
----------
|
|
35
|
+
json_serializer : Callable, optional
|
|
36
|
+
function to serialize `obj` to a JSON formatted `str`, by default json.dumps
|
|
37
|
+
json_deserializer : Callable, optional
|
|
38
|
+
function to deserialize `str`, `bytes`, bytearray` containing a JSON document to a Python `obj`,
|
|
39
|
+
by default json.loads
|
|
40
|
+
json_default : Callable, optional
|
|
41
|
+
function to coerce unserializable values, by default str
|
|
42
|
+
|
|
43
|
+
Only used when no custom JSON encoder is set
|
|
44
|
+
|
|
45
|
+
datefmt : str, optional
|
|
46
|
+
String directives (strftime) to format log timestamp.
|
|
47
|
+
|
|
48
|
+
See https://docs.python.org/3/library/time.html#time.strftime or
|
|
49
|
+
use_datetime_directive: str, optional
|
|
50
|
+
Interpret `datefmt` as a format string for `datetime.datetime.strftime`, rather than
|
|
51
|
+
`time.strftime` - Only useful when used alongside `datefmt`.
|
|
52
|
+
|
|
53
|
+
See https://docs.python.org/3/library/datetime.html#strftime-strptime-behavior . This
|
|
54
|
+
also supports a custom %F directive for milliseconds.
|
|
55
|
+
|
|
56
|
+
log_record_order : list, optional
|
|
57
|
+
set order of log keys when logging, by default ["level", "location", "message", "timestamp"]
|
|
58
|
+
|
|
59
|
+
utc : bool, optional
|
|
60
|
+
set logging timestamp to UTC, by default False to continue to use local time as per stdlib
|
|
61
|
+
use_rfc3339: bool, optional
|
|
62
|
+
Whether to use a popular dateformat that complies with both RFC3339 and ISO8601.
|
|
63
|
+
e.g., 2022-10-27T16:27:43.738+02:00.
|
|
64
|
+
kwargs
|
|
65
|
+
Key-value to persist in all log messages
|
|
66
|
+
"""
|
|
67
|
+
super().__init__(
|
|
68
|
+
json_serializer=json_serializer,
|
|
69
|
+
json_deserializer=json_deserializer,
|
|
70
|
+
json_default=json_default,
|
|
71
|
+
datefmt=datefmt,
|
|
72
|
+
use_datetime_directive=use_datetime_directive,
|
|
73
|
+
log_record_order=log_record_order,
|
|
74
|
+
utc=utc,
|
|
75
|
+
use_rfc3339=use_rfc3339,
|
|
76
|
+
**kwargs,
|
|
77
|
+
)
|
{aws_lambda_powertools-2.14.0 → aws_lambda_powertools-2.15.0}/aws_lambda_powertools/metrics/base.py
RENAMED
|
@@ -328,6 +328,28 @@ class MetricManager:
|
|
|
328
328
|
self.dimension_set.clear()
|
|
329
329
|
self.metadata_set.clear()
|
|
330
330
|
|
|
331
|
+
def flush_metrics(self, raise_on_empty_metrics: bool = False) -> None:
|
|
332
|
+
"""Manually flushes the metrics. This is normally not necessary,
|
|
333
|
+
unless you're running on other runtimes besides Lambda, where the @log_metrics
|
|
334
|
+
decorator already handles things for you.
|
|
335
|
+
|
|
336
|
+
Parameters
|
|
337
|
+
----------
|
|
338
|
+
raise_on_empty_metrics : bool, optional
|
|
339
|
+
raise exception if no metrics are emitted, by default False
|
|
340
|
+
"""
|
|
341
|
+
if not raise_on_empty_metrics and not self.metric_set:
|
|
342
|
+
warnings.warn(
|
|
343
|
+
"No application metrics to publish. The cold-start metric may be published if enabled. "
|
|
344
|
+
"If application metrics should never be empty, consider using 'raise_on_empty_metrics'",
|
|
345
|
+
stacklevel=2,
|
|
346
|
+
)
|
|
347
|
+
else:
|
|
348
|
+
logger.debug("Flushing existing metrics")
|
|
349
|
+
metrics = self.serialize_metric_set()
|
|
350
|
+
print(json.dumps(metrics, separators=(",", ":")))
|
|
351
|
+
self.clear_metrics()
|
|
352
|
+
|
|
331
353
|
def log_metrics(
|
|
332
354
|
self,
|
|
333
355
|
lambda_handler: Union[Callable[[Dict, Any], Any], Optional[Callable[[Dict, Any, Optional[Dict]], Any]]] = None,
|
|
@@ -390,16 +412,7 @@ class MetricManager:
|
|
|
390
412
|
if capture_cold_start_metric:
|
|
391
413
|
self._add_cold_start_metric(context=context)
|
|
392
414
|
finally:
|
|
393
|
-
|
|
394
|
-
warnings.warn(
|
|
395
|
-
"No application metrics to publish. The cold-start metric may be published if enabled. "
|
|
396
|
-
"If application metrics should never be empty, consider using 'raise_on_empty_metrics'",
|
|
397
|
-
stacklevel=2,
|
|
398
|
-
)
|
|
399
|
-
else:
|
|
400
|
-
metrics = self.serialize_metric_set()
|
|
401
|
-
self.clear_metrics()
|
|
402
|
-
print(json.dumps(metrics, separators=(",", ":")))
|
|
415
|
+
self.flush_metrics(raise_on_empty_metrics=raise_on_empty_metrics)
|
|
403
416
|
|
|
404
417
|
return response
|
|
405
418
|
|
|
@@ -26,7 +26,6 @@ from aws_lambda_powertools.utilities.data_classes.kinesis_stream_event import (
|
|
|
26
26
|
KinesisStreamRecord,
|
|
27
27
|
)
|
|
28
28
|
from aws_lambda_powertools.utilities.data_classes.sqs_event import SQSRecord
|
|
29
|
-
from aws_lambda_powertools.utilities.parser import ValidationError
|
|
30
29
|
from aws_lambda_powertools.utilities.typing import LambdaContext
|
|
31
30
|
|
|
32
31
|
logger = logging.getLogger(__name__)
|
|
@@ -496,9 +495,15 @@ class BatchProcessor(BasePartialBatchProcessor): # Keep old name for compatibil
|
|
|
496
495
|
result = self.handler(record=data)
|
|
497
496
|
|
|
498
497
|
return self.success_handler(record=record, result=result)
|
|
499
|
-
except
|
|
500
|
-
|
|
501
|
-
|
|
498
|
+
except Exception as exc:
|
|
499
|
+
# NOTE: Pydantic is an optional dependency, but when used and a poison pill scenario happens
|
|
500
|
+
# we need to handle that exception differently.
|
|
501
|
+
# We check for a public attr in validation errors coming from Pydantic exceptions (subclass or not)
|
|
502
|
+
# and we compare if it's coming from the same model that trigger the exception in the first place
|
|
503
|
+
model = getattr(exc, "model", None)
|
|
504
|
+
if model == self.model:
|
|
505
|
+
return self._register_model_validation_error_record(record)
|
|
506
|
+
|
|
502
507
|
return self.failure_handler(record=data, exception=sys.exc_info())
|
|
503
508
|
|
|
504
509
|
|
|
@@ -634,7 +639,13 @@ class AsyncBatchProcessor(BasePartialBatchProcessor):
|
|
|
634
639
|
result = await self.handler(record=data)
|
|
635
640
|
|
|
636
641
|
return self.success_handler(record=record, result=result)
|
|
637
|
-
except
|
|
638
|
-
|
|
639
|
-
|
|
642
|
+
except Exception as exc:
|
|
643
|
+
# NOTE: Pydantic is an optional dependency, but when used and a poison pill scenario happens
|
|
644
|
+
# we need to handle that exception differently.
|
|
645
|
+
# We check for a public attr in validation errors coming from Pydantic exceptions (subclass or not)
|
|
646
|
+
# and we compare if it's coming from the same model that trigger the exception in the first place
|
|
647
|
+
model = getattr(exc, "model", None)
|
|
648
|
+
if model == self.model:
|
|
649
|
+
return self._register_model_validation_error_record(record)
|
|
650
|
+
|
|
640
651
|
return self.failure_handler(record=data, exception=sys.exc_info())
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Batch processing exceptions
|
|
3
3
|
"""
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
4
6
|
import traceback
|
|
5
7
|
from types import TracebackType
|
|
6
8
|
from typing import List, Optional, Tuple, Type
|
|
@@ -9,10 +11,10 @@ ExceptionInfo = Tuple[Optional[Type[BaseException]], Optional[BaseException], Op
|
|
|
9
11
|
|
|
10
12
|
|
|
11
13
|
class BaseBatchProcessingError(Exception):
|
|
12
|
-
def __init__(self, msg="", child_exceptions:
|
|
14
|
+
def __init__(self, msg="", child_exceptions: List[ExceptionInfo] | None = None):
|
|
13
15
|
super().__init__(msg)
|
|
14
16
|
self.msg = msg
|
|
15
|
-
self.child_exceptions = child_exceptions
|
|
17
|
+
self.child_exceptions = child_exceptions or []
|
|
16
18
|
|
|
17
19
|
def format_exceptions(self, parent_exception_str):
|
|
18
20
|
exception_list = [f"{parent_exception_str}\n"]
|
|
@@ -27,7 +29,7 @@ class BaseBatchProcessingError(Exception):
|
|
|
27
29
|
class BatchProcessingError(BaseBatchProcessingError):
|
|
28
30
|
"""When all batch records failed to be processed"""
|
|
29
31
|
|
|
30
|
-
def __init__(self, msg="", child_exceptions:
|
|
32
|
+
def __init__(self, msg="", child_exceptions: List[ExceptionInfo] | None = None):
|
|
31
33
|
super().__init__(msg, child_exceptions)
|
|
32
34
|
|
|
33
35
|
def __str__(self):
|
|
@@ -21,8 +21,9 @@ class APIGatewayRouteArn:
|
|
|
21
21
|
stage: str,
|
|
22
22
|
http_method: str,
|
|
23
23
|
resource: str,
|
|
24
|
+
partition: str = "aws",
|
|
24
25
|
):
|
|
25
|
-
self.partition =
|
|
26
|
+
self.partition = partition
|
|
26
27
|
self.region = region
|
|
27
28
|
self.aws_account_id = aws_account_id
|
|
28
29
|
self.api_id = api_id
|
|
@@ -55,6 +56,7 @@ def parse_api_gateway_arn(arn: str) -> APIGatewayRouteArn:
|
|
|
55
56
|
arn_parts = arn.split(":")
|
|
56
57
|
api_gateway_arn_parts = arn_parts[5].split("/")
|
|
57
58
|
return APIGatewayRouteArn(
|
|
59
|
+
partition=arn_parts[1],
|
|
58
60
|
region=arn_parts[3],
|
|
59
61
|
aws_account_id=arn_parts[4],
|
|
60
62
|
api_id=api_gateway_arn_parts[0],
|
|
@@ -369,6 +371,7 @@ class APIGatewayAuthorizerResponse:
|
|
|
369
371
|
stage: str,
|
|
370
372
|
context: Optional[Dict] = None,
|
|
371
373
|
usage_identifier_key: Optional[str] = None,
|
|
374
|
+
partition: str = "aws",
|
|
372
375
|
):
|
|
373
376
|
"""
|
|
374
377
|
Parameters
|
|
@@ -401,6 +404,9 @@ class APIGatewayAuthorizerResponse:
|
|
|
401
404
|
If the API uses a usage plan (the apiKeySource is set to `AUTHORIZER`), the Lambda authorizer function
|
|
402
405
|
must return one of the usage plan's API keys as the usageIdentifierKey property value.
|
|
403
406
|
> **Note:** This only applies for REST APIs.
|
|
407
|
+
partition: str, optional
|
|
408
|
+
Optional, arn partition.
|
|
409
|
+
See https://docs.aws.amazon.com/IAM/latest/UserGuide/reference-arns.html
|
|
404
410
|
"""
|
|
405
411
|
self.principal_id = principal_id
|
|
406
412
|
self.region = region
|
|
@@ -412,6 +418,7 @@ class APIGatewayAuthorizerResponse:
|
|
|
412
418
|
self._allow_routes: List[Dict] = []
|
|
413
419
|
self._deny_routes: List[Dict] = []
|
|
414
420
|
self._resource_pattern = re.compile(self.path_regex)
|
|
421
|
+
self.partition = partition
|
|
415
422
|
|
|
416
423
|
@staticmethod
|
|
417
424
|
def from_route_arn(
|
|
@@ -443,7 +450,7 @@ class APIGatewayAuthorizerResponse:
|
|
|
443
450
|
raise ValueError(f"Invalid resource path: {resource}. Path should match {self.path_regex}")
|
|
444
451
|
|
|
445
452
|
resource_arn = APIGatewayRouteArn(
|
|
446
|
-
self.region, self.aws_account_id, self.api_id, self.stage, http_method, resource
|
|
453
|
+
self.region, self.aws_account_id, self.api_id, self.stage, http_method, resource, self.partition
|
|
447
454
|
).arn
|
|
448
455
|
|
|
449
456
|
route = {"resourceArn": resource_arn, "conditions": conditions}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import base64
|
|
2
2
|
import json
|
|
3
3
|
from collections.abc import Mapping
|
|
4
|
-
from typing import Any, Dict, Iterator, Optional
|
|
4
|
+
from typing import Any, Callable, Dict, Iterator, List, Optional
|
|
5
5
|
|
|
6
6
|
from aws_lambda_powertools.shared.headers_serializer import BaseHeadersSerializer
|
|
7
7
|
|
|
@@ -9,9 +9,19 @@ from aws_lambda_powertools.shared.headers_serializer import BaseHeadersSerialize
|
|
|
9
9
|
class DictWrapper(Mapping):
|
|
10
10
|
"""Provides a single read only access to a wrapper dict"""
|
|
11
11
|
|
|
12
|
-
def __init__(self, data: Dict[str, Any]):
|
|
12
|
+
def __init__(self, data: Dict[str, Any], json_deserializer: Optional[Callable] = None):
|
|
13
|
+
"""
|
|
14
|
+
Parameters
|
|
15
|
+
----------
|
|
16
|
+
data : Dict[str, Any]
|
|
17
|
+
Lambda Event Source Event payload
|
|
18
|
+
json_deserializer : Callable, optional
|
|
19
|
+
function to deserialize `str`, `bytes`, bytearray` containing a JSON document to a Python `obj`,
|
|
20
|
+
by default json.loads
|
|
21
|
+
"""
|
|
13
22
|
self._data = data
|
|
14
23
|
self._json_data: Optional[Any] = None
|
|
24
|
+
self._json_deserializer = json_deserializer or json.loads
|
|
15
25
|
|
|
16
26
|
def __getitem__(self, key: str) -> Any:
|
|
17
27
|
return self._data[key]
|
|
@@ -28,6 +38,49 @@ class DictWrapper(Mapping):
|
|
|
28
38
|
def __len__(self) -> int:
|
|
29
39
|
return len(self._data)
|
|
30
40
|
|
|
41
|
+
def __str__(self) -> str:
|
|
42
|
+
return str(self._str_helper())
|
|
43
|
+
|
|
44
|
+
def _str_helper(self) -> Dict[str, Any]:
|
|
45
|
+
"""
|
|
46
|
+
Recursively get a Dictionary of DictWrapper properties primarily
|
|
47
|
+
for use by __str__ for debugging purposes.
|
|
48
|
+
|
|
49
|
+
Will remove "raw_event" properties, and any defined by the Data Class
|
|
50
|
+
`_sensitive_properties` list field.
|
|
51
|
+
This should be used in case where secrets, such as access keys, are
|
|
52
|
+
stored in the Data Class but should not be logged out.
|
|
53
|
+
"""
|
|
54
|
+
properties = self._properties()
|
|
55
|
+
sensitive_properties = ["raw_event"]
|
|
56
|
+
if hasattr(self, "_sensitive_properties"):
|
|
57
|
+
sensitive_properties.extend(self._sensitive_properties) # pyright: ignore
|
|
58
|
+
|
|
59
|
+
result: Dict[str, Any] = {}
|
|
60
|
+
for property_key in properties:
|
|
61
|
+
if property_key in sensitive_properties:
|
|
62
|
+
result[property_key] = "[SENSITIVE]"
|
|
63
|
+
else:
|
|
64
|
+
try:
|
|
65
|
+
property_value = getattr(self, property_key)
|
|
66
|
+
result[property_key] = property_value
|
|
67
|
+
|
|
68
|
+
# Checks whether the class is a subclass of the parent class to perform a recursive operation.
|
|
69
|
+
if issubclass(property_value.__class__, DictWrapper):
|
|
70
|
+
result[property_key] = property_value._str_helper()
|
|
71
|
+
# Checks if the key is a list and if it is a subclass of the parent class
|
|
72
|
+
elif isinstance(property_value, list):
|
|
73
|
+
for seq, item in enumerate(property_value):
|
|
74
|
+
if issubclass(item.__class__, DictWrapper):
|
|
75
|
+
result[property_key][seq] = item._str_helper()
|
|
76
|
+
except Exception:
|
|
77
|
+
result[property_key] = "[Cannot be deserialized]"
|
|
78
|
+
|
|
79
|
+
return result
|
|
80
|
+
|
|
81
|
+
def _properties(self) -> List[str]:
|
|
82
|
+
return [p for p in dir(self.__class__) if isinstance(getattr(self.__class__, p), property)]
|
|
83
|
+
|
|
31
84
|
def get(self, key: str, default: Optional[Any] = None) -> Optional[Any]:
|
|
32
85
|
return self._data.get(key, default)
|
|
33
86
|
|
|
@@ -79,7 +132,7 @@ class BaseProxyEvent(DictWrapper):
|
|
|
79
132
|
def json_body(self) -> Any:
|
|
80
133
|
"""Parses the submitted body as json"""
|
|
81
134
|
if self._json_data is None:
|
|
82
|
-
self._json_data =
|
|
135
|
+
self._json_data = self._json_deserializer(self.decoded_body)
|
|
83
136
|
return self._json_data
|
|
84
137
|
|
|
85
138
|
@property
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import base64
|
|
2
|
-
import json
|
|
3
2
|
from typing import Any, Dict, Iterator, List, Optional
|
|
4
3
|
|
|
5
4
|
from aws_lambda_powertools.utilities.data_classes.common import DictWrapper
|
|
@@ -55,7 +54,7 @@ class KafkaEventRecord(DictWrapper):
|
|
|
55
54
|
def json_value(self) -> Any:
|
|
56
55
|
"""Decodes the text encoded data as JSON."""
|
|
57
56
|
if self._json_data is None:
|
|
58
|
-
self._json_data =
|
|
57
|
+
self._json_data = self._json_deserializer(self.decoded_value.decode("utf-8"))
|
|
59
58
|
return self._json_data
|
|
60
59
|
|
|
61
60
|
@property
|
|
@@ -117,7 +116,7 @@ class KafkaEvent(DictWrapper):
|
|
|
117
116
|
"""The Kafka records."""
|
|
118
117
|
for chunk in self["records"].values():
|
|
119
118
|
for record in chunk:
|
|
120
|
-
yield KafkaEventRecord(record)
|
|
119
|
+
yield KafkaEventRecord(data=record, json_deserializer=self._json_deserializer)
|
|
121
120
|
|
|
122
121
|
@property
|
|
123
122
|
def record(self) -> KafkaEventRecord:
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import base64
|
|
2
|
-
import json
|
|
3
2
|
from typing import Iterator, Optional
|
|
4
3
|
|
|
5
4
|
from aws_lambda_powertools.utilities.data_classes.common import DictWrapper
|
|
@@ -75,7 +74,7 @@ class KinesisFirehoseRecord(DictWrapper):
|
|
|
75
74
|
def data_as_json(self) -> dict:
|
|
76
75
|
"""Decoded base64-encoded data loaded to json"""
|
|
77
76
|
if self._json_data is None:
|
|
78
|
-
self._json_data =
|
|
77
|
+
self._json_data = self._json_deserializer(self.data_as_text)
|
|
79
78
|
return self._json_data
|
|
80
79
|
|
|
81
80
|
|
|
@@ -110,4 +109,4 @@ class KinesisFirehoseEvent(DictWrapper):
|
|
|
110
109
|
@property
|
|
111
110
|
def records(self) -> Iterator[KinesisFirehoseRecord]:
|
|
112
111
|
for record in self["records"]:
|
|
113
|
-
yield KinesisFirehoseRecord(record)
|
|
112
|
+
yield KinesisFirehoseRecord(data=record, json_deserializer=self._json_deserializer)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Dict, Iterator, Optional
|
|
1
|
+
from typing import Any, Dict, Iterator, Optional
|
|
2
2
|
|
|
3
3
|
from aws_lambda_powertools.utilities.data_classes.common import DictWrapper
|
|
4
4
|
|
|
@@ -103,6 +103,35 @@ class SQSRecord(DictWrapper):
|
|
|
103
103
|
"""The message's contents (not URL-encoded)."""
|
|
104
104
|
return self["body"]
|
|
105
105
|
|
|
106
|
+
@property
|
|
107
|
+
def json_body(self) -> Any:
|
|
108
|
+
"""Deserializes JSON string available in 'body' property
|
|
109
|
+
|
|
110
|
+
Notes
|
|
111
|
+
-----
|
|
112
|
+
|
|
113
|
+
**Strict typing**
|
|
114
|
+
|
|
115
|
+
Caller controls the type as we can't use recursive generics here.
|
|
116
|
+
|
|
117
|
+
JSON Union types would force caller to have to cast a type. Instead,
|
|
118
|
+
we choose Any to ease ergonomics and other tools receiving this data.
|
|
119
|
+
|
|
120
|
+
Examples
|
|
121
|
+
--------
|
|
122
|
+
|
|
123
|
+
**Type deserialized data from JSON string**
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
data: dict = record.json_body # {"telemetry": [], ...}
|
|
127
|
+
# or
|
|
128
|
+
data: list = record.json_body # ["telemetry_values"]
|
|
129
|
+
```
|
|
130
|
+
"""
|
|
131
|
+
if self._json_data is None:
|
|
132
|
+
self._json_data = self._json_deserializer(self["body"])
|
|
133
|
+
return self._json_data
|
|
134
|
+
|
|
106
135
|
@property
|
|
107
136
|
def attributes(self) -> SQSRecordAttributes:
|
|
108
137
|
"""A map of the attributes requested in ReceiveMessage to their respective values."""
|
|
@@ -133,6 +162,18 @@ class SQSRecord(DictWrapper):
|
|
|
133
162
|
"""aws region eg: us-east-1"""
|
|
134
163
|
return self["awsRegion"]
|
|
135
164
|
|
|
165
|
+
@property
|
|
166
|
+
def queue_url(self) -> str:
|
|
167
|
+
"""The URL of the queue."""
|
|
168
|
+
arn_parts = self["eventSourceARN"].split(":")
|
|
169
|
+
region = arn_parts[3]
|
|
170
|
+
account_id = arn_parts[4]
|
|
171
|
+
queue_name = arn_parts[5]
|
|
172
|
+
|
|
173
|
+
queue_url = f"https://sqs.{region}.amazonaws.com/{account_id}/{queue_name}"
|
|
174
|
+
|
|
175
|
+
return queue_url
|
|
176
|
+
|
|
136
177
|
|
|
137
178
|
class SQSEvent(DictWrapper):
|
|
138
179
|
"""SQS Event
|
|
@@ -145,4 +186,4 @@ class SQSEvent(DictWrapper):
|
|
|
145
186
|
@property
|
|
146
187
|
def records(self) -> Iterator[SQSRecord]:
|
|
147
188
|
for record in self["Records"]:
|
|
148
|
-
yield SQSRecord(record)
|
|
189
|
+
yield SQSRecord(data=record, json_deserializer=self._json_deserializer)
|
|
@@ -6,3 +6,8 @@ EVENTBRIDGE = "detail"
|
|
|
6
6
|
CLOUDWATCH_EVENTS_SCHEDULED = EVENTBRIDGE
|
|
7
7
|
KINESIS_DATA_STREAM = "Records[*].kinesis.powertools_json(powertools_base64(data))"
|
|
8
8
|
CLOUDWATCH_LOGS = "awslogs.powertools_base64_gzip(data) | powertools_json(@).logEvents[*]"
|
|
9
|
+
S3_SNS_SQS = "Records[*].powertools_json(body).powertools_json(Message).Records[0]"
|
|
10
|
+
S3_SQS = "Records[*].powertools_json(body).Records[0]"
|
|
11
|
+
S3_SNS_KINESIS_FIREHOSE = "records[*].powertools_json(powertools_base64(data)).powertools_json(Message).Records[0]"
|
|
12
|
+
S3_KINESIS_FIREHOSE = "records[*].powertools_json(powertools_base64(data)).Records[0]"
|
|
13
|
+
S3_EVENTBRIDGE_SQS = "Records[*].powertools_json(body).detail"
|
|
@@ -50,6 +50,10 @@ from .s3 import (
|
|
|
50
50
|
S3Model,
|
|
51
51
|
S3RecordModel,
|
|
52
52
|
)
|
|
53
|
+
from .s3_event_notification import (
|
|
54
|
+
S3SqsEventNotificationModel,
|
|
55
|
+
S3SqsEventNotificationRecordModel,
|
|
56
|
+
)
|
|
53
57
|
from .s3_object_event import (
|
|
54
58
|
S3ObjectConfiguration,
|
|
55
59
|
S3ObjectContext,
|
|
@@ -130,6 +134,8 @@ __all__ = [
|
|
|
130
134
|
"SqsRecordModel",
|
|
131
135
|
"SqsMsgAttributeModel",
|
|
132
136
|
"SqsAttributesModel",
|
|
137
|
+
"S3SqsEventNotificationModel",
|
|
138
|
+
"S3SqsEventNotificationRecordModel",
|
|
133
139
|
"APIGatewayProxyEventModel",
|
|
134
140
|
"APIGatewayEventRequestContext",
|
|
135
141
|
"APIGatewayEventAuthorizer",
|
aws_lambda_powertools-2.15.0/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from typing import List
|
|
2
|
+
|
|
3
|
+
from pydantic import Json
|
|
4
|
+
|
|
5
|
+
from aws_lambda_powertools.utilities.parser.models.s3 import S3Model
|
|
6
|
+
from aws_lambda_powertools.utilities.parser.models.sqs import SqsModel, SqsRecordModel
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class S3SqsEventNotificationRecordModel(SqsRecordModel):
|
|
10
|
+
body: Json[S3Model]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class S3SqsEventNotificationModel(SqsModel):
|
|
14
|
+
Records: List[S3SqsEventNotificationRecordModel]
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from datetime import datetime
|
|
2
|
-
from typing import Dict, List, Optional, Type, Union
|
|
2
|
+
from typing import Dict, List, Optional, Sequence, Type, Union
|
|
3
3
|
|
|
4
4
|
from pydantic import BaseModel
|
|
5
5
|
|
|
@@ -63,4 +63,4 @@ class SqsRecordModel(BaseModel):
|
|
|
63
63
|
|
|
64
64
|
|
|
65
65
|
class SqsModel(BaseModel):
|
|
66
|
-
Records:
|
|
66
|
+
Records: Sequence[SqsRecordModel]
|