aws-lambda-powertools 3.5.1a9__tar.gz → 3.6.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/PKG-INFO +1 -1
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/metrics/functions.py +27 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/metrics/metrics.py +2 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/metrics/provider/cloudwatch_emf/cloudwatch.py +5 -1
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/metrics/provider/datadog/datadog.py +3 -2
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/shared/constants.py +1 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/shared/version.py +1 -1
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_masking/base.py +204 -31
- aws_lambda_powertools-3.6.0/aws_lambda_powertools/utilities/data_masking/provider/base.py +189 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/pyproject.toml +1 -1
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/setup.py +1 -1
- aws_lambda_powertools-3.5.1a9/aws_lambda_powertools/utilities/data_masking/provider/base.py +0 -81
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/LICENSE +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/README.md +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/THIRD-PARTY-LICENSES +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/api_gateway.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/appsync.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/bedrock_agent.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/content_types.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/exceptions.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/graphql_appsync/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/graphql_appsync/_registry.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/graphql_appsync/base.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/graphql_appsync/exceptions.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/graphql_appsync/router.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/lambda_function_url.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/middlewares/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/middlewares/base.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/middlewares/openapi_validation.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/middlewares/schema_validation.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/openapi/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/openapi/compat.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/openapi/constants.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/openapi/dependant.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/openapi/encoders.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/openapi/exceptions.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/openapi/models.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/openapi/params.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/openapi/pydantic_loader.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/openapi/swagger_ui/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/openapi/swagger_ui/html.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/openapi/swagger_ui/oauth2.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/openapi/swagger_ui/swagger-ui-bundle.min.js +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/openapi/swagger_ui/swagger-ui.min.css +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/openapi/types.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/router.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/types.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/util.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/event_handler/vpc_lattice.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/exceptions/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/logging/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/logging/constants.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/logging/correlation_paths.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/logging/exceptions.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/logging/filters.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/logging/formatter.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/logging/formatters/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/logging/formatters/datadog.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/logging/lambda_context.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/logging/logger.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/logging/types.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/logging/utils.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/metrics/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/metrics/base.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/metrics/exceptions.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/metrics/metric.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/metrics/provider/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/metrics/provider/base.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/metrics/provider/cloudwatch_emf/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/metrics/provider/cloudwatch_emf/constants.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/metrics/provider/cloudwatch_emf/exceptions.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/metrics/provider/cloudwatch_emf/metric_properties.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/metrics/provider/cloudwatch_emf/types.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/metrics/provider/cold_start.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/metrics/provider/datadog/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/metrics/provider/datadog/metrics.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/metrics/provider/datadog/warnings.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/metrics/types.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/middleware_factory/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/middleware_factory/exceptions.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/middleware_factory/factory.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/package_logger.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/py.typed +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/shared/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/shared/cache_dict.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/shared/cookies.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/shared/dynamodb_deserializer.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/shared/functions.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/shared/headers_serializer.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/shared/json_encoder.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/shared/lazy_import.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/shared/types.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/shared/user_agent.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/tracing/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/tracing/base.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/tracing/extensions.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/tracing/tracer.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/batch/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/batch/base.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/batch/decorators.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/batch/exceptions.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/batch/sqs_fifo_partial_processor.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/batch/types.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/active_mq_event.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/alb_event.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/api_gateway_authorizer_event.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/appsync/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/appsync/scalar_types_utils.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/appsync_authorizer_event.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/appsync_resolver_event.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/aws_config_rule_event.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/bedrock_agent_event.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/cloud_watch_alarm_event.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/cloud_watch_custom_widget_event.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/cloud_watch_logs_event.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/cloudformation_custom_resource_event.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/code_deploy_lifecycle_hook_event.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/code_pipeline_job_event.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/cognito_user_pool_event.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/common.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/connect_contact_flow_event.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/dynamo_db_stream_event.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/event_bridge_event.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/event_source.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/kafka_event.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/kinesis_stream_event.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/lambda_function_url_event.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/rabbit_mq_event.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/s3_batch_operation_event.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/s3_event.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/s3_object_event.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/secrets_manager_event.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/ses_event.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/shared_functions.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/sns_event.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/sqs_event.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/transfer_family_event.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_classes/vpc_lattice.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_masking/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_masking/constants.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_masking/exceptions.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_masking/provider/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_masking/provider/kms/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/data_masking/provider/kms/aws_encryption_sdk.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/feature_flags/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/feature_flags/appconfig.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/feature_flags/base.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/feature_flags/comparators.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/feature_flags/constants.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/feature_flags/exceptions.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/feature_flags/feature_flags.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/feature_flags/schema.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/feature_flags/types.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/idempotency/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/idempotency/base.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/idempotency/config.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/idempotency/exceptions.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/idempotency/hook.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/idempotency/idempotency.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/idempotency/persistence/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/idempotency/persistence/base.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/idempotency/persistence/datarecord.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/idempotency/persistence/redis.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/idempotency/serialization/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/idempotency/serialization/base.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/idempotency/serialization/custom_dict.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/idempotency/serialization/dataclass.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/idempotency/serialization/functions.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/idempotency/serialization/no_op.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/idempotency/serialization/pydantic.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/jmespath_utils/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/jmespath_utils/envelopes.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parameters/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parameters/appconfig.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parameters/base.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parameters/constants.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parameters/dynamodb.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parameters/exceptions.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parameters/secrets.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parameters/ssm.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parameters/types.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/envelopes/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/envelopes/apigw.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/envelopes/apigw_websocket.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/envelopes/apigwv2.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/envelopes/base.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/envelopes/bedrock_agent.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/envelopes/cloudwatch.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/envelopes/dynamodb.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/envelopes/event_bridge.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/envelopes/kafka.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/envelopes/kinesis.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/envelopes/kinesis_firehose.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/envelopes/lambda_function_url.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/envelopes/sns.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/envelopes/sqs.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/envelopes/vpc_lattice.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/envelopes/vpc_latticev2.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/exceptions.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/functions.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/models/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/models/alb.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/models/apigw.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/models/apigw_websocket.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/models/apigwv2.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/models/bedrock_agent.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/models/cloudformation_custom_resource.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/models/cloudwatch.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/models/dynamodb.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/models/event_bridge.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/models/kafka.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/models/kinesis.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/models/kinesis_firehose.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/models/kinesis_firehose_sqs.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/models/lambda_function_url.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/models/s3.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/models/s3_batch_operation.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/models/s3_object_event.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/models/ses.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/models/sns.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/models/sqs.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/models/transfer_family.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/models/vpc_lattice.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/models/vpc_latticev2.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/parser.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/parser/types.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/serialization.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/streaming/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/streaming/_s3_seekable_io.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/streaming/compat.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/streaming/constants.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/streaming/s3_object.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/streaming/transformations/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/streaming/transformations/base.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/streaming/transformations/csv.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/streaming/transformations/gzip.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/streaming/transformations/zip.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/streaming/types.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/typing/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/typing/lambda_client_context.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/typing/lambda_client_context_mobile_client.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/typing/lambda_cognito_identity.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/typing/lambda_context.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/validation/__init__.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/validation/base.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/validation/envelopes.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/validation/exceptions.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/utilities/validation/validator.py +0 -0
- {aws_lambda_powertools-3.5.1a9 → aws_lambda_powertools-3.6.0}/aws_lambda_powertools/warnings/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: aws_lambda_powertools
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.6.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
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import os
|
|
3
4
|
from datetime import datetime
|
|
4
5
|
|
|
5
6
|
from aws_lambda_powertools.metrics.provider.cloudwatch_emf.exceptions import (
|
|
@@ -8,6 +9,7 @@ from aws_lambda_powertools.metrics.provider.cloudwatch_emf.exceptions import (
|
|
|
8
9
|
)
|
|
9
10
|
from aws_lambda_powertools.metrics.provider.cloudwatch_emf.metric_properties import MetricResolution, MetricUnit
|
|
10
11
|
from aws_lambda_powertools.shared import constants
|
|
12
|
+
from aws_lambda_powertools.shared.functions import strtobool
|
|
11
13
|
|
|
12
14
|
|
|
13
15
|
def extract_cloudwatch_metric_resolution_value(metric_resolutions: list, resolution: int | MetricResolution) -> int:
|
|
@@ -134,3 +136,28 @@ def convert_timestamp_to_emf_format(timestamp: int | datetime) -> int:
|
|
|
134
136
|
# Returning zero represents the initial date of epoch time,
|
|
135
137
|
# which will be skipped by Amazon CloudWatch.
|
|
136
138
|
return 0
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def is_metrics_disabled() -> bool:
|
|
142
|
+
"""
|
|
143
|
+
Determine if metrics should be disabled based on environment variables.
|
|
144
|
+
|
|
145
|
+
Returns:
|
|
146
|
+
bool: True if metrics are disabled, False otherwise.
|
|
147
|
+
|
|
148
|
+
Rules:
|
|
149
|
+
- If POWERTOOLS_DEV is True and POWERTOOLS_METRICS_DISABLED is True: Disable metrics
|
|
150
|
+
- If POWERTOOLS_METRICS_DISABLED is True: Disable metrics
|
|
151
|
+
- If POWERTOOLS_DEV is True and POWERTOOLS_METRICS_DISABLED is not set: Disable metrics
|
|
152
|
+
"""
|
|
153
|
+
|
|
154
|
+
is_dev_mode = strtobool(os.getenv(constants.POWERTOOLS_DEV_ENV, "false"))
|
|
155
|
+
is_metrics_disabled = strtobool(os.getenv(constants.METRICS_DISABLED_ENV, "false"))
|
|
156
|
+
|
|
157
|
+
disable_conditions = [
|
|
158
|
+
is_metrics_disabled,
|
|
159
|
+
is_metrics_disabled and is_dev_mode,
|
|
160
|
+
is_dev_mode and os.getenv(constants.METRICS_DISABLED_ENV) is None,
|
|
161
|
+
]
|
|
162
|
+
|
|
163
|
+
return any(disable_conditions)
|
|
@@ -15,6 +15,7 @@ from aws_lambda_powertools.metrics.functions import (
|
|
|
15
15
|
convert_timestamp_to_emf_format,
|
|
16
16
|
extract_cloudwatch_metric_resolution_value,
|
|
17
17
|
extract_cloudwatch_metric_unit_value,
|
|
18
|
+
is_metrics_disabled,
|
|
18
19
|
validate_emf_timestamp,
|
|
19
20
|
)
|
|
20
21
|
from aws_lambda_powertools.metrics.provider.base import BaseProvider
|
|
@@ -77,6 +78,7 @@ class AmazonCloudWatchEMFProvider(BaseProvider):
|
|
|
77
78
|
self.default_dimensions = default_dimensions or {}
|
|
78
79
|
self.namespace = resolve_env_var_choice(choice=namespace, env=os.getenv(constants.METRICS_NAMESPACE_ENV))
|
|
79
80
|
self.service = resolve_env_var_choice(choice=service, env=os.getenv(constants.SERVICE_NAME_ENV))
|
|
81
|
+
|
|
80
82
|
self.metadata_set = metadata_set if metadata_set is not None else {}
|
|
81
83
|
self.timestamp: int | None = None
|
|
82
84
|
|
|
@@ -127,6 +129,7 @@ class AmazonCloudWatchEMFProvider(BaseProvider):
|
|
|
127
129
|
MetricResolutionError
|
|
128
130
|
When metric resolution is not supported by CloudWatch
|
|
129
131
|
"""
|
|
132
|
+
|
|
130
133
|
if not isinstance(value, numbers.Number):
|
|
131
134
|
raise MetricValueError(f"{value} is not a valid number")
|
|
132
135
|
|
|
@@ -268,6 +271,7 @@ class AmazonCloudWatchEMFProvider(BaseProvider):
|
|
|
268
271
|
value : str
|
|
269
272
|
Dimension value
|
|
270
273
|
"""
|
|
274
|
+
|
|
271
275
|
logger.debug(f"Adding dimension: {name}:{value}")
|
|
272
276
|
if len(self.dimension_set) == MAX_DIMENSIONS:
|
|
273
277
|
raise SchemaValidationError(
|
|
@@ -374,7 +378,7 @@ class AmazonCloudWatchEMFProvider(BaseProvider):
|
|
|
374
378
|
"If application metrics should never be empty, consider using 'raise_on_empty_metrics'",
|
|
375
379
|
stacklevel=2,
|
|
376
380
|
)
|
|
377
|
-
|
|
381
|
+
elif not is_metrics_disabled():
|
|
378
382
|
logger.debug("Flushing existing metrics")
|
|
379
383
|
metrics = self.serialize_metric_set()
|
|
380
384
|
print(json.dumps(metrics, separators=(",", ":")))
|
|
@@ -10,6 +10,7 @@ import warnings
|
|
|
10
10
|
from typing import TYPE_CHECKING, Any
|
|
11
11
|
|
|
12
12
|
from aws_lambda_powertools.metrics.exceptions import MetricValueError, SchemaValidationError
|
|
13
|
+
from aws_lambda_powertools.metrics.functions import is_metrics_disabled
|
|
13
14
|
from aws_lambda_powertools.metrics.provider import BaseProvider
|
|
14
15
|
from aws_lambda_powertools.metrics.provider.datadog.warnings import DatadogDataValidationWarning
|
|
15
16
|
from aws_lambda_powertools.shared import constants
|
|
@@ -99,7 +100,6 @@ class DatadogProvider(BaseProvider):
|
|
|
99
100
|
>>> sales='sam'
|
|
100
101
|
>>> )
|
|
101
102
|
"""
|
|
102
|
-
|
|
103
103
|
# validating metric name
|
|
104
104
|
if not self._validate_datadog_metric_name(name):
|
|
105
105
|
docs = "https://docs.datadoghq.com/metrics/custom_metrics/#naming-custom-metrics"
|
|
@@ -180,6 +180,7 @@ class DatadogProvider(BaseProvider):
|
|
|
180
180
|
raise_on_empty_metrics : bool, optional
|
|
181
181
|
raise exception if no metrics are emitted, by default False
|
|
182
182
|
"""
|
|
183
|
+
|
|
183
184
|
if not raise_on_empty_metrics and len(self.metric_set) == 0:
|
|
184
185
|
warnings.warn(
|
|
185
186
|
"No application metrics to publish. The cold-start metric may be published if enabled. "
|
|
@@ -200,7 +201,7 @@ class DatadogProvider(BaseProvider):
|
|
|
200
201
|
timestamp=metric_item["e"],
|
|
201
202
|
tags=metric_item["t"],
|
|
202
203
|
)
|
|
203
|
-
|
|
204
|
+
elif not is_metrics_disabled():
|
|
204
205
|
# dd module not found: flush to log, this format can be recognized via datadog log forwarder
|
|
205
206
|
# https://github.com/Datadog/datadog-lambda-python/blob/main/datadog_lambda/metric.py#L77
|
|
206
207
|
for metric_item in metrics:
|
|
@@ -40,6 +40,7 @@ LAMBDA_LOG_LEVEL_ENV: str = "AWS_LAMBDA_LOG_LEVEL"
|
|
|
40
40
|
METRICS_NAMESPACE_ENV: str = "POWERTOOLS_METRICS_NAMESPACE"
|
|
41
41
|
DATADOG_FLUSH_TO_LOG: str = "DD_FLUSH_TO_LOG"
|
|
42
42
|
SERVICE_NAME_ENV: str = "POWERTOOLS_SERVICE_NAME"
|
|
43
|
+
METRICS_DISABLED_ENV: str = "POWERTOOLS_METRICS_DISABLED"
|
|
43
44
|
# If the timestamp of log event is more than 2 hours in future, the log event is skipped.
|
|
44
45
|
# If the timestamp of log event is more than 14 days in past, the log event is skipped.
|
|
45
46
|
# See https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AgentReference.html
|
|
@@ -9,7 +9,8 @@ from __future__ import annotations
|
|
|
9
9
|
import functools
|
|
10
10
|
import logging
|
|
11
11
|
import warnings
|
|
12
|
-
from
|
|
12
|
+
from copy import deepcopy
|
|
13
|
+
from typing import TYPE_CHECKING, Any, Callable, Mapping, Sequence
|
|
13
14
|
|
|
14
15
|
from jsonpath_ng.ext import parse
|
|
15
16
|
|
|
@@ -18,6 +19,7 @@ from aws_lambda_powertools.utilities.data_masking.exceptions import (
|
|
|
18
19
|
DataMaskingUnsupportedTypeError,
|
|
19
20
|
)
|
|
20
21
|
from aws_lambda_powertools.utilities.data_masking.provider import BaseProvider
|
|
22
|
+
from aws_lambda_powertools.warnings import PowertoolsUserWarning
|
|
21
23
|
|
|
22
24
|
if TYPE_CHECKING:
|
|
23
25
|
from numbers import Number
|
|
@@ -67,11 +69,39 @@ class DataMasking:
|
|
|
67
69
|
provider_options: dict | None = None,
|
|
68
70
|
**encryption_context: str,
|
|
69
71
|
) -> str:
|
|
72
|
+
"""
|
|
73
|
+
Encrypt data using the configured encryption provider.
|
|
74
|
+
|
|
75
|
+
Parameters
|
|
76
|
+
----------
|
|
77
|
+
data : dict, Mapping, Sequence, or Number
|
|
78
|
+
The data to encrypt.
|
|
79
|
+
provider_options : dict, optional
|
|
80
|
+
Provider-specific options for encryption.
|
|
81
|
+
**encryption_context : str
|
|
82
|
+
Additional key-value pairs for encryption context.
|
|
83
|
+
|
|
84
|
+
Returns
|
|
85
|
+
-------
|
|
86
|
+
str
|
|
87
|
+
The encrypted data as a base64-encoded string.
|
|
88
|
+
|
|
89
|
+
Example
|
|
90
|
+
--------
|
|
91
|
+
|
|
92
|
+
encryption_provider = AWSEncryptionSDKProvider(keys=[KMS_KEY_ARN])
|
|
93
|
+
data_masker = DataMasking(provider=encryption_provider)
|
|
94
|
+
encrypted = data_masker.encrypt({"secret": "value"})
|
|
95
|
+
"""
|
|
70
96
|
return self._apply_action(
|
|
71
97
|
data=data,
|
|
72
98
|
fields=None,
|
|
73
99
|
action=self.provider.encrypt,
|
|
74
100
|
provider_options=provider_options or {},
|
|
101
|
+
dynamic_mask=None,
|
|
102
|
+
custom_mask=None,
|
|
103
|
+
regex_pattern=None,
|
|
104
|
+
mask_format=None,
|
|
75
105
|
**encryption_context,
|
|
76
106
|
)
|
|
77
107
|
|
|
@@ -81,28 +111,91 @@ class DataMasking:
|
|
|
81
111
|
provider_options: dict | None = None,
|
|
82
112
|
**encryption_context: str,
|
|
83
113
|
) -> Any:
|
|
114
|
+
"""
|
|
115
|
+
Decrypt data using the configured encryption provider.
|
|
116
|
+
|
|
117
|
+
Parameters
|
|
118
|
+
----------
|
|
119
|
+
data : dict, Mapping, Sequence, or Number
|
|
120
|
+
The data to encrypt.
|
|
121
|
+
provider_options : dict, optional
|
|
122
|
+
Provider-specific options for encryption.
|
|
123
|
+
**encryption_context : str
|
|
124
|
+
Additional key-value pairs for encryption context.
|
|
125
|
+
|
|
126
|
+
Returns
|
|
127
|
+
-------
|
|
128
|
+
str
|
|
129
|
+
The encrypted data as a base64-encoded string.
|
|
130
|
+
|
|
131
|
+
Example
|
|
132
|
+
--------
|
|
133
|
+
|
|
134
|
+
encryption_provider = AWSEncryptionSDKProvider(keys=[KMS_KEY_ARN])
|
|
135
|
+
data_masker = DataMasking(provider=encryption_provider)
|
|
136
|
+
encrypted = data_masker.decrypt(encrypted_data)
|
|
137
|
+
"""
|
|
138
|
+
|
|
84
139
|
return self._apply_action(
|
|
85
140
|
data=data,
|
|
86
141
|
fields=None,
|
|
87
142
|
action=self.provider.decrypt,
|
|
88
143
|
provider_options=provider_options or {},
|
|
144
|
+
dynamic_mask=None,
|
|
145
|
+
custom_mask=None,
|
|
146
|
+
regex_pattern=None,
|
|
147
|
+
mask_format=None,
|
|
89
148
|
**encryption_context,
|
|
90
149
|
)
|
|
91
150
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
151
|
+
def erase(
|
|
152
|
+
self,
|
|
153
|
+
data: Any,
|
|
154
|
+
fields: list[str] | None = None,
|
|
155
|
+
*,
|
|
156
|
+
dynamic_mask: bool | None = None,
|
|
157
|
+
custom_mask: str | None = None,
|
|
158
|
+
regex_pattern: str | None = None,
|
|
159
|
+
mask_format: str | None = None,
|
|
160
|
+
masking_rules: dict | None = None,
|
|
161
|
+
) -> Any:
|
|
162
|
+
"""
|
|
163
|
+
Erase or mask sensitive data in the input.
|
|
100
164
|
|
|
101
|
-
|
|
102
|
-
|
|
165
|
+
Parameters
|
|
166
|
+
----------
|
|
167
|
+
data : Any
|
|
168
|
+
The data to be erased or masked.
|
|
169
|
+
fields : list of str, optional
|
|
170
|
+
List of field names to be erased or masked.
|
|
171
|
+
dynamic_mask : bool, optional
|
|
172
|
+
Whether to use dynamic masking.
|
|
173
|
+
custom_mask : str, optional
|
|
174
|
+
Custom mask to apply instead of the default.
|
|
175
|
+
regex_pattern : str, optional
|
|
176
|
+
Regular expression pattern for identifying data to mask.
|
|
177
|
+
mask_format : str, optional
|
|
178
|
+
Format string for the mask.
|
|
179
|
+
masking_rules : dict, optional
|
|
180
|
+
Dictionary of custom masking rules.
|
|
103
181
|
|
|
104
|
-
|
|
105
|
-
|
|
182
|
+
Returns
|
|
183
|
+
-------
|
|
184
|
+
Any
|
|
185
|
+
The data with sensitive information erased or masked.
|
|
186
|
+
"""
|
|
187
|
+
if masking_rules:
|
|
188
|
+
return self._apply_masking_rules(data=data, masking_rules=masking_rules)
|
|
189
|
+
else:
|
|
190
|
+
return self._apply_action(
|
|
191
|
+
data=data,
|
|
192
|
+
fields=fields,
|
|
193
|
+
action=self.provider.erase,
|
|
194
|
+
dynamic_mask=dynamic_mask,
|
|
195
|
+
custom_mask=custom_mask,
|
|
196
|
+
regex_pattern=regex_pattern,
|
|
197
|
+
mask_format=mask_format,
|
|
198
|
+
)
|
|
106
199
|
|
|
107
200
|
def _apply_action(
|
|
108
201
|
self,
|
|
@@ -110,8 +203,12 @@ class DataMasking:
|
|
|
110
203
|
fields: list[str] | None,
|
|
111
204
|
action: Callable,
|
|
112
205
|
provider_options: dict | None = None,
|
|
113
|
-
|
|
114
|
-
|
|
206
|
+
dynamic_mask: bool | None = None,
|
|
207
|
+
custom_mask: str | None = None,
|
|
208
|
+
regex_pattern: str | None = None,
|
|
209
|
+
mask_format: str | None = None,
|
|
210
|
+
**kwargs: Any,
|
|
211
|
+
) -> Any:
|
|
115
212
|
"""
|
|
116
213
|
Helper method to determine whether to apply a given action to the entire input data
|
|
117
214
|
or to specific fields if the 'fields' argument is specified.
|
|
@@ -127,8 +224,6 @@ class DataMasking:
|
|
|
127
224
|
and returns the modified value.
|
|
128
225
|
provider_options : dict
|
|
129
226
|
Provider specific keyword arguments to propagate; used as an escape hatch.
|
|
130
|
-
encryption_context: str
|
|
131
|
-
Encryption context to use in encrypt and decrypt operations.
|
|
132
227
|
|
|
133
228
|
Returns
|
|
134
229
|
-------
|
|
@@ -143,11 +238,23 @@ class DataMasking:
|
|
|
143
238
|
fields=fields,
|
|
144
239
|
action=action,
|
|
145
240
|
provider_options=provider_options,
|
|
146
|
-
|
|
241
|
+
dynamic_mask=dynamic_mask,
|
|
242
|
+
custom_mask=custom_mask,
|
|
243
|
+
regex_pattern=regex_pattern,
|
|
244
|
+
mask_format=mask_format,
|
|
245
|
+
**kwargs,
|
|
147
246
|
)
|
|
148
247
|
else:
|
|
149
248
|
logger.debug(f"Running action {action.__name__} with the entire data")
|
|
150
|
-
return action(
|
|
249
|
+
return action(
|
|
250
|
+
data=data,
|
|
251
|
+
provider_options=provider_options,
|
|
252
|
+
dynamic_mask=dynamic_mask,
|
|
253
|
+
custom_mask=custom_mask,
|
|
254
|
+
regex_pattern=regex_pattern,
|
|
255
|
+
mask_format=mask_format,
|
|
256
|
+
**kwargs,
|
|
257
|
+
)
|
|
151
258
|
|
|
152
259
|
def _apply_action_to_fields(
|
|
153
260
|
self,
|
|
@@ -155,6 +262,10 @@ class DataMasking:
|
|
|
155
262
|
fields: list,
|
|
156
263
|
action: Callable,
|
|
157
264
|
provider_options: dict | None = None,
|
|
265
|
+
dynamic_mask: bool | None = None,
|
|
266
|
+
custom_mask: str | None = None,
|
|
267
|
+
regex_pattern: str | None = None,
|
|
268
|
+
mask_format: str | None = None,
|
|
158
269
|
**encryption_context: str,
|
|
159
270
|
) -> dict | str:
|
|
160
271
|
"""
|
|
@@ -201,8 +312,10 @@ class DataMasking:
|
|
|
201
312
|
new_dict = {'a': {'b': {'c': '*****'}}, 'x': {'y': '*****'}}
|
|
202
313
|
```
|
|
203
314
|
"""
|
|
315
|
+
if not fields:
|
|
316
|
+
raise ValueError("Fields parameter cannot be empty")
|
|
204
317
|
|
|
205
|
-
data_parsed: dict = self._normalize_data_to_parse(
|
|
318
|
+
data_parsed: dict = self._normalize_data_to_parse(data)
|
|
206
319
|
|
|
207
320
|
# For in-place updates, json_parse accepts a callback function
|
|
208
321
|
# this function must receive 3 args: field_value, fields, field_name
|
|
@@ -211,6 +324,10 @@ class DataMasking:
|
|
|
211
324
|
self._call_action,
|
|
212
325
|
action=action,
|
|
213
326
|
provider_options=provider_options,
|
|
327
|
+
dynamic_mask=dynamic_mask,
|
|
328
|
+
custom_mask=custom_mask,
|
|
329
|
+
regex_pattern=regex_pattern,
|
|
330
|
+
mask_format=mask_format,
|
|
214
331
|
**encryption_context, # type: ignore[arg-type]
|
|
215
332
|
)
|
|
216
333
|
|
|
@@ -232,12 +349,6 @@ class DataMasking:
|
|
|
232
349
|
# For in-place updates, json_parse accepts a callback function
|
|
233
350
|
# that receives 3 args: field_value, fields, field_name
|
|
234
351
|
# We create a partial callback to pre-populate known provider options (action, provider opts, enc ctx)
|
|
235
|
-
update_callback = functools.partial(
|
|
236
|
-
self._call_action,
|
|
237
|
-
action=action,
|
|
238
|
-
provider_options=provider_options,
|
|
239
|
-
**encryption_context, # type: ignore[arg-type]
|
|
240
|
-
)
|
|
241
352
|
|
|
242
353
|
json_parse.update(
|
|
243
354
|
data_parsed,
|
|
@@ -246,6 +357,59 @@ class DataMasking:
|
|
|
246
357
|
|
|
247
358
|
return data_parsed
|
|
248
359
|
|
|
360
|
+
def _apply_masking_rules(self, data: dict, masking_rules: dict) -> dict:
|
|
361
|
+
"""
|
|
362
|
+
Apply masking rules to data, supporting both simple field names and complex path expressions.
|
|
363
|
+
|
|
364
|
+
Args:
|
|
365
|
+
data: The dictionary containing data to mask
|
|
366
|
+
masking_rules: Dictionary mapping field names or path expressions to masking rules
|
|
367
|
+
|
|
368
|
+
Returns:
|
|
369
|
+
dict: The masked data dictionary
|
|
370
|
+
"""
|
|
371
|
+
result = deepcopy(data)
|
|
372
|
+
|
|
373
|
+
for path, rule in masking_rules.items():
|
|
374
|
+
try:
|
|
375
|
+
jsonpath_expr = parse(f"$.{path}")
|
|
376
|
+
matches = jsonpath_expr.find(result)
|
|
377
|
+
|
|
378
|
+
if not matches:
|
|
379
|
+
warnings.warn(f"No matches found for path: {path}", stacklevel=2)
|
|
380
|
+
continue
|
|
381
|
+
|
|
382
|
+
for match in matches:
|
|
383
|
+
try:
|
|
384
|
+
value = match.value
|
|
385
|
+
if value is not None:
|
|
386
|
+
masked_value = self.provider.erase(str(value), **rule)
|
|
387
|
+
match.full_path.update(result, masked_value)
|
|
388
|
+
|
|
389
|
+
except Exception as e:
|
|
390
|
+
warnings.warn(
|
|
391
|
+
f"Error masking value for path {path}: {str(e)}",
|
|
392
|
+
category=PowertoolsUserWarning,
|
|
393
|
+
stacklevel=2,
|
|
394
|
+
)
|
|
395
|
+
continue
|
|
396
|
+
|
|
397
|
+
except Exception as e:
|
|
398
|
+
warnings.warn(f"Error processing path {path}: {str(e)}", category=PowertoolsUserWarning, stacklevel=2)
|
|
399
|
+
continue
|
|
400
|
+
|
|
401
|
+
return result
|
|
402
|
+
|
|
403
|
+
def _mask_nested_field(self, data: dict, field_path: str, mask_function):
|
|
404
|
+
keys = field_path.split(".")
|
|
405
|
+
current = data
|
|
406
|
+
for key in keys[:-1]:
|
|
407
|
+
current = current.get(key, {})
|
|
408
|
+
if not isinstance(current, dict):
|
|
409
|
+
return
|
|
410
|
+
if keys[-1] in current:
|
|
411
|
+
current[keys[-1]] = self.provider.erase(current[keys[-1]], **mask_function)
|
|
412
|
+
|
|
249
413
|
@staticmethod
|
|
250
414
|
def _call_action(
|
|
251
415
|
field_value: Any,
|
|
@@ -253,6 +417,10 @@ class DataMasking:
|
|
|
253
417
|
field_name: str,
|
|
254
418
|
action: Callable,
|
|
255
419
|
provider_options: dict[str, Any] | None = None,
|
|
420
|
+
dynamic_mask: bool | None = None,
|
|
421
|
+
custom_mask: str | None = None,
|
|
422
|
+
regex_pattern: str | None = None,
|
|
423
|
+
mask_format: str | None = None,
|
|
256
424
|
**encryption_context,
|
|
257
425
|
) -> None:
|
|
258
426
|
"""
|
|
@@ -270,13 +438,18 @@ class DataMasking:
|
|
|
270
438
|
Returns:
|
|
271
439
|
- fields[field_name]: Returns the processed field value
|
|
272
440
|
"""
|
|
273
|
-
fields[field_name] = action(
|
|
441
|
+
fields[field_name] = action(
|
|
442
|
+
field_value,
|
|
443
|
+
provider_options=provider_options,
|
|
444
|
+
dynamic_mask=dynamic_mask,
|
|
445
|
+
custom_mask=custom_mask,
|
|
446
|
+
regex_pattern=regex_pattern,
|
|
447
|
+
mask_format=mask_format,
|
|
448
|
+
**encryption_context,
|
|
449
|
+
)
|
|
274
450
|
return fields[field_name]
|
|
275
451
|
|
|
276
|
-
def _normalize_data_to_parse(self,
|
|
277
|
-
if not fields:
|
|
278
|
-
raise ValueError("No fields specified.")
|
|
279
|
-
|
|
452
|
+
def _normalize_data_to_parse(self, data: str | dict) -> dict:
|
|
280
453
|
if isinstance(data, str):
|
|
281
454
|
# Parse JSON string as dictionary
|
|
282
455
|
data_parsed = self.json_deserializer(data)
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import functools
|
|
4
|
+
import json
|
|
5
|
+
import re
|
|
6
|
+
from typing import Any, Callable
|
|
7
|
+
|
|
8
|
+
from aws_lambda_powertools.utilities.data_masking.constants import DATA_MASKING_STRING
|
|
9
|
+
|
|
10
|
+
PRESERVE_CHARS = set("-_. ")
|
|
11
|
+
_regex_cache = {}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class BaseProvider:
|
|
15
|
+
"""
|
|
16
|
+
The BaseProvider class serves as an abstract base class for data masking providers.
|
|
17
|
+
|
|
18
|
+
Example
|
|
19
|
+
--------
|
|
20
|
+
```python
|
|
21
|
+
from aws_lambda_powertools.utilities._data_masking.provider import BaseProvider
|
|
22
|
+
from aws_lambda_powertools.utilities.data_masking import DataMasking
|
|
23
|
+
|
|
24
|
+
class MyCustomProvider(BaseProvider):
|
|
25
|
+
def encrypt(self, data) -> str:
|
|
26
|
+
# Implementation logic for data encryption
|
|
27
|
+
|
|
28
|
+
def decrypt(self, data) -> Any:
|
|
29
|
+
# Implementation logic for data decryption
|
|
30
|
+
|
|
31
|
+
def erase(self, data) -> Any | Iterable:
|
|
32
|
+
# Implementation logic for data masking
|
|
33
|
+
pass
|
|
34
|
+
|
|
35
|
+
def lambda_handler(event, context):
|
|
36
|
+
provider = MyCustomProvider(["secret-key"])
|
|
37
|
+
data_masker = DataMasking(provider=provider)
|
|
38
|
+
|
|
39
|
+
data = {
|
|
40
|
+
"project": "powertools",
|
|
41
|
+
"sensitive": "password"
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
encrypted = data_masker.encrypt(data)
|
|
45
|
+
|
|
46
|
+
return encrypted
|
|
47
|
+
```
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
def __init__(
|
|
51
|
+
self,
|
|
52
|
+
json_serializer: Callable[..., str] = functools.partial(json.dumps, ensure_ascii=False),
|
|
53
|
+
json_deserializer: Callable[[str], Any] = json.loads,
|
|
54
|
+
) -> None:
|
|
55
|
+
self.json_serializer = json_serializer
|
|
56
|
+
self.json_deserializer = json_deserializer
|
|
57
|
+
|
|
58
|
+
def encrypt(self, data, provider_options: dict | None = None, **encryption_context: str) -> str:
|
|
59
|
+
"""
|
|
60
|
+
Abstract method for encrypting data. Subclasses must implement this method.
|
|
61
|
+
"""
|
|
62
|
+
raise NotImplementedError("Subclasses must implement encrypt()")
|
|
63
|
+
|
|
64
|
+
def decrypt(self, data, provider_options: dict | None = None, **encryption_context: str) -> Any:
|
|
65
|
+
"""
|
|
66
|
+
Abstract method for decrypting data. Subclasses must implement this method.
|
|
67
|
+
"""
|
|
68
|
+
raise NotImplementedError("Subclasses must implement decrypt()")
|
|
69
|
+
|
|
70
|
+
def erase(
|
|
71
|
+
self,
|
|
72
|
+
data: Any,
|
|
73
|
+
dynamic_mask: bool | None = None,
|
|
74
|
+
custom_mask: str | None = None,
|
|
75
|
+
regex_pattern: str | None = None,
|
|
76
|
+
mask_format: str | None = None,
|
|
77
|
+
masking_rules: dict | None = None,
|
|
78
|
+
**kwargs,
|
|
79
|
+
) -> Any:
|
|
80
|
+
|
|
81
|
+
result: Any = DATA_MASKING_STRING
|
|
82
|
+
|
|
83
|
+
if not any([dynamic_mask, custom_mask, regex_pattern, mask_format, masking_rules]):
|
|
84
|
+
if isinstance(data, (str, int, float, dict, bytes)):
|
|
85
|
+
return DATA_MASKING_STRING
|
|
86
|
+
elif isinstance(data, (list, tuple, set)):
|
|
87
|
+
return type(data)([DATA_MASKING_STRING] * len(data))
|
|
88
|
+
else:
|
|
89
|
+
return DATA_MASKING_STRING
|
|
90
|
+
|
|
91
|
+
if isinstance(data, (str, int, float)):
|
|
92
|
+
result = self._mask_primitive(str(data), dynamic_mask, custom_mask, regex_pattern, mask_format)
|
|
93
|
+
elif isinstance(data, dict):
|
|
94
|
+
result = self._mask_dict(
|
|
95
|
+
data,
|
|
96
|
+
dynamic_mask,
|
|
97
|
+
custom_mask,
|
|
98
|
+
regex_pattern,
|
|
99
|
+
mask_format,
|
|
100
|
+
masking_rules,
|
|
101
|
+
)
|
|
102
|
+
elif isinstance(data, (list, tuple, set)):
|
|
103
|
+
result = self._mask_iterable(
|
|
104
|
+
data,
|
|
105
|
+
dynamic_mask,
|
|
106
|
+
custom_mask,
|
|
107
|
+
regex_pattern,
|
|
108
|
+
mask_format,
|
|
109
|
+
masking_rules,
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
return result
|
|
113
|
+
|
|
114
|
+
def _mask_primitive(
|
|
115
|
+
self,
|
|
116
|
+
data: str,
|
|
117
|
+
dynamic_mask: bool | None,
|
|
118
|
+
custom_mask: str | None,
|
|
119
|
+
regex_pattern: str | None,
|
|
120
|
+
mask_format: str | None,
|
|
121
|
+
) -> str:
|
|
122
|
+
if regex_pattern and mask_format:
|
|
123
|
+
return self._regex_mask(data, regex_pattern, mask_format)
|
|
124
|
+
elif custom_mask:
|
|
125
|
+
return self._pattern_mask(data, custom_mask)
|
|
126
|
+
|
|
127
|
+
return self._custom_erase(data)
|
|
128
|
+
|
|
129
|
+
def _mask_dict(
|
|
130
|
+
self,
|
|
131
|
+
data: dict,
|
|
132
|
+
dynamic_mask: bool | None,
|
|
133
|
+
custom_mask: str | None,
|
|
134
|
+
regex_pattern: str | None,
|
|
135
|
+
mask_format: str | None,
|
|
136
|
+
masking_rules: dict | None,
|
|
137
|
+
) -> dict:
|
|
138
|
+
return {
|
|
139
|
+
k: self.erase(
|
|
140
|
+
v,
|
|
141
|
+
dynamic_mask=dynamic_mask,
|
|
142
|
+
custom_mask=custom_mask,
|
|
143
|
+
regex_pattern=regex_pattern,
|
|
144
|
+
mask_format=mask_format,
|
|
145
|
+
masking_rules=masking_rules,
|
|
146
|
+
)
|
|
147
|
+
for k, v in data.items()
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
def _mask_iterable(
|
|
151
|
+
self,
|
|
152
|
+
data: list | tuple | set,
|
|
153
|
+
dynamic_mask: bool | None,
|
|
154
|
+
custom_mask: str | None,
|
|
155
|
+
regex_pattern: str | None,
|
|
156
|
+
mask_format: str | None,
|
|
157
|
+
masking_rules: dict | None,
|
|
158
|
+
) -> list | tuple | set:
|
|
159
|
+
masked_data = [
|
|
160
|
+
self.erase(
|
|
161
|
+
item,
|
|
162
|
+
dynamic_mask=dynamic_mask,
|
|
163
|
+
custom_mask=custom_mask,
|
|
164
|
+
regex_pattern=regex_pattern,
|
|
165
|
+
mask_format=mask_format,
|
|
166
|
+
masking_rules=masking_rules,
|
|
167
|
+
)
|
|
168
|
+
for item in data
|
|
169
|
+
]
|
|
170
|
+
return type(data)(masked_data)
|
|
171
|
+
|
|
172
|
+
def _pattern_mask(self, data: str, pattern: str) -> str:
|
|
173
|
+
"""Apply pattern masking to string data."""
|
|
174
|
+
return pattern[: len(data)] if len(pattern) >= len(data) else pattern
|
|
175
|
+
|
|
176
|
+
def _regex_mask(self, data: str, regex_pattern: str, mask_format: str) -> str:
|
|
177
|
+
"""Apply regex masking to string data."""
|
|
178
|
+
try:
|
|
179
|
+
if regex_pattern not in _regex_cache:
|
|
180
|
+
_regex_cache[regex_pattern] = re.compile(regex_pattern)
|
|
181
|
+
return _regex_cache[regex_pattern].sub(mask_format, data)
|
|
182
|
+
except re.error:
|
|
183
|
+
return data
|
|
184
|
+
|
|
185
|
+
def _custom_erase(self, data: str) -> str:
|
|
186
|
+
if not data:
|
|
187
|
+
return ""
|
|
188
|
+
|
|
189
|
+
return "".join("*" if char not in PRESERVE_CHARS else char for char in data)
|