aws-lambda-powertools 3.34.0__tar.gz → 3.35.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-3.34.0 → aws_lambda_powertools-3.35.0}/PKG-INFO +1 -1
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/api_gateway.py +43 -7
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/http_resolver.py +68 -13
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/openapi/schema_generator.py +1 -1
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/metrics/metrics.py +1 -4
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/metrics/provider/cloudwatch_emf/cloudwatch.py +2 -2
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/shared/version.py +1 -1
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/batch/exceptions.py +2 -2
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/batch/types.py +5 -4
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/api_gateway_authorizer_event.py +5 -2
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_masking/base.py +23 -24
- aws_lambda_powertools-3.35.0/aws_lambda_powertools/utilities/data_masking/exceptions.py +40 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_masking/provider/base.py +3 -2
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/feature_flags/appconfig.py +11 -1
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/feature_flags/comparators.py +7 -2
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/feature_flags/constants.py +1 -1
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/feature_flags/feature_flags.py +43 -6
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/feature_flags/schema.py +40 -4
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/idempotency/persistence/base.py +4 -1
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/idempotency/persistence/redis.py +6 -4
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/kafka/consumer_records.py +6 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/kafka/deserializer/avro.py +35 -2
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/kafka/deserializer/deserializer.py +20 -6
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/kafka/schema_config.py +26 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parameters/ssm.py +6 -1
- aws_lambda_powertools-3.35.0/aws_lambda_powertools/utilities/parser/__init__.py +44 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/models/apigw.py +36 -36
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/models/apigw_websocket.py +3 -3
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/models/apigwv2.py +20 -20
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/models/appsync.py +10 -10
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/models/appsync_events.py +6 -6
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/models/bedrock_agent.py +4 -4
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/models/cloudwatch.py +2 -2
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/models/cognito.py +42 -42
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/models/dynamodb.py +6 -6
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/models/event_bridge.py +2 -2
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/models/iot_registry_events.py +6 -6
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/models/kafka.py +4 -4
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/models/kinesis_firehose.py +3 -3
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/models/kinesis_firehose_sqs.py +3 -3
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/models/s3.py +19 -19
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/models/s3_batch_operation.py +5 -5
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/models/s3_object_event.py +4 -4
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/models/ses.py +5 -5
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/models/sns.py +6 -6
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/models/sqs.py +9 -9
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/models/transfer_family.py +2 -2
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/models/vpc_latticev2.py +14 -14
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/streaming/_s3_seekable_io.py +4 -2
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/pyproject.toml +3 -3
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/setup.py +1 -1
- aws_lambda_powertools-3.34.0/aws_lambda_powertools/utilities/data_masking/exceptions.py +0 -34
- aws_lambda_powertools-3.34.0/aws_lambda_powertools/utilities/parser/__init__.py +0 -19
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/LICENSE +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/README.md +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/THIRD-PARTY-LICENSES +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/appsync.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/bedrock_agent.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/bedrock_agent_function.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/content_types.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/depends.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/events_appsync/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/events_appsync/_registry.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/events_appsync/appsync_events.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/events_appsync/base.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/events_appsync/exceptions.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/events_appsync/functions.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/events_appsync/router.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/events_appsync/types.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/exception_handling.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/exceptions.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/graphql_appsync/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/graphql_appsync/_registry.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/graphql_appsync/base.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/graphql_appsync/exceptions.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/graphql_appsync/router.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/lambda_function_url.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/middlewares/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/middlewares/async_utils.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/middlewares/base.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/middlewares/openapi_validation.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/middlewares/schema_validation.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/openapi/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/openapi/compat.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/openapi/config.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/openapi/constants.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/openapi/dependant.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/openapi/encoders.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/openapi/exceptions.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/openapi/merge.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/openapi/models.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/openapi/params.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/openapi/pydantic_loader.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/openapi/swagger_ui/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/openapi/swagger_ui/html.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/openapi/swagger_ui/oauth2.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/openapi/swagger_ui/swagger-ui-bundle.min.js +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/openapi/swagger_ui/swagger-ui.min.css +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/openapi/types.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/request.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/router.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/types.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/util.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/event_handler/vpc_lattice.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/exceptions/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/logging/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/logging/buffer/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/logging/buffer/cache.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/logging/buffer/config.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/logging/buffer/functions.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/logging/buffer/handler.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/logging/constants.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/logging/correlation_paths.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/logging/exceptions.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/logging/filters.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/logging/formatter.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/logging/formatters/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/logging/formatters/datadog.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/logging/lambda_context.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/logging/logger.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/logging/types.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/logging/utils.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/metrics/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/metrics/base.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/metrics/exceptions.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/metrics/functions.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/metrics/metric.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/metrics/provider/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/metrics/provider/base.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/metrics/provider/cloudwatch_emf/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/metrics/provider/cloudwatch_emf/constants.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/metrics/provider/cloudwatch_emf/exceptions.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/metrics/provider/cloudwatch_emf/metric_properties.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/metrics/provider/cloudwatch_emf/types.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/metrics/provider/cold_start.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/metrics/provider/datadog/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/metrics/provider/datadog/datadog.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/metrics/provider/datadog/metrics.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/metrics/provider/datadog/warnings.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/metrics/types.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/middleware_factory/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/middleware_factory/exceptions.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/middleware_factory/factory.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/package_logger.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/py.typed +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/shared/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/shared/cache_dict.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/shared/constants.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/shared/cookies.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/shared/dynamodb_deserializer.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/shared/functions.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/shared/headers_serializer.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/shared/json_encoder.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/shared/lazy_import.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/shared/types.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/shared/user_agent.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/tracing/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/tracing/base.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/tracing/extensions.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/tracing/tracer.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/batch/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/batch/base.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/batch/decorators.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/batch/sqs_fifo_partial_processor.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/circuit_breaker/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/circuit_breaker/base.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/circuit_breaker/circuit_breaker.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/circuit_breaker/config.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/circuit_breaker/exceptions.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/circuit_breaker/persistence/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/circuit_breaker/persistence/base.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/circuit_breaker/persistence/dynamodb.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/circuit_breaker/persistence/record.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/circuit_breaker/states.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/active_mq_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/alb_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/api_gateway_websocket_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/appsync/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/appsync/scalar_types_utils.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/appsync_authorizer_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/appsync_resolver_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/appsync_resolver_events_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/aws_config_rule_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/bedrock_agent_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/bedrock_agent_function_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/cloud_watch_alarm_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/cloud_watch_custom_widget_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/cloud_watch_logs_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/cloudformation_custom_resource_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/code_deploy_lifecycle_hook_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/code_pipeline_job_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/cognito_user_pool_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/common.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/connect_contact_flow_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/dynamo_db_stream_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/event_bridge_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/event_source.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/iot_registry_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/kafka_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/kinesis_stream_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/lambda_function_url_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/rabbit_mq_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/s3_batch_operation_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/s3_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/s3_object_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/secrets_manager_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/ses_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/shared_functions.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/sns_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/sqs_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/transfer_family_event.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_classes/vpc_lattice.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_masking/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_masking/constants.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_masking/provider/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_masking/provider/kms/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/data_masking/provider/kms/aws_encryption_sdk.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/feature_flags/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/feature_flags/base.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/feature_flags/exceptions.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/feature_flags/types.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/idempotency/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/idempotency/base.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/idempotency/config.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/idempotency/exceptions.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/idempotency/hook.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/idempotency/idempotency.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/idempotency/persistence/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/idempotency/persistence/cache.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/idempotency/persistence/datarecord.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/idempotency/serialization/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/idempotency/serialization/base.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/idempotency/serialization/custom_dict.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/idempotency/serialization/dataclass.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/idempotency/serialization/functions.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/idempotency/serialization/no_op.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/idempotency/serialization/pydantic.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/jmespath_utils/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/jmespath_utils/envelopes.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/kafka/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/kafka/deserializer/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/kafka/deserializer/base.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/kafka/deserializer/default.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/kafka/deserializer/json.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/kafka/deserializer/protobuf.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/kafka/exceptions.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/kafka/kafka_consumer.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/kafka/serialization/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/kafka/serialization/base.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/kafka/serialization/custom_dict.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/kafka/serialization/dataclass.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/kafka/serialization/pydantic.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/kafka/serialization/serialization.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/kafka/serialization/types.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/metadata/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/metadata/exceptions.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/metadata/lambda_metadata.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parameters/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parameters/appconfig.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parameters/base.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parameters/constants.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parameters/dynamodb.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parameters/exceptions.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parameters/secrets.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parameters/types.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/envelopes/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/envelopes/apigw.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/envelopes/apigw_websocket.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/envelopes/apigwv2.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/envelopes/base.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/envelopes/bedrock_agent.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/envelopes/cloudwatch.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/envelopes/dynamodb.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/envelopes/event_bridge.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/envelopes/kafka.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/envelopes/kinesis.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/envelopes/kinesis_firehose.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/envelopes/lambda_function_url.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/envelopes/sns.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/envelopes/sqs.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/envelopes/vpc_lattice.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/envelopes/vpc_latticev2.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/exceptions.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/functions.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/models/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/models/alb.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/models/cloudformation_custom_resource.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/models/kinesis.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/models/lambda_function_url.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/models/vpc_lattice.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/parser.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/parser/types.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/serialization.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/streaming/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/streaming/compat.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/streaming/constants.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/streaming/s3_object.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/streaming/transformations/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/streaming/transformations/base.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/streaming/transformations/csv.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/streaming/transformations/gzip.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/streaming/transformations/zip.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/streaming/types.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/typing/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/typing/lambda_client_context.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/typing/lambda_client_context_mobile_client.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/typing/lambda_cognito_identity.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/typing/lambda_context.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/validation/__init__.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/validation/base.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/validation/envelopes.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/validation/exceptions.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/utilities/validation/validator.py +0 -0
- {aws_lambda_powertools-3.34.0 → aws_lambda_powertools-3.35.0}/aws_lambda_powertools/warnings/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: aws_lambda_powertools
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.35.0
|
|
4
4
|
Summary: Powertools for AWS Lambda (Python) is a developer toolkit to implement Serverless best practices and increase developer velocity.
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: aws_lambda_powertools,aws,tracing,logging,lambda,powertools,feature_flags,idempotency,middleware
|
|
@@ -3035,21 +3035,18 @@ class ApiGatewayResolver(BaseRouter):
|
|
|
3035
3035
|
An optional prefix to be added to the originally defined rule
|
|
3036
3036
|
"""
|
|
3037
3037
|
|
|
3038
|
-
# Add reference to parent ApiGatewayResolver to support use cases where people subclass it to add custom logic
|
|
3039
|
-
router.api_resolver = self
|
|
3040
|
-
|
|
3041
3038
|
logger.debug("Merging App context with Router context")
|
|
3042
3039
|
self.context.update(**router.context)
|
|
3043
3040
|
|
|
3041
|
+
# Delegate request state to the resolver after preserving the router context.
|
|
3042
|
+
router.api_resolver = self
|
|
3043
|
+
|
|
3044
3044
|
logger.debug("Appending Router middlewares into App middlewares.")
|
|
3045
3045
|
self._router_middlewares = self._router_middlewares + router._router_middlewares
|
|
3046
3046
|
|
|
3047
3047
|
logger.debug("Appending Router exception_handler into App exception_handler.")
|
|
3048
3048
|
self.exception_handler_manager.update_exception_handlers(router._exception_handlers)
|
|
3049
3049
|
|
|
3050
|
-
# use pointer to allow context clearance after event is processed e.g., resolve(evt, ctx)
|
|
3051
|
-
router.context = self.context
|
|
3052
|
-
|
|
3053
3050
|
# Iterate through the routes defined in the router to configure and apply middlewares for each route
|
|
3054
3051
|
for route, func in router._routes.items():
|
|
3055
3052
|
new_route = route
|
|
@@ -3112,9 +3109,48 @@ class Router(BaseRouter):
|
|
|
3112
3109
|
self._routes: dict[tuple, Callable] = {}
|
|
3113
3110
|
self._routes_with_middleware: dict[tuple, list[Callable]] = {}
|
|
3114
3111
|
self.api_resolver: BaseRouter | None = None
|
|
3115
|
-
self.
|
|
3112
|
+
self._context: dict = {} # early init as customers might add context before event resolution
|
|
3116
3113
|
self._exception_handlers: dict[type, Callable] = {}
|
|
3117
3114
|
|
|
3115
|
+
@property
|
|
3116
|
+
def current_event(self) -> BaseProxyEvent:
|
|
3117
|
+
if self.api_resolver is not None:
|
|
3118
|
+
return self.api_resolver.current_event
|
|
3119
|
+
return BaseRouter.current_event
|
|
3120
|
+
|
|
3121
|
+
@current_event.setter
|
|
3122
|
+
def current_event(self, value: BaseProxyEvent) -> None:
|
|
3123
|
+
if self.api_resolver is not None:
|
|
3124
|
+
self.api_resolver.current_event = value
|
|
3125
|
+
else:
|
|
3126
|
+
BaseRouter.current_event = value
|
|
3127
|
+
|
|
3128
|
+
@property
|
|
3129
|
+
def lambda_context(self) -> LambdaContext:
|
|
3130
|
+
if self.api_resolver is not None:
|
|
3131
|
+
return self.api_resolver.lambda_context
|
|
3132
|
+
return BaseRouter.lambda_context
|
|
3133
|
+
|
|
3134
|
+
@lambda_context.setter
|
|
3135
|
+
def lambda_context(self, value: LambdaContext) -> None:
|
|
3136
|
+
if self.api_resolver is not None:
|
|
3137
|
+
self.api_resolver.lambda_context = value
|
|
3138
|
+
else:
|
|
3139
|
+
BaseRouter.lambda_context = value
|
|
3140
|
+
|
|
3141
|
+
@property
|
|
3142
|
+
def context(self) -> dict:
|
|
3143
|
+
if self.api_resolver is not None:
|
|
3144
|
+
return self.api_resolver.context
|
|
3145
|
+
return self._context
|
|
3146
|
+
|
|
3147
|
+
@context.setter
|
|
3148
|
+
def context(self, value: dict) -> None:
|
|
3149
|
+
if self.api_resolver is not None:
|
|
3150
|
+
self.api_resolver.context = value
|
|
3151
|
+
else:
|
|
3152
|
+
self._context = value
|
|
3153
|
+
|
|
3118
3154
|
def route(
|
|
3119
3155
|
self,
|
|
3120
3156
|
rule: str,
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import base64
|
|
4
|
+
from contextvars import ContextVar
|
|
5
|
+
from dataclasses import dataclass, field
|
|
4
6
|
from typing import TYPE_CHECKING, Any, Callable
|
|
5
7
|
from urllib.parse import parse_qs
|
|
6
8
|
|
|
@@ -13,6 +15,8 @@ from aws_lambda_powertools.shared.headers_serializer import BaseHeadersSerialize
|
|
|
13
15
|
from aws_lambda_powertools.utilities.data_classes.common import BaseProxyEvent
|
|
14
16
|
|
|
15
17
|
if TYPE_CHECKING:
|
|
18
|
+
from collections.abc import Mapping, MutableMapping
|
|
19
|
+
|
|
16
20
|
from aws_lambda_powertools.shared.cookies import Cookie
|
|
17
21
|
|
|
18
22
|
|
|
@@ -95,7 +99,7 @@ class HttpProxyEvent(BaseProxyEvent):
|
|
|
95
99
|
return instance
|
|
96
100
|
|
|
97
101
|
@classmethod
|
|
98
|
-
def from_asgi(cls, scope:
|
|
102
|
+
def from_asgi(cls, scope: Mapping[str, Any], body: bytes | None = None) -> HttpProxyEvent:
|
|
99
103
|
"""
|
|
100
104
|
Create an HttpProxyEvent from an ASGI scope dict.
|
|
101
105
|
|
|
@@ -159,6 +163,14 @@ class MockLambdaContext:
|
|
|
159
163
|
return 300000 # 5 minutes
|
|
160
164
|
|
|
161
165
|
|
|
166
|
+
@dataclass
|
|
167
|
+
class _RequestState:
|
|
168
|
+
event: BaseProxyEvent | None = None
|
|
169
|
+
lambda_context: Any = None
|
|
170
|
+
context: dict = field(default_factory=dict)
|
|
171
|
+
processed_stack_frames: list[str] = field(default_factory=list)
|
|
172
|
+
|
|
173
|
+
|
|
162
174
|
class HttpResolverLocal(ApiGatewayResolver):
|
|
163
175
|
"""
|
|
164
176
|
ASGI-compatible HTTP resolver.
|
|
@@ -204,6 +216,8 @@ class HttpResolverLocal(ApiGatewayResolver):
|
|
|
204
216
|
strip_prefixes: list[str | Any] | None = None,
|
|
205
217
|
enable_validation: bool = False,
|
|
206
218
|
):
|
|
219
|
+
self._startup_state = _RequestState()
|
|
220
|
+
self._request_state: ContextVar[_RequestState | None] = ContextVar("local_http_request", default=None)
|
|
207
221
|
super().__init__(
|
|
208
222
|
proxy_type=ProxyEventType.APIGatewayProxyEvent, # Use REST API format internally
|
|
209
223
|
cors=cors,
|
|
@@ -212,7 +226,46 @@ class HttpResolverLocal(ApiGatewayResolver):
|
|
|
212
226
|
strip_prefixes=strip_prefixes,
|
|
213
227
|
enable_validation=enable_validation,
|
|
214
228
|
)
|
|
215
|
-
|
|
229
|
+
|
|
230
|
+
@property
|
|
231
|
+
def _state(self) -> _RequestState:
|
|
232
|
+
return self._request_state.get() or self._startup_state
|
|
233
|
+
|
|
234
|
+
# Powertools declares these as mutable attributes. Properties preserve that
|
|
235
|
+
# interface while directing each task to its own state. asyncio.to_thread
|
|
236
|
+
# propagates the ContextVar, so middleware sees the same request dictionary.
|
|
237
|
+
@property
|
|
238
|
+
def current_event(self) -> BaseProxyEvent:
|
|
239
|
+
# Preserve the inherited synchronous resolve() path outside ASGI calls.
|
|
240
|
+
return self._state.event or BaseRouter.current_event
|
|
241
|
+
|
|
242
|
+
@current_event.setter
|
|
243
|
+
def current_event(self, value: BaseProxyEvent) -> None:
|
|
244
|
+
self._state.event = value
|
|
245
|
+
|
|
246
|
+
@property
|
|
247
|
+
def lambda_context(self) -> Any:
|
|
248
|
+
return self._state.lambda_context or BaseRouter.lambda_context
|
|
249
|
+
|
|
250
|
+
@lambda_context.setter
|
|
251
|
+
def lambda_context(self, value: Any) -> None:
|
|
252
|
+
self._state.lambda_context = value
|
|
253
|
+
|
|
254
|
+
@property
|
|
255
|
+
def context(self) -> dict:
|
|
256
|
+
return self._state.context
|
|
257
|
+
|
|
258
|
+
@context.setter
|
|
259
|
+
def context(self, value: dict) -> None:
|
|
260
|
+
self._state.context = value
|
|
261
|
+
|
|
262
|
+
@property
|
|
263
|
+
def processed_stack_frames(self) -> list[str]:
|
|
264
|
+
return self._state.processed_stack_frames
|
|
265
|
+
|
|
266
|
+
@processed_stack_frames.setter
|
|
267
|
+
def processed_stack_frames(self, value: list[str]) -> None:
|
|
268
|
+
self._state.processed_stack_frames = value
|
|
216
269
|
|
|
217
270
|
def _to_proxy_event(self, event: dict) -> BaseProxyEvent:
|
|
218
271
|
"""Convert event dict to HttpProxyEvent."""
|
|
@@ -234,7 +287,7 @@ class HttpResolverLocal(ApiGatewayResolver):
|
|
|
234
287
|
response_builder = await super()._resolve_async()
|
|
235
288
|
return response_builder.build(self.current_event, self._cors)
|
|
236
289
|
|
|
237
|
-
async def asgi_handler(self, scope:
|
|
290
|
+
async def asgi_handler(self, scope: MutableMapping[str, Any], receive: Callable, send: Callable) -> None:
|
|
238
291
|
"""
|
|
239
292
|
ASGI interface - allows running with uvicorn/hypercorn/etc.
|
|
240
293
|
|
|
@@ -274,25 +327,27 @@ class HttpResolverLocal(ApiGatewayResolver):
|
|
|
274
327
|
# Create mock Lambda context
|
|
275
328
|
context: Any = MockLambdaContext()
|
|
276
329
|
|
|
277
|
-
#
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
330
|
+
# Never write BaseRouter's class attributes: another ASGI request may
|
|
331
|
+
# enter while validation or the handler is awaiting I/O.
|
|
332
|
+
state = _RequestState(
|
|
333
|
+
event=self._to_proxy_event(event._data),
|
|
334
|
+
lambda_context=context,
|
|
335
|
+
context=self._startup_state.context.copy(),
|
|
336
|
+
)
|
|
337
|
+
token = self._request_state.set(state)
|
|
283
338
|
try:
|
|
284
|
-
# Use async resolve
|
|
285
339
|
response = await self._resolve_async()
|
|
286
340
|
finally:
|
|
287
|
-
|
|
288
|
-
|
|
341
|
+
# Reset only this task's binding. Middleware threads may still be
|
|
342
|
+
# unwinding after cancellation and retain their request's state.
|
|
343
|
+
self._request_state.reset(token)
|
|
289
344
|
|
|
290
345
|
# Send HTTP response
|
|
291
346
|
await self._send_response(send, response)
|
|
292
347
|
|
|
293
348
|
async def __call__( # type: ignore[override]
|
|
294
349
|
self,
|
|
295
|
-
scope:
|
|
350
|
+
scope: MutableMapping[str, Any],
|
|
296
351
|
receive: Callable,
|
|
297
352
|
send: Callable,
|
|
298
353
|
) -> None:
|
|
@@ -538,7 +538,7 @@ def _resolve_response_payload(
|
|
|
538
538
|
model_payload_typed = cast(OpenAPIResponseContentModel, payload)
|
|
539
539
|
return_field = next(
|
|
540
540
|
filter(
|
|
541
|
-
lambda model: model.type_
|
|
541
|
+
lambda model: model.type_ == model_payload_typed["model"],
|
|
542
542
|
dependant.response_extra_models,
|
|
543
543
|
),
|
|
544
544
|
)
|
|
@@ -174,7 +174,6 @@ class Metrics:
|
|
|
174
174
|
)
|
|
175
175
|
|
|
176
176
|
def set_default_dimensions(self, **dimensions) -> None:
|
|
177
|
-
self.provider.set_default_dimensions(**dimensions)
|
|
178
177
|
"""Persist dimensions across Lambda invocations
|
|
179
178
|
|
|
180
179
|
Parameters
|
|
@@ -195,9 +194,7 @@ class Metrics:
|
|
|
195
194
|
def lambda_handler():
|
|
196
195
|
return True
|
|
197
196
|
"""
|
|
198
|
-
|
|
199
|
-
self.add_dimension(name, value)
|
|
200
|
-
|
|
197
|
+
self.provider.set_default_dimensions(**dimensions)
|
|
201
198
|
self.default_dimensions.update(**dimensions)
|
|
202
199
|
|
|
203
200
|
def clear_default_dimensions(self) -> None:
|
|
@@ -87,7 +87,7 @@ class AmazonCloudWatchEMFProvider(BaseProvider):
|
|
|
87
87
|
):
|
|
88
88
|
self.metric_set = metric_set if metric_set is not None else {}
|
|
89
89
|
self.dimension_set = dimension_set if dimension_set is not None else {}
|
|
90
|
-
self.default_dimensions = default_dimensions
|
|
90
|
+
self.default_dimensions = default_dimensions if default_dimensions is not None else {}
|
|
91
91
|
self.namespace = resolve_env_var_choice(choice=namespace, env=os.getenv(constants.METRICS_NAMESPACE_ENV))
|
|
92
92
|
self.service = resolve_env_var_choice(choice=service, env=os.getenv(constants.SERVICE_NAME_ENV))
|
|
93
93
|
self.function_name = function_name
|
|
@@ -317,7 +317,7 @@ class AmazonCloudWatchEMFProvider(BaseProvider):
|
|
|
317
317
|
)
|
|
318
318
|
return
|
|
319
319
|
|
|
320
|
-
if name in self.dimension_set
|
|
320
|
+
if name in self.dimension_set and self.dimension_set[name] != value:
|
|
321
321
|
warnings.warn(
|
|
322
322
|
f"Dimension '{name}' has already been added. The previous value will be overwritten.",
|
|
323
323
|
category=PowertoolsUserWarning,
|
|
@@ -6,9 +6,9 @@ from __future__ import annotations
|
|
|
6
6
|
|
|
7
7
|
import traceback
|
|
8
8
|
from types import TracebackType
|
|
9
|
-
from typing import
|
|
9
|
+
from typing import Tuple, Type
|
|
10
10
|
|
|
11
|
-
ExceptionInfo = Tuple[
|
|
11
|
+
ExceptionInfo = Tuple[Type[BaseException] | None, BaseException | None, TracebackType | None]
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
class BaseBatchProcessingError(Exception):
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import sys
|
|
4
|
-
from typing import
|
|
4
|
+
from typing import Type, TypedDict, Union
|
|
5
5
|
|
|
6
6
|
has_pydantic = "pydantic" in sys.modules
|
|
7
7
|
|
|
@@ -14,15 +14,16 @@ if has_pydantic: # pragma: no cover
|
|
|
14
14
|
)
|
|
15
15
|
from aws_lambda_powertools.utilities.parser.models.kafka import KafkaRecordModel
|
|
16
16
|
|
|
17
|
-
BatchTypeModels =
|
|
17
|
+
BatchTypeModels = (
|
|
18
18
|
Union[
|
|
19
19
|
Type[SqsRecordModel],
|
|
20
20
|
Type[DynamoDBStreamRecordModel],
|
|
21
21
|
Type[KinesisDataStreamRecordModel],
|
|
22
22
|
Type[KafkaRecordModel],
|
|
23
23
|
]
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
| None
|
|
25
|
+
)
|
|
26
|
+
BatchSqsTypeModel = Type[SqsRecordModel] | None
|
|
26
27
|
else: # pragma: no cover
|
|
27
28
|
BatchTypeModels = "BatchTypeModels" # type: ignore
|
|
28
29
|
BatchSqsTypeModel = "BatchSqsTypeModel" # type: ignore
|
|
@@ -520,8 +520,11 @@ class APIGatewayAuthorizerResponse:
|
|
|
520
520
|
"""Adds a route to the internal lists of allowed or denied routes. Each object in
|
|
521
521
|
the internal list contains a resource ARN and a condition statement. The condition
|
|
522
522
|
statement can be null."""
|
|
523
|
-
|
|
524
|
-
|
|
523
|
+
allowed_values = [verb.value for verb in HttpVerb]
|
|
524
|
+
if http_method in HttpVerb.__members__:
|
|
525
|
+
http_method = HttpVerb[http_method].value
|
|
526
|
+
|
|
527
|
+
if http_method not in allowed_values:
|
|
525
528
|
raise ValueError(f"Invalid HTTP verb: '{http_method}'. Use either '{allowed_values}'")
|
|
526
529
|
|
|
527
530
|
if not self._resource_pattern.match(resource):
|
|
@@ -16,11 +16,11 @@ from typing import TYPE_CHECKING, Any
|
|
|
16
16
|
from jsonpath_ng.ext import parse
|
|
17
17
|
|
|
18
18
|
from aws_lambda_powertools.utilities.data_masking.exceptions import (
|
|
19
|
+
DataMaskingError,
|
|
19
20
|
DataMaskingFieldNotFoundError,
|
|
20
21
|
DataMaskingUnsupportedTypeError,
|
|
21
22
|
)
|
|
22
23
|
from aws_lambda_powertools.utilities.data_masking.provider import BaseProvider
|
|
23
|
-
from aws_lambda_powertools.warnings import PowertoolsUserWarning
|
|
24
24
|
|
|
25
25
|
if TYPE_CHECKING:
|
|
26
26
|
from collections.abc import Callable, Mapping, Sequence
|
|
@@ -395,10 +395,10 @@ class DataMasking:
|
|
|
395
395
|
if not result_parse:
|
|
396
396
|
if self.raise_on_missing_field:
|
|
397
397
|
# If the data for the field is not found, raise an exception.
|
|
398
|
-
raise DataMaskingFieldNotFoundError(f"Field or expression {field_parse} not found
|
|
398
|
+
raise DataMaskingFieldNotFoundError(f"Field or expression {field_parse} not found")
|
|
399
399
|
else:
|
|
400
400
|
# If the data for the field is not found, warning.
|
|
401
|
-
warnings.warn(f"Field or expression {field_parse} not found
|
|
401
|
+
warnings.warn(f"Field or expression {field_parse} not found", stacklevel=2)
|
|
402
402
|
|
|
403
403
|
# For in-place updates, json_parse accepts a callback function
|
|
404
404
|
# that receives 3 args: field_value, fields, field_name
|
|
@@ -427,31 +427,30 @@ class DataMasking:
|
|
|
427
427
|
for path, rule in masking_rules.items():
|
|
428
428
|
try:
|
|
429
429
|
jsonpath_expr = parse(f"$.{path}")
|
|
430
|
-
|
|
430
|
+
except Exception as exc:
|
|
431
|
+
raise DataMaskingError(f"Invalid masking path: {path}") from exc
|
|
431
432
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
433
|
+
matches = jsonpath_expr.find(result)
|
|
434
|
+
if not matches:
|
|
435
|
+
if self.raise_on_missing_field:
|
|
436
|
+
raise DataMaskingFieldNotFoundError(f"Field or expression {path} not found")
|
|
435
437
|
|
|
436
|
-
for
|
|
437
|
-
try:
|
|
438
|
-
value = match.value
|
|
439
|
-
if value is not None:
|
|
440
|
-
masked_value = self.provider.erase(str(value), **rule)
|
|
441
|
-
match.full_path.update(result, masked_value)
|
|
442
|
-
|
|
443
|
-
except Exception as e:
|
|
444
|
-
warnings.warn(
|
|
445
|
-
f"Error masking value for path {path}: {str(e)}",
|
|
446
|
-
category=PowertoolsUserWarning,
|
|
447
|
-
stacklevel=2,
|
|
448
|
-
)
|
|
449
|
-
continue
|
|
450
|
-
|
|
451
|
-
except Exception as e:
|
|
452
|
-
warnings.warn(f"Error processing path {path}: {str(e)}", category=PowertoolsUserWarning, stacklevel=2)
|
|
438
|
+
warnings.warn(f"No matches found for path: {path}", stacklevel=2)
|
|
453
439
|
continue
|
|
454
440
|
|
|
441
|
+
for match in matches:
|
|
442
|
+
value = match.value
|
|
443
|
+
if value is None:
|
|
444
|
+
continue
|
|
445
|
+
|
|
446
|
+
try:
|
|
447
|
+
masked_value = self.provider.erase(str(value), **rule)
|
|
448
|
+
match.full_path.update(result, masked_value)
|
|
449
|
+
except DataMaskingError:
|
|
450
|
+
raise
|
|
451
|
+
except Exception as exc:
|
|
452
|
+
raise DataMaskingError(f"Failed to mask field at path: {path}") from exc
|
|
453
|
+
|
|
455
454
|
return result
|
|
456
455
|
|
|
457
456
|
def _mask_nested_field(self, data: dict, field_path: str, mask_function):
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
class DataMaskingError(Exception):
|
|
2
|
+
"""
|
|
3
|
+
Base exception for data masking failures.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class DataMaskingUnsupportedTypeError(DataMaskingError):
|
|
8
|
+
"""
|
|
9
|
+
UnsupportedType Error
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class DataMaskingDecryptKeyError(DataMaskingError):
|
|
14
|
+
"""
|
|
15
|
+
Decrypting with an invalid AWS KMS Key ARN.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class DataMaskingEncryptKeyError(DataMaskingError):
|
|
20
|
+
"""
|
|
21
|
+
Encrypting with an invalid AWS KMS Key ARN.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class DataMaskingDecryptValueError(DataMaskingError):
|
|
26
|
+
"""
|
|
27
|
+
Decrypting an invalid field.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class DataMaskingContextMismatchError(DataMaskingError):
|
|
32
|
+
"""
|
|
33
|
+
Decrypting with the incorrect encryption context.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class DataMaskingFieldNotFoundError(DataMaskingError):
|
|
38
|
+
"""
|
|
39
|
+
Field not found.
|
|
40
|
+
"""
|
|
@@ -6,6 +6,7 @@ import re
|
|
|
6
6
|
from typing import TYPE_CHECKING, Any
|
|
7
7
|
|
|
8
8
|
from aws_lambda_powertools.utilities.data_masking.constants import DATA_MASKING_STRING
|
|
9
|
+
from aws_lambda_powertools.utilities.data_masking.exceptions import DataMaskingError
|
|
9
10
|
|
|
10
11
|
if TYPE_CHECKING:
|
|
11
12
|
from collections.abc import Callable
|
|
@@ -183,8 +184,8 @@ class BaseProvider:
|
|
|
183
184
|
if regex_pattern not in _regex_cache:
|
|
184
185
|
_regex_cache[regex_pattern] = re.compile(regex_pattern)
|
|
185
186
|
return _regex_cache[regex_pattern].sub(mask_format, data)
|
|
186
|
-
except re.error:
|
|
187
|
-
|
|
187
|
+
except re.error as exc:
|
|
188
|
+
raise DataMaskingError("Invalid regex pattern") from exc
|
|
188
189
|
|
|
189
190
|
def _custom_erase(self, data: str) -> str:
|
|
190
191
|
if not data:
|
|
@@ -86,6 +86,10 @@ class AppConfigStore(StoreProvider):
|
|
|
86
86
|
boto3_client=boto3_client,
|
|
87
87
|
boto3_session=boto3_session,
|
|
88
88
|
)
|
|
89
|
+
# Memoised envelope extraction: (raw document, extracted config). The Parameters cache hands back the
|
|
90
|
+
# same raw dict until expiry, so we can reuse the extracted result rather than re-running the JMESPath
|
|
91
|
+
# query and producing a new object on every call.
|
|
92
|
+
self._last_extracted: tuple[dict[str, Any], dict[str, Any]] | None = None
|
|
89
93
|
|
|
90
94
|
# Override the user agent to use "feature_flags" instead of "parameters"
|
|
91
95
|
self._register_feature_flags_user_agent()
|
|
@@ -140,11 +144,17 @@ class AppConfigStore(StoreProvider):
|
|
|
140
144
|
config = self.get_raw_configuration
|
|
141
145
|
|
|
142
146
|
if self.envelope:
|
|
147
|
+
if self._last_extracted is not None and self._last_extracted[0] is config:
|
|
148
|
+
self.logger.debug("Envelope enabled; reusing previously extracted config for cached document")
|
|
149
|
+
return self._last_extracted[1]
|
|
150
|
+
|
|
143
151
|
self.logger.debug("Envelope enabled; extracting data from config", extra={"envelope": self.envelope})
|
|
144
|
-
|
|
152
|
+
extracted = jmespath_utils.query(
|
|
145
153
|
data=config,
|
|
146
154
|
envelope=self.envelope,
|
|
147
155
|
jmespath_options=self.jmespath_options,
|
|
148
156
|
)
|
|
157
|
+
self._last_extracted = (config, extracted)
|
|
158
|
+
return extracted
|
|
149
159
|
|
|
150
160
|
return config
|
|
@@ -55,10 +55,15 @@ def compare_time_range(context_value: Any, condition_value: dict) -> bool:
|
|
|
55
55
|
start_time = current_time.replace(hour=int(start_hour), minute=int(start_min))
|
|
56
56
|
end_time = current_time.replace(hour=int(end_hour), minute=int(end_min))
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
# Compare full minutes-since-midnight so that ranges within the same hour (e.g. 23:30 -> 23:00)
|
|
59
|
+
# are correctly detected as crossing midnight.
|
|
60
|
+
start_minutes = int(start_hour) * 60 + int(start_min)
|
|
61
|
+
end_minutes = int(end_hour) * 60 + int(end_min)
|
|
62
|
+
|
|
63
|
+
if end_minutes < start_minutes:
|
|
59
64
|
# In normal circumstances, we need to assert **both** conditions
|
|
60
65
|
"""
|
|
61
|
-
# When the end
|
|
66
|
+
# When the end time is earlier than start time, it means we are crossing a day's boundary.
|
|
62
67
|
# In this case we need to assert that current_time is **either** on one side or the other side of the boundary
|
|
63
68
|
#
|
|
64
69
|
# ┌─────┐ ┌─────┐ ┌─────┐
|
|
@@ -9,5 +9,5 @@ CONDITION_VALUE = "value"
|
|
|
9
9
|
CONDITION_ACTION = "action"
|
|
10
10
|
FEATURE_DEFAULT_VAL_TYPE_KEY = "boolean_type"
|
|
11
11
|
TIME_RANGE_FORMAT = "%H:%M" # hour:min 24 hours clock
|
|
12
|
-
TIME_RANGE_PATTERN = re.compile(r"2[0-3]
|
|
12
|
+
TIME_RANGE_PATTERN = re.compile(r"(?:2[0-3]|[01]\d):[0-5]\d") # 24 hour clock, exactly HH:MM
|
|
13
13
|
HOUR_MIN_SEPARATOR = ":"
|
|
@@ -81,11 +81,30 @@ class FeatureFlags:
|
|
|
81
81
|
self.store = store
|
|
82
82
|
self.logger = logger or logging.getLogger(__name__)
|
|
83
83
|
self._exception_handlers: dict[Exception, Callable] = {}
|
|
84
|
+
# Last document that passed schema validation. We keep a strong reference so its id() can't be
|
|
85
|
+
# recycled by a different object, which lets us safely skip re-validation on store cache hits.
|
|
86
|
+
self._last_validated_config: dict | None = None
|
|
84
87
|
|
|
85
|
-
def _match_by_action(
|
|
88
|
+
def _match_by_action(
|
|
89
|
+
self,
|
|
90
|
+
action: str,
|
|
91
|
+
condition_value: Any,
|
|
92
|
+
context_value: Any,
|
|
93
|
+
context_key_present: bool = True,
|
|
94
|
+
) -> bool:
|
|
86
95
|
try:
|
|
87
96
|
func = RULE_ACTION_MAPPING.get(action, lambda a, b: False)
|
|
88
|
-
|
|
97
|
+
matched = func(context_value, condition_value)
|
|
98
|
+
|
|
99
|
+
if not context_key_present:
|
|
100
|
+
# A key absent from the context never satisfies a condition. Without this, `None` would be
|
|
101
|
+
# compared as a regular value and negative actions (NOT_EQUALS, NOT_IN, ...) would match.
|
|
102
|
+
# We still run the comparator first so that any exception it raises (e.g. ANY_IN_VALUE on a
|
|
103
|
+
# non-list) reaches registered validation exception handlers exactly as it did before.
|
|
104
|
+
self.logger.debug(f"context key not present, condition does not match: action={action}")
|
|
105
|
+
return False
|
|
106
|
+
|
|
107
|
+
return matched
|
|
89
108
|
except Exception as exc:
|
|
90
109
|
self.logger.debug(f"caught exception while matching action: action={action}, exception={str(exc)}")
|
|
91
110
|
|
|
@@ -115,9 +134,10 @@ class FeatureFlags:
|
|
|
115
134
|
return False
|
|
116
135
|
|
|
117
136
|
for condition in conditions:
|
|
118
|
-
|
|
137
|
+
cond_key = condition.get(schema.CONDITION_KEY, "")
|
|
119
138
|
cond_action = condition.get(schema.CONDITION_ACTION, "")
|
|
120
139
|
cond_value = condition.get(schema.CONDITION_VALUE)
|
|
140
|
+
context_key_present = True
|
|
121
141
|
|
|
122
142
|
# time based rule actions have no user context. the context is the condition key
|
|
123
143
|
if cond_action in (
|
|
@@ -125,9 +145,17 @@ class FeatureFlags:
|
|
|
125
145
|
schema.RuleAction.SCHEDULE_BETWEEN_DATETIME_RANGE.value,
|
|
126
146
|
schema.RuleAction.SCHEDULE_BETWEEN_DAYS_OF_WEEK.value,
|
|
127
147
|
):
|
|
128
|
-
context_value =
|
|
129
|
-
|
|
130
|
-
|
|
148
|
+
context_value = cond_key # e.g., CURRENT_TIME
|
|
149
|
+
else:
|
|
150
|
+
context_key_present = cond_key in context
|
|
151
|
+
context_value = context.get(cond_key)
|
|
152
|
+
|
|
153
|
+
if not self._match_by_action(
|
|
154
|
+
action=cond_action,
|
|
155
|
+
condition_value=cond_value,
|
|
156
|
+
context_value=context_value,
|
|
157
|
+
context_key_present=context_key_present,
|
|
158
|
+
):
|
|
131
159
|
self.logger.debug(
|
|
132
160
|
f"rule did not match action, rule_name={rule_name}, rule_value={rule_match_value}, "
|
|
133
161
|
f"name={feature_name}, context_value={str(context_value)} ",
|
|
@@ -210,8 +238,17 @@ class FeatureFlags:
|
|
|
210
238
|
# parse result conf as JSON, keep in cache for max age defined in store
|
|
211
239
|
self.logger.debug(f"Fetching schema from registered store, store={self.store}")
|
|
212
240
|
config: dict = self.store.get_configuration()
|
|
241
|
+
|
|
242
|
+
# Stores that serve from cache (e.g. AppConfigStore via Parameters) return the same dict object until
|
|
243
|
+
# expiry, so identity is a reliable signal that we've already validated this exact document.
|
|
244
|
+
# A store that applies an envelope returns a fresh object each time and will still be validated.
|
|
245
|
+
if config is self._last_validated_config:
|
|
246
|
+
self.logger.debug("Schema already validated, skipping validation")
|
|
247
|
+
return config
|
|
248
|
+
|
|
213
249
|
validator = schema.SchemaValidator(schema=config, logger=self.logger)
|
|
214
250
|
validator.validate()
|
|
251
|
+
self._last_validated_config = config
|
|
215
252
|
|
|
216
253
|
return config
|
|
217
254
|
|