22from datetime import datetime
33from typing import Any , Dict , List , Literal , Optional , Type , Union
44
5- from pydantic import BaseModel , field_validator
6-
5+ from pydantic import BaseModel , Field , field_validator
76from aws_lambda_powertools .shared .dynamodb_deserializer import TypeDeserializer
87
98_DESERIALIZER = TypeDeserializer ()
109
1110
1211class DynamoDBStreamChangedRecordModel (BaseModel ):
13- ApproximateCreationDateTime : Optional [datetime ] = None
14- Keys : Dict [str , Any ]
15- NewImage : Optional [Union [Dict [str , Any ], Type [BaseModel ], BaseModel ]] = None
16- OldImage : Optional [Union [Dict [str , Any ], Type [BaseModel ], BaseModel ]] = None
17- SequenceNumber : str
18- SizeBytes : int
19- StreamViewType : Literal ["NEW_AND_OLD_IMAGES" , "KEYS_ONLY" , "NEW_IMAGE" , "OLD_IMAGE" ]
20-
21- # context on why it's commented: https://github.com/aws-powertools/powertools-lambda-python/pull/118
22- # since both images are optional, they can both be None. However, at least one must
23- # exist in a legal model of NEW_AND_OLD_IMAGES type
24- # @root_validator
25- # def check_one_image_exists(cls, values): # noqa: ERA001
26- # new_img, old_img = values.get("NewImage"), values.get("OldImage") # noqa: ERA001
27- # stream_type = values.get("StreamViewType") # noqa: ERA001
28- # if stream_type == "NEW_AND_OLD_IMAGES" and not new_img and not old_img: # noqa: ERA001
29- # raise TypeError("DynamoDB streams model failed validation, missing both new & old stream images") # noqa: ERA001,E501
30- # return values # noqa: ERA001
12+ ApproximateCreationDateTime : Optional [float ] = Field ( # AWS sends this as Unix epoch float
13+ default = None ,
14+ description = "The approximate date and time when the stream record was created (Unix epoch time)." ,
15+ examples = [1693997155.0 ]
16+ )
17+ Keys : Dict [str , Any ] = Field (
18+ description = "Primary key attributes for the item." ,
19+ examples = [{"Id" : {"N" : "101" }}]
20+ )
21+ NewImage : Optional [Union [Dict [str , Any ], Type [BaseModel ], BaseModel ]] = Field (
22+ default = None ,
23+ description = "The item after modifications, in DynamoDB attribute-value format." ,
24+ examples = [{
25+ "Message" : {"S" : "New item!" },
26+ "Id" : {"N" : "101" }
27+ }]
28+ )
29+ OldImage : Optional [Union [Dict [str , Any ], Type [BaseModel ], BaseModel ]] = Field (
30+ default = None ,
31+ description = "The item before modifications, in DynamoDB attribute-value format." ,
32+ examples = [{
33+ "Message" : {"S" : "Old item!" },
34+ "Id" : {"N" : "100" }
35+ }]
36+ )
37+ SequenceNumber : str = Field (
38+ description = "A unique identifier for the stream record." ,
39+ examples = ["222" ]
40+ )
41+ SizeBytes : int = Field (
42+ description = "The size of the stream record, in bytes." ,
43+ examples = [26 ]
44+ )
45+ StreamViewType : Literal ["NEW_AND_OLD_IMAGES" , "KEYS_ONLY" , "NEW_IMAGE" , "OLD_IMAGE" ] = Field (
46+ description = "The type of data included in the stream record." ,
47+ examples = ["NEW_AND_OLD_IMAGES" ]
48+ )
3149
3250 @field_validator ("Keys" , "NewImage" , "OldImage" , mode = "before" )
3351 def deserialize_field (cls , value ):
34- return {k : _DESERIALIZER .deserialize (v ) for k , v in value .items ()}
52+ return {k : _DESERIALIZER .deserialize (v ) for k , v in value .items ()} if value else value
3553
3654
3755class UserIdentity (BaseModel ):
38- type : Literal ["Service" ] # noqa: VNE003, A003
39- principalId : Literal ["dynamodb.amazonaws.com" ]
56+ type : Literal ["Service" ] = Field (
57+ default = "Service" ,
58+ description = "The type of identity that made the request, which is always 'Service' for DynamoDB streams." ,
59+ examples = ["Service" ]
60+ )
61+ principalId : str = Field (
62+ description = "The unique identifier for the principal that made the request." ,
63+ examples = ["dynamodb.amazonaws.com" ]
64+ )
4065
4166
4267class DynamoDBStreamRecordModel (BaseModel ):
43- eventID : str
44- eventName : Literal ["INSERT" , "MODIFY" , "REMOVE" ]
45- eventVersion : float
46- eventSource : Literal ["aws:dynamodb" ]
47- awsRegion : str
48- eventSourceARN : str
49- dynamodb : DynamoDBStreamChangedRecordModel
50- userIdentity : Optional [UserIdentity ] = None
68+ eventID : str = Field (
69+ description = "A unique identifier for the event." ,
70+ examples = ["1" ]
71+ )
72+ eventName : Literal ["INSERT" , "MODIFY" , "REMOVE" ] = Field (
73+ description = "The type of operation that was performed on the item." ,
74+ examples = ["INSERT" ]
75+ )
76+ eventVersion : str = Field (
77+ default = "1.0" ,
78+ description = "The version of the stream record format." ,
79+ examples = ["1.0" ]
80+ )
81+ eventSource : str = Field (
82+ default = "aws:dynamodb" ,
83+ description = "The source of the event, which is always 'aws:dynamodb' for DynamoDB streams." ,
84+ examples = ["aws:dynamodb" ]
85+ )
86+ awsRegion : str = Field (
87+ description = "The AWS region where the stream record was generated." ,
88+ examples = ["us-west-2" ]
89+ )
90+ eventSourceARN : str = Field (
91+ description = "The Amazon Resource Name (ARN) of the DynamoDB stream." ,
92+ examples = ["arn:aws:dynamodb:us-west-2:123456789012:table/ExampleTable/stream/2021-01-01T00:00:00.000" ]
93+ )
94+ dynamodb : DynamoDBStreamChangedRecordModel = Field (
95+ description = "Contains the details of the DynamoDB stream record." ,
96+ examples = [{
97+ "ApproximateCreationDateTime" : 1693997155.0 ,
98+ "Keys" : {"Id" : {"N" : "101" }},
99+ "NewImage" : {"Message" : {"S" : "New item!" }, "Id" : {"N" : "101" }},
100+ "OldImage" : {"Message" : {"S" : "Old item!" }, "Id" : {"N" : "100" }},
101+ "SequenceNumber" : "222" ,
102+ "SizeBytes" : 26 ,
103+ "StreamViewType" : "NEW_AND_OLD_IMAGES"
104+ }]
105+ )
106+ userIdentity : Optional [UserIdentity ] = Field (
107+ default = None ,
108+ description = "Information about the identity that made the request." ,
109+ examples = [{"type" : "Service" , "principalId" : "dynamodb.amazonaws.com" }]
110+ )
51111
52112
53113class DynamoDBStreamModel (BaseModel ):
54- Records : List [DynamoDBStreamRecordModel ]
114+ Records : List [DynamoDBStreamRecordModel ] = Field (
115+ description = "A list of records that contain the details of the DynamoDB stream events." ,
116+ examples = [{
117+ "eventID" : "1" ,
118+ "eventName" : "INSERT" ,
119+ "eventVersion" : "1.0" ,
120+ "eventSource" : "aws:dynamodb" ,
121+ "awsRegion" : "us-west-2" ,
122+ "eventSourceARN" : "arn:aws:dynamodb:us-west-2:123456789012:table/ExampleTable/stream/2021-01-01T00:00:00.000" ,
123+ "dynamodb" : {
124+ "ApproximateCreationDateTime" : 1693997155.0 ,
125+ "Keys" : {"Id" : {"N" : "101" }},
126+ "NewImage" : {"Message" : {"S" : "New item!" }, "Id" : {"N" : "101" }},
127+ "OldImage" : {"Message" : {"S" : "Old item!" }, "Id" : {"N" : "100" }},
128+ "SequenceNumber" : "222" ,
129+ "SizeBytes" : 26 ,
130+ "StreamViewType" : "NEW_AND_OLD_IMAGES"
131+ },
132+ "userIdentity" : {"type" : "Service" , "principalId" : "dynamodb.amazonaws.com" }
133+ }]
134+ )
0 commit comments