Skip to content
Next Next commit
fix(event-handler): allow for @app.not_found() decorator
Changes: - allow for `@app.not_found()` decorator - add typing to `strtobool` and add code coverage
  • Loading branch information
Michael Brewer committed Dec 23, 2021
commit a3adb5fe4408cf7fe2d009f84950bc7d7b98553c
6 changes: 4 additions & 2 deletions aws_lambda_powertools/event_handler/api_gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,7 @@ def _remove_prefix(self, path: str) -> str:
@staticmethod
def _path_starts_with(path: str, prefix: str):
"""Returns true if the `path` starts with a prefix plus a `/`"""
if not isinstance(prefix, str) or len(prefix) == 0:
if not isinstance(prefix, str) or prefix == "":
return False

return path.startswith(prefix + "/")
Expand Down Expand Up @@ -633,7 +633,9 @@ def _call_route(self, route: Route, args: Dict[str, str]) -> ResponseBuilder:

raise

def not_found(self, func: Callable):
def not_found(self, func: Optional[Callable] = None):
if func is None:
return self.exception_handler(NotFoundError)
return self.exception_handler(NotFoundError)(func)

def exception_handler(self, exc_class: Type[Exception]):
Expand Down
11 changes: 5 additions & 6 deletions aws_lambda_powertools/shared/functions.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
from typing import Any, Optional, Union


def strtobool(value):
def strtobool(value: str) -> bool:
value = value.lower()
if value in ("y", "yes", "t", "true", "on", "1"):
return 1
elif value in ("n", "no", "f", "false", "off", "0"):
return 0
else:
raise ValueError("invalid truth value %r" % (value,))
return True
if value in ("n", "no", "f", "false", "off", "0"):
return False
raise ValueError(f"invalid truth value '{value}'")


def resolve_truthy_env_var_choice(env: str, choice: Optional[bool] = None) -> bool:
Expand Down
18 changes: 17 additions & 1 deletion tests/functional/event_handler/test_api_gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -1142,10 +1142,26 @@ def handle_not_found(exc: NotFoundError) -> Response:
return Response(status_code=404, content_type=content_types.TEXT_PLAIN, body="I am a teapot!")

# WHEN calling the event handler
# AND not route is found
# AND no route is found
result = app(LOAD_GW_EVENT, {})

# THEN call the exception_handler
assert result["statusCode"] == 404
assert result["headers"]["Content-Type"] == content_types.TEXT_PLAIN
assert result["body"] == "I am a teapot!"


def test_exception_handler_not_found_alt():
# GIVEN a resolver with `@app.not_found()`
app = ApiGatewayResolver()

@app.not_found()
def handle_not_found(_) -> Response:
return Response(status_code=404, content_type=content_types.APPLICATION_JSON, body="{}")

# WHEN calling the event handler
# AND no route is found
result = app(LOAD_GW_EVENT, {})

# THEN call the @app.not_found() function
assert result["statusCode"] == 404
20 changes: 19 additions & 1 deletion tests/functional/test_shared_functions.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from aws_lambda_powertools.shared.functions import resolve_env_var_choice, resolve_truthy_env_var_choice
import pytest

from aws_lambda_powertools.shared.functions import resolve_env_var_choice, resolve_truthy_env_var_choice, strtobool


def test_resolve_env_var_choice_explicit_wins_over_env_var():
Expand All @@ -9,3 +11,19 @@ def test_resolve_env_var_choice_explicit_wins_over_env_var():
def test_resolve_env_var_choice_env_wins_over_absent_explicit():
assert resolve_truthy_env_var_choice(env="true") == 1
assert resolve_env_var_choice(env="something") == "something"


@pytest.mark.parametrize("true_value", ["y", "yes", "t", "true", "on", "1"])
def test_strtobool_true(true_value):
assert strtobool(true_value)


@pytest.mark.parametrize("false_value", ["n", "no", "f", "false", "off", "0"])
def test_strtobool_false(false_value):
assert strtobool(false_value) is False


def test_strtobool_value_error():
with pytest.raises(ValueError) as exp:
strtobool("fail")
assert str(exp.value) == "invalid truth value 'fail'"