5
5
6
6
from aws_lambda_powertools .middleware_factory import lambda_handler_decorator
7
7
8
+ from ..typing import LambdaContext
8
9
from .envelopes .base import BaseEnvelope
9
10
from .exceptions import InvalidEnvelopeError , InvalidSchemaTypeError , SchemaValidationError
10
11
15
16
def parser (
16
17
handler : Callable [[Dict , Any ], Any ],
17
18
event : Dict [str , Any ],
18
- context : Dict [ str , Any ] ,
19
+ context : LambdaContext ,
19
20
schema : BaseModel ,
20
21
envelope : Optional [BaseEnvelope ] = None ,
21
22
) -> Any :
22
- """Decorator to conduct advanced parsing & validation for lambda handlers events
23
+ """Lambda handler decorator to parse & validate events using Pydantic models
23
24
24
- As Lambda follows (event, context) signature we can remove some of the boilerplate
25
- and also capture any exception any Lambda function throws as metadata.
26
- event will be the parsed and passed as a BaseModel Pydantic class of the input type "schema"
27
- to the lambda handler.
28
- event will be extracted from the envelope in case envelope is not None.
29
- In case envelope is None, the complete event is parsed to match the schema parameter BaseModel definition.
30
- In case envelope is not None, first the event is parsed as the envelope's schema definition, and the user
31
- message is extracted and parsed again as the schema parameter's definition.
25
+ It requires a schema that implements Pydantic BaseModel to parse & validate the event.
26
+
27
+ When an envelope is given, it'll use the following logic:
28
+
29
+ 1. Parse the event against envelope schema first e.g. EnvelopeSchema(**event)
30
+ 2. Envelope will extract a given key to be parsed against the schema e.g. event.detail
31
+
32
+ This is useful when you need to confirm event wrapper structure, and
33
+ b) selectively extract a portion of your payload for parsing & validation.
34
+
35
+ NOTE: If envelope is omitted, the complete event is parsed to match the schema parameter BaseModel definition.
32
36
33
37
Example
34
38
-------
35
- **Lambda function using validation decorator**
39
+ **Lambda handler decorator to parse & validate event**
40
+
41
+ class Order(BaseModel):
42
+ id: int
43
+ description: str
44
+ ...
45
+
46
+ @parser(schema=Order)
47
+ def handler(event: Order, context: LambdaContext):
48
+ ...
49
+
50
+ **Lambda handler decorator to parse & validate event - using built-in envelope**
51
+
52
+ class Order(BaseModel):
53
+ id: int
54
+ description: str
55
+ ...
36
56
37
- @parser(schema=MyBusiness , envelope=envelopes.EVENTBRIDGE)
38
- def handler(event: MyBusiness , context: LambdaContext):
57
+ @parser(schema=Order , envelope=envelopes.EVENTBRIDGE)
58
+ def handler(event: Order , context: LambdaContext):
39
59
...
40
60
41
61
Parameters
42
62
----------
43
- handler: input for lambda_handler_decorator, wraps the handler lambda
44
- event: AWS event dictionary
45
- context: AWS lambda context
46
- schema: pydantic BaseModel class. This is the user data schema that will replace the event.
47
- event parameter will be parsed and a new schema object will be created from it.
48
- envelope: what envelope to extract the schema from, can be any AWS service that is currently
49
- supported in the envelopes module. Can be None.
63
+ handler: Callable
64
+ Method to annotate on
65
+ event: Dict
66
+ Lambda event to be parsed & validated
67
+ context: LambdaContext
68
+ Lambda context object
69
+ schema: BaseModel
70
+ Your data schema that will replace the event.
71
+ envelope: BaseEnvelope
72
+ Optional envelope to extract the schema from
50
73
51
74
Raises
52
75
------
53
76
SchemaValidationError
54
77
When input event does not conform with schema provided
55
78
InvalidSchemaTypeError
56
79
When schema given does not implement BaseModel
80
+ InvalidEnvelopeError
81
+ When envelope given does not implement BaseEnvelope
57
82
"""
58
83
parsed_event = parse (event = event , schema = schema , envelope = envelope )
59
84
logger .debug (f"Calling handler { handler .__name__ } " )
60
85
return handler (parsed_event , context )
61
86
62
87
63
88
def parse (event : Dict [str , Any ], schema : BaseModel , envelope : Optional [BaseEnvelope ] = None ) -> Any :
64
- """
65
- Standalone parse function to conduct advanced parsing & validation for lambda handlers events
89
+ """Standalone function to parse & validate events using Pydantic models
66
90
67
- As Lambda follows (event, context) signature we can remove some of the boilerplate
68
- and also capture any exception any Lambda function throws as metadata.
69
- event will be the parsed and passed as a BaseModel Pydantic class of the input type "schema"
70
- to the lambda handler.
71
- event will be extracted from the envelope in case envelope is not None.
72
- In case envelope is None, the complete event is parsed to match the schema parameter BaseModel definition.
73
- In case envelope is not None, first the event is parsed as the envelope's schema definition, and the user
74
- message is extracted and parsed again as the schema parameter's definition.
91
+ Typically used when you need fine-grained control over error handling compared to parser decorator.
75
92
76
93
Example
77
94
-------
78
- **Lambda function using standalone parse**
79
95
80
- def handler(event: MyBusiness , context: LambdaContext):
81
- parse(event=event, schema=MyBusiness, envelope=envelopes.EVENTBRIDGE)
96
+ **Lambda handler decorator to parse & validate event**
97
+
98
+ from aws_lambda_powertools.utilities.parser.exceptions import SchemaValidationError
99
+
100
+ class Order(BaseModel):
101
+ id: int
102
+ description: str
82
103
...
83
104
105
+ def handler(event: Order, context: LambdaContext):
106
+ try:
107
+ parse(schema=Order)
108
+ except SchemaValidationError:
109
+ ...
110
+
111
+ **Lambda handler decorator to parse & validate event - using built-in envelope**
112
+
113
+ class Order(BaseModel):
114
+ id: int
115
+ description: str
116
+ ...
117
+
118
+ def handler(event: Order, context: LambdaContext):
119
+ try:
120
+ parse(schema=Order, envelope=envelopes.EVENTBRIDGE)
121
+ except SchemaValidationError:
122
+ ...
123
+
84
124
Parameters
85
125
----------
86
- event: AWS event dictionary
87
- schema: pydantic BaseModel class. This is the user data schema that will replace the event.
88
- event parameter will be parsed and a new schema object will be created from it.
89
- envelope: what envelope to extract the schema from, can be any AWS service that is currently
90
- supported in the envelopes module. Can be None.
126
+ event: Dict
127
+ Lambda event to be parsed & validated
128
+ schema: BaseModel
129
+ Your data schema that will replace the event.
130
+ envelope: BaseEnvelope
131
+ Optional envelope to extract the schema from
91
132
92
133
Raises
93
134
------
@@ -101,7 +142,7 @@ def handler(event: MyBusiness , context: LambdaContext):
101
142
if envelope and callable (envelope ):
102
143
try :
103
144
logger .debug (f"Parsing and validating event schema with envelope={ envelope } " )
104
- return envelope ().parse (event = event , schema = schema )
145
+ return envelope ().parse (data = event , schema = schema )
105
146
except AttributeError :
106
147
raise InvalidEnvelopeError (f"Envelope must implement BaseEnvelope, envelope={ envelope } " )
107
148
except (ValidationError , TypeError ) as e :
0 commit comments