aws-lambda-powertools 3.28.0__tar.gz → 3.30.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.28.0 → aws_lambda_powertools-3.30.0}/PKG-INFO +2 -2
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/__init__.py +2 -1
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/api_gateway.py +206 -10
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/appsync.py +2 -2
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/bedrock_agent.py +7 -2
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/graphql_appsync/_registry.py +1 -1
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/graphql_appsync/base.py +3 -9
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/http_resolver.py +12 -188
- aws_lambda_powertools-3.30.0/aws_lambda_powertools/event_handler/middlewares/async_utils.py +224 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/middlewares/openapi_validation.py +10 -6
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/openapi/models.py +169 -169
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/openapi/params.py +3 -1
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/openapi/swagger_ui/oauth2.py +8 -6
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/util.py +2 -2
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/shared/version.py +1 -1
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/batch/base.py +19 -3
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/batch/sqs_fifo_partial_processor.py +9 -2
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/common.py +2 -2
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_masking/provider/base.py +1 -1
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/idempotency/base.py +2 -2
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/idempotency/persistence/redis.py +16 -13
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parameters/ssm.py +1 -1
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/envelopes/apigw.py +4 -4
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/envelopes/apigw_websocket.py +4 -4
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/envelopes/apigwv2.py +4 -4
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/envelopes/base.py +5 -1
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/envelopes/bedrock_agent.py +7 -7
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/envelopes/cloudwatch.py +4 -4
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/envelopes/dynamodb.py +4 -4
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/envelopes/event_bridge.py +4 -4
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/envelopes/kafka.py +4 -4
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/envelopes/kinesis.py +4 -4
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/envelopes/kinesis_firehose.py +4 -4
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/envelopes/lambda_function_url.py +4 -4
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/envelopes/sns.py +7 -7
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/envelopes/sqs.py +4 -4
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/envelopes/vpc_lattice.py +4 -4
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/envelopes/vpc_latticev2.py +4 -4
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/functions.py +2 -2
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/parser.py +5 -1
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/pyproject.toml +8 -7
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/setup.py +3 -3
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/LICENSE +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/README.md +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/THIRD-PARTY-LICENSES +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/bedrock_agent_function.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/content_types.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/depends.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/events_appsync/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/events_appsync/_registry.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/events_appsync/appsync_events.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/events_appsync/base.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/events_appsync/exceptions.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/events_appsync/functions.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/events_appsync/router.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/events_appsync/types.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/exception_handling.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/exceptions.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/graphql_appsync/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/graphql_appsync/exceptions.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/graphql_appsync/router.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/lambda_function_url.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/middlewares/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/middlewares/base.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/middlewares/schema_validation.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/openapi/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/openapi/compat.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/openapi/config.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/openapi/constants.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/openapi/dependant.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/openapi/encoders.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/openapi/exceptions.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/openapi/merge.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/openapi/pydantic_loader.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/openapi/schema_generator.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/openapi/swagger_ui/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/openapi/swagger_ui/html.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/openapi/swagger_ui/swagger-ui-bundle.min.js +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/openapi/swagger_ui/swagger-ui.min.css +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/openapi/types.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/request.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/router.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/types.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/event_handler/vpc_lattice.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/exceptions/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/logging/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/logging/buffer/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/logging/buffer/cache.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/logging/buffer/config.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/logging/buffer/functions.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/logging/buffer/handler.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/logging/constants.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/logging/correlation_paths.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/logging/exceptions.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/logging/filters.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/logging/formatter.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/logging/formatters/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/logging/formatters/datadog.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/logging/lambda_context.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/logging/logger.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/logging/types.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/logging/utils.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/metrics/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/metrics/base.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/metrics/exceptions.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/metrics/functions.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/metrics/metric.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/metrics/metrics.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/metrics/provider/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/metrics/provider/base.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/metrics/provider/cloudwatch_emf/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/metrics/provider/cloudwatch_emf/cloudwatch.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/metrics/provider/cloudwatch_emf/constants.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/metrics/provider/cloudwatch_emf/exceptions.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/metrics/provider/cloudwatch_emf/metric_properties.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/metrics/provider/cloudwatch_emf/types.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/metrics/provider/cold_start.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/metrics/provider/datadog/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/metrics/provider/datadog/datadog.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/metrics/provider/datadog/metrics.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/metrics/provider/datadog/warnings.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/metrics/types.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/middleware_factory/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/middleware_factory/exceptions.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/middleware_factory/factory.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/package_logger.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/py.typed +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/shared/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/shared/cache_dict.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/shared/constants.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/shared/cookies.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/shared/dynamodb_deserializer.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/shared/functions.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/shared/headers_serializer.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/shared/json_encoder.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/shared/lazy_import.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/shared/types.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/shared/user_agent.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/tracing/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/tracing/base.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/tracing/extensions.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/tracing/tracer.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/batch/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/batch/decorators.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/batch/exceptions.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/batch/types.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/active_mq_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/alb_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/api_gateway_authorizer_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/api_gateway_websocket_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/appsync/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/appsync/scalar_types_utils.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/appsync_authorizer_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/appsync_resolver_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/appsync_resolver_events_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/aws_config_rule_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/bedrock_agent_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/bedrock_agent_function_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/cloud_watch_alarm_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/cloud_watch_custom_widget_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/cloud_watch_logs_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/cloudformation_custom_resource_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/code_deploy_lifecycle_hook_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/code_pipeline_job_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/cognito_user_pool_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/connect_contact_flow_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/dynamo_db_stream_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/event_bridge_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/event_source.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/iot_registry_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/kafka_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/kinesis_stream_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/lambda_function_url_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/rabbit_mq_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/s3_batch_operation_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/s3_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/s3_object_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/secrets_manager_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/ses_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/shared_functions.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/sns_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/sqs_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/transfer_family_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_classes/vpc_lattice.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_masking/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_masking/base.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_masking/constants.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_masking/exceptions.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_masking/provider/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_masking/provider/kms/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/data_masking/provider/kms/aws_encryption_sdk.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/feature_flags/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/feature_flags/appconfig.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/feature_flags/base.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/feature_flags/comparators.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/feature_flags/constants.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/feature_flags/exceptions.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/feature_flags/feature_flags.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/feature_flags/schema.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/feature_flags/types.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/idempotency/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/idempotency/config.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/idempotency/exceptions.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/idempotency/hook.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/idempotency/idempotency.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/idempotency/persistence/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/idempotency/persistence/base.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/idempotency/persistence/cache.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/idempotency/persistence/datarecord.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/idempotency/serialization/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/idempotency/serialization/base.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/idempotency/serialization/custom_dict.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/idempotency/serialization/dataclass.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/idempotency/serialization/functions.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/idempotency/serialization/no_op.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/idempotency/serialization/pydantic.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/jmespath_utils/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/jmespath_utils/envelopes.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/kafka/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/kafka/consumer_records.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/kafka/deserializer/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/kafka/deserializer/avro.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/kafka/deserializer/base.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/kafka/deserializer/default.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/kafka/deserializer/deserializer.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/kafka/deserializer/json.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/kafka/deserializer/protobuf.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/kafka/exceptions.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/kafka/kafka_consumer.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/kafka/schema_config.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/kafka/serialization/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/kafka/serialization/base.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/kafka/serialization/custom_dict.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/kafka/serialization/dataclass.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/kafka/serialization/pydantic.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/kafka/serialization/serialization.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/kafka/serialization/types.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/metadata/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/metadata/exceptions.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/metadata/lambda_metadata.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parameters/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parameters/appconfig.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parameters/base.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parameters/constants.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parameters/dynamodb.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parameters/exceptions.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parameters/secrets.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parameters/types.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/envelopes/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/exceptions.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/models/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/models/alb.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/models/apigw.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/models/apigw_websocket.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/models/apigwv2.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/models/appsync.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/models/appsync_events.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/models/bedrock_agent.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/models/cloudformation_custom_resource.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/models/cloudwatch.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/models/cognito.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/models/dynamodb.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/models/event_bridge.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/models/iot_registry_events.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/models/kafka.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/models/kinesis.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/models/kinesis_firehose.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/models/kinesis_firehose_sqs.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/models/lambda_function_url.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/models/s3.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/models/s3_batch_operation.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/models/s3_object_event.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/models/ses.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/models/sns.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/models/sqs.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/models/transfer_family.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/models/vpc_lattice.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/models/vpc_latticev2.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/parser/types.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/serialization.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/streaming/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/streaming/_s3_seekable_io.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/streaming/compat.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/streaming/constants.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/streaming/s3_object.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/streaming/transformations/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/streaming/transformations/base.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/streaming/transformations/csv.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/streaming/transformations/gzip.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/streaming/transformations/zip.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/streaming/types.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/typing/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/typing/lambda_client_context.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/typing/lambda_client_context_mobile_client.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/typing/lambda_cognito_identity.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/typing/lambda_context.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/validation/__init__.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/validation/base.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/validation/envelopes.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/validation/exceptions.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.0}/aws_lambda_powertools/utilities/validation/validator.py +0 -0
- {aws_lambda_powertools-3.28.0 → aws_lambda_powertools-3.30.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.30.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
|
|
@@ -29,7 +29,7 @@ Provides-Extra: tracer
|
|
|
29
29
|
Provides-Extra: validation
|
|
30
30
|
Provides-Extra: valkey
|
|
31
31
|
Requires-Dist: avro (>=1.12.0,<2.0.0) ; extra == "kafka-consumer-avro"
|
|
32
|
-
Requires-Dist: aws-encryption-sdk (>=3.1.1,<5.0.0) ; extra == "all" or extra == "datamasking"
|
|
32
|
+
Requires-Dist: aws-encryption-sdk (>=3.3.1,!=4.0.0,!=4.0.1,!=4.0.2,!=4.0.3,!=4.0.4,<5.0.0) ; extra == "all" or extra == "datamasking"
|
|
33
33
|
Requires-Dist: aws-xray-sdk (>=2.8.0,<3.0.0) ; extra == "tracer" or extra == "all"
|
|
34
34
|
Requires-Dist: boto3 (>=1.34.32,<2.0.0) ; extra == "aws-sdk"
|
|
35
35
|
Requires-Dist: datadog-lambda (>=8.114.0,<9.0.0) ; extra == "datadog"
|
|
@@ -18,7 +18,7 @@ from aws_lambda_powertools.event_handler.bedrock_agent_function import (
|
|
|
18
18
|
)
|
|
19
19
|
from aws_lambda_powertools.event_handler.depends import DependencyResolutionError, Depends
|
|
20
20
|
from aws_lambda_powertools.event_handler.events_appsync.appsync_events import AppSyncEventsResolver
|
|
21
|
-
from aws_lambda_powertools.event_handler.http_resolver import HttpResolverLocal
|
|
21
|
+
from aws_lambda_powertools.event_handler.http_resolver import HttpResolver, HttpResolverLocal
|
|
22
22
|
from aws_lambda_powertools.event_handler.lambda_function_url import (
|
|
23
23
|
LambdaFunctionUrlResolver,
|
|
24
24
|
)
|
|
@@ -39,6 +39,7 @@ __all__ = [
|
|
|
39
39
|
"CORSConfig",
|
|
40
40
|
"Depends",
|
|
41
41
|
"DependencyResolutionError",
|
|
42
|
+
"HttpResolver",
|
|
42
43
|
"HttpResolverLocal",
|
|
43
44
|
"LambdaFunctionUrlResolver",
|
|
44
45
|
"Request",
|
|
@@ -613,6 +613,63 @@ class Route:
|
|
|
613
613
|
|
|
614
614
|
self._middleware_stack_built = True
|
|
615
615
|
|
|
616
|
+
async def call_async(
|
|
617
|
+
self,
|
|
618
|
+
router_middlewares: list[Callable],
|
|
619
|
+
app: ApiGatewayResolver,
|
|
620
|
+
route_arguments: dict[str, str],
|
|
621
|
+
) -> dict | tuple | Response:
|
|
622
|
+
from aws_lambda_powertools.event_handler.middlewares.async_utils import (
|
|
623
|
+
AsyncMiddlewareFrame,
|
|
624
|
+
_registered_api_adapter_async,
|
|
625
|
+
)
|
|
626
|
+
|
|
627
|
+
all_middlewares: list[Callable[..., Any]] = []
|
|
628
|
+
|
|
629
|
+
route_validation_enabled = (
|
|
630
|
+
self.enable_validation if self.enable_validation is not None else app._enable_validation
|
|
631
|
+
)
|
|
632
|
+
|
|
633
|
+
if route_validation_enabled and not hasattr(app, "_request_validation_middleware"):
|
|
634
|
+
from aws_lambda_powertools.event_handler.middlewares.openapi_validation import (
|
|
635
|
+
OpenAPIRequestValidationMiddleware,
|
|
636
|
+
OpenAPIResponseValidationMiddleware,
|
|
637
|
+
)
|
|
638
|
+
|
|
639
|
+
app._request_validation_middleware = OpenAPIRequestValidationMiddleware()
|
|
640
|
+
app._response_validation_middleware = OpenAPIResponseValidationMiddleware(
|
|
641
|
+
validation_serializer=app._serializer,
|
|
642
|
+
has_response_validation_error=app._has_response_validation_error,
|
|
643
|
+
)
|
|
644
|
+
|
|
645
|
+
if route_validation_enabled and hasattr(app, "_request_validation_middleware"):
|
|
646
|
+
all_middlewares.append(app._request_validation_middleware)
|
|
647
|
+
|
|
648
|
+
all_middlewares.extend(router_middlewares + self.middlewares)
|
|
649
|
+
|
|
650
|
+
if route_validation_enabled and hasattr(app, "_response_validation_middleware"):
|
|
651
|
+
all_middlewares.append(app._response_validation_middleware)
|
|
652
|
+
|
|
653
|
+
all_middlewares.append(_registered_api_adapter_async)
|
|
654
|
+
|
|
655
|
+
logger.debug(f"Building async middleware stack: {all_middlewares}")
|
|
656
|
+
|
|
657
|
+
if app._debug:
|
|
658
|
+
print(f"\nProcessing Route (async):::{self.func.__name__} ({app.context['_path']})")
|
|
659
|
+
print("\nAsync Middleware Stack:")
|
|
660
|
+
print("=================")
|
|
661
|
+
print("\n".join(getattr(item, "__name__", "Unknown") for item in all_middlewares))
|
|
662
|
+
print("=================")
|
|
663
|
+
|
|
664
|
+
app.append_context(_route_args=route_arguments)
|
|
665
|
+
|
|
666
|
+
# Build async chain from inside-out (not cached, avoids state conflicts with sync cache)
|
|
667
|
+
next_handler: Callable = self.func
|
|
668
|
+
for handler in reversed(all_middlewares):
|
|
669
|
+
next_handler = AsyncMiddlewareFrame(current_middleware=handler, next_middleware=next_handler)
|
|
670
|
+
|
|
671
|
+
return await next_handler(app)
|
|
672
|
+
|
|
616
673
|
@property
|
|
617
674
|
def dependant(self) -> Dependant:
|
|
618
675
|
if self._dependant is None:
|
|
@@ -2509,6 +2566,154 @@ class ApiGatewayResolver(BaseRouter):
|
|
|
2509
2566
|
|
|
2510
2567
|
return response
|
|
2511
2568
|
|
|
2569
|
+
async def resolve_async(self, event: Mapping[str, Any], context: LambdaContext) -> dict[str, Any]:
|
|
2570
|
+
"""Async version of resolve() for native async handler support.
|
|
2571
|
+
|
|
2572
|
+
Use this method when your route handlers use async/await. The resolution
|
|
2573
|
+
pipeline supports both sync and async handlers transparently.
|
|
2574
|
+
|
|
2575
|
+
Parameters
|
|
2576
|
+
----------
|
|
2577
|
+
event: dict[str, Any]
|
|
2578
|
+
Event
|
|
2579
|
+
context: LambdaContext
|
|
2580
|
+
Lambda context
|
|
2581
|
+
Returns
|
|
2582
|
+
-------
|
|
2583
|
+
dict
|
|
2584
|
+
Returns the dict response
|
|
2585
|
+
|
|
2586
|
+
Example
|
|
2587
|
+
-------
|
|
2588
|
+
|
|
2589
|
+
```python
|
|
2590
|
+
import asyncio
|
|
2591
|
+
from aws_lambda_powertools.event_handler import APIGatewayHttpResolver
|
|
2592
|
+
|
|
2593
|
+
app = APIGatewayHttpResolver()
|
|
2594
|
+
|
|
2595
|
+
@app.get("/async")
|
|
2596
|
+
async def async_handler():
|
|
2597
|
+
return {"message": "async works"}
|
|
2598
|
+
|
|
2599
|
+
def lambda_handler(event, context):
|
|
2600
|
+
return asyncio.run(app.resolve_async(event, context))
|
|
2601
|
+
```
|
|
2602
|
+
"""
|
|
2603
|
+
if isinstance(event, BaseProxyEvent):
|
|
2604
|
+
warnings.warn(
|
|
2605
|
+
"You don't need to serialize event to Event Source Data Class when using Event Handler; "
|
|
2606
|
+
"see issue #1152",
|
|
2607
|
+
stacklevel=2,
|
|
2608
|
+
)
|
|
2609
|
+
event = event.raw_event
|
|
2610
|
+
|
|
2611
|
+
if self._debug:
|
|
2612
|
+
print(self._serializer(cast(dict, event)))
|
|
2613
|
+
|
|
2614
|
+
BaseRouter.current_event = self._to_proxy_event(cast(dict, event))
|
|
2615
|
+
BaseRouter.lambda_context = context
|
|
2616
|
+
|
|
2617
|
+
response = (await self._resolve_async()).build(self.current_event, self._cors)
|
|
2618
|
+
|
|
2619
|
+
if self._debug:
|
|
2620
|
+
print("\nProcessed Middlewares:")
|
|
2621
|
+
print("======================")
|
|
2622
|
+
print("\n".join(self.processed_stack_frames))
|
|
2623
|
+
print("======================")
|
|
2624
|
+
|
|
2625
|
+
self.clear_context()
|
|
2626
|
+
|
|
2627
|
+
return response
|
|
2628
|
+
|
|
2629
|
+
async def _resolve_async(self) -> ResponseBuilder:
|
|
2630
|
+
method = self.current_event.http_method.upper()
|
|
2631
|
+
path = self._remove_prefix(self.current_event.path)
|
|
2632
|
+
|
|
2633
|
+
registered_routes = self._static_routes + self._dynamic_routes
|
|
2634
|
+
|
|
2635
|
+
for route in registered_routes:
|
|
2636
|
+
if method != route.method:
|
|
2637
|
+
continue
|
|
2638
|
+
match_results: Match | None = route.rule.match(path)
|
|
2639
|
+
if match_results:
|
|
2640
|
+
logger.debug("Found a registered route. Calling async function")
|
|
2641
|
+
self.append_context(_route=route, _path=path)
|
|
2642
|
+
|
|
2643
|
+
route_keys = self._convert_matches_into_route_keys(match_results)
|
|
2644
|
+
return await self._call_route_async(route, route_keys)
|
|
2645
|
+
|
|
2646
|
+
return await self._handle_not_found_async(method=method, path=path)
|
|
2647
|
+
|
|
2648
|
+
async def _call_route_async(self, route: Route, route_arguments: dict[str, str]) -> ResponseBuilder:
|
|
2649
|
+
try:
|
|
2650
|
+
self._reset_processed_stack()
|
|
2651
|
+
|
|
2652
|
+
response = await route.call_async(
|
|
2653
|
+
router_middlewares=self._router_middlewares,
|
|
2654
|
+
app=self,
|
|
2655
|
+
route_arguments=route_arguments,
|
|
2656
|
+
)
|
|
2657
|
+
|
|
2658
|
+
return self._response_builder_class(
|
|
2659
|
+
response=self._to_response(response), # type: ignore[arg-type]
|
|
2660
|
+
serializer=self._serializer,
|
|
2661
|
+
route=route,
|
|
2662
|
+
)
|
|
2663
|
+
except Exception as exc:
|
|
2664
|
+
response_builder = self._call_exception_handler(exc, route)
|
|
2665
|
+
if response_builder:
|
|
2666
|
+
return response_builder
|
|
2667
|
+
|
|
2668
|
+
logger.exception(exc)
|
|
2669
|
+
if self._debug:
|
|
2670
|
+
return self._response_builder_class(
|
|
2671
|
+
response=Response(
|
|
2672
|
+
status_code=500,
|
|
2673
|
+
content_type=content_types.TEXT_PLAIN,
|
|
2674
|
+
body="".join(traceback.format_exc()),
|
|
2675
|
+
),
|
|
2676
|
+
serializer=self._serializer,
|
|
2677
|
+
route=route,
|
|
2678
|
+
)
|
|
2679
|
+
|
|
2680
|
+
raise
|
|
2681
|
+
|
|
2682
|
+
async def _handle_not_found_async(self, method: str, path: str) -> ResponseBuilder:
|
|
2683
|
+
logger.debug(f"No match found for path {path} and method {method}")
|
|
2684
|
+
|
|
2685
|
+
def not_found_handler():
|
|
2686
|
+
_headers: dict[str, Any] = {}
|
|
2687
|
+
|
|
2688
|
+
if self._cors and method == "OPTIONS":
|
|
2689
|
+
logger.debug("Pre-flight request detected. Returning CORS with empty response")
|
|
2690
|
+
_headers["Access-Control-Allow-Methods"] = CORSConfig.build_allow_methods(self._cors_methods)
|
|
2691
|
+
return Response(status_code=204, content_type=None, headers=_headers, body="")
|
|
2692
|
+
|
|
2693
|
+
custom_not_found_handler = self.exception_handler_manager.lookup_exception_handler(NotFoundError)
|
|
2694
|
+
if custom_not_found_handler:
|
|
2695
|
+
return custom_not_found_handler(NotFoundError())
|
|
2696
|
+
|
|
2697
|
+
return Response(
|
|
2698
|
+
status_code=HTTPStatus.NOT_FOUND.value,
|
|
2699
|
+
content_type=content_types.APPLICATION_JSON,
|
|
2700
|
+
headers=_headers,
|
|
2701
|
+
body={"statusCode": HTTPStatus.NOT_FOUND.value, "message": "Not found"},
|
|
2702
|
+
)
|
|
2703
|
+
|
|
2704
|
+
route = Route(
|
|
2705
|
+
rule=self._compile_regex(r".*"),
|
|
2706
|
+
method=method,
|
|
2707
|
+
path=path,
|
|
2708
|
+
func=not_found_handler,
|
|
2709
|
+
cors=self._cors_enabled,
|
|
2710
|
+
compress=False,
|
|
2711
|
+
)
|
|
2712
|
+
|
|
2713
|
+
self.append_context(_route=route, _path=path)
|
|
2714
|
+
|
|
2715
|
+
return await self._call_route_async(route=route, route_arguments={})
|
|
2716
|
+
|
|
2512
2717
|
def __call__(self, event, context) -> Any:
|
|
2513
2718
|
return self.resolve(event, context)
|
|
2514
2719
|
|
|
@@ -3138,22 +3343,13 @@ class ALBResolver(ApiGatewayResolver):
|
|
|
3138
3343
|
# ALB doesn't have a stage variable, so we just return an empty string
|
|
3139
3344
|
return ""
|
|
3140
3345
|
|
|
3141
|
-
# BedrockResponse is not used here but adding the same signature to keep strong typing
|
|
3142
3346
|
@override
|
|
3143
3347
|
def _to_response(self, result: dict | tuple | Response | BedrockResponse) -> Response | BedrockResponse:
|
|
3144
3348
|
"""Convert the route's result to a Response
|
|
3145
3349
|
|
|
3146
3350
|
ALB requires a non-null body otherwise it converts as HTTP 5xx
|
|
3147
|
-
|
|
3148
|
-
3 main result types are supported:
|
|
3149
|
-
|
|
3150
|
-
- Dict[str, Any]: Rest api response with just the Dict to json stringify and content-type is set to
|
|
3151
|
-
application/json
|
|
3152
|
-
- Tuple[dict, int]: Same dict handling as above but with the option of including a status code
|
|
3153
|
-
- Response: returned as is, and allows for more flexibility
|
|
3154
3351
|
"""
|
|
3155
|
-
|
|
3156
|
-
# NOTE: Minor override for early return on Response with null body for ALB
|
|
3352
|
+
# ALB doesn't support null body - convert before building the final response
|
|
3157
3353
|
if isinstance(result, Response) and result.body is None:
|
|
3158
3354
|
logger.debug("ALB doesn't allow None responses; converting to empty string")
|
|
3159
3355
|
result.body = ""
|
|
@@ -392,7 +392,7 @@ class AppSyncResolver(Router):
|
|
|
392
392
|
----------
|
|
393
393
|
type_name : str, optional
|
|
394
394
|
GraphQL type e.g., Query, Mutation, by default "*" meaning any
|
|
395
|
-
field_name :
|
|
395
|
+
field_name : str | None, optional
|
|
396
396
|
GraphQL field e.g., getTodo, createTodo, by default None
|
|
397
397
|
|
|
398
398
|
Returns
|
|
@@ -447,7 +447,7 @@ class AppSyncResolver(Router):
|
|
|
447
447
|
----------
|
|
448
448
|
type_name : str, optional
|
|
449
449
|
GraphQL type e.g., Query, Mutation, by default "*" meaning any
|
|
450
|
-
field_name :
|
|
450
|
+
field_name : str | None, optional
|
|
451
451
|
GraphQL field e.g., getTodo, createTodo, by default None
|
|
452
452
|
raise_on_error : bool, optional
|
|
453
453
|
Whether to fail entire batch upon error, or handle errors gracefully (None), by default False
|
|
@@ -99,12 +99,17 @@ class BedrockAgentResolver(ApiGatewayResolver):
|
|
|
99
99
|
|
|
100
100
|
current_event: BedrockAgentEvent
|
|
101
101
|
|
|
102
|
-
def __init__(
|
|
102
|
+
def __init__(
|
|
103
|
+
self,
|
|
104
|
+
debug: bool = False,
|
|
105
|
+
enable_validation: bool = True,
|
|
106
|
+
serializer: Callable[[dict], str] | None = None,
|
|
107
|
+
):
|
|
103
108
|
super().__init__(
|
|
104
109
|
proxy_type=ProxyEventType.BedrockAgentEvent,
|
|
105
110
|
cors=None,
|
|
106
111
|
debug=debug,
|
|
107
|
-
serializer=
|
|
112
|
+
serializer=serializer,
|
|
108
113
|
strip_prefixes=None,
|
|
109
114
|
enable_validation=enable_validation,
|
|
110
115
|
json_body_deserializer=None,
|
|
@@ -25,8 +25,6 @@ class BaseRouter(ABC):
|
|
|
25
25
|
Examples
|
|
26
26
|
--------
|
|
27
27
|
```python
|
|
28
|
-
from typing import Optional
|
|
29
|
-
|
|
30
28
|
from aws_lambda_powertools.event_handler import AppSyncResolver
|
|
31
29
|
from aws_lambda_powertools.utilities.data_classes import AppSyncResolverEvent
|
|
32
30
|
from aws_lambda_powertools.utilities.typing import LambdaContext
|
|
@@ -34,7 +32,7 @@ class BaseRouter(ABC):
|
|
|
34
32
|
app = AppSyncResolver()
|
|
35
33
|
|
|
36
34
|
@app.resolver(type_name="Query", field_name="getPost")
|
|
37
|
-
def related_posts(event: AppSyncResolverEvent) ->
|
|
35
|
+
def related_posts(event: AppSyncResolverEvent) -> list | None:
|
|
38
36
|
return {"success": "ok"}
|
|
39
37
|
|
|
40
38
|
def lambda_handler(event, context: LambdaContext) -> dict:
|
|
@@ -76,8 +74,6 @@ class BaseRouter(ABC):
|
|
|
76
74
|
Examples
|
|
77
75
|
--------
|
|
78
76
|
```python
|
|
79
|
-
from typing import Optional
|
|
80
|
-
|
|
81
77
|
from aws_lambda_powertools.event_handler import AppSyncResolver
|
|
82
78
|
from aws_lambda_powertools.utilities.data_classes import AppSyncResolverEvent
|
|
83
79
|
from aws_lambda_powertools.utilities.typing import LambdaContext
|
|
@@ -85,7 +81,7 @@ class BaseRouter(ABC):
|
|
|
85
81
|
app = AppSyncResolver()
|
|
86
82
|
|
|
87
83
|
@app.batch_resolver(type_name="Query", field_name="getPost")
|
|
88
|
-
def related_posts(event: AppSyncResolverEvent, id) ->
|
|
84
|
+
def related_posts(event: AppSyncResolverEvent, id) -> list | None:
|
|
89
85
|
return {"post_id": id}
|
|
90
86
|
|
|
91
87
|
def lambda_handler(event, context: LambdaContext) -> dict:
|
|
@@ -127,8 +123,6 @@ class BaseRouter(ABC):
|
|
|
127
123
|
Examples
|
|
128
124
|
--------
|
|
129
125
|
```python
|
|
130
|
-
from typing import Optional
|
|
131
|
-
|
|
132
126
|
from aws_lambda_powertools.event_handler import AppSyncResolver
|
|
133
127
|
from aws_lambda_powertools.utilities.data_classes import AppSyncResolverEvent
|
|
134
128
|
from aws_lambda_powertools.utilities.typing import LambdaContext
|
|
@@ -136,7 +130,7 @@ class BaseRouter(ABC):
|
|
|
136
130
|
app = AppSyncResolver()
|
|
137
131
|
|
|
138
132
|
@app.async_batch_resolver(type_name="Query", field_name="getPost")
|
|
139
|
-
async def related_posts(event: AppSyncResolverEvent, id) ->
|
|
133
|
+
async def related_posts(event: AppSyncResolverEvent, id) -> list | None:
|
|
140
134
|
return {"post_id": id}
|
|
141
135
|
|
|
142
136
|
def lambda_handler(event, context: LambdaContext) -> dict:
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import asyncio
|
|
4
3
|
import base64
|
|
5
|
-
import inspect
|
|
6
|
-
import threading
|
|
7
|
-
import warnings
|
|
8
4
|
from typing import TYPE_CHECKING, Any, Callable
|
|
9
5
|
from urllib.parse import parse_qs
|
|
10
6
|
|
|
@@ -12,8 +8,6 @@ from aws_lambda_powertools.event_handler.api_gateway import (
|
|
|
12
8
|
ApiGatewayResolver,
|
|
13
9
|
BaseRouter,
|
|
14
10
|
ProxyEventType,
|
|
15
|
-
Response,
|
|
16
|
-
Route,
|
|
17
11
|
)
|
|
18
12
|
from aws_lambda_powertools.shared.headers_serializer import BaseHeadersSerializer
|
|
19
13
|
from aws_lambda_powertools.utilities.data_classes.common import BaseProxyEvent
|
|
@@ -167,21 +161,16 @@ class MockLambdaContext:
|
|
|
167
161
|
|
|
168
162
|
class HttpResolverLocal(ApiGatewayResolver):
|
|
169
163
|
"""
|
|
170
|
-
ASGI-compatible HTTP resolver
|
|
164
|
+
ASGI-compatible HTTP resolver.
|
|
171
165
|
|
|
172
|
-
|
|
173
|
-
It allows you to run your Powertools application locally with any ASGI server
|
|
166
|
+
It allows you to run your Powertools application with any ASGI server
|
|
174
167
|
(uvicorn, hypercorn, daphne, etc.) while maintaining full compatibility with Lambda.
|
|
175
168
|
|
|
176
169
|
The same code works in both environments - locally via ASGI and in Lambda via the handler.
|
|
170
|
+
If your Lambda is behind Lambda Web Adapter or any other HTTP proxy, it works seamlessly.
|
|
177
171
|
|
|
178
172
|
Supports both sync and async route handlers.
|
|
179
173
|
|
|
180
|
-
WARNING
|
|
181
|
-
-------
|
|
182
|
-
This is intended for local development and testing only.
|
|
183
|
-
The API may change in future releases. Do not use in production environments.
|
|
184
|
-
|
|
185
174
|
Example
|
|
186
175
|
-------
|
|
187
176
|
```python
|
|
@@ -215,11 +204,6 @@ class HttpResolverLocal(ApiGatewayResolver):
|
|
|
215
204
|
strip_prefixes: list[str | Any] | None = None,
|
|
216
205
|
enable_validation: bool = False,
|
|
217
206
|
):
|
|
218
|
-
warnings.warn(
|
|
219
|
-
"HttpResolverLocal is intended for local development and testing only. "
|
|
220
|
-
"The API may change in future releases. Do not use in production environments.",
|
|
221
|
-
stacklevel=2,
|
|
222
|
-
)
|
|
223
207
|
super().__init__(
|
|
224
208
|
proxy_type=ProxyEventType.APIGatewayProxyEvent, # Use REST API format internally
|
|
225
209
|
cors=cors,
|
|
@@ -240,177 +224,14 @@ class HttpResolverLocal(ApiGatewayResolver):
|
|
|
240
224
|
"""Return the base path for HTTP resolver (no stage prefix)."""
|
|
241
225
|
return ""
|
|
242
226
|
|
|
243
|
-
async def _resolve_async(self) -> dict:
|
|
244
|
-
"""
|
|
245
|
-
method = self.current_event.http_method.upper()
|
|
246
|
-
path = self._remove_prefix(self.current_event.path)
|
|
227
|
+
async def _resolve_async(self) -> dict: # type: ignore[override]
|
|
228
|
+
"""Thin async resolver: delegates entirely to the parent and serializes to dict.
|
|
247
229
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
if method != route.method:
|
|
252
|
-
continue
|
|
253
|
-
match_results = route.rule.match(path)
|
|
254
|
-
if match_results:
|
|
255
|
-
self.append_context(_route=route, _path=path)
|
|
256
|
-
route_keys = self._convert_matches_into_route_keys(match_results)
|
|
257
|
-
return await self._call_route_async(route, route_keys)
|
|
258
|
-
|
|
259
|
-
# Handle not found
|
|
260
|
-
return await self._handle_not_found_async()
|
|
261
|
-
|
|
262
|
-
async def _call_route_async(self, route: Route, route_arguments: dict[str, str]) -> dict:
|
|
263
|
-
"""Call route handler, supporting both sync and async handlers."""
|
|
264
|
-
from aws_lambda_powertools.event_handler.api_gateway import ResponseBuilder
|
|
265
|
-
|
|
266
|
-
try:
|
|
267
|
-
self._reset_processed_stack()
|
|
268
|
-
|
|
269
|
-
# Get the route args (may be modified by validation middleware)
|
|
270
|
-
self.append_context(_route_args=route_arguments)
|
|
271
|
-
|
|
272
|
-
# Run middleware chain (sync for now, handlers can be async)
|
|
273
|
-
response = await self._run_middleware_chain_async(route)
|
|
274
|
-
|
|
275
|
-
response_builder: ResponseBuilder = ResponseBuilder(
|
|
276
|
-
response=response,
|
|
277
|
-
serializer=self._serializer,
|
|
278
|
-
route=route,
|
|
279
|
-
)
|
|
280
|
-
|
|
281
|
-
return response_builder.build(self.current_event, self._cors)
|
|
282
|
-
|
|
283
|
-
except Exception as exc:
|
|
284
|
-
exc_response_builder = self._call_exception_handler(exc, route)
|
|
285
|
-
if exc_response_builder:
|
|
286
|
-
return exc_response_builder.build(self.current_event, self._cors)
|
|
287
|
-
raise
|
|
288
|
-
|
|
289
|
-
async def _run_middleware_chain_async(self, route: Route) -> Response:
|
|
290
|
-
"""Run the middleware chain, awaiting async handlers."""
|
|
291
|
-
# Build middleware list
|
|
292
|
-
all_middlewares: list[Callable[..., Any]] = []
|
|
293
|
-
|
|
294
|
-
# Determine if validation should be enabled for this route
|
|
295
|
-
# If route has explicit enable_validation setting, use it; otherwise, use resolver's global setting
|
|
296
|
-
route_validation_enabled = (
|
|
297
|
-
route.enable_validation if route.enable_validation is not None else self._enable_validation
|
|
298
|
-
)
|
|
299
|
-
|
|
300
|
-
if route_validation_enabled and hasattr(self, "_request_validation_middleware"):
|
|
301
|
-
all_middlewares.append(self._request_validation_middleware)
|
|
302
|
-
|
|
303
|
-
all_middlewares.extend(self._router_middlewares + route.middlewares)
|
|
304
|
-
|
|
305
|
-
if route_validation_enabled and hasattr(self, "_response_validation_middleware"):
|
|
306
|
-
all_middlewares.append(self._response_validation_middleware)
|
|
307
|
-
|
|
308
|
-
# Create the final handler that calls the route function
|
|
309
|
-
async def final_handler(app):
|
|
310
|
-
route_args = app.context.get("_route_args", {})
|
|
311
|
-
result = route.func(**route_args)
|
|
312
|
-
|
|
313
|
-
# Await if coroutine
|
|
314
|
-
if inspect.iscoroutine(result):
|
|
315
|
-
result = await result
|
|
316
|
-
|
|
317
|
-
return self._to_response(result)
|
|
318
|
-
|
|
319
|
-
# Build middleware chain from end to start
|
|
320
|
-
next_handler = final_handler
|
|
321
|
-
|
|
322
|
-
for middleware in reversed(all_middlewares):
|
|
323
|
-
next_handler = self._wrap_middleware_async(middleware, next_handler)
|
|
324
|
-
|
|
325
|
-
return await next_handler(self)
|
|
326
|
-
|
|
327
|
-
def _wrap_middleware_async(self, middleware: Callable, next_handler: Callable) -> Callable:
|
|
328
|
-
"""Wrap a middleware to work in async context.
|
|
329
|
-
|
|
330
|
-
For sync middlewares, we split execution into pre/post phases around the
|
|
331
|
-
call to next(). The sync middleware runs its pre-processing (e.g. request
|
|
332
|
-
validation), then we intercept the next() call, await the async handler,
|
|
333
|
-
and resume the middleware with the real response so post-processing
|
|
334
|
-
(e.g. response validation) sees the actual data.
|
|
230
|
+
The parent's _resolve_async handles route matching, CORS preflight, not-found
|
|
231
|
+
logic, and exception handling. The only adaptation needed here is converting
|
|
232
|
+
the returned ResponseBuilder into the dict format that asgi_handler expects.
|
|
335
233
|
"""
|
|
336
|
-
|
|
337
|
-
async def wrapped(app):
|
|
338
|
-
if inspect.iscoroutinefunction(middleware):
|
|
339
|
-
return await middleware(app, next_handler)
|
|
340
|
-
|
|
341
|
-
# We use an Event to coordinate: the sync middleware runs in a thread,
|
|
342
|
-
# calls sync_next which signals us to resolve the async handler,
|
|
343
|
-
# then waits for the real response.
|
|
344
|
-
middleware_called_next = asyncio.Event()
|
|
345
|
-
next_app_holder: list = []
|
|
346
|
-
real_response_holder: list = []
|
|
347
|
-
middleware_result_holder: list = []
|
|
348
|
-
middleware_error_holder: list = []
|
|
349
|
-
|
|
350
|
-
def sync_next(app):
|
|
351
|
-
next_app_holder.append(app)
|
|
352
|
-
middleware_called_next.set()
|
|
353
|
-
# Block this thread until the real response is available
|
|
354
|
-
event = threading.Event()
|
|
355
|
-
next_app_holder.append(event)
|
|
356
|
-
event.wait()
|
|
357
|
-
return real_response_holder[0]
|
|
358
|
-
|
|
359
|
-
def run_middleware():
|
|
360
|
-
try:
|
|
361
|
-
result = middleware(app, sync_next)
|
|
362
|
-
middleware_result_holder.append(result)
|
|
363
|
-
except Exception as e:
|
|
364
|
-
middleware_error_holder.append(e)
|
|
365
|
-
|
|
366
|
-
thread = threading.Thread(target=run_middleware, daemon=True)
|
|
367
|
-
thread.start()
|
|
368
|
-
|
|
369
|
-
# Wait for the middleware to call next()
|
|
370
|
-
await middleware_called_next.wait()
|
|
371
|
-
|
|
372
|
-
# Now resolve the async next_handler
|
|
373
|
-
real_response = await next_handler(next_app_holder[0])
|
|
374
|
-
real_response_holder.append(real_response)
|
|
375
|
-
|
|
376
|
-
# Signal the thread that the response is ready
|
|
377
|
-
threading_event = next_app_holder[1]
|
|
378
|
-
threading_event.set()
|
|
379
|
-
|
|
380
|
-
# Wait for the middleware thread to finish
|
|
381
|
-
thread.join()
|
|
382
|
-
|
|
383
|
-
if middleware_error_holder:
|
|
384
|
-
raise middleware_error_holder[0]
|
|
385
|
-
|
|
386
|
-
return middleware_result_holder[0]
|
|
387
|
-
|
|
388
|
-
return wrapped
|
|
389
|
-
|
|
390
|
-
async def _handle_not_found_async(self) -> dict:
|
|
391
|
-
"""Handle 404 responses, using custom not_found handler if registered."""
|
|
392
|
-
from http import HTTPStatus
|
|
393
|
-
|
|
394
|
-
from aws_lambda_powertools.event_handler.api_gateway import ResponseBuilder
|
|
395
|
-
from aws_lambda_powertools.event_handler.exceptions import NotFoundError
|
|
396
|
-
|
|
397
|
-
# Check for custom not_found handler
|
|
398
|
-
custom_not_found_handler = self.exception_handler_manager.lookup_exception_handler(NotFoundError)
|
|
399
|
-
if custom_not_found_handler:
|
|
400
|
-
response = custom_not_found_handler(NotFoundError())
|
|
401
|
-
else:
|
|
402
|
-
response = Response(
|
|
403
|
-
status_code=HTTPStatus.NOT_FOUND.value,
|
|
404
|
-
content_type="application/json",
|
|
405
|
-
body={"statusCode": HTTPStatus.NOT_FOUND.value, "message": "Not found"},
|
|
406
|
-
)
|
|
407
|
-
|
|
408
|
-
response_builder: ResponseBuilder = ResponseBuilder(
|
|
409
|
-
response=response,
|
|
410
|
-
serializer=self._serializer,
|
|
411
|
-
route=None,
|
|
412
|
-
)
|
|
413
|
-
|
|
234
|
+
response_builder = await super()._resolve_async()
|
|
414
235
|
return response_builder.build(self.current_event, self._cors)
|
|
415
236
|
|
|
416
237
|
async def asgi_handler(self, scope: dict, receive: Callable, send: Callable) -> None:
|
|
@@ -519,3 +340,6 @@ class HttpResolverLocal(ApiGatewayResolver):
|
|
|
519
340
|
"body": body_bytes,
|
|
520
341
|
},
|
|
521
342
|
)
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
HttpResolver = HttpResolverLocal
|