aws-lambda-powertools 3.34.0__tar.gz → 3.35.0__tar.gz

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