From c16386f94aca7fc6ad34aff70f713733be493d8b Mon Sep 17 00:00:00 2001
From: Leandro Damascena <lcdama@amazon.pt>
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