Skip to content

Commit 0106f79

Browse files
committed
move to generics for parser
1 parent 4a5cd55 commit 0106f79

File tree

2 files changed

+19
-11
lines changed

2 files changed

+19
-11
lines changed

aws_lambda_powertools/utilities/parser/envelopes/base.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
from __future__ import annotations
2+
13
import logging
24
from abc import ABC, abstractmethod
3-
from typing import Any, Dict, Optional, Type, TypeVar, Union
5+
from typing import Any, Dict, Optional, TypeVar, Union
46

57
from pydantic import TypeAdapter
68

7-
from aws_lambda_powertools.utilities.parser.types import Model
9+
T = TypeVar("T")
810

911
logger = logging.getLogger(__name__)
1012

@@ -13,7 +15,7 @@ class BaseEnvelope(ABC):
1315
"""ABC implementation for creating a supported Envelope"""
1416

1517
@staticmethod
16-
def _parse(data: Optional[Union[Dict[str, Any], Any]], model: Type[Model]) -> Union[Model, None]:
18+
def _parse(data: Optional[Union[Dict[str, Any], Any]], model: type[T]) -> Union[T, None]:
1719
"""Parses envelope data against model provided
1820
1921
Parameters
@@ -42,7 +44,7 @@ def _parse(data: Optional[Union[Dict[str, Any], Any]], model: Type[Model]) -> Un
4244
return adapter.validate_python(data)
4345

4446
@abstractmethod
45-
def parse(self, data: Optional[Union[Dict[str, Any], Any]], model: Type[Model]):
47+
def parse(self, data: Optional[Union[Dict[str, Any], Any]], model: type[T]):
4648
"""Implementation to parse data against envelope model, then against the data model
4749
4850
NOTE: Call `_parse` method to fully parse data with model provided.

aws_lambda_powertools/utilities/parser/parser.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
1+
from __future__ import annotations
2+
13
import logging
24
import typing
3-
from typing import Any, Callable, Dict, Optional, Type, overload
5+
from typing import Any, Callable, Dict, Optional, Type, TypeVar, overload
46

57
from pydantic import PydanticSchemaGenerationError, TypeAdapter, ValidationError
68

79
from aws_lambda_powertools.middleware_factory import lambda_handler_decorator
810
from aws_lambda_powertools.utilities.parser.envelopes.base import Envelope
911
from aws_lambda_powertools.utilities.parser.exceptions import InvalidEnvelopeError, InvalidModelTypeError
10-
from aws_lambda_powertools.utilities.parser.types import EventParserReturnType, Model
12+
from aws_lambda_powertools.utilities.parser.types import EventParserReturnType
1113
from aws_lambda_powertools.utilities.typing import LambdaContext
1214

15+
T = TypeVar("T")
16+
1317
logger = logging.getLogger(__name__)
1418

1519

@@ -18,7 +22,7 @@ def event_parser(
1822
handler: Callable[..., EventParserReturnType],
1923
event: Dict[str, Any],
2024
context: LambdaContext,
21-
model: Optional[Type[Model]] = None,
25+
model: Optional[type[T]] = None,
2226
envelope: Optional[Type[Envelope]] = None,
2327
**kwargs: Any,
2428
) -> EventParserReturnType:
@@ -108,14 +112,14 @@ def handler(event: Order, context: LambdaContext):
108112

109113

110114
@overload
111-
def parse(event: Dict[str, Any], model: Type[Model]) -> Model: ... # pragma: no cover
115+
def parse(event: Dict[str, Any], model: type[T]) -> T: ... # pragma: no cover
112116

113117

114118
@overload
115-
def parse(event: Dict[str, Any], model: Type[Model], envelope: Type[Envelope]) -> Model: ... # pragma: no cover
119+
def parse(event: Dict[str, Any], model: type[T], envelope: Type[Envelope]) -> T: ... # pragma: no cover
116120

117121

118-
def parse(event: Dict[str, Any], model: Type[Model], envelope: Optional[Type[Envelope]] = None):
122+
def parse(event: Dict[str, Any], model: type[T], envelope: Optional[Type[Envelope]] = None):
119123
"""Standalone function to parse & validate events using Pydantic models
120124
121125
Typically used when you need fine-grained control over error handling compared to event_parser decorator.
@@ -192,7 +196,9 @@ def handler(event: Order, context: LambdaContext):
192196
# Pydantic raises PydanticSchemaGenerationError when the model is not a Pydantic model
193197
# This is seen in the tests where we pass a non-Pydantic model type to the parser or
194198
# when we pass a data structure that does not match the model (trying to parse a true/false/etc into a model)
195-
except (ValidationError, PydanticSchemaGenerationError) as exc:
199+
except PydanticSchemaGenerationError as exc:
200+
raise InvalidModelTypeError(f"The event supplied is unable to be validated into {type(model)}") from exc
201+
except ValidationError as exc:
196202
raise InvalidModelTypeError(
197203
f"Error: {str(exc)}. Please ensure the Input model inherits from BaseModel,\n"
198204
"and your payload adheres to the specified Input model structure.\n"

0 commit comments

Comments
 (0)