Skip to content

Commit 9d3c809

Browse files
Changing highlights + import
1 parent ebf6eda commit 9d3c809

File tree

5 files changed

+59
-33
lines changed

5 files changed

+59
-33
lines changed

docs/utilities/parser.md

+7-7
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ The `@event_parser` decorator automatically parses the incoming event into the s
4242

4343
=== "getting_started_with_parser.py"
4444

45-
```python hl_lines="3 10"
45+
```python hl_lines="3 11"
4646
--8<-- "examples/parser/src/getting_started_with_parser.py"
4747
```
4848

@@ -58,7 +58,7 @@ You can use the `parse()` function when you need to have flexibility with differ
5858

5959
=== "parser_function.py"
6060

61-
```python hl_lines="3 14"
61+
```python hl_lines="3 15"
6262
--8<-- "examples/parser/src/parser_function.py"
6363
```
6464

@@ -144,7 +144,7 @@ Use the model to validate and extract relevant information from the incoming eve
144144

145145
=== "Custom data model"
146146

147-
```python hl_lines="4 8 16"
147+
```python hl_lines="4 8 17"
148148
--8<-- "examples/parser/src/custom_data_model_with_eventbridge.py"
149149
```
150150

@@ -164,7 +164,7 @@ Envelopes can be used via `envelope` parameter available in both `parse` functio
164164

165165
=== "Envelopes using event parser decorator"
166166

167-
```python hl_lines="3 6-10 12"
167+
```python hl_lines="3 7-10 13"
168168
--8<-- "examples/parser/src/envelope_with_event_parser.py"
169169
```
170170

@@ -203,7 +203,7 @@ Here's a snippet of how the EventBridge envelope we demonstrated previously is i
203203

204204
=== "Bring your own envelope with Event Bridge"
205205

206-
```python hl_lines="6 12-18"
206+
```python hl_lines="6 13-19"
207207
--8<-- "examples/parser/src/bring_your_own_envelope.py"
208208
```
209209

@@ -269,7 +269,7 @@ Wrap these fields with [Pydantic&#39;s Json Type](https://pydantic-docs.helpmanu
269269

270270
=== "Validate string fields containing JSON data"
271271

272-
```python hl_lines="3 14"
272+
```python hl_lines="5 24"
273273
--8<-- "examples/parser/src/string_fields_contain_json.py"
274274
```
275275

@@ -287,7 +287,7 @@ Pydantic's definition of _serialization_ is broader than usual. It includes conv
287287

288288
Read more at [Serialization for Pydantic documentation](https://docs.pydantic.dev/latest/concepts/serialization/#model_copy){target="_blank" rel="nofollow"}.
289289

290-
```python title="serialization_parser.py" hl_lines="39-40"
290+
```python title="serialization_parser.py" hl_lines="36-37"
291291
--8<-- "examples/parser/src/serialization_parser.py"
292292
```
293293

Original file line numberDiff line numberDiff line change
@@ -1,26 +1,27 @@
1-
from aws_lambda_powertools.utilities.parser import parse, BaseModel
2-
from aws_lambda_powertools.utilities.parser import field_validator
1+
from aws_lambda_powertools.utilities.parser import BaseModel, field_validator, parse
32
from aws_lambda_powertools.utilities.typing import LambdaContext
43

4+
55
class HelloWorldModel(BaseModel):
66
message: str
77
sender: str
88

9-
@field_validator('*')
9+
@field_validator("*")
1010
def has_whitespace(cls, v):
11-
if ' ' not in v:
11+
if " " not in v:
1212
raise ValueError("Must have whitespace...")
1313
return v
1414

15+
1516
def lambda_handler(event: dict, context: LambdaContext):
1617
try:
1718
parsed_event = parse(model=HelloWorldModel, event=event)
1819
return {
1920
"statusCode": 200,
20-
"body": f"Received message: {parsed_event.message}"
21+
"body": f"Received message: {parsed_event.message}",
2122
}
2223
except ValueError as e:
2324
return {
2425
"statusCode": 400,
25-
"body": str(e)
26-
}
26+
"body": str(e),
27+
}

examples/parser/src/sqs_model_event.py

+8-6
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
from aws_lambda_powertools.utilities.typing import LambdaContext
44

55

6-
def lambda_handler(event: dict, context: LambdaContext) -> None:
6+
def lambda_handler(event: dict, context: LambdaContext) -> list:
77
parsed_event = parse(model=SqsModel, event=event)
88

99
results = []
1010
for record in parsed_event.Records:
11-
results.append({
12-
'Message ID':record.messageId,
13-
'body':record.body
14-
})
15-
return results
11+
results.append(
12+
{
13+
"message_id": record.messageId,
14+
"body": record.body,
15+
},
16+
)
17+
return results

examples/parser/src/string_fields_contain_json.py

+13-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
1-
from typing import Any, Type
1+
from __future__ import annotations
2+
3+
from typing import TYPE_CHECKING, Any
24

35
from pydantic import BaseModel, Json
46

57
from aws_lambda_powertools.utilities.parser import BaseEnvelope, event_parser
8+
from aws_lambda_powertools.utilities.parser.functions import (
9+
_parse_and_validate_event,
10+
_retrieve_or_set_model_from_cache,
11+
)
612
from aws_lambda_powertools.utilities.typing import LambdaContext
713

14+
if TYPE_CHECKING:
15+
from aws_lambda_powertools.utilities.parser.types import T
16+
817

918
class CancelOrder(BaseModel):
1019
order_id: int
@@ -16,8 +25,9 @@ class CancelOrderModel(BaseModel):
1625

1726

1827
class CustomEnvelope(BaseEnvelope):
19-
def parse(self, data: dict, model: Type[BaseModel]) -> Any:
20-
return model.model_validate({"body": data.get("body", {})})
28+
def parse(self, data: dict[str, Any] | Any | None, model: type[T]):
29+
adapter = _retrieve_or_set_model_from_cache(model=model)
30+
return _parse_and_validate_event(data=data, adapter=adapter)
2131

2232

2333
@event_parser(model=CancelOrderModel, envelope=CustomEnvelope)
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,38 @@
1+
from __future__ import annotations
2+
13
import json
2-
from typing import Any, Type
3-
from aws_lambda_powertools.utilities.parser import event_parser, BaseEnvelope, BaseModel
4-
from aws_lambda_powertools.utilities.validation import validator
4+
from typing import TYPE_CHECKING, Any
5+
6+
from aws_lambda_powertools.utilities.parser import BaseEnvelope, BaseModel, event_parser
7+
from aws_lambda_powertools.utilities.parser.functions import (
8+
_parse_and_validate_event,
9+
_retrieve_or_set_model_from_cache,
10+
)
511
from aws_lambda_powertools.utilities.typing import LambdaContext
12+
from aws_lambda_powertools.utilities.validation import validator
13+
14+
if TYPE_CHECKING:
15+
from aws_lambda_powertools.utilities.parser.types import T
16+
617

718
class CancelOrder(BaseModel):
819
order_id: int
920
reason: str
1021

22+
1123
class CancelOrderModel(BaseModel):
1224
body: CancelOrder
1325

1426
@validator("body", pre=True)
1527
def transform_body_to_dict(cls, value):
16-
if isinstance(value, str):
17-
return json.loads(value)
18-
return value
28+
return json.loads(value) if isinstance(value, str) else value
29+
1930

2031
class CustomEnvelope(BaseEnvelope):
21-
def parse(self, data: dict, model: Type[BaseModel]) -> Any:
22-
return model.model_validate({"body": data.get("body", {})})
32+
def parse(self, data: dict[str, Any] | Any | None, model: type[T]):
33+
adapter = _retrieve_or_set_model_from_cache(model=model)
34+
return _parse_and_validate_event(data=data, adapter=adapter)
35+
2336

2437
@event_parser(model=CancelOrderModel, envelope=CustomEnvelope)
2538
def lambda_handler(event: CancelOrderModel, context: LambdaContext):
@@ -32,5 +45,5 @@ def lambda_handler(event: CancelOrderModel, context: LambdaContext):
3245

3346
return {
3447
"statusCode": 200,
35-
"body": json.dumps({"message": f"Order {cancel_order.order_id} cancelled successfully"})
36-
}
48+
"body": json.dumps({"message": f"Order {cancel_order.order_id} cancelled successfully"}),
49+
}

0 commit comments

Comments
 (0)