Skip to content

Commit f42161f

Browse files
committed
refactor(parser): improves S3 models with examples and descriptions
1 parent c8dbd4f commit f42161f

File tree

2 files changed

+181
-19
lines changed

2 files changed

+181
-19
lines changed

.gitleaksignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,8 @@ examples/batch_processing/src/context_manager_access_output_pydantic.txt:aws-acc
33
examples/batch_processing/src/context_manager_access_output.txt:aws-access-token:10
44
aws_lambda_powertools/utilities/parser/models/s3.py:aws-access-token:32
55
aws_lambda_powertools/utilities/parser/models/s3.py:aws-access-token:34
6-
aws_lambda_powertools/utilities/parser/models/s3.py:aws-access-token:70
6+
aws_lambda_powertools/utilities/parser/models/s3.py:aws-access-token:70
7+
aws_lambda_powertools/utilities/parser/models/s3.py:aws-access-token:345
8+
aws_lambda_powertools/utilities/parser/models/s3.py:aws-access-token:393
9+
aws_lambda_powertools/utilities/parser/models/s3.py:aws-access-token:463
10+
aws_lambda_powertools/utilities/parser/models/s3.py:generic-api-key:345

aws_lambda_powertools/utilities/parser/models/s3.py

Lines changed: 176 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,12 @@
1010

1111

1212
class S3EventRecordGlacierRestoreEventData(BaseModel):
13-
lifecycleRestorationExpiryTime: datetime
13+
lifecycleRestorationExpiryTime: datetime = Field(
14+
description="The time, in ISO-8601 format, of Restore Expiry.",
15+
examples=[
16+
"1970-01-01T00:00:00.000Z",
17+
],
18+
)
1419
lifecycleRestoreStorageClass: str = Field(
1520
description="Source storage class for restore.",
1621
examples=[
@@ -22,12 +27,22 @@ class S3EventRecordGlacierRestoreEventData(BaseModel):
2227

2328

2429
class S3EventRecordGlacierEventData(BaseModel):
25-
restoreEventData: S3EventRecordGlacierRestoreEventData
30+
restoreEventData: S3EventRecordGlacierRestoreEventData = Field(
31+
description="Event data produced only for 's3:ObjectRestore:Completed' events.",
32+
examples=[
33+
{
34+
"restoreEventData": {
35+
"lifecycleRestorationExpiryTime": "1970-01-01T00:00:00.000Z",
36+
"lifecycleRestoreStorageClass": "glacier",
37+
},
38+
},
39+
],
40+
)
2641

2742

2843
class S3Identity(BaseModel):
2944
principalId: str = Field(
30-
description="Amazon customer ID of the user who caused the event.",
45+
description="Amazon identifier of the user, role, account or services who caused the event.",
3146
examples=[
3247
"AIDAJDPLRKLG7UEXAMPLE",
3348
"A1YQ72UWCM96UF",
@@ -37,7 +52,14 @@ class S3Identity(BaseModel):
3752

3853

3954
class S3RequestParameters(BaseModel):
40-
sourceIPAddress: Union[IPvAnyNetwork, Literal["s3.amazonaws.com"]]
55+
sourceIPAddress: Union[IPvAnyNetwork, Literal["s3.amazonaws.com"]] = Field(
56+
description="Source IP address of the request.",
57+
examples=[
58+
"0.0.0.0",
59+
"205.255.255.255",
60+
"s3.amazonaws.com",
61+
],
62+
)
4163

4264

4365
class S3ResponseElements(BaseModel):
@@ -81,7 +103,10 @@ class S3Bucket(BaseModel):
81103
"sourcebucket",
82104
],
83105
)
84-
ownerIdentity: S3OwnerIdentify
106+
ownerIdentity: S3OwnerIdentify = Field(
107+
description="Amazon customer ID of the bucket owner.",
108+
examples=[{"principalId": "A3NL1KOZZKExample"}, {"principalId": "A1YQ72UWCM96UF"}],
109+
)
85110
arn: str = Field(
86111
description="The ARN of the Amazon S3 bucket.",
87112
examples=[
@@ -146,8 +171,29 @@ class S3Message(BaseModel):
146171
"b1d3a482-96eb-4d3a-abd7-763662a6ba94",
147172
],
148173
)
149-
bucket: S3Bucket
150-
object: S3Object # noqa: A003
174+
bucket: S3Bucket = Field(
175+
description="The S3 bucket object.",
176+
examples=[
177+
{
178+
"bucket": {
179+
"name": "lambda-artifacts-deafc19498e3f2df",
180+
"ownerIdentity": {"principalId": "A3I5XTEXAMAI3E"},
181+
"arn": "arn:aws:s3:::lambda-artifacts-deafc19498e3f2df",
182+
},
183+
},
184+
],
185+
)
186+
object: S3Object = Field(
187+
description="The S3 object object.",
188+
examples=[
189+
{
190+
"key": "b21b84d653bb07b05b1e6b33684dc11b",
191+
"size": 1305107,
192+
"eTag": "b21b84d653bb07b05b1e6b33684dc11b",
193+
"sequencer": "0C0F6F405D6ED209E1",
194+
},
195+
],
196+
) # noqa: A003
151197

152198

153199
class S3EventNotificationObjectModel(BaseModel):
@@ -209,8 +255,21 @@ class S3EventNotificationEventBridgeDetailModel(BaseModel):
209255
"0",
210256
],
211257
)
212-
bucket: S3EventNotificationEventBridgeBucketModel
213-
object: S3EventNotificationObjectModel # noqa: A003
258+
bucket: S3EventNotificationEventBridgeBucketModel = Field(
259+
description="Bucket object of the event sent from S3 to EventBridge.",
260+
examples=[{"name": "example-bucket"}],
261+
)
262+
object: S3EventNotificationObjectModel = Field(
263+
description="The S3 object object.",
264+
examples=[
265+
{
266+
"key": "b21b84d653bb07b05b1e6b33684dc11b",
267+
"size": 1305107,
268+
"eTag": "b21b84d653bb07b05b1e6b33684dc11b",
269+
"sequencer": "0C0F6F405D6ED209E1",
270+
},
271+
],
272+
) # noqa: A003
214273
request_id: str = Field(
215274
...,
216275
alias="request-id",
@@ -234,7 +293,7 @@ class S3EventNotificationEventBridgeDetailModel(BaseModel):
234293
description="Source IP address of S3 request. Only present for events triggered by an S3 request.",
235294
examples=[
236295
"0.0.0.0",
237-
"255.255.255.255",
296+
"205.255.255.255",
238297
],
239298
)
240299
reason: Optional[str] = Field(
@@ -289,7 +348,25 @@ class S3EventNotificationEventBridgeDetailModel(BaseModel):
289348

290349

291350
class S3EventNotificationEventBridgeModel(EventBridgeModel): # type: ignore[override]
292-
detail: S3EventNotificationEventBridgeDetailModel
351+
detail: S3EventNotificationEventBridgeDetailModel = Field(
352+
description="Object representing the details of the S3 Event Notification sent to EventBridge.",
353+
examples=[
354+
{
355+
"version": "0",
356+
"bucket": {"name": "example-bucket"},
357+
"object": {
358+
"key": "IMG_m7fzo3.jpg",
359+
"size": 184662,
360+
"etag": "4e68adba0abe2dc8653dc3354e14c01d",
361+
"sequencer": "006408CAD69598B05E",
362+
},
363+
"request-id": "57H08PA84AB1JZW0",
364+
"requester": "123456789012",
365+
"source-ip-address": "34.252.34.74",
366+
"reason": "PutObject",
367+
},
368+
],
369+
)
293370

294371

295372
class S3RecordModel(BaseModel):
@@ -300,7 +377,11 @@ class S3RecordModel(BaseModel):
300377
"1.9",
301378
],
302379
)
303-
eventSource: Literal["aws:s3"]
380+
eventSource: Literal["aws:s3"] = Field(
381+
default="aws:s3",
382+
description="Source of the event.",
383+
examples=["aws:s3"],
384+
)
304385
awsRegion: str = Field(
305386
description="The AWS region where the event occurred.",
306387
examples=[
@@ -324,11 +405,56 @@ class S3RecordModel(BaseModel):
324405
"LifecycleExpiration:Delete",
325406
],
326407
)
327-
userIdentity: S3Identity
328-
requestParameters: S3RequestParameters
329-
responseElements: S3ResponseElements
330-
s3: S3Message
331-
glacierEventData: Optional[S3EventRecordGlacierEventData] = None
408+
userIdentity: S3Identity = Field(
409+
description="Amazon identifier of the user, role, account or services who caused the event.",
410+
examples=[{"principalId": "AWS:AIDAINPONIXQXHT3IKHL2"}],
411+
)
412+
requestParameters: S3RequestParameters = Field(
413+
description="Source IP address of the request.",
414+
examples=[{"sourceIPAddress": "205.255.255.255"}],
415+
)
416+
responseElements: S3ResponseElements = Field(
417+
description="Response elements from an Amazon S3 response object. Useful if you want to trace a request by "
418+
"following up with AWS Support.",
419+
examples=[
420+
{
421+
"x-amz-request-id": "D82B88E5F771F645",
422+
"x-amz-id-2": "vlR7PnpV2Ce81l0PRw6jlUpck7Jo5ZsQjryTjKlc5aLWGVHPZLj5NeC6qMa0emYBDXOo6QBU0Wo=",
423+
},
424+
],
425+
)
426+
s3: S3Message = Field(
427+
description="The Amazon S3 message object.",
428+
examples=[
429+
{
430+
"s3SchemaVersion": "1.0",
431+
"configurationId": "828aa6fc-f7b5-4305-8584-487c791949c1",
432+
"bucket": {
433+
"name": "lambda-artifacts-deafc19498e3f2df",
434+
"ownerIdentity": {"principalId": "A3I5XTEXAMAI3E"},
435+
"arn": "arn:aws:s3:::lambda-artifacts-deafc19498e3f2df",
436+
},
437+
"object": {
438+
"key": "b21b84d653bb07b05b1e6b33684dc11b",
439+
"size": 1305107,
440+
"eTag": "b21b84d653bb07b05b1e6b33684dc11b",
441+
"sequencer": "0C0F6F405D6ED209E1",
442+
},
443+
},
444+
],
445+
)
446+
glacierEventData: Optional[S3EventRecordGlacierEventData] = Field(
447+
default=None,
448+
description="The Glacier event data object.",
449+
examples=[
450+
{
451+
"restoreEventData": {
452+
"lifecycleRestorationExpiryTime": "1970-01-01T00:01:00.000Z",
453+
"lifecycleRestoreStorageClass": "standard",
454+
},
455+
},
456+
],
457+
)
332458

333459
@model_validator(mode="before")
334460
def validate_s3_object(cls, values):
@@ -342,4 +468,36 @@ def validate_s3_object(cls, values):
342468

343469

344470
class S3Model(BaseModel):
345-
Records: List[S3RecordModel]
471+
Records: List[S3RecordModel] = Field(
472+
description="List of S3 records included in this event.",
473+
examples=[
474+
{
475+
"eventVersion": "2.1",
476+
"eventSource": "aws:s3",
477+
"awsRegion": "us-east-2",
478+
"eventTime": "2019-09-03T19:37:27.192Z",
479+
"eventName": "ObjectCreated:Put",
480+
"userIdentity": {"principalId": "AWS:AIDAINPONIXQXHT3IKHL2"},
481+
"requestParameters": {"sourceIPAddress": "205.255.255.255"},
482+
"responseElements": {
483+
"x-amz-request-id": "D82B88E5F771F645",
484+
"x-amz-id-2": "vlR7PnpV2Ce81l0PRw6jlUpck7Jo5ZsQjryTjKlc5aLWGVHPZLj5NeC6qMa0emYBDXOo6QBU0Wo=",
485+
},
486+
"s3": {
487+
"s3SchemaVersion": "1.0",
488+
"configurationId": "828aa6fc-f7b5-4305-8584-487c791949c1",
489+
"bucket": {
490+
"name": "lambda-artifacts-deafc19498e3f2df",
491+
"ownerIdentity": {"principalId": "A3I5XTEXAMAI3E"},
492+
"arn": "arn:aws:s3:::lambda-artifacts-deafc19498e3f2df",
493+
},
494+
"object": {
495+
"key": "b21b84d653bb07b05b1e6b33684dc11b",
496+
"size": 1305107,
497+
"eTag": "b21b84d653bb07b05b1e6b33684dc11b",
498+
"sequencer": "0C0F6F405D6ED209E1",
499+
},
500+
},
501+
},
502+
],
503+
)

0 commit comments

Comments
 (0)