From c16386f94aca7fc6ad34aff70f713733be493d8b Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Fri, 19 Jul 2024 16:42:04 +0100 Subject: [PATCH] Adding top-level method to be according others in the class --- .pre-commit-config.yaml | 2 +- .../utilities/parameters/ssm.py | 76 +++++++++++++++---- tests/functional/test_logger_utils.py | 10 +-- 3 files changed, 68 insertions(+), 20 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1fbd55f3197..0a9cee41d5a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,7 +19,7 @@ repos: types: [python] - id: ruff name: linting-format::ruff - entry: poetry run ruff + entry: poetry run ruff check language: system types: [python] - repo: https://github.com/igorshubovych/markdownlint-cli diff --git a/aws_lambda_powertools/utilities/parameters/ssm.py b/aws_lambda_powertools/utilities/parameters/ssm.py index 76553bda0fe..891e1f3ada3 100644 --- a/aws_lambda_powertools/utilities/parameters/ssm.py +++ b/aws_lambda_powertools/utilities/parameters/ssm.py @@ -125,6 +125,63 @@ def __init__( config=config, ) + def get_multiple( # type: ignore[override] + self, + path: str, + max_age: Optional[int] = None, + transform: TransformOptions = None, + raise_on_transform_error: bool = False, + decrypt: Optional[bool] = None, + force_fetch: bool = False, + recursive: bool = False, + **sdk_options, + ) -> Union[Dict[str, str], Dict[str, dict], Dict[str, bytes]]: + """ + Retrieve multiple parameters based on a path prefix + + Parameters + ---------- + path: str + Parameter path used to retrieve multiple parameters + max_age: int, optional + Maximum age of the cached value + transform: str, optional + Optional transformation of the parameter value. Supported values + are "json" for JSON strings, "binary" for base 64 encoded + values or "auto" which looks at the attribute key to determine the type. + raise_on_transform_error: bool, optional + Raises an exception if any transform fails, otherwise this will + return a None value for each transform that failed + force_fetch: bool, optional + Force update even before a cached item has expired, defaults to False + recursive: bool, optional + If this should retrieve the parameter values recursively or not + sdk_options: dict, optional + Arguments that will be passed directly to the underlying API call + + Raises + ------ + GetParameterError + When the parameter provider fails to retrieve parameter values for + a given path. + TransformParameterError + When the parameter provider fails to transform a parameter value. + """ + + # If max_age is not set, resolve it from the environment variable, defaulting to DEFAULT_MAX_AGE_SECS + max_age = resolve_max_age(env=os.getenv(constants.PARAMETERS_MAX_AGE_ENV, DEFAULT_MAX_AGE_SECS), choice=max_age) + + # If decrypt is not set, resolve it from the environment variable, defaulting to False + decrypt = resolve_truthy_env_var_choice( + env=os.getenv(constants.PARAMETERS_SSM_DECRYPT_ENV, "false"), + choice=decrypt, + ) + + sdk_options["decrypt"] = decrypt + sdk_options["recursive"] = recursive + + return super().get_multiple(path, max_age, transform, force_fetch, raise_on_transform_error, **sdk_options) + # We break Liskov substitution principle due to differences in signatures of this method and superclass get method # We ignore mypy error, as changes to the signature here or in a superclass is a breaking change to users def get( # type: ignore[override] @@ -341,12 +398,6 @@ def _get_multiple( Dictionary of options that will be passed to the Parameter Store get_parameters_by_path API call """ - # If decrypt is not set, resolve it from the environment variable, defaulting to False - decrypt = resolve_truthy_env_var_choice( - env=os.getenv(constants.PARAMETERS_SSM_DECRYPT_ENV, "false"), - choice=decrypt, - ) - # Explicit arguments will take precedence over keyword arguments sdk_options["Path"] = path sdk_options["WithDecryption"] = decrypt @@ -788,14 +839,12 @@ def get_parameter( choice=decrypt, ) - # Add to `decrypt` sdk_options to we can have an explicit option for this - sdk_options["decrypt"] = decrypt - return DEFAULT_PROVIDERS["ssm"].get( - name, + name=name, max_age=max_age, transform=transform, force_fetch=force_fetch, + decrypt=decrypt, **sdk_options, ) @@ -928,15 +977,14 @@ def get_parameters( choice=decrypt, ) - sdk_options["recursive"] = recursive - sdk_options["decrypt"] = decrypt - return DEFAULT_PROVIDERS["ssm"].get_multiple( - path, + path=path, max_age=max_age, transform=transform, raise_on_transform_error=raise_on_transform_error, force_fetch=force_fetch, + recursive=recursive, + decrypt=decrypt, **sdk_options, ) diff --git a/tests/functional/test_logger_utils.py b/tests/functional/test_logger_utils.py index 5a95e2c54a2..61a2bb8654e 100644 --- a/tests/functional/test_logger_utils.py +++ b/tests/functional/test_logger_utils.py @@ -65,11 +65,11 @@ def test_copy_config_to_ext_loggers(stdout, logger, log_level): logs = capture_multiple_logging_statements_output(stdout) # THEN all external loggers used Powertools for AWS Lambda (Python) handler, formatter and log level - for index, logger in enumerate([logger_1, logger_2]): - assert len(logger.handlers) == 1 - assert isinstance(logger.handlers[0], logging.StreamHandler) - assert isinstance(logger.handlers[0].formatter, formatter.LambdaPowertoolsFormatter) - assert logger.level == log_level.INFO.value + for index, in_logger in enumerate([logger_1, logger_2]): + assert len(in_logger.handlers) == 1 + assert isinstance(in_logger.handlers[0], logging.StreamHandler) + assert isinstance(in_logger.handlers[0].formatter, formatter.LambdaPowertoolsFormatter) + assert in_logger.level == log_level.INFO.value assert logs[index]["message"] == msg assert logs[index]["level"] == log_level.INFO.name