Skip to content

Commit 65ab4b0

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

File tree

2 files changed

+179
-19
lines changed

2 files changed

+179
-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: 174 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,13 @@ 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+
"255.255.255.255",
59+
"s3.amazonaws.com",
60+
],
61+
)
4162

4263

4364
class S3ResponseElements(BaseModel):
@@ -81,7 +102,10 @@ class S3Bucket(BaseModel):
81102
"sourcebucket",
82103
],
83104
)
84-
ownerIdentity: S3OwnerIdentify
105+
ownerIdentity: S3OwnerIdentify = Field(
106+
description="Amazon customer ID of the bucket owner.",
107+
examples=[{"principalId": "A3NL1KOZZKExample"}, {"principalId": "A1YQ72UWCM96UF"}],
108+
)
85109
arn: str = Field(
86110
description="The ARN of the Amazon S3 bucket.",
87111
examples=[
@@ -146,8 +170,29 @@ class S3Message(BaseModel):
146170
"b1d3a482-96eb-4d3a-abd7-763662a6ba94",
147171
],
148172
)
149-
bucket: S3Bucket
150-
object: S3Object # noqa: A003
173+
bucket: S3Bucket = Field(
174+
description="The S3 bucket object.",
175+
examples=[
176+
{
177+
"bucket": {
178+
"name": "lambda-artifacts-deafc19498e3f2df",
179+
"ownerIdentity": {"principalId": "A3I5XTEXAMAI3E"},
180+
"arn": "arn:aws:s3:::lambda-artifacts-deafc19498e3f2df",
181+
},
182+
},
183+
],
184+
)
185+
object: S3Object = Field(
186+
description="The S3 object object.",
187+
examples=[
188+
{
189+
"key": "b21b84d653bb07b05b1e6b33684dc11b",
190+
"size": 1305107,
191+
"eTag": "b21b84d653bb07b05b1e6b33684dc11b",
192+
"sequencer": "0C0F6F405D6ED209E1",
193+
},
194+
],
195+
) # noqa: A003
151196

152197

153198
class S3EventNotificationObjectModel(BaseModel):
@@ -209,8 +254,21 @@ class S3EventNotificationEventBridgeDetailModel(BaseModel):
209254
"0",
210255
],
211256
)
212-
bucket: S3EventNotificationEventBridgeBucketModel
213-
object: S3EventNotificationObjectModel # noqa: A003
257+
bucket: S3EventNotificationEventBridgeBucketModel = Field(
258+
description="Bucket object of the event sent from S3 to EventBridge.",
259+
examples=[{"name": "example-bucket"}],
260+
)
261+
object: S3EventNotificationObjectModel = Field(
262+
description="The S3 object object.",
263+
examples=[
264+
{
265+
"key": "b21b84d653bb07b05b1e6b33684dc11b",
266+
"size": 1305107,
267+
"eTag": "b21b84d653bb07b05b1e6b33684dc11b",
268+
"sequencer": "0C0F6F405D6ED209E1",
269+
},
270+
],
271+
) # noqa: A003
214272
request_id: str = Field(
215273
...,
216274
alias="request-id",
@@ -233,7 +291,6 @@ class S3EventNotificationEventBridgeDetailModel(BaseModel):
233291
alias="source-ip-address",
234292
description="Source IP address of S3 request. Only present for events triggered by an S3 request.",
235293
examples=[
236-
"0.0.0.0",
237294
"255.255.255.255",
238295
],
239296
)
@@ -289,7 +346,25 @@ class S3EventNotificationEventBridgeDetailModel(BaseModel):
289346

290347

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

294369

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

333457
@model_validator(mode="before")
334458
def validate_s3_object(cls, values):
@@ -342,4 +466,36 @@ def validate_s3_object(cls, values):
342466

343467

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

0 commit comments

Comments
 (0)