Skip to content

Commit 1ee0a36

Browse files
Addressing Heitor's feedback
1 parent 44c1943 commit 1ee0a36

File tree

3 files changed

+72
-7
lines changed

3 files changed

+72
-7
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
class PowertoolsWarning(UserWarning):
2+
"""
3+
This class provides a custom Warning tailored for better clarity when certain situations occur.
4+
It offers more informative and relevant warning messages, allowing customers to easily suppress
5+
or handle this specific warning type as needed.
6+
7+
Parameters
8+
----------
9+
message: str
10+
The warning message to be displayed.
11+
"""
12+
13+
def __init__(self, message):
14+
self.message = message
15+
super().__init__(message)
16+
17+
def __str__(self):
18+
return self.message

aws_lambda_powertools/utilities/idempotency/idempotency.py

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
55
import functools
66
import logging
77
import os
8+
import warnings
89
from inspect import isclass
910
from typing import Any, Callable, Dict, Optional, Type, Union, cast
1011

1112
from aws_lambda_powertools.middleware_factory import lambda_handler_decorator
1213
from aws_lambda_powertools.shared import constants
13-
from aws_lambda_powertools.shared.functions import strtobool
14+
from aws_lambda_powertools.shared.functions import powertools_dev_is_set, strtobool
15+
from aws_lambda_powertools.shared.powertools_warnings import PowertoolsWarning
1416
from aws_lambda_powertools.shared.types import AnyCallableT
1517
from aws_lambda_powertools.utilities.idempotency.base import IdempotencyHandler
1618
from aws_lambda_powertools.utilities.idempotency.config import IdempotencyConfig
@@ -67,9 +69,16 @@ def idempotent(
6769
>>> return {"StatusCode": 200}
6870
"""
6971

70-
# Check if the IDEMPOTENCY_DISABLED_ENV environment variable is set to True
71-
# If IDEMPOTENCY_DISABLED_ENV is not set or set to any false value, the function will be idempotent by default
72+
# Skip idempotency controls when POWERTOOLS_IDEMPOTENCY_DISABLED has a truthy value
73+
# Raises a warning if not running in development mode
7274
if strtobool(os.getenv(constants.IDEMPOTENCY_DISABLED_ENV, "false")):
75+
if not powertools_dev_is_set():
76+
warnings.warn(
77+
message="Disabling idempotency is intended for development environments only "
78+
"and should not be used in production.",
79+
category=PowertoolsWarning,
80+
stacklevel=2,
81+
)
7382
return handler(event, context, **kwargs)
7483

7584
config = config or IdempotencyConfig()
@@ -153,9 +162,16 @@ def process_order(customer_id: str, order: dict, **kwargs):
153162

154163
@functools.wraps(function)
155164
def decorate(*args, **kwargs):
156-
# Check if the IDEMPOTENCY_DISABLED_ENV environment variable is set to True
157-
# If IDEMPOTENCY_DISABLED_ENV is not set or set to any false value, the function will be idempotent by default
158-
if strtobool(os.getenv(constants.IDEMPOTENCY_DISABLED_ENV, "0")):
165+
# Skip idempotency controls when POWERTOOLS_IDEMPOTENCY_DISABLED has a truthy value
166+
# Raises a warning if not running in development mode
167+
if strtobool(os.getenv(constants.IDEMPOTENCY_DISABLED_ENV, "false")):
168+
if not powertools_dev_is_set():
169+
warnings.warn(
170+
message="Disabling idempotency is intended for development environments only "
171+
"and should not be used in production.",
172+
category=PowertoolsWarning,
173+
stacklevel=2,
174+
)
159175
return function(*args, **kwargs)
160176

161177
if data_keyword_argument not in kwargs:

tests/functional/idempotency/test_idempotency.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from pytest import FixtureRequest
1313
from pytest_mock import MockerFixture
1414

15+
from aws_lambda_powertools.shared.powertools_warnings import PowertoolsWarning
1516
from aws_lambda_powertools.utilities.data_classes import (
1617
APIGatewayProxyEventV2,
1718
event_source,
@@ -1668,7 +1669,7 @@ def dummy(payload):
16681669

16691670

16701671
@pytest.mark.parametrize("idempotency_disabled_value", ["1", "y", "yes", "t", "true", "on"])
1671-
def test_idempotency_enabled_envvar(
1672+
def test_idempotency_enabled_envvar_in_dev_environment(
16721673
monkeypatch,
16731674
lambda_context,
16741675
persistence_store: DynamoDBPersistenceLayer,
@@ -1680,6 +1681,7 @@ def test_idempotency_enabled_envvar(
16801681
persistence_store.client = MagicMock()
16811682

16821683
monkeypatch.setenv("POWERTOOLS_IDEMPOTENCY_DISABLED", str(idempotency_disabled_value))
1684+
monkeypatch.setenv("POWERTOOLS_DEV", "true")
16831685

16841686
@idempotent_function(data_keyword_argument="data", persistence_store=persistence_store)
16851687
def dummy(data):
@@ -1695,6 +1697,35 @@ def dummy_handler(event, context):
16951697
assert len(persistence_store.client.method_calls) == 0
16961698

16971699

1700+
@pytest.mark.parametrize("idempotency_disabled_value", ["1", "y", "yes", "t", "true", "on"])
1701+
def test_idempotency_enabled_envvar_in_non_dev_environment(
1702+
monkeypatch,
1703+
lambda_context,
1704+
persistence_store: DynamoDBPersistenceLayer,
1705+
idempotency_disabled_value,
1706+
):
1707+
# Scenario to validate no requests sent to dynamodb table when 'POWERTOOLS_IDEMPOTENCY_DISABLED' is set
1708+
mock_event = {"data": "value"}
1709+
1710+
persistence_store.client = MagicMock()
1711+
1712+
monkeypatch.setenv("POWERTOOLS_IDEMPOTENCY_DISABLED", str(idempotency_disabled_value))
1713+
1714+
@idempotent_function(data_keyword_argument="data", persistence_store=persistence_store)
1715+
def dummy(data):
1716+
return {"message": "hello"}
1717+
1718+
@idempotent(persistence_store=persistence_store)
1719+
def dummy_handler(event, context):
1720+
return {"message": "hi"}
1721+
1722+
with pytest.warns(PowertoolsWarning, match="Disabling idempotency is intended for development environments*"):
1723+
dummy(data=mock_event)
1724+
dummy_handler(mock_event, lambda_context)
1725+
1726+
assert len(persistence_store.client.method_calls) == 0
1727+
1728+
16981729
@pytest.mark.parametrize("idempotency_disabled_value", ["0", "n", "no", "f", "false", "off"])
16991730
def test_idempotency_disabled_envvar(
17001731
monkeypatch,

0 commit comments

Comments
 (0)