aws-lambda-powertools 2.35.1__tar.gz → 2.36.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 (240) hide show
  1. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/PKG-INFO +1 -1
  2. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/event_handler/api_gateway.py +51 -32
  3. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/event_handler/openapi/types.py +1 -1
  4. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/logging/logger.py +1 -1
  5. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/metrics/base.py +32 -1
  6. aws_lambda_powertools-2.36.0/aws_lambda_powertools/metrics/functions.py +137 -0
  7. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/metrics/metrics.py +13 -0
  8. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/metrics/provider/cloudwatch_emf/cloudwatch.py +29 -1
  9. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/shared/constants.py +41 -33
  10. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/shared/functions.py +5 -7
  11. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/shared/version.py +1 -1
  12. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/tracing/tracer.py +14 -7
  13. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/batch/exceptions.py +16 -0
  14. aws_lambda_powertools-2.36.0/aws_lambda_powertools/utilities/batch/sqs_fifo_partial_processor.py +114 -0
  15. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/__init__.py +14 -0
  16. aws_lambda_powertools-2.36.0/aws_lambda_powertools/utilities/data_classes/cloud_watch_alarm_event.py +243 -0
  17. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/common.py +8 -5
  18. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parameters/__init__.py +4 -2
  19. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parameters/base.py +6 -0
  20. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parameters/exceptions.py +8 -0
  21. aws_lambda_powertools-2.36.0/aws_lambda_powertools/utilities/parameters/secrets.py +444 -0
  22. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parameters/ssm.py +209 -4
  23. aws_lambda_powertools-2.36.0/aws_lambda_powertools/utilities/parameters/types.py +20 -0
  24. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/pyproject.toml +23 -23
  25. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/setup.py +1 -1
  26. aws_lambda_powertools-2.35.1/aws_lambda_powertools/metrics/functions.py +0 -71
  27. aws_lambda_powertools-2.35.1/aws_lambda_powertools/utilities/batch/sqs_fifo_partial_processor.py +0 -92
  28. aws_lambda_powertools-2.35.1/aws_lambda_powertools/utilities/parameters/secrets.py +0 -184
  29. aws_lambda_powertools-2.35.1/aws_lambda_powertools/utilities/parameters/types.py +0 -3
  30. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/LICENSE +0 -0
  31. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/README.md +0 -0
  32. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/THIRD-PARTY-LICENSES +0 -0
  33. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/__init__.py +0 -0
  34. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/event_handler/__init__.py +0 -0
  35. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/event_handler/appsync.py +0 -0
  36. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/event_handler/bedrock_agent.py +0 -0
  37. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/event_handler/content_types.py +0 -0
  38. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/event_handler/exceptions.py +0 -0
  39. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/event_handler/lambda_function_url.py +0 -0
  40. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/event_handler/middlewares/__init__.py +0 -0
  41. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/event_handler/middlewares/base.py +0 -0
  42. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/event_handler/middlewares/openapi_validation.py +0 -0
  43. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/event_handler/middlewares/schema_validation.py +0 -0
  44. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/event_handler/openapi/__init__.py +0 -0
  45. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/event_handler/openapi/compat.py +0 -0
  46. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/event_handler/openapi/constants.py +0 -0
  47. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/event_handler/openapi/dependant.py +0 -0
  48. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/event_handler/openapi/encoders.py +0 -0
  49. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/event_handler/openapi/exceptions.py +0 -0
  50. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/event_handler/openapi/models.py +0 -0
  51. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/event_handler/openapi/params.py +0 -0
  52. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/event_handler/openapi/pydantic_loader.py +0 -0
  53. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/event_handler/openapi/swagger_ui/__init__.py +0 -0
  54. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/event_handler/openapi/swagger_ui/html.py +0 -0
  55. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/event_handler/openapi/swagger_ui/swagger-ui-bundle.min.js +0 -0
  56. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/event_handler/openapi/swagger_ui/swagger-ui.min.css +0 -0
  57. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/event_handler/router.py +0 -0
  58. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/event_handler/types.py +0 -0
  59. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/event_handler/util.py +0 -0
  60. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/event_handler/vpc_lattice.py +0 -0
  61. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/exceptions/__init__.py +0 -0
  62. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/logging/__init__.py +0 -0
  63. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/logging/correlation_paths.py +0 -0
  64. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/logging/exceptions.py +0 -0
  65. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/logging/filters.py +0 -0
  66. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/logging/formatter.py +0 -0
  67. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/logging/formatters/__init__.py +0 -0
  68. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/logging/formatters/datadog.py +0 -0
  69. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/logging/lambda_context.py +0 -0
  70. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/logging/types.py +0 -0
  71. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/logging/utils.py +0 -0
  72. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/metrics/__init__.py +0 -0
  73. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/metrics/exceptions.py +0 -0
  74. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/metrics/metric.py +0 -0
  75. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/metrics/provider/__init__.py +0 -0
  76. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/metrics/provider/base.py +0 -0
  77. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/metrics/provider/cloudwatch_emf/__init__.py +0 -0
  78. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/metrics/provider/cloudwatch_emf/constants.py +0 -0
  79. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/metrics/provider/cloudwatch_emf/exceptions.py +0 -0
  80. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/metrics/provider/cloudwatch_emf/metric_properties.py +0 -0
  81. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/metrics/provider/cloudwatch_emf/types.py +0 -0
  82. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/metrics/provider/cold_start.py +0 -0
  83. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/metrics/provider/datadog/__init__.py +0 -0
  84. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/metrics/provider/datadog/datadog.py +0 -0
  85. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/metrics/provider/datadog/metrics.py +0 -0
  86. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/metrics/provider/datadog/warnings.py +0 -0
  87. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/metrics/types.py +0 -0
  88. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/middleware_factory/__init__.py +0 -0
  89. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/middleware_factory/exceptions.py +0 -0
  90. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/middleware_factory/factory.py +0 -0
  91. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/package_logger.py +0 -0
  92. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/py.typed +0 -0
  93. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/shared/__init__.py +0 -0
  94. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/shared/cache_dict.py +0 -0
  95. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/shared/cookies.py +0 -0
  96. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/shared/headers_serializer.py +0 -0
  97. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/shared/json_encoder.py +0 -0
  98. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/shared/lazy_import.py +0 -0
  99. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/shared/types.py +0 -0
  100. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/shared/user_agent.py +0 -0
  101. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/tracing/__init__.py +0 -0
  102. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/tracing/base.py +0 -0
  103. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/tracing/extensions.py +0 -0
  104. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/__init__.py +0 -0
  105. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/batch/__init__.py +0 -0
  106. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/batch/base.py +0 -0
  107. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/batch/decorators.py +0 -0
  108. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/batch/types.py +0 -0
  109. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/active_mq_event.py +0 -0
  110. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/alb_event.py +0 -0
  111. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/api_gateway_authorizer_event.py +0 -0
  112. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py +0 -0
  113. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/appsync/__init__.py +0 -0
  114. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/appsync/scalar_types_utils.py +0 -0
  115. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/appsync_authorizer_event.py +0 -0
  116. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/appsync_resolver_event.py +0 -0
  117. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/aws_config_rule_event.py +0 -0
  118. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/bedrock_agent_event.py +0 -0
  119. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/cloud_watch_custom_widget_event.py +0 -0
  120. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/cloud_watch_logs_event.py +0 -0
  121. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/code_pipeline_job_event.py +0 -0
  122. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/cognito_user_pool_event.py +0 -0
  123. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/connect_contact_flow_event.py +0 -0
  124. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/dynamo_db_stream_event.py +0 -0
  125. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/event_bridge_event.py +0 -0
  126. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/event_source.py +0 -0
  127. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/kafka_event.py +0 -0
  128. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py +0 -0
  129. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/kinesis_stream_event.py +0 -0
  130. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/lambda_function_url_event.py +0 -0
  131. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/rabbit_mq_event.py +0 -0
  132. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/s3_batch_operation_event.py +0 -0
  133. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/s3_event.py +0 -0
  134. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/s3_object_event.py +0 -0
  135. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/secrets_manager_event.py +0 -0
  136. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/ses_event.py +0 -0
  137. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/shared_functions.py +0 -0
  138. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/sns_event.py +0 -0
  139. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/sqs_event.py +0 -0
  140. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_classes/vpc_lattice.py +0 -0
  141. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_masking/__init__.py +0 -0
  142. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_masking/base.py +0 -0
  143. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_masking/constants.py +0 -0
  144. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_masking/exceptions.py +0 -0
  145. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_masking/provider/__init__.py +0 -0
  146. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_masking/provider/base.py +0 -0
  147. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_masking/provider/kms/__init__.py +0 -0
  148. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/data_masking/provider/kms/aws_encryption_sdk.py +0 -0
  149. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/feature_flags/__init__.py +0 -0
  150. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/feature_flags/appconfig.py +0 -0
  151. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/feature_flags/base.py +0 -0
  152. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/feature_flags/comparators.py +0 -0
  153. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/feature_flags/exceptions.py +0 -0
  154. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/feature_flags/feature_flags.py +0 -0
  155. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/feature_flags/schema.py +0 -0
  156. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/idempotency/__init__.py +0 -0
  157. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/idempotency/base.py +0 -0
  158. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/idempotency/config.py +0 -0
  159. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/idempotency/exceptions.py +0 -0
  160. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/idempotency/idempotency.py +0 -0
  161. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/idempotency/persistence/__init__.py +0 -0
  162. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/idempotency/persistence/base.py +0 -0
  163. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/idempotency/persistence/datarecord.py +0 -0
  164. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py +0 -0
  165. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/idempotency/persistence/redis.py +0 -0
  166. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/idempotency/serialization/__init__.py +0 -0
  167. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/idempotency/serialization/base.py +0 -0
  168. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/idempotency/serialization/custom_dict.py +0 -0
  169. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/idempotency/serialization/dataclass.py +0 -0
  170. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/idempotency/serialization/no_op.py +0 -0
  171. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/idempotency/serialization/pydantic.py +0 -0
  172. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/jmespath_utils/__init__.py +0 -0
  173. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/jmespath_utils/envelopes.py +0 -0
  174. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parameters/appconfig.py +0 -0
  175. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parameters/dynamodb.py +0 -0
  176. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/__init__.py +0 -0
  177. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/compat.py +0 -0
  178. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/envelopes/__init__.py +0 -0
  179. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/envelopes/apigw.py +0 -0
  180. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/envelopes/apigwv2.py +0 -0
  181. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/envelopes/base.py +0 -0
  182. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/envelopes/bedrock_agent.py +0 -0
  183. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/envelopes/cloudwatch.py +0 -0
  184. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/envelopes/dynamodb.py +0 -0
  185. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/envelopes/event_bridge.py +0 -0
  186. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/envelopes/kafka.py +0 -0
  187. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/envelopes/kinesis.py +0 -0
  188. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/envelopes/kinesis_firehose.py +0 -0
  189. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/envelopes/lambda_function_url.py +0 -0
  190. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/envelopes/sns.py +0 -0
  191. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/envelopes/sqs.py +0 -0
  192. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/envelopes/vpc_lattice.py +0 -0
  193. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/envelopes/vpc_latticev2.py +0 -0
  194. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/exceptions.py +0 -0
  195. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/models/__init__.py +0 -0
  196. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/models/alb.py +0 -0
  197. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/models/apigw.py +0 -0
  198. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/models/apigwv2.py +0 -0
  199. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/models/bedrock_agent.py +0 -0
  200. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/models/cloudformation_custom_resource.py +0 -0
  201. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/models/cloudwatch.py +0 -0
  202. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/models/dynamodb.py +0 -0
  203. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/models/event_bridge.py +0 -0
  204. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/models/kafka.py +0 -0
  205. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/models/kinesis.py +0 -0
  206. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/models/kinesis_firehose.py +0 -0
  207. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/models/kinesis_firehose_sqs.py +0 -0
  208. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/models/lambda_function_url.py +0 -0
  209. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/models/s3.py +0 -0
  210. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/models/s3_batch_operation.py +0 -0
  211. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py +0 -0
  212. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/models/s3_object_event.py +0 -0
  213. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/models/ses.py +0 -0
  214. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/models/sns.py +0 -0
  215. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/models/sqs.py +0 -0
  216. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/models/vpc_lattice.py +0 -0
  217. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/models/vpc_latticev2.py +0 -0
  218. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/parser.py +0 -0
  219. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/pydantic.py +0 -0
  220. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/parser/types.py +0 -0
  221. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/serialization.py +0 -0
  222. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/streaming/__init__.py +0 -0
  223. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/streaming/_s3_seekable_io.py +0 -0
  224. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/streaming/compat.py +0 -0
  225. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/streaming/s3_object.py +0 -0
  226. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/streaming/transformations/__init__.py +0 -0
  227. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/streaming/transformations/base.py +0 -0
  228. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/streaming/transformations/csv.py +0 -0
  229. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/streaming/transformations/gzip.py +0 -0
  230. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/streaming/transformations/zip.py +0 -0
  231. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/typing/__init__.py +0 -0
  232. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/typing/lambda_client_context.py +0 -0
  233. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/typing/lambda_client_context_mobile_client.py +0 -0
  234. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/typing/lambda_cognito_identity.py +0 -0
  235. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/typing/lambda_context.py +0 -0
  236. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/validation/__init__.py +0 -0
  237. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/validation/base.py +0 -0
  238. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/validation/envelopes.py +0 -0
  239. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/validation/exceptions.py +0 -0
  240. {aws_lambda_powertools-2.35.1 → aws_lambda_powertools-2.36.0}/aws_lambda_powertools/utilities/validation/validator.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: aws-lambda-powertools
3
- Version: 2.35.1
3
+ Version: 2.36.0
4
4
  Summary: Powertools for AWS Lambda (Python) is a developer toolkit to implement Serverless best practices and increase developer velocity.
5
5
  Home-page: https://github.com/aws-powertools/powertools-lambda-python
6
6
  License: MIT
@@ -503,6 +503,18 @@ class Route:
503
503
  if request_body_oai:
504
504
  operation["requestBody"] = request_body_oai
505
505
 
506
+ # Validation failure response (422) will always be part of the schema
507
+ operation_responses: Dict[int, OpenAPIResponse] = {
508
+ 422: {
509
+ "description": "Validation Error",
510
+ "content": {
511
+ "application/json": {
512
+ "schema": {"$ref": COMPONENT_REF_PREFIX + "HTTPValidationError"},
513
+ },
514
+ },
515
+ },
516
+ }
517
+
506
518
  # Add the response to the OpenAPI operation
507
519
  if self.responses:
508
520
  for status_code in list(self.responses):
@@ -549,45 +561,34 @@ class Route:
549
561
 
550
562
  response["content"][content_type] = new_payload
551
563
 
552
- operation["responses"] = self.responses
564
+ # Merge the user provided response with the default responses
565
+ operation_responses[status_code] = response
553
566
  else:
554
567
  # Set the default 200 response
555
- responses = operation.setdefault("responses", {})
556
- success_response = responses.setdefault(200, {})
557
- success_response["description"] = self.response_description or _DEFAULT_OPENAPI_RESPONSE_DESCRIPTION
558
- success_response["content"] = {"application/json": {"schema": {}}}
559
- json_response = success_response["content"].setdefault("application/json", {})
560
-
561
- # Add the response schema to the OpenAPI 200 response
562
- json_response.update(
563
- self._openapi_operation_return(
564
- param=dependant.return_param,
565
- model_name_map=model_name_map,
566
- field_mapping=field_mapping,
567
- ),
568
+ response_schema = self._openapi_operation_return(
569
+ param=dependant.return_param,
570
+ model_name_map=model_name_map,
571
+ field_mapping=field_mapping,
568
572
  )
569
573
 
570
- # Add validation failure response (422)
571
- operation["responses"][422] = {
572
- "description": "Validation Error",
573
- "content": {
574
- "application/json": {
575
- "schema": {"$ref": COMPONENT_REF_PREFIX + "HTTPValidationError"},
576
- },
577
- },
574
+ # Add the response schema to the OpenAPI 200 response
575
+ operation_responses[200] = {
576
+ "description": self.response_description or _DEFAULT_OPENAPI_RESPONSE_DESCRIPTION,
577
+ "content": {"application/json": response_schema},
578
578
  }
579
579
 
580
- # Add the validation error schema to the definitions, but only if it hasn't been added yet
581
- if "ValidationError" not in definitions:
582
- definitions.update(
583
- {
584
- "ValidationError": validation_error_definition,
585
- "HTTPValidationError": validation_error_response_definition,
586
- },
587
- )
588
-
580
+ operation["responses"] = operation_responses
589
581
  path[self.method.lower()] = operation
590
582
 
583
+ # Add the validation error schema to the definitions, but only if it hasn't been added yet
584
+ if "ValidationError" not in definitions:
585
+ definitions.update(
586
+ {
587
+ "ValidationError": validation_error_definition,
588
+ "HTTPValidationError": validation_error_response_definition,
589
+ },
590
+ )
591
+
591
592
  # Generate the response schema
592
593
  return path, definitions
593
594
 
@@ -1623,6 +1624,7 @@ class ApiGatewayResolver(BaseRouter):
1623
1624
  license_info: Optional["License"] = None,
1624
1625
  swagger_base_url: Optional[str] = None,
1625
1626
  middlewares: Optional[List[Callable[..., Response]]] = None,
1627
+ compress: bool = False,
1626
1628
  ):
1627
1629
  """
1628
1630
  Returns the OpenAPI schema as a JSON serializable dict
@@ -1655,11 +1657,13 @@ class ApiGatewayResolver(BaseRouter):
1655
1657
  The base url for the swagger UI. If not provided, we will serve a recent version of the Swagger UI.
1656
1658
  middlewares: List[Callable[..., Response]], optional
1657
1659
  List of middlewares to be used for the swagger route.
1660
+ compress: bool, default = False
1661
+ Whether or not to enable gzip compression swagger route.
1658
1662
  """
1659
1663
  from aws_lambda_powertools.event_handler.openapi.compat import model_json
1660
1664
  from aws_lambda_powertools.event_handler.openapi.models import Server
1661
1665
 
1662
- @self.get(path, middlewares=middlewares, include_in_schema=False)
1666
+ @self.get(path, middlewares=middlewares, include_in_schema=False, compress=compress)
1663
1667
  def swagger_handler():
1664
1668
  base_path = self._get_base_path()
1665
1669
 
@@ -2130,6 +2134,9 @@ class ApiGatewayResolver(BaseRouter):
2130
2134
  logger.debug("Appending Router middlewares into App middlewares.")
2131
2135
  self._router_middlewares = self._router_middlewares + router._router_middlewares
2132
2136
 
2137
+ logger.debug("Appending Router exception_handler into App exception_handler.")
2138
+ self._exception_handlers.update(router._exception_handlers)
2139
+
2133
2140
  # use pointer to allow context clearance after event is processed e.g., resolve(evt, ctx)
2134
2141
  router.context = self.context
2135
2142
 
@@ -2195,6 +2202,7 @@ class Router(BaseRouter):
2195
2202
  self._routes_with_middleware: Dict[tuple, List[Callable]] = {}
2196
2203
  self.api_resolver: Optional[BaseRouter] = None
2197
2204
  self.context = {} # early init as customers might add context before event resolution
2205
+ self._exception_handlers: Dict[Type, Callable] = {}
2198
2206
 
2199
2207
  def route(
2200
2208
  self,
@@ -2249,6 +2257,17 @@ class Router(BaseRouter):
2249
2257
 
2250
2258
  return register_route
2251
2259
 
2260
+ def exception_handler(self, exc_class: Union[Type[Exception], List[Type[Exception]]]):
2261
+ def register_exception_handler(func: Callable):
2262
+ if isinstance(exc_class, list):
2263
+ for exp in exc_class:
2264
+ self._exception_handlers[exp] = func
2265
+ else:
2266
+ self._exception_handlers[exc_class] = func
2267
+ return func
2268
+
2269
+ return register_exception_handler
2270
+
2252
2271
 
2253
2272
  class APIGatewayRestResolver(ApiGatewayResolver):
2254
2273
  current_event: APIGatewayProxyEvent
@@ -28,7 +28,7 @@ validation_error_definition = {
28
28
  "type": "array",
29
29
  "items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
30
30
  },
31
- "msg": {"title": "Message", "type": "string"},
31
+ # For security reasons, we hide **msg** details (don't leak Python, Pydantic or filenames)
32
32
  "type": {"title": "Error Type", "type": "string"},
33
33
  },
34
34
  "required": ["loc", "msg", "type"],
@@ -580,7 +580,7 @@ class Logger:
580
580
  extra=extra,
581
581
  )
582
582
 
583
- def append_keys(self, **additional_keys) -> None:
583
+ def append_keys(self, **additional_keys: object) -> None:
584
584
  self.registered_formatter.append_keys(**additional_keys)
585
585
 
586
586
  def remove_keys(self, keys: Iterable[str]) -> None:
@@ -17,6 +17,7 @@ from aws_lambda_powertools.metrics.exceptions import (
17
17
  MetricValueError,
18
18
  SchemaValidationError,
19
19
  )
20
+ from aws_lambda_powertools.metrics.functions import convert_timestamp_to_emf_format, validate_emf_timestamp
20
21
  from aws_lambda_powertools.metrics.provider import cold_start
21
22
  from aws_lambda_powertools.metrics.provider.cloudwatch_emf.constants import MAX_DIMENSIONS, MAX_METRICS
22
23
  from aws_lambda_powertools.metrics.provider.cloudwatch_emf.metric_properties import MetricResolution, MetricUnit
@@ -76,6 +77,8 @@ class MetricManager:
76
77
  self.namespace = resolve_env_var_choice(choice=namespace, env=os.getenv(constants.METRICS_NAMESPACE_ENV))
77
78
  self.service = resolve_env_var_choice(choice=service, env=os.getenv(constants.SERVICE_NAME_ENV))
78
79
  self.metadata_set = metadata_set if metadata_set is not None else {}
80
+ self.timestamp: int | None = None
81
+
79
82
  self._metric_units = [unit.value for unit in MetricUnit]
80
83
  self._metric_unit_valid_options = list(MetricUnit.__members__)
81
84
  self._metric_resolutions = [resolution.value for resolution in MetricResolution]
@@ -224,7 +227,7 @@ class MetricManager:
224
227
 
225
228
  return {
226
229
  "_aws": {
227
- "Timestamp": int(datetime.datetime.now().timestamp() * 1000), # epoch
230
+ "Timestamp": self.timestamp or int(datetime.datetime.now().timestamp() * 1000), # epoch
228
231
  "CloudWatchMetrics": [
229
232
  {
230
233
  "Namespace": self.namespace, # "test_namespace"
@@ -296,6 +299,31 @@ class MetricManager:
296
299
  else:
297
300
  self.metadata_set[str(key)] = value
298
301
 
302
+ def set_timestamp(self, timestamp: int | datetime.datetime):
303
+ """
304
+ Set the timestamp for the metric.
305
+
306
+ Parameters:
307
+ -----------
308
+ timestamp: int | datetime.datetime
309
+ The timestamp to create the metric.
310
+ If an integer is provided, it is assumed to be the epoch time in milliseconds.
311
+ If a datetime object is provided, it will be converted to epoch time in milliseconds.
312
+ """
313
+ # The timestamp must be a Datetime object or an integer representing an epoch time.
314
+ # This should not exceed 14 days in the past or be more than 2 hours in the future.
315
+ # Any metrics failing to meet this criteria will be skipped by Amazon CloudWatch.
316
+ # See: https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Embedded_Metric_Format_Specification.html
317
+ # See: https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CloudWatch-Logs-Monitoring-CloudWatch-Metrics.html
318
+ if not validate_emf_timestamp(timestamp):
319
+ warnings.warn(
320
+ "This metric doesn't meet the requirements and will be skipped by Amazon CloudWatch. "
321
+ "Ensure the timestamp is within 14 days past or 2 hours future.",
322
+ stacklevel=2,
323
+ )
324
+
325
+ self.timestamp = convert_timestamp_to_emf_format(timestamp)
326
+
299
327
  def clear_metrics(self) -> None:
300
328
  logger.debug("Clearing out existing metric set from memory")
301
329
  self.metric_set.clear()
@@ -576,6 +604,9 @@ def single_metric(
576
604
  Metric value
577
605
  namespace: str
578
606
  Namespace for metrics
607
+ default_dimensions: Dict[str, str], optional
608
+ Metric dimensions as key=value that will always be present
609
+
579
610
 
580
611
  Yields
581
612
  -------
@@ -0,0 +1,137 @@
1
+ from __future__ import annotations
2
+
3
+ from datetime import datetime
4
+
5
+ from aws_lambda_powertools.metrics.provider.cloudwatch_emf.exceptions import (
6
+ MetricResolutionError,
7
+ MetricUnitError,
8
+ )
9
+ from aws_lambda_powertools.metrics.provider.cloudwatch_emf.metric_properties import MetricResolution, MetricUnit
10
+ from aws_lambda_powertools.shared import constants
11
+ from aws_lambda_powertools.shared.types import List
12
+
13
+
14
+ def extract_cloudwatch_metric_resolution_value(metric_resolutions: List, resolution: int | MetricResolution) -> int:
15
+ """Return metric value from CloudWatch metric unit whether that's str or MetricResolution enum
16
+
17
+ Parameters
18
+ ----------
19
+ unit : Union[int, MetricResolution]
20
+ Metric resolution
21
+
22
+ Returns
23
+ -------
24
+ int
25
+ Metric resolution value must be 1 or 60
26
+
27
+ Raises
28
+ ------
29
+ MetricResolutionError
30
+ When metric resolution is not supported by CloudWatch
31
+ """
32
+ if isinstance(resolution, MetricResolution):
33
+ return resolution.value
34
+
35
+ if isinstance(resolution, int) and resolution in metric_resolutions:
36
+ return resolution
37
+
38
+ raise MetricResolutionError(
39
+ f"Invalid metric resolution '{resolution}', expected either option: {metric_resolutions}", # noqa: E501
40
+ )
41
+
42
+
43
+ def extract_cloudwatch_metric_unit_value(metric_units: List, metric_valid_options: List, unit: str | MetricUnit) -> str:
44
+ """Return metric value from CloudWatch metric unit whether that's str or MetricUnit enum
45
+
46
+ Parameters
47
+ ----------
48
+ unit : Union[str, MetricUnit]
49
+ Metric unit
50
+
51
+ Returns
52
+ -------
53
+ str
54
+ Metric unit value (e.g. "Seconds", "Count/Second")
55
+
56
+ Raises
57
+ ------
58
+ MetricUnitError
59
+ When metric unit is not supported by CloudWatch
60
+ """
61
+
62
+ if isinstance(unit, str):
63
+ if unit in metric_valid_options:
64
+ unit = MetricUnit[unit].value
65
+
66
+ if unit not in metric_units:
67
+ raise MetricUnitError(
68
+ f"Invalid metric unit '{unit}', expected either option: {metric_valid_options}",
69
+ )
70
+
71
+ if isinstance(unit, MetricUnit):
72
+ unit = unit.value
73
+
74
+ return unit
75
+
76
+
77
+ def validate_emf_timestamp(timestamp: int | datetime) -> bool:
78
+ """
79
+ Validates a given timestamp based on CloudWatch Timestamp guidelines.
80
+
81
+ Timestamp must meet CloudWatch requirements, otherwise an InvalidTimestampError will be raised.
82
+ See [Timestamps](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch_concepts.html#about_timestamp)
83
+ for valid values.
84
+
85
+ Parameters:
86
+ ----------
87
+ timestamp: int | datetime
88
+ Datetime object or epoch time in milliseconds representing the timestamp to validate.
89
+
90
+ Returns
91
+ -------
92
+ bool
93
+ Valid or not timestamp values
94
+ """
95
+
96
+ if not isinstance(timestamp, (int, datetime)):
97
+ return False
98
+
99
+ if isinstance(timestamp, datetime):
100
+ # Converting timestamp to epoch time in milliseconds
101
+ timestamp = int(timestamp.timestamp() * 1000)
102
+
103
+ # Consider current timezone when working with date and time
104
+ current_timezone = datetime.now().astimezone().tzinfo
105
+
106
+ current_time = int(datetime.now(current_timezone).timestamp() * 1000)
107
+ min_valid_timestamp = current_time - constants.EMF_MAX_TIMESTAMP_PAST_AGE
108
+ max_valid_timestamp = current_time + constants.EMF_MAX_TIMESTAMP_FUTURE_AGE
109
+
110
+ return min_valid_timestamp <= timestamp <= max_valid_timestamp
111
+
112
+
113
+ def convert_timestamp_to_emf_format(timestamp: int | datetime) -> int:
114
+ """
115
+ Converts a timestamp to EMF compatible format.
116
+
117
+ Parameters
118
+ ----------
119
+ timestamp: int | datetime
120
+ The timestamp to convert. If already in epoch milliseconds format, returns it as is.
121
+ If datetime object, converts it to milliseconds since Unix epoch.
122
+
123
+ Returns:
124
+ --------
125
+ int
126
+ The timestamp converted to EMF compatible format (milliseconds since Unix epoch).
127
+ """
128
+ if isinstance(timestamp, int):
129
+ return timestamp
130
+
131
+ try:
132
+ return int(round(timestamp.timestamp() * 1000))
133
+ except AttributeError:
134
+ # If this point is reached, it indicates timestamp is not a datetime object
135
+ # Returning zero represents the initial date of epoch time,
136
+ # which will be skipped by Amazon CloudWatch.
137
+ return 0
@@ -125,6 +125,19 @@ class Metrics:
125
125
  def add_metadata(self, key: str, value: Any) -> None:
126
126
  self.provider.add_metadata(key=key, value=value)
127
127
 
128
+ def set_timestamp(self, timestamp: int):
129
+ """
130
+ Set the timestamp for the metric.
131
+
132
+ Parameters:
133
+ -----------
134
+ timestamp: int | datetime.datetime
135
+ The timestamp to create the metric.
136
+ If an integer is provided, it is assumed to be the epoch time in milliseconds.
137
+ If a datetime object is provided, it will be converted to epoch time in milliseconds.
138
+ """
139
+ self.provider.set_timestamp(timestamp=timestamp)
140
+
128
141
  def flush_metrics(self, raise_on_empty_metrics: bool = False) -> None:
129
142
  self.provider.flush_metrics(raise_on_empty_metrics=raise_on_empty_metrics)
130
143
 
@@ -12,8 +12,10 @@ from typing import Any, Dict, List
12
12
  from aws_lambda_powertools.metrics.base import single_metric
13
13
  from aws_lambda_powertools.metrics.exceptions import MetricValueError, SchemaValidationError
14
14
  from aws_lambda_powertools.metrics.functions import (
15
+ convert_timestamp_to_emf_format,
15
16
  extract_cloudwatch_metric_resolution_value,
16
17
  extract_cloudwatch_metric_unit_value,
18
+ validate_emf_timestamp,
17
19
  )
18
20
  from aws_lambda_powertools.metrics.provider.base import BaseProvider
19
21
  from aws_lambda_powertools.metrics.provider.cloudwatch_emf.constants import MAX_DIMENSIONS, MAX_METRICS
@@ -73,6 +75,7 @@ class AmazonCloudWatchEMFProvider(BaseProvider):
73
75
  self.namespace = resolve_env_var_choice(choice=namespace, env=os.getenv(constants.METRICS_NAMESPACE_ENV))
74
76
  self.service = resolve_env_var_choice(choice=service, env=os.getenv(constants.SERVICE_NAME_ENV))
75
77
  self.metadata_set = metadata_set if metadata_set is not None else {}
78
+ self.timestamp: int | None = None
76
79
 
77
80
  self._metric_units = [unit.value for unit in MetricUnit]
78
81
  self._metric_unit_valid_options = list(MetricUnit.__members__)
@@ -231,7 +234,7 @@ class AmazonCloudWatchEMFProvider(BaseProvider):
231
234
 
232
235
  return {
233
236
  "_aws": {
234
- "Timestamp": int(datetime.datetime.now().timestamp() * 1000), # epoch
237
+ "Timestamp": self.timestamp or int(datetime.datetime.now().timestamp() * 1000), # epoch
235
238
  "CloudWatchMetrics": [
236
239
  {
237
240
  "Namespace": self.namespace, # "test_namespace"
@@ -304,6 +307,31 @@ class AmazonCloudWatchEMFProvider(BaseProvider):
304
307
  else:
305
308
  self.metadata_set[str(key)] = value
306
309
 
310
+ def set_timestamp(self, timestamp: int | datetime.datetime):
311
+ """
312
+ Set the timestamp for the metric.
313
+
314
+ Parameters:
315
+ -----------
316
+ timestamp: int | datetime.datetime
317
+ The timestamp to create the metric.
318
+ If an integer is provided, it is assumed to be the epoch time in milliseconds.
319
+ If a datetime object is provided, it will be converted to epoch time in milliseconds.
320
+ """
321
+ # The timestamp must be a Datetime object or an integer representing an epoch time.
322
+ # This should not exceed 14 days in the past or be more than 2 hours in the future.
323
+ # Any metrics failing to meet this criteria will be skipped by Amazon CloudWatch.
324
+ # See: https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Embedded_Metric_Format_Specification.html
325
+ # See: https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CloudWatch-Logs-Monitoring-CloudWatch-Metrics.html
326
+ if not validate_emf_timestamp(timestamp):
327
+ warnings.warn(
328
+ "This metric doesn't meet the requirements and will be skipped by Amazon CloudWatch. "
329
+ "Ensure the timestamp is within 14 days past or 2 hours future.",
330
+ stacklevel=2,
331
+ )
332
+
333
+ self.timestamp = convert_timestamp_to_emf_format(timestamp)
334
+
307
335
  def clear_metrics(self) -> None:
308
336
  logger.debug("Clearing out existing metric set from memory")
309
337
  self.metric_set.clear()
@@ -1,32 +1,17 @@
1
+ # Tracer constants
1
2
  TRACER_CAPTURE_RESPONSE_ENV: str = "POWERTOOLS_TRACER_CAPTURE_RESPONSE"
2
3
  TRACER_CAPTURE_ERROR_ENV: str = "POWERTOOLS_TRACER_CAPTURE_ERROR"
3
4
  TRACER_DISABLED_ENV: str = "POWERTOOLS_TRACE_DISABLED"
5
+ XRAY_SDK_MODULE: str = "aws_xray_sdk"
6
+ XRAY_SDK_CORE_MODULE: str = "aws_xray_sdk.core"
7
+ XRAY_TRACE_ID_ENV: str = "_X_AMZN_TRACE_ID"
8
+ MIDDLEWARE_FACTORY_TRACE_ENV: str = "POWERTOOLS_TRACE_MIDDLEWARES"
9
+ INVALID_XRAY_NAME_CHARACTERS = r"[?;*()!$~^<>]"
4
10
 
11
+ # Logger constants
5
12
  LOGGER_LOG_SAMPLING_RATE: str = "POWERTOOLS_LOGGER_SAMPLE_RATE"
6
13
  LOGGER_LOG_EVENT_ENV: str = "POWERTOOLS_LOGGER_LOG_EVENT"
7
14
  LOGGER_LOG_DEDUPLICATION_ENV: str = "POWERTOOLS_LOG_DEDUPLICATION_DISABLED"
8
-
9
- MIDDLEWARE_FACTORY_TRACE_ENV: str = "POWERTOOLS_TRACE_MIDDLEWARES"
10
-
11
- METRICS_NAMESPACE_ENV: str = "POWERTOOLS_METRICS_NAMESPACE"
12
-
13
- DATADOG_FLUSH_TO_LOG: str = "DD_FLUSH_TO_LOG"
14
-
15
- SERVICE_NAME_ENV: str = "POWERTOOLS_SERVICE_NAME"
16
- XRAY_TRACE_ID_ENV: str = "_X_AMZN_TRACE_ID"
17
- LAMBDA_TASK_ROOT_ENV: str = "LAMBDA_TASK_ROOT"
18
-
19
-
20
- LAMBDA_FUNCTION_NAME_ENV: str = "AWS_LAMBDA_FUNCTION_NAME"
21
-
22
- XRAY_SDK_MODULE: str = "aws_xray_sdk"
23
- XRAY_SDK_CORE_MODULE: str = "aws_xray_sdk.core"
24
-
25
- IDEMPOTENCY_DISABLED_ENV: str = "POWERTOOLS_IDEMPOTENCY_DISABLED"
26
-
27
- PARAMETERS_SSM_DECRYPT_ENV: str = "POWERTOOLS_PARAMETERS_SSM_DECRYPT"
28
- PARAMETERS_MAX_AGE_ENV: str = "POWERTOOLS_PARAMETERS_MAX_AGE"
29
-
30
15
  LOGGER_LAMBDA_CONTEXT_KEYS = [
31
16
  "function_arn",
32
17
  "function_memory_size",
@@ -35,17 +20,6 @@ LOGGER_LAMBDA_CONTEXT_KEYS = [
35
20
  "cold_start",
36
21
  "xray_trace_id",
37
22
  ]
38
-
39
- # JSON indentation level
40
- PRETTY_INDENT: int = 4
41
- COMPACT_INDENT = None
42
-
43
- POWERTOOLS_DEV_ENV: str = "POWERTOOLS_DEV"
44
- POWERTOOLS_DEBUG_ENV: str = "POWERTOOLS_DEBUG"
45
- POWERTOOLS_LOG_LEVEL_ENV: str = "POWERTOOLS_LOG_LEVEL"
46
- POWERTOOLS_LOG_LEVEL_LEGACY_ENV: str = "LOG_LEVEL"
47
- LAMBDA_LOG_LEVEL_ENV: str = "AWS_LAMBDA_LOG_LEVEL"
48
-
49
23
  # Mapping of Lambda log levels to Python logging levels
50
24
  # https://docs.aws.amazon.com/lambda/latest/dg/configuration-logging.html#configuration-logging-log-levels
51
25
  LAMBDA_ADVANCED_LOGGING_LEVELS = {
@@ -57,3 +31,37 @@ LAMBDA_ADVANCED_LOGGING_LEVELS = {
57
31
  "ERROR": "ERROR",
58
32
  "FATAL": "CRITICAL",
59
33
  }
34
+ POWERTOOLS_LOG_LEVEL_ENV: str = "POWERTOOLS_LOG_LEVEL"
35
+ POWERTOOLS_LOG_LEVEL_LEGACY_ENV: str = "LOG_LEVEL"
36
+ LAMBDA_LOG_LEVEL_ENV: str = "AWS_LAMBDA_LOG_LEVEL"
37
+
38
+ # Metrics constants
39
+ METRICS_NAMESPACE_ENV: str = "POWERTOOLS_METRICS_NAMESPACE"
40
+ DATADOG_FLUSH_TO_LOG: str = "DD_FLUSH_TO_LOG"
41
+ SERVICE_NAME_ENV: str = "POWERTOOLS_SERVICE_NAME"
42
+ # If the timestamp of log event is more than 2 hours in future, the log event is skipped.
43
+ # If the timestamp of log event is more than 14 days in past, the log event is skipped.
44
+ # See https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AgentReference.html
45
+ EMF_MAX_TIMESTAMP_PAST_AGE = 14 * 24 * 60 * 60 * 1000 # 14 days
46
+ EMF_MAX_TIMESTAMP_FUTURE_AGE = 2 * 60 * 60 * 1000 # 2 hours
47
+
48
+ # Parameters constants
49
+ PARAMETERS_SSM_DECRYPT_ENV: str = "POWERTOOLS_PARAMETERS_SSM_DECRYPT"
50
+ PARAMETERS_MAX_AGE_ENV: str = "POWERTOOLS_PARAMETERS_MAX_AGE"
51
+
52
+ # Runtime and environment constants
53
+ LAMBDA_TASK_ROOT_ENV: str = "LAMBDA_TASK_ROOT"
54
+ SAM_LOCAL_ENV: str = "AWS_SAM_LOCAL"
55
+ CHALICE_LOCAL_ENV: str = "AWS_CHALICE_CLI_MODE"
56
+ LAMBDA_FUNCTION_NAME_ENV: str = "AWS_LAMBDA_FUNCTION_NAME"
57
+
58
+ # Debug constants
59
+ POWERTOOLS_DEV_ENV: str = "POWERTOOLS_DEV"
60
+ POWERTOOLS_DEBUG_ENV: str = "POWERTOOLS_DEBUG"
61
+
62
+ # JSON constants
63
+ PRETTY_INDENT: int = 4
64
+ COMPACT_INDENT = None
65
+
66
+ # Idempotency constants
67
+ IDEMPOTENCY_DISABLED_ENV: str = "POWERTOOLS_IDEMPOTENCY_DISABLED"
@@ -4,6 +4,7 @@ import base64
4
4
  import itertools
5
5
  import logging
6
6
  import os
7
+ import re
7
8
  import warnings
8
9
  from binascii import Error as BinAsciiError
9
10
  from pathlib import Path
@@ -275,13 +276,10 @@ def abs_lambda_path(relative_path: str = "") -> str:
275
276
  If the path is empty, it will return the current working directory.
276
277
  """
277
278
  # Retrieve the LAMBDA_TASK_ROOT environment variable or default to an empty string
278
- current_working_directory = os.environ.get("LAMBDA_TASK_ROOT", "")
279
+ current_working_directory = os.environ.get("LAMBDA_TASK_ROOT", "") or str(Path.cwd())
279
280
 
280
- # If LAMBDA_TASK_ROOT is not set, use the current working directory
281
- if not current_working_directory:
282
- current_working_directory = str(Path.cwd())
281
+ return str(Path(current_working_directory, relative_path))
283
282
 
284
- # Combine the current working directory and the relative path to get the absolute path
285
- absolute_path = str(Path(current_working_directory, relative_path))
286
283
 
287
- return absolute_path
284
+ def sanitize_xray_segment_name(name: str) -> str:
285
+ return re.sub(constants.INVALID_XRAY_NAME_CHARACTERS, "", name)
@@ -1,3 +1,3 @@
1
1
  """Exposes version constant to avoid circular dependencies."""
2
2
 
3
- VERSION = "2.35.1"
3
+ VERSION = "2.36.0"
@@ -7,11 +7,15 @@ import numbers
7
7
  import os
8
8
  from typing import Any, Callable, Dict, List, Optional, Sequence, Union, cast, overload
9
9
 
10
- from ..shared import constants
11
- from ..shared.functions import resolve_env_var_choice, resolve_truthy_env_var_choice
12
- from ..shared.lazy_import import LazyLoader
13
- from ..shared.types import AnyCallableT
14
- from .base import BaseProvider, BaseSegment
10
+ from aws_lambda_powertools.shared import constants
11
+ from aws_lambda_powertools.shared.functions import (
12
+ resolve_env_var_choice,
13
+ resolve_truthy_env_var_choice,
14
+ sanitize_xray_segment_name,
15
+ )
16
+ from aws_lambda_powertools.shared.lazy_import import LazyLoader
17
+ from aws_lambda_powertools.shared.types import AnyCallableT
18
+ from aws_lambda_powertools.tracing.base import BaseProvider, BaseSegment
15
19
 
16
20
  is_cold_start = True
17
21
  logger = logging.getLogger(__name__)
@@ -520,7 +524,8 @@ class Tracer:
520
524
  )
521
525
 
522
526
  # Example: app.ClassA.get_all # noqa ERA001
523
- method_name = f"{method.__module__}.{method.__qualname__}"
527
+ # Valid characters can be found at http://docs.aws.amazon.com/xray/latest/devguide/xray-api-segmentdocuments.html
528
+ method_name = sanitize_xray_segment_name(f"{method.__module__}.{method.__qualname__}")
524
529
 
525
530
  capture_response = resolve_truthy_env_var_choice(
526
531
  env=os.getenv(constants.TRACER_CAPTURE_RESPONSE_ENV, "true"),
@@ -766,13 +771,15 @@ class Tracer:
766
771
  """
767
772
  logger.debug("Verifying whether Tracing has been disabled")
768
773
  is_lambda_env = os.getenv(constants.LAMBDA_TASK_ROOT_ENV)
774
+ is_lambda_sam_cli = os.getenv(constants.SAM_LOCAL_ENV)
775
+ is_chalice_cli = os.getenv(constants.CHALICE_LOCAL_ENV)
769
776
  is_disabled = resolve_truthy_env_var_choice(env=os.getenv(constants.TRACER_DISABLED_ENV, "false"))
770
777
 
771
778
  if is_disabled:
772
779
  logger.debug("Tracing has been disabled via env var POWERTOOLS_TRACE_DISABLED")
773
780
  return is_disabled
774
781
 
775
- if not is_lambda_env:
782
+ if not is_lambda_env or (is_lambda_sam_cli or is_chalice_cli):
776
783
  logger.debug("Running outside Lambda env; disabling Tracing")
777
784
  return True
778
785
 
@@ -36,3 +36,19 @@ class BatchProcessingError(BaseBatchProcessingError):
36
36
  def __str__(self):
37
37
  parent_exception_str = super(BatchProcessingError, self).__str__()
38
38
  return self.format_exceptions(parent_exception_str)
39
+
40
+
41
+ class SQSFifoCircuitBreakerError(Exception):
42
+ """
43
+ Signals a record not processed due to the SQS FIFO processing being interrupted
44
+ """
45
+
46
+ pass
47
+
48
+
49
+ class SQSFifoMessageGroupCircuitBreakerError(Exception):
50
+ """
51
+ Signals a record not processed due to the SQS FIFO message group processing being interrupted
52
+ """
53
+
54
+ pass