From 5977f2e781d659616ec5a47e5caa16c8047a47d6 Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Fri, 1 May 2020 11:33:26 +0100 Subject: [PATCH 1/6] improv: test all metric units --- python/tests/functional/test_metrics.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/python/tests/functional/test_metrics.py b/python/tests/functional/test_metrics.py index 703c8788ac..c860bfe21a 100644 --- a/python/tests/functional/test_metrics.py +++ b/python/tests/functional/test_metrics.py @@ -303,3 +303,11 @@ def lambda_handler(evt, context): with pytest.raises(SchemaValidationError): lambda_handler({}, {}) + +def test_all_metric_units(metric, dimension, namespace): + + for unit in MetricUnit: + metric['unit'] = unit.value + with single_metric(**metric) as my_metric: + my_metric.add_dimension(**dimension) + my_metric.add_namespace(**namespace) From 43abcc19f78b58a76283d66e1b8d78ab51611d1e Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Fri, 1 May 2020 14:19:16 +0100 Subject: [PATCH 2/6] fix: correct MetricUnit model values --- python/aws_lambda_powertools/helper/models.py | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/python/aws_lambda_powertools/helper/models.py b/python/aws_lambda_powertools/helper/models.py index 424e5bf3ae..16a5df3669 100644 --- a/python/aws_lambda_powertools/helper/models.py +++ b/python/aws_lambda_powertools/helper/models.py @@ -89,17 +89,17 @@ class MetricUnit(Enum): Terabits = "Terabits" Percent = "Percent" Count = "Count" - BytesPerSecond = "Second" - KilobytesPerSecond = "Second" - MegabytesPerSecond = "Second" - GigabytesPerSecond = "Second" - TerabytesPerSecond = "Second" - BitsPerSecond = "Second" - KilobitsPerSecond = "Second" - MegabitsPerSecond = "Second" - GigabitsPerSecond = "Second" - TerabitsPerSecond = "Second" - CountPerSecond = "Second" + BytesPerSecond = "Bytes/Second" + KilobytesPerSecond = "Kilobytes/Second" + MegabytesPerSecond = "Megabytes/Second" + GigabytesPerSecond = "Gigabytes/Second" + TerabytesPerSecond = "Terabytes/Second" + BitsPerSecond = "Bits/Second" + KilobitsPerSecond = "Kilobits/Second" + MegabitsPerSecond = "Megabits/Second" + GigabitsPerSecond = "Gigabits/Second" + TerabitsPerSecond = "Terabits/Second" + CountPerSecond = "Count/Second" def build_metric_unit_from_str(unit: Union[str, MetricUnit]) -> MetricUnit: From b42ead1cede0d06652440d0398f231d58389bfa9 Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Fri, 1 May 2020 14:19:33 +0100 Subject: [PATCH 3/6] fix: metric unit as string branch logic --- python/aws_lambda_powertools/metrics/base.py | 21 +++++++++++++------- python/tests/functional/test_metrics.py | 21 ++++++++++++++++++-- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/python/aws_lambda_powertools/metrics/base.py b/python/aws_lambda_powertools/metrics/base.py index 8d561abf71..b53030a73b 100644 --- a/python/aws_lambda_powertools/metrics/base.py +++ b/python/aws_lambda_powertools/metrics/base.py @@ -53,6 +53,8 @@ def __init__(self, metric_set: Dict[str, str] = None, dimension_set: Dict = None self.metric_set = metric_set or {} self.dimension_set = dimension_set or {} self.namespace = os.getenv("POWERTOOLS_METRICS_NAMESPACE") or namespace + self._metric_units = [unit.value for unit in MetricUnit] + self._metric_unit_options = list(MetricUnit.__members__) def add_namespace(self, name: str): """Adds given metric namespace @@ -105,14 +107,19 @@ def add_metric(self, name: str, unit: MetricUnit, value: Union[float, int]): if not isinstance(value, numbers.Number): raise MetricValueError(f"{value} is not a valid number") - if not isinstance(unit, MetricUnit): - try: - unit = MetricUnit[unit] - except KeyError: - unit_options = list(MetricUnit.__members__) - raise MetricUnitError(f"Invalid metric unit '{unit}', expected either option: {unit_options}") + if isinstance(unit, str): + if unit in self._metric_unit_options: + unit = MetricUnit[unit].value - metric = {"Unit": unit.value, "Value": float(value)} + if unit not in self._metric_units: # str correta + raise MetricUnitError( + f"Invalid metric unit '{unit}', expected either option: {self._metric_unit_options}" + ) + + if isinstance(unit, MetricUnit): + unit = MetricUnit[unit].value + + metric = {"Unit": unit, "Value": float(value)} logger.debug(f"Adding metric: {name} with {metric}") self.metric_set[name] = metric diff --git a/python/tests/functional/test_metrics.py b/python/tests/functional/test_metrics.py index c860bfe21a..54228ab9c2 100644 --- a/python/tests/functional/test_metrics.py +++ b/python/tests/functional/test_metrics.py @@ -304,10 +304,27 @@ def lambda_handler(evt, context): with pytest.raises(SchemaValidationError): lambda_handler({}, {}) -def test_all_metric_units(metric, dimension, namespace): +def test_all_metric_units_string(metric, dimension, namespace): + + # "Seconds", "BytesPerSecond", etc. for unit in MetricUnit: - metric['unit'] = unit.value + metric["unit"] = unit.name + with single_metric(**metric) as my_metric: + my_metric.add_dimension(**dimension) + my_metric.add_namespace(**namespace) + + with pytest.raises(MetricUnitError): + metric["unit"] = "seconds" + with single_metric(**metric) as my_metric: + my_metric.add_dimension(**dimension) + my_metric.add_namespace(**namespace) + + all_metric_units = [unit.value for unit in MetricUnit] + + # "Seconds", "Bytes/Second", etc. + for unit in all_metric_units: + metric["unit"] = unit with single_metric(**metric) as my_metric: my_metric.add_dimension(**dimension) my_metric.add_namespace(**namespace) From b36b4a1f5f0f1dac78707c02500588538f5636bd Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Fri, 1 May 2020 14:28:44 +0100 Subject: [PATCH 4/6] chore: refactor --- python/aws_lambda_powertools/metrics/base.py | 46 +++++++++++++++----- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/python/aws_lambda_powertools/metrics/base.py b/python/aws_lambda_powertools/metrics/base.py index b53030a73b..38e513f19a 100644 --- a/python/aws_lambda_powertools/metrics/base.py +++ b/python/aws_lambda_powertools/metrics/base.py @@ -107,18 +107,7 @@ def add_metric(self, name: str, unit: MetricUnit, value: Union[float, int]): if not isinstance(value, numbers.Number): raise MetricValueError(f"{value} is not a valid number") - if isinstance(unit, str): - if unit in self._metric_unit_options: - unit = MetricUnit[unit].value - - if unit not in self._metric_units: # str correta - raise MetricUnitError( - f"Invalid metric unit '{unit}', expected either option: {self._metric_unit_options}" - ) - - if isinstance(unit, MetricUnit): - unit = MetricUnit[unit].value - + unit = self.__extract_metric_unit_value(unit=unit) metric = {"Unit": unit, "Value": float(value)} logger.debug(f"Adding metric: {name} with {metric}") self.metric_set[name] = metric @@ -212,3 +201,36 @@ def add_dimension(self, name: str, value: str): """ logger.debug(f"Adding dimension: {name}:{value}") self.dimension_set[name] = value + + def __extract_metric_unit_value(self, unit: Union[str, MetricUnit]) -> str: + """Return metric value from metric unit whether that's str or MetricUnit enum + + Parameters + ---------- + unit : Union[str, MetricUnit] + Metric unit + + Returns + ------- + str + Metric unit value (e.g. "Seconds", "Count/Second") + + Raises + ------ + MetricUnitError + When metric unit is not supported by CloudWatch + """ + + if isinstance(unit, str): + if unit in self._metric_unit_options: + unit = MetricUnit[unit].value + + if unit not in self._metric_units: # str correta + raise MetricUnitError( + f"Invalid metric unit '{unit}', expected either option: {self._metric_unit_options}" + ) + + if isinstance(unit, MetricUnit): + unit = unit.value + + return unit From 6dc17cbf172198950b29fdb75590ca7291207bb2 Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Fri, 1 May 2020 14:30:01 +0100 Subject: [PATCH 5/6] chore: test str --- python/tests/functional/test_metrics.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/tests/functional/test_metrics.py b/python/tests/functional/test_metrics.py index 54228ab9c2..7c6990668b 100644 --- a/python/tests/functional/test_metrics.py +++ b/python/tests/functional/test_metrics.py @@ -307,7 +307,7 @@ def lambda_handler(evt, context): def test_all_metric_units_string(metric, dimension, namespace): - # "Seconds", "BytesPerSecond", etc. + # metric unit as MetricUnit key e.g. "Seconds", "BytesPerSecond" for unit in MetricUnit: metric["unit"] = unit.name with single_metric(**metric) as my_metric: @@ -322,7 +322,7 @@ def test_all_metric_units_string(metric, dimension, namespace): all_metric_units = [unit.value for unit in MetricUnit] - # "Seconds", "Bytes/Second", etc. + # metric unit as MetricUnit value e.g. "Seconds", "Bytes/Second" for unit in all_metric_units: metric["unit"] = unit with single_metric(**metric) as my_metric: From 06fb34308164eddf7f45c57db318af31d9469bb9 Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Fri, 1 May 2020 14:33:50 +0100 Subject: [PATCH 6/6] chore: bump version with metric unit patch --- python/HISTORY.md | 20 ++++++++++++++++++++ python/pyproject.toml | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/python/HISTORY.md b/python/HISTORY.md index 8001c9bba2..69d85ad9f2 100644 --- a/python/HISTORY.md +++ b/python/HISTORY.md @@ -1,7 +1,27 @@ # HISTORY +## May 1st + +**0.8.1** + +* Fix metric unit casting logic if one passes plain string (value or key) +* Fix `MetricUnit` enum values for + - `BytesPerSecond` + - `KilobytesPerSecond` + - `MegabytesPerSecond` + - `GigabytesPerSecond` + - `TerabytesPerSecond` + - `BitsPerSecond` + - `KilobitsPerSecond` + - `MegabitsPerSecond` + - `GigabitsPerSecond` + - `TerabitsPerSecond` + - `CountPerSecond` + ## April 24th +**0.8.0** + * Introduces `Logger` for stuctured logging as a replacement for `logger_setup` * Introduces `Logger.inject_lambda_context` decorator as a replacement for `logger_inject_lambda_context` * Raise `DeprecationWarning` exception for both `logger_setup`, `logger_inject_lambda_context` diff --git a/python/pyproject.toml b/python/pyproject.toml index 8b21c9dce8..99a3564ca2 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "aws_lambda_powertools" -version = "0.8.0" +version = "0.8.1" description = "Python utilities for AWS Lambda functions including but not limited to tracing, logging and custom metric" authors = ["Amazon Web Services"] classifiers=[