Skip to content

Commit a7e4563

Browse files
committed
refactor(parser): Improve SNS models with examples and descriptions
Enhances the SNS parser models with field descriptions and examples using Pydantic's Field() functionality. This improvement provides better documentation and metadata for SNS event parsing, following the pattern established in PR #7100. All field descriptions are based on official AWS SNS documentation and include realistic examples from actual test events. Closes #7117
1 parent bb3c13e commit a7e4563

File tree

1 file changed

+113
-19
lines changed
  • aws_lambda_powertools/utilities/parser/models

1 file changed

+113
-19
lines changed

aws_lambda_powertools/utilities/parser/models/sns.py

Lines changed: 113 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,102 @@
22
from typing import Dict, List, Literal, Optional, Union
33
from typing import Type as TypingType
44

5-
from pydantic import BaseModel, model_validator
5+
from pydantic import BaseModel, Field, model_validator
66
from pydantic.networks import HttpUrl
77

88

99
class SnsMsgAttributeModel(BaseModel):
10-
Type: str
11-
Value: str
10+
Type: str = Field(
11+
description="The data type of the message attribute (String, Number, Binary, or custom data type).",
12+
examples=["String", "Number", "Binary", "String.Array", "Number.Array"],
13+
)
14+
Value: str = Field(
15+
description="The value of the message attribute. All values are strings, even for Number types.",
16+
examples=["TestString", "123", "TestBinary", '["item1", "item2"]'],
17+
)
1218

1319

1420
class SnsNotificationModel(BaseModel):
15-
Subject: Optional[str] = None
16-
TopicArn: str
17-
UnsubscribeUrl: HttpUrl
18-
Type: Literal["Notification"]
19-
MessageAttributes: Optional[Dict[str, SnsMsgAttributeModel]] = None
20-
Message: Union[str, TypingType[BaseModel]]
21-
MessageId: str
22-
SigningCertUrl: Optional[HttpUrl] = None # NOTE: FIFO opt-in removes attribute
23-
Signature: Optional[str] = None # NOTE: FIFO opt-in removes attribute
24-
Timestamp: datetime
25-
SignatureVersion: Optional[str] = None # NOTE: FIFO opt-in removes attribute
21+
Subject: Optional[str] = Field(
22+
default=None,
23+
description="The subject parameter provided when the notification was published to the topic.",
24+
examples=["TestInvoke", "Alert: System maintenance", "Order Confirmation", None],
25+
)
26+
TopicArn: str = Field(
27+
description="The Amazon Resource Name (ARN) for the topic that this message was published to.",
28+
examples=[
29+
"arn:aws:sns:us-east-2:123456789012:sns-lambda",
30+
"arn:aws:sns:eu-west-1:123456789012:notification-topic",
31+
"arn:aws:sns:us-west-2:123456789012:alerts.fifo",
32+
],
33+
)
34+
UnsubscribeUrl: HttpUrl = Field(
35+
description="A URL that you can use to unsubscribe the endpoint from this topic.",
36+
examples=[
37+
"https://sns.us-east-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-2:123456789012:test-lambda:21be56ed-a058-49f5-8c98-aedd2564c486",
38+
"https://sns.eu-west-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:eu-west-1:123456789012:notification-topic:abcd1234-5678-90ef-ghij-klmnopqrstuv",
39+
],
40+
)
41+
Type: Literal["Notification"] = Field(
42+
description="The type of message. For Lambda triggers, this is always 'Notification'.",
43+
examples=["Notification"],
44+
)
45+
MessageAttributes: Optional[Dict[str, SnsMsgAttributeModel]] = Field(
46+
default=None,
47+
description="User-defined message attributes as key-value pairs with type information.",
48+
examples=[
49+
{"Test": {"Type": "String", "Value": "TestString"}},
50+
{"priority": {"Type": "Number", "Value": "1"}, "env": {"Type": "String", "Value": "prod"}},
51+
None,
52+
],
53+
)
54+
Message: Union[str, TypingType[BaseModel]] = Field(
55+
description="The message value specified when the notification was published to the topic.",
56+
examples=[
57+
"Hello from SNS!",
58+
'{"alert": "CPU usage above 80%", "instance": "i-1234567890abcdef0"}',
59+
'{"order_id": 12345, "status": "confirmed", "total": 99.99}',
60+
],
61+
)
62+
MessageId: str = Field(
63+
description="A Universally Unique Identifier, unique for each message published.",
64+
examples=[
65+
"95df01b4-ee98-5cb9-9903-4c221d41eb5e",
66+
"da41e39f-ea4d-435a-b922-c6aae3915ebe",
67+
"f3c8d4e2-1a2b-4c5d-9e8f-7g6h5i4j3k2l",
68+
],
69+
)
70+
SigningCertUrl: Optional[HttpUrl] = Field(
71+
default=None,
72+
description="The URL to the certificate that was used to sign the message. Not present for FIFO topics with content-based deduplication.",
73+
examples=[
74+
"https://sns.us-east-2.amazonaws.com/SimpleNotificationService-1234567890.pem",
75+
"https://sns.eu-west-1.amazonaws.com/SimpleNotificationService-0987654321.pem",
76+
None,
77+
],
78+
) # NOTE: FIFO opt-in removes attribute
79+
Signature: Optional[str] = Field(
80+
default=None,
81+
description="Base64-encoded SHA1withRSA signature of the message. Not present for FIFO topics with content-based deduplication.",
82+
examples=[
83+
"tcc6faL2yUC6dgZdmrwh1Y4cGa/ebXEkAi6RibDsvpi+tE/1+82j...65r==",
84+
"EXAMPLEw6JRNwm1LFQL4ICB0bnXrdB8ClRMTQFPGBfHs...EXAMPLEw==",
85+
None,
86+
],
87+
) # NOTE: FIFO opt-in removes attribute
88+
Timestamp: datetime = Field(
89+
description="The time (GMT) when the notification was published.",
90+
examples=[
91+
"2019-01-02T12:45:07.000Z",
92+
"2023-06-15T10:30:00.000Z",
93+
"2023-12-25T18:45:30.123Z",
94+
],
95+
)
96+
SignatureVersion: Optional[str] = Field(
97+
default=None,
98+
description="Version of the Amazon SNS signature used. Not present for FIFO topics with content-based deduplication.",
99+
examples=["1", "2", None],
100+
) # NOTE: FIFO opt-in removes attribute
26101

27102
@model_validator(mode="before")
28103
def check_sqs_protocol(cls, values):
@@ -37,11 +112,30 @@ def check_sqs_protocol(cls, values):
37112

38113

39114
class SnsRecordModel(BaseModel):
40-
EventSource: Literal["aws:sns"]
41-
EventVersion: str
42-
EventSubscriptionArn: str
43-
Sns: SnsNotificationModel
115+
EventSource: Literal["aws:sns"] = Field(
116+
description="The AWS service that invoked the function.",
117+
examples=["aws:sns"],
118+
)
119+
EventVersion: str = Field(
120+
description="The version of the event schema.",
121+
examples=["1.0", "2.0"],
122+
)
123+
EventSubscriptionArn: str = Field(
124+
description="The Amazon Resource Name (ARN) of the subscription.",
125+
examples=[
126+
"arn:aws:sns:us-east-2:123456789012:sns-lambda:21be56ed-a058-49f5-8c98-aedd2564c486",
127+
"arn:aws:sns:eu-west-1:123456789012:notification-topic:abcd1234-5678-90ef-ghij-klmnopqrstuv",
128+
],
129+
)
130+
Sns: SnsNotificationModel = Field(
131+
description="The SNS message that triggered the Lambda function.",
132+
)
44133

45134

46135
class SnsModel(BaseModel):
47-
Records: List[SnsRecordModel]
136+
Records: List[SnsRecordModel] = Field(
137+
description="A list of SNS message records included in the event.",
138+
examples=[
139+
[{"EventSource": "aws:sns", "Sns": {"MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e"}}]
140+
],
141+
)

0 commit comments

Comments
 (0)