Skip to content

Commit 0cf950b

Browse files
refactor(parser): Improve SNS models with examples and descriptions (#7287)
* 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 * style: apply ruff formatting to SNS models Fix CI formatting issues as requested by leandrodamascena * style: fix line length issues in SNS models Break long lines over 120 characters following ALB/Kinesis pattern as requested by leandrodamascena. Use parentheses for multi-line strings and break long URL examples. * Fix styles * Fix styles --------- Co-authored-by: Leandro Damascena <[email protected]>
1 parent 1a52214 commit 0cf950b

File tree

1 file changed

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

1 file changed

+125
-19
lines changed

aws_lambda_powertools/utilities/parser/models/sns.py

Lines changed: 125 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,116 @@
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+
(
38+
"https://sns.us-east-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn= \
39+
arn:aws:sns:us-east-2:123456789012:test-lambda:21be56ed-a058-49f5-8c98-aedd2564c486"
40+
),
41+
(
42+
"https://sns.eu-west-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn= \
43+
arn:aws:sns:eu-west-1:123456789012:notification-topic:abcd1234-5678-90ef-ghij-klmnopqrstuv"
44+
),
45+
],
46+
)
47+
Type: Literal["Notification"] = Field(
48+
description="The type of message. For Lambda triggers, this is always 'Notification'.",
49+
examples=["Notification"],
50+
)
51+
MessageAttributes: Optional[Dict[str, SnsMsgAttributeModel]] = Field(
52+
default=None,
53+
description="User-defined message attributes as key-value pairs with type information.",
54+
examples=[
55+
{"Test": {"Type": "String", "Value": "TestString"}},
56+
{"priority": {"Type": "Number", "Value": "1"}, "env": {"Type": "String", "Value": "prod"}},
57+
None,
58+
],
59+
)
60+
Message: Union[str, TypingType[BaseModel]] = Field(
61+
description="The message value specified when the notification was published to the topic.",
62+
examples=[
63+
"Hello from SNS!",
64+
'{"alert": "CPU usage above 80%", "instance": "i-1234567890abcdef0"}',
65+
'{"order_id": 12345, "status": "confirmed", "total": 99.99}',
66+
],
67+
)
68+
MessageId: str = Field(
69+
description="A Universally Unique Identifier, unique for each message published.",
70+
examples=[
71+
"95df01b4-ee98-5cb9-9903-4c221d41eb5e",
72+
"da41e39f-ea4d-435a-b922-c6aae3915ebe",
73+
"f3c8d4e2-1a2b-4c5d-9e8f-7g6h5i4j3k2l",
74+
],
75+
)
76+
SigningCertUrl: Optional[HttpUrl] = Field(
77+
default=None,
78+
description=(
79+
"The URL to the certificate that was used to sign the message. "
80+
"Not present for FIFO topics with content-based deduplication."
81+
),
82+
examples=[
83+
"https://sns.us-east-2.amazonaws.com/SimpleNotificationService-1234567890.pem",
84+
"https://sns.eu-west-1.amazonaws.com/SimpleNotificationService-0987654321.pem",
85+
None,
86+
],
87+
) # NOTE: FIFO opt-in removes attribute
88+
Signature: Optional[str] = Field(
89+
default=None,
90+
description=(
91+
"Base64-encoded SHA1withRSA signature of the message. "
92+
"Not present for FIFO topics with content-based deduplication."
93+
),
94+
examples=[
95+
"tcc6faL2yUC6dgZdmrwh1Y4cGa/ebXEkAi6RibDsvpi+tE/1+82j...65r==",
96+
"EXAMPLEw6JRNwm1LFQL4ICB0bnXrdB8ClRMTQFPGBfHs...EXAMPLEw==",
97+
None,
98+
],
99+
) # NOTE: FIFO opt-in removes attribute
100+
Timestamp: datetime = Field(
101+
description="The time (GMT) when the notification was published.",
102+
examples=[
103+
"2019-01-02T12:45:07.000Z",
104+
"2023-06-15T10:30:00.000Z",
105+
"2023-12-25T18:45:30.123Z",
106+
],
107+
)
108+
SignatureVersion: Optional[str] = Field(
109+
default=None,
110+
description=(
111+
"Version of the Amazon SNS signature used. Not present for FIFO topics with content-based deduplication."
112+
),
113+
examples=["1", "2", None],
114+
) # NOTE: FIFO opt-in removes attribute
26115

27116
@model_validator(mode="before")
28117
def check_sqs_protocol(cls, values):
@@ -37,11 +126,28 @@ def check_sqs_protocol(cls, values):
37126

38127

39128
class SnsRecordModel(BaseModel):
40-
EventSource: Literal["aws:sns"]
41-
EventVersion: str
42-
EventSubscriptionArn: str
43-
Sns: SnsNotificationModel
129+
EventSource: Literal["aws:sns"] = Field(
130+
description="The AWS service that invoked the function.",
131+
examples=["aws:sns"],
132+
)
133+
EventVersion: str = Field(
134+
description="The version of the event schema.",
135+
examples=["1.0", "2.0"],
136+
)
137+
EventSubscriptionArn: str = Field(
138+
description="The Amazon Resource Name (ARN) of the subscription.",
139+
examples=[
140+
"arn:aws:sns:us-east-2:123456789012:sns-lambda:21be56ed-a058-49f5-8c98-aedd2564c486",
141+
"arn:aws:sns:eu-west-1:123456789012:notification-topic:abcd1234-5678-90ef-ghij-klmnopqrstuv",
142+
],
143+
)
144+
Sns: SnsNotificationModel = Field(
145+
description="The SNS message that triggered the Lambda function.",
146+
)
44147

45148

46149
class SnsModel(BaseModel):
47-
Records: List[SnsRecordModel]
150+
Records: List[SnsRecordModel] = Field(
151+
description="A list of SNS message records included in the event.",
152+
examples=[[{"EventSource": "aws:sns", "Sns": {"MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e"}}]],
153+
)

0 commit comments

Comments
 (0)