aws-lambda-powertools 3.26.0__tar.gz → 3.27.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.
Files changed (307) hide show
  1. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/PKG-INFO +2 -2
  2. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/__init__.py +2 -0
  3. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/api_gateway.py +76 -0
  4. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/http_resolver.py +55 -25
  5. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/middlewares/openapi_validation.py +210 -7
  6. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/openapi/dependant.py +10 -4
  7. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/openapi/merge.py +11 -4
  8. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/openapi/params.py +124 -1
  9. aws_lambda_powertools-3.27.0/aws_lambda_powertools/event_handler/request.py +115 -0
  10. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/shared/version.py +1 -1
  11. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/api_gateway_authorizer_event.py +4 -4
  12. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py +11 -0
  13. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/common.py +42 -1
  14. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_masking/base.py +1 -1
  15. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/feature_flags/feature_flags.py +9 -9
  16. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/idempotency/base.py +1 -1
  17. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/idempotency/persistence/base.py +4 -1
  18. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/kafka/deserializer/protobuf.py +3 -1
  19. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/metadata/lambda_metadata.py +1 -0
  20. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parameters/base.py +1 -1
  21. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parameters/dynamodb.py +2 -2
  22. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parameters/secrets.py +2 -2
  23. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parameters/ssm.py +2 -2
  24. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/pyproject.toml +7 -7
  25. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/setup.py +2 -2
  26. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/LICENSE +0 -0
  27. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/README.md +0 -0
  28. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/THIRD-PARTY-LICENSES +0 -0
  29. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/__init__.py +0 -0
  30. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/appsync.py +0 -0
  31. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/bedrock_agent.py +0 -0
  32. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/bedrock_agent_function.py +0 -0
  33. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/content_types.py +0 -0
  34. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/events_appsync/__init__.py +0 -0
  35. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/events_appsync/_registry.py +0 -0
  36. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/events_appsync/appsync_events.py +0 -0
  37. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/events_appsync/base.py +0 -0
  38. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/events_appsync/exceptions.py +0 -0
  39. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/events_appsync/functions.py +0 -0
  40. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/events_appsync/router.py +0 -0
  41. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/events_appsync/types.py +0 -0
  42. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/exception_handling.py +0 -0
  43. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/exceptions.py +0 -0
  44. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/graphql_appsync/__init__.py +0 -0
  45. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/graphql_appsync/_registry.py +0 -0
  46. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/graphql_appsync/base.py +0 -0
  47. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/graphql_appsync/exceptions.py +0 -0
  48. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/graphql_appsync/router.py +0 -0
  49. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/lambda_function_url.py +0 -0
  50. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/middlewares/__init__.py +0 -0
  51. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/middlewares/base.py +0 -0
  52. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/middlewares/schema_validation.py +0 -0
  53. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/openapi/__init__.py +0 -0
  54. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/openapi/compat.py +0 -0
  55. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/openapi/config.py +0 -0
  56. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/openapi/constants.py +0 -0
  57. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/openapi/encoders.py +0 -0
  58. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/openapi/exceptions.py +0 -0
  59. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/openapi/models.py +0 -0
  60. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/openapi/pydantic_loader.py +0 -0
  61. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/openapi/swagger_ui/__init__.py +0 -0
  62. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/openapi/swagger_ui/html.py +0 -0
  63. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/openapi/swagger_ui/oauth2.py +0 -0
  64. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/openapi/swagger_ui/swagger-ui-bundle.min.js +0 -0
  65. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/openapi/swagger_ui/swagger-ui.min.css +0 -0
  66. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/openapi/types.py +0 -0
  67. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/router.py +0 -0
  68. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/types.py +0 -0
  69. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/util.py +0 -0
  70. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/event_handler/vpc_lattice.py +0 -0
  71. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/exceptions/__init__.py +0 -0
  72. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/logging/__init__.py +0 -0
  73. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/logging/buffer/__init__.py +0 -0
  74. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/logging/buffer/cache.py +0 -0
  75. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/logging/buffer/config.py +0 -0
  76. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/logging/buffer/functions.py +0 -0
  77. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/logging/buffer/handler.py +0 -0
  78. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/logging/constants.py +0 -0
  79. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/logging/correlation_paths.py +0 -0
  80. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/logging/exceptions.py +0 -0
  81. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/logging/filters.py +0 -0
  82. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/logging/formatter.py +0 -0
  83. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/logging/formatters/__init__.py +0 -0
  84. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/logging/formatters/datadog.py +0 -0
  85. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/logging/lambda_context.py +0 -0
  86. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/logging/logger.py +0 -0
  87. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/logging/types.py +0 -0
  88. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/logging/utils.py +0 -0
  89. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/metrics/__init__.py +0 -0
  90. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/metrics/base.py +0 -0
  91. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/metrics/exceptions.py +0 -0
  92. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/metrics/functions.py +0 -0
  93. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/metrics/metric.py +0 -0
  94. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/metrics/metrics.py +0 -0
  95. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/metrics/provider/__init__.py +0 -0
  96. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/metrics/provider/base.py +0 -0
  97. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/metrics/provider/cloudwatch_emf/__init__.py +0 -0
  98. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/metrics/provider/cloudwatch_emf/cloudwatch.py +0 -0
  99. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/metrics/provider/cloudwatch_emf/constants.py +0 -0
  100. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/metrics/provider/cloudwatch_emf/exceptions.py +0 -0
  101. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/metrics/provider/cloudwatch_emf/metric_properties.py +0 -0
  102. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/metrics/provider/cloudwatch_emf/types.py +0 -0
  103. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/metrics/provider/cold_start.py +0 -0
  104. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/metrics/provider/datadog/__init__.py +0 -0
  105. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/metrics/provider/datadog/datadog.py +0 -0
  106. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/metrics/provider/datadog/metrics.py +0 -0
  107. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/metrics/provider/datadog/warnings.py +0 -0
  108. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/metrics/types.py +0 -0
  109. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/middleware_factory/__init__.py +0 -0
  110. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/middleware_factory/exceptions.py +0 -0
  111. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/middleware_factory/factory.py +0 -0
  112. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/package_logger.py +0 -0
  113. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/py.typed +0 -0
  114. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/shared/__init__.py +0 -0
  115. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/shared/cache_dict.py +0 -0
  116. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/shared/constants.py +0 -0
  117. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/shared/cookies.py +0 -0
  118. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/shared/dynamodb_deserializer.py +0 -0
  119. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/shared/functions.py +0 -0
  120. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/shared/headers_serializer.py +0 -0
  121. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/shared/json_encoder.py +0 -0
  122. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/shared/lazy_import.py +0 -0
  123. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/shared/types.py +0 -0
  124. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/shared/user_agent.py +0 -0
  125. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/tracing/__init__.py +0 -0
  126. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/tracing/base.py +0 -0
  127. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/tracing/extensions.py +0 -0
  128. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/tracing/tracer.py +0 -0
  129. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/__init__.py +0 -0
  130. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/batch/__init__.py +0 -0
  131. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/batch/base.py +0 -0
  132. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/batch/decorators.py +0 -0
  133. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/batch/exceptions.py +0 -0
  134. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/batch/sqs_fifo_partial_processor.py +0 -0
  135. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/batch/types.py +0 -0
  136. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/__init__.py +0 -0
  137. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/active_mq_event.py +0 -0
  138. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/alb_event.py +0 -0
  139. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/api_gateway_websocket_event.py +0 -0
  140. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/appsync/__init__.py +0 -0
  141. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/appsync/scalar_types_utils.py +0 -0
  142. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/appsync_authorizer_event.py +0 -0
  143. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/appsync_resolver_event.py +0 -0
  144. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/appsync_resolver_events_event.py +0 -0
  145. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/aws_config_rule_event.py +0 -0
  146. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/bedrock_agent_event.py +0 -0
  147. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/bedrock_agent_function_event.py +0 -0
  148. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/cloud_watch_alarm_event.py +0 -0
  149. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/cloud_watch_custom_widget_event.py +0 -0
  150. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/cloud_watch_logs_event.py +0 -0
  151. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/cloudformation_custom_resource_event.py +0 -0
  152. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/code_deploy_lifecycle_hook_event.py +0 -0
  153. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/code_pipeline_job_event.py +0 -0
  154. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/cognito_user_pool_event.py +0 -0
  155. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/connect_contact_flow_event.py +0 -0
  156. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/dynamo_db_stream_event.py +0 -0
  157. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/event_bridge_event.py +0 -0
  158. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/event_source.py +0 -0
  159. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/iot_registry_event.py +0 -0
  160. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/kafka_event.py +0 -0
  161. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py +0 -0
  162. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/kinesis_stream_event.py +0 -0
  163. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/lambda_function_url_event.py +0 -0
  164. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/rabbit_mq_event.py +0 -0
  165. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/s3_batch_operation_event.py +0 -0
  166. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/s3_event.py +0 -0
  167. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/s3_object_event.py +0 -0
  168. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/secrets_manager_event.py +0 -0
  169. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/ses_event.py +0 -0
  170. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/shared_functions.py +0 -0
  171. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/sns_event.py +0 -0
  172. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/sqs_event.py +0 -0
  173. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/transfer_family_event.py +0 -0
  174. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_classes/vpc_lattice.py +0 -0
  175. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_masking/__init__.py +0 -0
  176. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_masking/constants.py +0 -0
  177. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_masking/exceptions.py +0 -0
  178. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_masking/provider/__init__.py +0 -0
  179. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_masking/provider/base.py +0 -0
  180. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_masking/provider/kms/__init__.py +0 -0
  181. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/data_masking/provider/kms/aws_encryption_sdk.py +0 -0
  182. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/feature_flags/__init__.py +0 -0
  183. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/feature_flags/appconfig.py +0 -0
  184. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/feature_flags/base.py +0 -0
  185. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/feature_flags/comparators.py +0 -0
  186. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/feature_flags/constants.py +0 -0
  187. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/feature_flags/exceptions.py +0 -0
  188. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/feature_flags/schema.py +0 -0
  189. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/feature_flags/types.py +0 -0
  190. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/idempotency/__init__.py +0 -0
  191. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/idempotency/config.py +0 -0
  192. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/idempotency/exceptions.py +0 -0
  193. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/idempotency/hook.py +0 -0
  194. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/idempotency/idempotency.py +0 -0
  195. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/idempotency/persistence/__init__.py +0 -0
  196. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/idempotency/persistence/cache.py +0 -0
  197. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/idempotency/persistence/datarecord.py +0 -0
  198. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py +0 -0
  199. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/idempotency/persistence/redis.py +0 -0
  200. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/idempotency/serialization/__init__.py +0 -0
  201. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/idempotency/serialization/base.py +0 -0
  202. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/idempotency/serialization/custom_dict.py +0 -0
  203. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/idempotency/serialization/dataclass.py +0 -0
  204. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/idempotency/serialization/functions.py +0 -0
  205. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/idempotency/serialization/no_op.py +0 -0
  206. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/idempotency/serialization/pydantic.py +0 -0
  207. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/jmespath_utils/__init__.py +0 -0
  208. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/jmespath_utils/envelopes.py +0 -0
  209. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/kafka/__init__.py +0 -0
  210. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/kafka/consumer_records.py +0 -0
  211. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/kafka/deserializer/__init__.py +0 -0
  212. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/kafka/deserializer/avro.py +0 -0
  213. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/kafka/deserializer/base.py +0 -0
  214. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/kafka/deserializer/default.py +0 -0
  215. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/kafka/deserializer/deserializer.py +0 -0
  216. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/kafka/deserializer/json.py +0 -0
  217. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/kafka/exceptions.py +0 -0
  218. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/kafka/kafka_consumer.py +0 -0
  219. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/kafka/schema_config.py +0 -0
  220. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/kafka/serialization/__init__.py +0 -0
  221. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/kafka/serialization/base.py +0 -0
  222. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/kafka/serialization/custom_dict.py +0 -0
  223. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/kafka/serialization/dataclass.py +0 -0
  224. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/kafka/serialization/pydantic.py +0 -0
  225. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/kafka/serialization/serialization.py +0 -0
  226. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/kafka/serialization/types.py +0 -0
  227. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/metadata/__init__.py +0 -0
  228. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/metadata/exceptions.py +0 -0
  229. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parameters/__init__.py +0 -0
  230. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parameters/appconfig.py +0 -0
  231. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parameters/constants.py +0 -0
  232. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parameters/exceptions.py +0 -0
  233. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parameters/types.py +0 -0
  234. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/__init__.py +0 -0
  235. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/envelopes/__init__.py +0 -0
  236. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/envelopes/apigw.py +0 -0
  237. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/envelopes/apigw_websocket.py +0 -0
  238. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/envelopes/apigwv2.py +0 -0
  239. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/envelopes/base.py +0 -0
  240. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/envelopes/bedrock_agent.py +0 -0
  241. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/envelopes/cloudwatch.py +0 -0
  242. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/envelopes/dynamodb.py +0 -0
  243. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/envelopes/event_bridge.py +0 -0
  244. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/envelopes/kafka.py +0 -0
  245. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/envelopes/kinesis.py +0 -0
  246. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/envelopes/kinesis_firehose.py +0 -0
  247. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/envelopes/lambda_function_url.py +0 -0
  248. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/envelopes/sns.py +0 -0
  249. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/envelopes/sqs.py +0 -0
  250. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/envelopes/vpc_lattice.py +0 -0
  251. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/envelopes/vpc_latticev2.py +0 -0
  252. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/exceptions.py +0 -0
  253. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/functions.py +0 -0
  254. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/models/__init__.py +0 -0
  255. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/models/alb.py +0 -0
  256. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/models/apigw.py +0 -0
  257. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/models/apigw_websocket.py +0 -0
  258. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/models/apigwv2.py +0 -0
  259. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/models/appsync.py +0 -0
  260. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/models/appsync_events.py +0 -0
  261. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/models/bedrock_agent.py +0 -0
  262. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/models/cloudformation_custom_resource.py +0 -0
  263. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/models/cloudwatch.py +0 -0
  264. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/models/cognito.py +0 -0
  265. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/models/dynamodb.py +0 -0
  266. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/models/event_bridge.py +0 -0
  267. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/models/iot_registry_events.py +0 -0
  268. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/models/kafka.py +0 -0
  269. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/models/kinesis.py +0 -0
  270. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/models/kinesis_firehose.py +0 -0
  271. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/models/kinesis_firehose_sqs.py +0 -0
  272. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/models/lambda_function_url.py +0 -0
  273. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/models/s3.py +0 -0
  274. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/models/s3_batch_operation.py +0 -0
  275. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py +0 -0
  276. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/models/s3_object_event.py +0 -0
  277. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/models/ses.py +0 -0
  278. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/models/sns.py +0 -0
  279. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/models/sqs.py +0 -0
  280. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/models/transfer_family.py +0 -0
  281. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/models/vpc_lattice.py +0 -0
  282. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/models/vpc_latticev2.py +0 -0
  283. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/parser.py +0 -0
  284. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/parser/types.py +0 -0
  285. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/serialization.py +0 -0
  286. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/streaming/__init__.py +0 -0
  287. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/streaming/_s3_seekable_io.py +0 -0
  288. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/streaming/compat.py +0 -0
  289. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/streaming/constants.py +0 -0
  290. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/streaming/s3_object.py +0 -0
  291. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/streaming/transformations/__init__.py +0 -0
  292. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/streaming/transformations/base.py +0 -0
  293. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/streaming/transformations/csv.py +0 -0
  294. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/streaming/transformations/gzip.py +0 -0
  295. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/streaming/transformations/zip.py +0 -0
  296. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/streaming/types.py +0 -0
  297. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/typing/__init__.py +0 -0
  298. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/typing/lambda_client_context.py +0 -0
  299. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/typing/lambda_client_context_mobile_client.py +0 -0
  300. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/typing/lambda_cognito_identity.py +0 -0
  301. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/typing/lambda_context.py +0 -0
  302. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/validation/__init__.py +0 -0
  303. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/validation/base.py +0 -0
  304. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/validation/envelopes.py +0 -0
  305. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/validation/exceptions.py +0 -0
  306. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.0}/aws_lambda_powertools/utilities/validation/validator.py +0 -0
  307. {aws_lambda_powertools-3.26.0 → aws_lambda_powertools-3.27.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.26.0
3
+ Version: 3.27.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
@@ -36,7 +36,7 @@ Requires-Dist: datadog-lambda (>=8.114.0,<9.0.0) ; extra == "datadog"
36
36
  Requires-Dist: fastjsonschema (>=2.14.5,<3.0.0) ; extra == "validation" or extra == "all"
37
37
  Requires-Dist: jmespath (>=1.0.1,<2.0.0)
38
38
  Requires-Dist: jsonpath-ng (>=1.6.0,<2.0.0) ; extra == "all" or extra == "datamasking"
39
- Requires-Dist: protobuf (>=6.30.2,<7.0.0) ; extra == "kafka-consumer-protobuf"
39
+ Requires-Dist: protobuf (>=6.30.2,<8.0.0) ; extra == "kafka-consumer-protobuf"
40
40
  Requires-Dist: pydantic (>=2.4.0,<3.0.0) ; extra == "parser" or extra == "all"
41
41
  Requires-Dist: pydantic-settings (>=2.6.1,<3.0.0) ; extra == "all"
42
42
  Requires-Dist: redis (>=4.4,<8.0) ; extra == "redis"
@@ -21,6 +21,7 @@ from aws_lambda_powertools.event_handler.http_resolver import HttpResolverLocal
21
21
  from aws_lambda_powertools.event_handler.lambda_function_url import (
22
22
  LambdaFunctionUrlResolver,
23
23
  )
24
+ from aws_lambda_powertools.event_handler.request import Request
24
25
  from aws_lambda_powertools.event_handler.vpc_lattice import VPCLatticeResolver, VPCLatticeV2Resolver
25
26
 
26
27
  __all__ = [
@@ -37,6 +38,7 @@ __all__ = [
37
38
  "CORSConfig",
38
39
  "HttpResolverLocal",
39
40
  "LambdaFunctionUrlResolver",
41
+ "Request",
40
42
  "Response",
41
43
  "VPCLatticeResolver",
42
44
  "VPCLatticeV2Resolver",
@@ -42,6 +42,7 @@ from aws_lambda_powertools.event_handler.openapi.types import (
42
42
  validation_error_definition,
43
43
  validation_error_response_definition,
44
44
  )
45
+ from aws_lambda_powertools.event_handler.request import Request
45
46
  from aws_lambda_powertools.event_handler.util import (
46
47
  _FrozenDict,
47
48
  _FrozenListDict,
@@ -466,6 +467,11 @@ class Route:
466
467
 
467
468
  self.custom_response_validation_http_code = custom_response_validation_http_code
468
469
 
470
+ # Caches the name of any Request-typed parameter in the handler.
471
+ # Avoids re-scanning the signature on every invocation.
472
+ self.request_param_name: str | None = None
473
+ self.request_param_name_checked: bool = False
474
+
469
475
  def __call__(
470
476
  self,
471
477
  router_middlewares: list[Callable],
@@ -1608,6 +1614,47 @@ class BaseRouter(ABC):
1608
1614
  """Resets routing context"""
1609
1615
  self.context.clear()
1610
1616
 
1617
+ @property
1618
+ def request(self) -> Request:
1619
+ """Current resolved :class:`Request` object.
1620
+
1621
+ Available inside middleware and in route handlers that declare a parameter
1622
+ typed as :class:`Request <aws_lambda_powertools.event_handler.request.Request>`.
1623
+
1624
+ Raises
1625
+ ------
1626
+ RuntimeError
1627
+ When accessed before route resolution (i.e. outside of middleware / handler scope).
1628
+
1629
+ Examples
1630
+ --------
1631
+ **Middleware**
1632
+
1633
+ ```python
1634
+ def my_middleware(app, next_middleware):
1635
+ req = app.request
1636
+ print(req.route, req.method, req.path_parameters)
1637
+ return next_middleware(app)
1638
+ ```
1639
+ """
1640
+ cached: Request | None = self.context.get("_request")
1641
+ if cached is not None:
1642
+ return cached
1643
+
1644
+ route: Route | None = self.context.get("_route")
1645
+ if route is None:
1646
+ raise RuntimeError(
1647
+ "app.request is only available after route resolution. Use it inside middleware or a route handler.",
1648
+ )
1649
+
1650
+ request = Request(
1651
+ route_path=route.openapi_path,
1652
+ path_parameters=self.context.get("_route_args", {}),
1653
+ current_event=self.current_event,
1654
+ )
1655
+ self.context["_request"] = request
1656
+ return request
1657
+
1611
1658
 
1612
1659
  class MiddlewareFrame:
1613
1660
  """
@@ -1680,6 +1727,24 @@ class MiddlewareFrame:
1680
1727
  return self.current_middleware(app, self.next_middleware)
1681
1728
 
1682
1729
 
1730
+ def _find_request_param_name(func: Callable) -> str | None:
1731
+ """Return the name of the first parameter annotated as ``Request``, or ``None``."""
1732
+ from typing import get_type_hints
1733
+
1734
+ try:
1735
+ # get_type_hints resolves string annotations from ``from __future__ import annotations``
1736
+ # using the function's own module globals.
1737
+ hints = get_type_hints(func)
1738
+ except Exception:
1739
+ hints = {}
1740
+
1741
+ for param_name, annotation in hints.items():
1742
+ if annotation is Request:
1743
+ return param_name
1744
+
1745
+ return None
1746
+
1747
+
1683
1748
  def _registered_api_adapter(
1684
1749
  app: ApiGatewayResolver,
1685
1750
  next_middleware: Callable[..., Any],
@@ -1708,6 +1773,17 @@ def _registered_api_adapter(
1708
1773
  """
1709
1774
  route_args: dict = app.context.get("_route_args", {})
1710
1775
  logger.debug(f"Calling API Route Handler: {route_args}")
1776
+
1777
+ # Inject a Request object when the handler declares a parameter typed as Request.
1778
+ # Lookup is cached on the Route object to avoid repeated signature inspection.
1779
+ route: Route | None = app.context.get("_route")
1780
+ if route is not None:
1781
+ if not route.request_param_name_checked:
1782
+ route.request_param_name = _find_request_param_name(next_middleware)
1783
+ route.request_param_name_checked = True
1784
+ if route.request_param_name:
1785
+ route_args = {**route_args, route.request_param_name: app.request}
1786
+
1711
1787
  return app._to_response(next_middleware(**route_args))
1712
1788
 
1713
1789
 
@@ -3,6 +3,7 @@ from __future__ import annotations
3
3
  import asyncio
4
4
  import base64
5
5
  import inspect
6
+ import threading
6
7
  import warnings
7
8
  from typing import TYPE_CHECKING, Any, Callable
8
9
  from urllib.parse import parse_qs
@@ -324,36 +325,65 @@ class HttpResolverLocal(ApiGatewayResolver):
324
325
  return await next_handler(self)
325
326
 
326
327
  def _wrap_middleware_async(self, middleware: Callable, next_handler: Callable) -> Callable:
327
- """Wrap a middleware to work in async context."""
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.
335
+ """
328
336
 
329
337
  async def wrapped(app):
330
- # Create a next_middleware that the sync middleware can call
331
- def sync_next(app):
332
- # This will be called by sync middleware
333
- # We need to run the async next_handler
334
- loop = asyncio.get_event_loop()
335
- if loop.is_running():
336
- # We're in an async context, create a task
337
- future = asyncio.ensure_future(next_handler(app))
338
- # Store for later await
339
- app.context["_async_next_result"] = future
340
- return Response(status_code=200, body="") # Placeholder
341
- else: # pragma: no cover
342
- return loop.run_until_complete(next_handler(app))
343
-
344
- # Check if middleware is async
345
338
  if inspect.iscoroutinefunction(middleware):
346
- result = await middleware(app, next_handler)
347
- else:
348
- # Sync middleware - need special handling
349
- result = middleware(app, sync_next)
339
+ return await middleware(app, next_handler)
350
340
 
351
- # Check if we stored an async result
352
- if "_async_next_result" in app.context:
353
- future = app.context.pop("_async_next_result")
354
- result = await future
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 = []
355
349
 
356
- return result
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]
357
387
 
358
388
  return wrapped
359
389
 
@@ -1,12 +1,15 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import base64
3
4
  import dataclasses
4
5
  import json
5
6
  import logging
6
- from typing import TYPE_CHECKING, Any, Callable, Mapping, MutableMapping, Sequence, cast
7
+ import warnings
8
+ from typing import TYPE_CHECKING, Any, Callable, Mapping, MutableMapping, Sequence, Union, cast
7
9
  from urllib.parse import parse_qs
8
10
 
9
11
  from pydantic import BaseModel
12
+ from typing_extensions import get_args, get_origin
10
13
 
11
14
  from aws_lambda_powertools.event_handler.middlewares import BaseMiddlewareHandler
12
15
  from aws_lambda_powertools.event_handler.openapi.compat import (
@@ -24,7 +27,8 @@ from aws_lambda_powertools.event_handler.openapi.exceptions import (
24
27
  RequestValidationError,
25
28
  ResponseValidationError,
26
29
  )
27
- from aws_lambda_powertools.event_handler.openapi.params import Param
30
+ from aws_lambda_powertools.event_handler.openapi.params import Param, UploadFile
31
+ from aws_lambda_powertools.event_handler.openapi.types import UnionType
28
32
 
29
33
  if TYPE_CHECKING:
30
34
  from pydantic.fields import FieldInfo
@@ -42,6 +46,7 @@ logger = logging.getLogger(__name__)
42
46
  CONTENT_DISPOSITION_NAME_PARAM = "name="
43
47
  APPLICATION_JSON_CONTENT_TYPE = "application/json"
44
48
  APPLICATION_FORM_CONTENT_TYPE = "application/x-www-form-urlencoded"
49
+ MULTIPART_FORM_DATA_CONTENT_TYPE = "multipart/form-data"
45
50
 
46
51
 
47
52
  class OpenAPIRequestValidationMiddleware(BaseMiddlewareHandler):
@@ -94,10 +99,17 @@ class OpenAPIRequestValidationMiddleware(BaseMiddlewareHandler):
94
99
  headers,
95
100
  )
96
101
 
102
+ # Process cookie values
103
+ cookie_values, cookie_errors = _request_params_to_args(
104
+ route.dependant.cookie_params,
105
+ app.current_event.resolved_cookies_field,
106
+ )
107
+
97
108
  values.update(path_values)
98
109
  values.update(query_values)
99
110
  values.update(header_values)
100
- errors += path_errors + query_errors + header_errors
111
+ values.update(cookie_values)
112
+ errors += path_errors + query_errors + header_errors + cookie_errors
101
113
 
102
114
  # Process the request body, if it exists
103
115
  if route.dependant.body_params:
@@ -132,14 +144,18 @@ class OpenAPIRequestValidationMiddleware(BaseMiddlewareHandler):
132
144
  elif content_type.startswith(APPLICATION_FORM_CONTENT_TYPE):
133
145
  return self._parse_form_data(app)
134
146
 
147
+ # Handle multipart/form-data (file uploads)
148
+ elif content_type.startswith(MULTIPART_FORM_DATA_CONTENT_TYPE):
149
+ return self._parse_multipart_data(app, content_type)
150
+
135
151
  else:
136
152
  raise RequestUnsupportedContentType(
137
- "Only JSON body or Form() are supported",
153
+ "Unsupported content type",
138
154
  errors=[
139
155
  {
140
156
  "type": "unsupported_content_type",
141
157
  "loc": ("body",),
142
- "msg": "Only JSON body or Form() are supported",
158
+ "msg": f"Unsupported content type: {content_type}",
143
159
  "input": {},
144
160
  "ctx": {},
145
161
  },
@@ -186,6 +202,49 @@ class OpenAPIRequestValidationMiddleware(BaseMiddlewareHandler):
186
202
  ],
187
203
  ) from e
188
204
 
205
+ def _parse_multipart_data(self, app: EventHandlerInstance, content_type: str) -> dict[str, Any]:
206
+ """Parse multipart/form-data from the request body (file uploads)."""
207
+ try:
208
+ # Extract the boundary from the content-type header
209
+ boundary = _extract_multipart_boundary(content_type)
210
+ if not boundary:
211
+ raise ValueError("Missing boundary in multipart/form-data content-type header")
212
+
213
+ # Get raw body bytes
214
+ raw_body = app.current_event.body or ""
215
+ if app.current_event.is_base64_encoded:
216
+ body_bytes = base64.b64decode(raw_body)
217
+ else:
218
+ warnings.warn(
219
+ "Received multipart/form-data without base64 encoding. "
220
+ "Binary file uploads may be corrupted. "
221
+ "If using API Gateway REST API (v1), configure Binary Media Types "
222
+ "to include 'multipart/form-data'. "
223
+ "See: https://docs.aws.amazon.com/apigateway/latest/developerguide/"
224
+ "api-gateway-payload-encodings.html",
225
+ stacklevel=2,
226
+ )
227
+ # Use latin-1 to preserve all byte values (0-255) since the body
228
+ # may contain raw binary data that isn't valid UTF-8
229
+ body_bytes = raw_body.encode("latin-1")
230
+
231
+ return _parse_multipart_body(body_bytes, boundary)
232
+
233
+ except ValueError:
234
+ raise
235
+ except Exception as e:
236
+ raise RequestValidationError(
237
+ [
238
+ {
239
+ "type": "multipart_invalid",
240
+ "loc": ("body",),
241
+ "msg": "Multipart form data parsing error",
242
+ "input": {},
243
+ "ctx": {"error": str(e)},
244
+ },
245
+ ],
246
+ ) from e
247
+
189
248
 
190
249
  class OpenAPIResponseValidationMiddleware(BaseMiddlewareHandler):
191
250
  """
@@ -389,7 +448,12 @@ def _request_body_to_args(
389
448
  continue
390
449
 
391
450
  value = _normalize_field_value(value=value, field_info=field.field_info)
392
- values[field.name] = _validate_field(field=field, value=value, loc=loc, existing_errors=errors)
451
+
452
+ # UploadFile objects bypass Pydantic validation — they're already constructed
453
+ if isinstance(value, UploadFile):
454
+ values[field.name] = value
455
+ else:
456
+ values[field.name] = _validate_field(field=field, value=value, loc=loc, existing_errors=errors)
393
457
 
394
458
  return values, errors
395
459
 
@@ -431,9 +495,45 @@ def _handle_missing_field_value(
431
495
  values[field.name] = field.get_default()
432
496
 
433
497
 
498
+ def _is_or_contains_sequence(annotation: Any) -> bool:
499
+ """
500
+ Check if annotation is a sequence or Union/RootModel containing a sequence.
501
+
502
+ This function handles complex type annotations like:
503
+ - List[Model] - direct sequence
504
+ - Union[Model, List[Model]] - checks if any Union member is a sequence
505
+ - Optional[List[Model]] - Union[List[Model], None]
506
+ - RootModel[List[Model]] - checks if the RootModel wraps a sequence
507
+ - Optional[RootModel[List[Model]]] - Union member that is a RootModel
508
+ - RootModel[Union[Model, List[Model]]] - RootModel wrapping a Union with a sequence
509
+ """
510
+ # Direct sequence check
511
+ if field_annotation_is_sequence(annotation):
512
+ return True
513
+
514
+ # Check Union members — recurse so we catch RootModel inside Union
515
+ origin = get_origin(annotation)
516
+ if origin is Union or origin is UnionType:
517
+ for arg in get_args(annotation):
518
+ if _is_or_contains_sequence(arg):
519
+ return True
520
+
521
+ # Check if it's a RootModel wrapping a sequence (or Union containing a sequence)
522
+ if lenient_issubclass(annotation, BaseModel) and getattr(annotation, "__pydantic_root_model__", False):
523
+ if hasattr(annotation, "model_fields") and "root" in annotation.model_fields:
524
+ root_annotation = annotation.model_fields["root"].annotation
525
+ return _is_or_contains_sequence(root_annotation)
526
+
527
+ return False
528
+
529
+
434
530
  def _normalize_field_value(value: Any, field_info: FieldInfo) -> Any:
435
531
  """Normalize field value, converting lists to single values for non-sequence fields."""
436
- if field_annotation_is_sequence(field_info.annotation):
532
+ # When annotation is bytes but value is UploadFile, extract raw content
533
+ if isinstance(value, UploadFile) and field_info.annotation is bytes:
534
+ return value.content
535
+
536
+ if _is_or_contains_sequence(field_info.annotation):
437
537
  return value
438
538
  elif isinstance(value, list) and value:
439
539
  return value[0]
@@ -546,3 +646,106 @@ def _get_param_value(
546
646
  value = input_dict.get(field_name)
547
647
 
548
648
  return value
649
+
650
+
651
+ def _extract_multipart_boundary(content_type: str) -> str | None:
652
+ """Extract the boundary string from a multipart/form-data content-type header."""
653
+ for segment in content_type.split(";"):
654
+ stripped = segment.strip()
655
+ if stripped.startswith("boundary="):
656
+ boundary = stripped[len("boundary=") :]
657
+ # Remove optional quotes around boundary
658
+ if boundary.startswith('"') and boundary.endswith('"'):
659
+ boundary = boundary[1:-1]
660
+ return boundary
661
+ return None
662
+
663
+
664
+ def _parse_multipart_body(body: bytes, boundary: str) -> dict[str, Any]:
665
+ """
666
+ Parse a multipart/form-data body into a dict of field names to values.
667
+
668
+ File fields get bytes values; regular form fields get string values.
669
+ Multiple values for the same field name are collected into lists.
670
+ """
671
+ delimiter = f"--{boundary}".encode()
672
+ end_delimiter = f"--{boundary}--".encode()
673
+
674
+ result: dict[str, Any] = {}
675
+
676
+ # Split body by the boundary delimiter
677
+ raw_parts = body.split(delimiter)
678
+
679
+ for raw_part in raw_parts:
680
+ # Skip the preamble (before first boundary) and epilogue (after closing boundary)
681
+ if not raw_part or raw_part.strip() == b"" or raw_part.strip() == b"--":
682
+ continue
683
+
684
+ # Remove the end delimiter marker if present
685
+ chunk = raw_part
686
+ if chunk.endswith(end_delimiter):
687
+ chunk = chunk[: -len(end_delimiter)]
688
+
689
+ # Strip leading \r\n
690
+ if chunk.startswith(b"\r\n"):
691
+ chunk = chunk[2:]
692
+
693
+ # Strip trailing \r\n
694
+ if chunk.endswith(b"\r\n"):
695
+ chunk = chunk[:-2]
696
+
697
+ # Split headers from body at the double CRLF
698
+ header_end = chunk.find(b"\r\n\r\n")
699
+ if header_end == -1:
700
+ continue
701
+
702
+ header_section = chunk[:header_end].decode("utf-8")
703
+ body_section = chunk[header_end + 4 :]
704
+
705
+ # Parse Content-Disposition to get the field name and optional filename
706
+ field_name = None
707
+ filename = None
708
+ content_type_header = None
709
+
710
+ for header_line in header_section.split("\r\n"):
711
+ header_lower = header_line.lower()
712
+ if header_lower.startswith("content-disposition:"):
713
+ field_name = _extract_header_param(header_line, "name")
714
+ filename = _extract_header_param(header_line, "filename")
715
+ elif header_lower.startswith("content-type:"):
716
+ content_type_header = header_line.split(":", 1)[1].strip()
717
+
718
+ if field_name is None:
719
+ continue
720
+
721
+ # If it has a filename, it's a file upload — wrap as UploadFile
722
+ # Otherwise it's a regular form field — decode to string
723
+ if filename is not None:
724
+ value: Any = UploadFile(content=body_section, filename=filename, content_type=content_type_header)
725
+ else:
726
+ value = body_section.decode("utf-8")
727
+
728
+ # Collect multiple values for same field name into a list
729
+ if field_name in result:
730
+ existing = result[field_name]
731
+ if isinstance(existing, list):
732
+ existing.append(value)
733
+ else:
734
+ result[field_name] = [existing, value]
735
+ else:
736
+ result[field_name] = value
737
+
738
+ return result
739
+
740
+
741
+ def _extract_header_param(header_line: str, param_name: str) -> str | None:
742
+ """Extract a parameter value from a header line (e.g., name="file" from Content-Disposition)."""
743
+ search = f'{param_name}="'
744
+ idx = header_line.find(search)
745
+ if idx == -1:
746
+ return None
747
+ start = idx + len(search)
748
+ end = header_line.find('"', start)
749
+ if end == -1:
750
+ return None
751
+ return header_line[start:end]
@@ -13,15 +13,16 @@ from aws_lambda_powertools.event_handler.openapi.compat import (
13
13
  from aws_lambda_powertools.event_handler.openapi.params import (
14
14
  Body,
15
15
  Dependant,
16
+ File,
16
17
  Form,
17
18
  Param,
18
19
  ParamTypes,
19
- _File,
20
20
  analyze_param,
21
21
  create_response_field,
22
22
  get_flat_dependant,
23
23
  )
24
24
  from aws_lambda_powertools.event_handler.openapi.types import OpenAPIResponse, OpenAPIResponseContentModel
25
+ from aws_lambda_powertools.event_handler.request import Request
25
26
 
26
27
  if TYPE_CHECKING:
27
28
  from collections.abc import Callable
@@ -187,6 +188,11 @@ def get_dependant(
187
188
 
188
189
  # Add each parameter to the dependant model
189
190
  for param_name, param in signature_params.items():
191
+ # Request-typed parameters are injected by the resolver at call time;
192
+ # they carry no OpenAPI meaning and must be excluded from schema generation.
193
+ if param.annotation is Request:
194
+ continue
195
+
190
196
  # If the parameter is a path parameter, we need to set the in_ field to "path".
191
197
  is_path_param = param_name in path_param_names
192
198
 
@@ -364,9 +370,9 @@ def get_body_field_info(
364
370
  if not required:
365
371
  body_field_info_kwargs["default"] = None
366
372
 
367
- if any(isinstance(f.field_info, _File) for f in flat_dependant.body_params):
368
- # MAINTENANCE: body_field_info: type[Body] = _File
369
- raise NotImplementedError("_File fields are not supported in request bodies")
373
+ if any(isinstance(f.field_info, File) for f in flat_dependant.body_params):
374
+ body_field_info = Body
375
+ body_field_info_kwargs["media_type"] = "multipart/form-data"
370
376
  elif any(isinstance(f.field_info, Form) for f in flat_dependant.body_params):
371
377
  body_field_info = Body
372
378
  body_field_info_kwargs["media_type"] = "application/x-www-form-urlencoded"
@@ -67,11 +67,18 @@ def _file_has_resolver(file_path: Path, resolver_name: str) -> bool:
67
67
  return False
68
68
 
69
69
  for node in ast.walk(tree):
70
+ targets: list[ast.expr] = []
71
+ value: ast.expr | None = None
70
72
  if isinstance(node, ast.Assign):
71
- for target in node.targets:
72
- if isinstance(target, ast.Name) and target.id == resolver_name:
73
- if _is_resolver_call(node.value):
74
- return True
73
+ targets = node.targets
74
+ value = node.value
75
+ elif isinstance(node, ast.AnnAssign):
76
+ targets = [node.target]
77
+ value = node.value
78
+ for target in targets:
79
+ if isinstance(target, ast.Name) and target.id == resolver_name:
80
+ if value is not None and _is_resolver_call(value):
81
+ return True
75
82
  return False
76
83
 
77
84