0
# Data Classes
1
2
Type-safe data classes representing AWS event structures for Lambda triggers including API Gateway, S3, DynamoDB, Kinesis, SQS, SNS, CloudWatch events, and many other AWS services. These classes provide convenient property access and automatic parsing of complex event structures.
3
4
## Capabilities
5
6
### Event Source Decorator
7
8
Decorator for automatically parsing Lambda events into data class instances.
9
10
```python { .api }
11
def event_source(data_class: type) -> Callable:
12
"""
13
Decorator to automatically parse Lambda event into data class.
14
15
Parameters:
16
- data_class: Data class type to parse event into
17
18
Returns:
19
Decorated function that receives parsed event as first parameter
20
"""
21
```
22
23
### API Gateway Events
24
25
Data classes for API Gateway proxy integration events.
26
27
```python { .api }
28
class APIGatewayProxyEvent:
29
"""API Gateway Lambda Proxy Integration event"""
30
31
@property
32
def body(self) -> str | None:
33
"""Raw request body as string"""
34
35
@property
36
def json_body(self) -> Any:
37
"""Parse JSON request body (caches result)"""
38
39
@property
40
def headers(self) -> Dict[str, str]:
41
"""Request headers (case-insensitive access)"""
42
43
@property
44
def query_string_parameters(self) -> Dict[str, str] | None:
45
"""Query string parameters"""
46
47
@property
48
def multi_value_query_string_parameters(self) -> Dict[str, List[str]] | None:
49
"""Multi-value query string parameters"""
50
51
@property
52
def path_parameters(self) -> Dict[str, str] | None:
53
"""Path parameters from route"""
54
55
@property
56
def stage_variables(self) -> Dict[str, str] | None:
57
"""API Gateway stage variables"""
58
59
@property
60
def request_context(self) -> Dict[str, Any]:
61
"""API Gateway request context"""
62
63
@property
64
def is_base64_encoded(self) -> bool:
65
"""Whether body is base64 encoded"""
66
67
def get_query_string_value(
68
self,
69
name: str,
70
default_value: str = None
71
) -> str | None:
72
"""
73
Get query string parameter value.
74
75
Parameters:
76
- name: Parameter name
77
- default_value: Default if not found
78
79
Returns:
80
Parameter value or default
81
"""
82
83
def get_header_value(
84
self,
85
name: str,
86
default_value: str = None,
87
case_sensitive: bool = False
88
) -> str | None:
89
"""
90
Get header value with optional case sensitivity.
91
92
Parameters:
93
- name: Header name
94
- default_value: Default if not found
95
- case_sensitive: Whether to match case exactly
96
97
Returns:
98
Header value or default
99
"""
100
101
class APIGatewayProxyEventV2:
102
"""API Gateway HTTP API (v2.0) event"""
103
104
@property
105
def body(self) -> str | None:
106
"""Raw request body"""
107
108
@property
109
def json_body(self) -> Any:
110
"""Parse JSON request body"""
111
112
@property
113
def headers(self) -> Dict[str, str]:
114
"""Request headers"""
115
116
@property
117
def query_string_parameters(self) -> Dict[str, str] | None:
118
"""Query string parameters"""
119
120
@property
121
def path_parameters(self) -> Dict[str, str] | None:
122
"""Path parameters"""
123
124
@property
125
def stage_variables(self) -> Dict[str, str] | None:
126
"""Stage variables"""
127
128
@property
129
def request_context(self) -> Dict[str, Any]:
130
"""HTTP API request context"""
131
132
@property
133
def cookies(self) -> List[str] | None:
134
"""Request cookies"""
135
136
class APIGatewayWebSocketEvent:
137
"""API Gateway WebSocket event"""
138
139
@property
140
def body(self) -> str | None:
141
"""WebSocket message body"""
142
143
@property
144
def request_context(self) -> Dict[str, Any]:
145
"""WebSocket request context"""
146
147
@property
148
def connection_id(self) -> str:
149
"""WebSocket connection ID"""
150
151
@property
152
def route_key(self) -> str:
153
"""WebSocket route key"""
154
```
155
156
### Application Load Balancer Events
157
158
Data class for ALB target group Lambda integration.
159
160
```python { .api }
161
class ALBEvent:
162
"""Application Load Balancer event"""
163
164
@property
165
def body(self) -> str | None:
166
"""Request body"""
167
168
@property
169
def json_body(self) -> Any:
170
"""Parse JSON request body"""
171
172
@property
173
def headers(self) -> Dict[str, str]:
174
"""Request headers"""
175
176
@property
177
def query_string_parameters(self) -> Dict[str, str] | None:
178
"""Query parameters"""
179
180
@property
181
def multi_value_headers(self) -> Dict[str, List[str]] | None:
182
"""Multi-value headers"""
183
184
@property
185
def multi_value_query_string_parameters(self) -> Dict[str, List[str]] | None:
186
"""Multi-value query parameters"""
187
188
@property
189
def request_context(self) -> Dict[str, Any]:
190
"""ALB request context"""
191
192
@property
193
def is_base64_encoded(self) -> bool:
194
"""Whether body is base64 encoded"""
195
```
196
197
### Lambda Function URL Events
198
199
Data class for Lambda Function URLs.
200
201
```python { .api }
202
class LambdaFunctionUrlEvent:
203
"""Lambda Function URL event"""
204
205
@property
206
def body(self) -> str | None:
207
"""Request body"""
208
209
@property
210
def json_body(self) -> Any:
211
"""Parse JSON request body"""
212
213
@property
214
def headers(self) -> Dict[str, str]:
215
"""Request headers"""
216
217
@property
218
def query_string_parameters(self) -> Dict[str, str] | None:
219
"""Query parameters"""
220
221
@property
222
def request_context(self) -> Dict[str, Any]:
223
"""Function URL request context"""
224
225
@property
226
def cookies(self) -> List[str] | None:
227
"""Request cookies"""
228
229
@property
230
def is_base64_encoded(self) -> bool:
231
"""Whether body is base64 encoded"""
232
```
233
234
### AppSync Events
235
236
Data classes for AWS AppSync GraphQL events.
237
238
```python { .api }
239
class AppSyncResolverEvent:
240
"""AppSync direct Lambda resolver event"""
241
242
@property
243
def arguments(self) -> Dict[str, Any]:
244
"""GraphQL field arguments"""
245
246
@property
247
def identity(self) -> Dict[str, Any]:
248
"""AppSync identity information"""
249
250
@property
251
def source(self) -> Dict[str, Any]:
252
"""Parent object for field resolution"""
253
254
@property
255
def request(self) -> Dict[str, Any]:
256
"""AppSync request information"""
257
258
@property
259
def prev(self) -> Dict[str, Any]:
260
"""Previous resolver result in pipeline"""
261
262
@property
263
def info(self) -> Dict[str, Any]:
264
"""GraphQL query information"""
265
266
@property
267
def stash(self) -> Dict[str, Any]:
268
"""Pipeline resolver stash"""
269
270
class AppSyncResolverEventsEvent:
271
"""AppSync Events resolver event"""
272
273
@property
274
def arguments(self) -> Dict[str, Any]:
275
"""Event arguments"""
276
277
@property
278
def identity(self) -> Dict[str, Any]:
279
"""Identity information"""
280
281
@property
282
def request(self) -> Dict[str, Any]:
283
"""Request information"""
284
```
285
286
### SQS Events
287
288
Data classes for Amazon SQS events.
289
290
```python { .api }
291
class SQSEvent:
292
"""SQS Lambda trigger event"""
293
294
@property
295
def records(self) -> List[SQSRecord]:
296
"""List of SQS records"""
297
298
class SQSRecord:
299
"""Individual SQS record"""
300
301
@property
302
def body(self) -> str:
303
"""Message body"""
304
305
@property
306
def json_body(self) -> Any:
307
"""Parse JSON message body"""
308
309
@property
310
def receipt_handle(self) -> str:
311
"""SQS receipt handle"""
312
313
@property
314
def message_id(self) -> str:
315
"""SQS message ID"""
316
317
@property
318
def md5_of_body(self) -> str:
319
"""MD5 hash of message body"""
320
321
@property
322
def event_source(self) -> str:
323
"""Event source (aws:sqs)"""
324
325
@property
326
def event_source_arn(self) -> str:
327
"""SQS queue ARN"""
328
329
@property
330
def aws_region(self) -> str:
331
"""AWS region"""
332
333
@property
334
def attributes(self) -> Dict[str, Any]:
335
"""SQS message attributes"""
336
337
@property
338
def message_attributes(self) -> Dict[str, Any]:
339
"""SQS message attributes"""
340
```
341
342
### SNS Events
343
344
Data classes for Amazon SNS events.
345
346
```python { .api }
347
class SNSEvent:
348
"""SNS Lambda trigger event"""
349
350
@property
351
def records(self) -> List[SNSRecord]:
352
"""List of SNS records"""
353
354
class SNSRecord:
355
"""Individual SNS record"""
356
357
@property
358
def sns(self) -> Dict[str, Any]:
359
"""SNS message data"""
360
361
@property
362
def subject(self) -> str | None:
363
"""SNS message subject"""
364
365
@property
366
def message(self) -> str:
367
"""SNS message body"""
368
369
@property
370
def json_message(self) -> Any:
371
"""Parse JSON SNS message"""
372
373
@property
374
def message_id(self) -> str:
375
"""SNS message ID"""
376
377
@property
378
def topic_arn(self) -> str:
379
"""SNS topic ARN"""
380
381
@property
382
def timestamp(self) -> str:
383
"""Message timestamp"""
384
385
@property
386
def message_attributes(self) -> Dict[str, Any]:
387
"""SNS message attributes"""
388
```
389
390
### S3 Events
391
392
Data classes for Amazon S3 events.
393
394
```python { .api }
395
class S3Event:
396
"""S3 Lambda trigger event"""
397
398
@property
399
def records(self) -> List[S3Record]:
400
"""List of S3 records"""
401
402
class S3Record:
403
"""Individual S3 record"""
404
405
@property
406
def s3(self) -> Dict[str, Any]:
407
"""S3 event data"""
408
409
@property
410
def bucket_name(self) -> str:
411
"""S3 bucket name"""
412
413
@property
414
def object_key(self) -> str:
415
"""S3 object key (URL decoded)"""
416
417
@property
418
def object_size(self) -> int | None:
419
"""S3 object size in bytes"""
420
421
@property
422
def object_etag(self) -> str | None:
423
"""S3 object ETag"""
424
425
@property
426
def object_version_id(self) -> str | None:
427
"""S3 object version ID"""
428
429
@property
430
def event_name(self) -> str:
431
"""S3 event name (e.g., ObjectCreated:Put)"""
432
433
@property
434
def event_source(self) -> str:
435
"""Event source (aws:s3)"""
436
437
@property
438
def aws_region(self) -> str:
439
"""AWS region"""
440
441
@property
442
def user_identity(self) -> Dict[str, Any]:
443
"""User identity information"""
444
445
class S3EventBridgeNotificationEvent:
446
"""S3 EventBridge notification event"""
447
448
@property
449
def detail(self) -> Dict[str, Any]:
450
"""Event detail"""
451
452
@property
453
def bucket_name(self) -> str:
454
"""S3 bucket name"""
455
456
@property
457
def object_key(self) -> str:
458
"""S3 object key"""
459
460
@property
461
def object_size(self) -> int | None:
462
"""Object size in bytes"""
463
464
class S3BatchOperationEvent:
465
"""S3 Batch Operations event"""
466
467
@property
468
def invocation_id(self) -> str:
469
"""Batch operation invocation ID"""
470
471
@property
472
def invocation_schema_version(self) -> str:
473
"""Schema version"""
474
475
@property
476
def tasks(self) -> List[Dict[str, Any]]:
477
"""List of batch operation tasks"""
478
479
class S3BatchOperationResponse:
480
"""S3 Batch Operations response"""
481
482
def __init__(
483
self,
484
invocation_id: str,
485
treat_missing_keys_as: str = "PermanentFailure",
486
invocation_schema_version: str = "1.0",
487
results: List[S3BatchOperationResponseRecord] = None,
488
):
489
"""
490
Create S3 Batch Operations response.
491
492
Parameters:
493
- invocation_id: Batch operation invocation ID
494
- treat_missing_keys_as: How to handle missing keys
495
- invocation_schema_version: Schema version
496
- results: List of operation results
497
"""
498
499
class S3BatchOperationResponseRecord:
500
"""Individual S3 Batch Operations result"""
501
502
def __init__(
503
self,
504
task_id: str,
505
result_code: str,
506
result_string: str = None,
507
):
508
"""
509
Create batch operation result record.
510
511
Parameters:
512
- task_id: Task identifier
513
- result_code: Result code (Succeeded, PermanentFailure, etc.)
514
- result_string: Optional result description
515
"""
516
```
517
518
### DynamoDB Events
519
520
Data classes for DynamoDB Streams events.
521
522
```python { .api }
523
class DynamoDBStreamEvent:
524
"""DynamoDB Streams Lambda trigger event"""
525
526
@property
527
def records(self) -> List[DynamoDBRecord]:
528
"""List of DynamoDB Stream records"""
529
530
class DynamoDBRecord:
531
"""Individual DynamoDB Stream record"""
532
533
@property
534
def aws_region(self) -> str:
535
"""AWS region"""
536
537
@property
538
def dynamodb(self) -> Dict[str, Any]:
539
"""DynamoDB stream record data"""
540
541
@property
542
def event_id(self) -> str:
543
"""Event ID"""
544
545
@property
546
def event_name(self) -> str:
547
"""Event name (INSERT, MODIFY, REMOVE)"""
548
549
@property
550
def event_source(self) -> str:
551
"""Event source (aws:dynamodb)"""
552
553
@property
554
def event_source_arn(self) -> str:
555
"""DynamoDB table stream ARN"""
556
557
@property
558
def event_version(self) -> str:
559
"""Event version"""
560
561
@property
562
def user_identity(self) -> Dict[str, Any] | None:
563
"""User identity information"""
564
```
565
566
### Kinesis Events
567
568
Data classes for Amazon Kinesis events.
569
570
```python { .api }
571
class KinesisStreamEvent:
572
"""Kinesis Data Streams Lambda trigger event"""
573
574
@property
575
def records(self) -> List[KinesisStreamRecord]:
576
"""List of Kinesis records"""
577
578
class KinesisStreamRecord:
579
"""Individual Kinesis Stream record"""
580
581
@property
582
def kinesis(self) -> Dict[str, Any]:
583
"""Kinesis record data"""
584
585
@property
586
def data(self) -> str:
587
"""Base64 encoded record data"""
588
589
@property
590
def data_as_bytes(self) -> bytes:
591
"""Record data as bytes"""
592
593
@property
594
def data_as_text(self) -> str:
595
"""Record data as UTF-8 text"""
596
597
@property
598
def data_as_json(self) -> Any:
599
"""Parse record data as JSON"""
600
601
@property
602
def partition_key(self) -> str:
603
"""Kinesis partition key"""
604
605
@property
606
def sequence_number(self) -> str:
607
"""Kinesis sequence number"""
608
609
@property
610
def approximate_arrival_timestamp(self) -> int:
611
"""Approximate arrival timestamp"""
612
613
@property
614
def event_source(self) -> str:
615
"""Event source (aws:kinesis)"""
616
617
@property
618
def event_source_arn(self) -> str:
619
"""Kinesis stream ARN"""
620
621
@property
622
def aws_region(self) -> str:
623
"""AWS region"""
624
625
class KinesisFirehoseEvent:
626
"""Kinesis Data Firehose transformation event"""
627
628
@property
629
def invocation_id(self) -> str:
630
"""Firehose invocation ID"""
631
632
@property
633
def delivery_stream_arn(self) -> str:
634
"""Firehose delivery stream ARN"""
635
636
@property
637
def region(self) -> str:
638
"""AWS region"""
639
640
@property
641
def records(self) -> List[KinesisFirehoseDataTransformationRecord]:
642
"""List of records to transform"""
643
644
class KinesisFirehoseDataTransformationRecord:
645
"""Kinesis Firehose transformation record"""
646
647
@property
648
def record_id(self) -> str:
649
"""Record ID"""
650
651
@property
652
def approximate_arrival_timestamp(self) -> int:
653
"""Approximate arrival timestamp"""
654
655
@property
656
def data(self) -> str:
657
"""Base64 encoded record data"""
658
659
@property
660
def data_as_bytes(self) -> bytes:
661
"""Record data as bytes"""
662
663
@property
664
def data_as_text(self) -> str:
665
"""Record data as UTF-8 text"""
666
667
@property
668
def data_as_json(self) -> Any:
669
"""Parse record data as JSON"""
670
671
@property
672
def kms_key_id(self) -> str | None:
673
"""KMS key ID for encryption"""
674
675
@property
676
def metadata(self) -> KinesisFirehoseDataTransformationRecordMetadata | None:
677
"""Record metadata"""
678
679
class KinesisFirehoseDataTransformationRecordMetadata:
680
"""Kinesis Firehose record metadata"""
681
682
@property
683
def partition_keys(self) -> Dict[str, str]:
684
"""Partition keys for S3 delivery"""
685
686
class KinesisFirehoseDataTransformationResponse:
687
"""Kinesis Firehose transformation response"""
688
689
def __init__(self, records: List[Dict[str, Any]]):
690
"""
691
Create Firehose transformation response.
692
693
Parameters:
694
- records: List of transformed records with recordId, result, and data
695
"""
696
```
697
698
### EventBridge Events
699
700
Data classes for Amazon EventBridge events.
701
702
```python { .api }
703
class EventBridgeEvent:
704
"""EventBridge (CloudWatch Events) event"""
705
706
@property
707
def version(self) -> str:
708
"""Event version"""
709
710
@property
711
def id(self) -> str:
712
"""Event ID"""
713
714
@property
715
def detail_type(self) -> str:
716
"""Event detail type"""
717
718
@property
719
def source(self) -> str:
720
"""Event source"""
721
722
@property
723
def account(self) -> str:
724
"""AWS account ID"""
725
726
@property
727
def time(self) -> str:
728
"""Event time (ISO 8601)"""
729
730
@property
731
def region(self) -> str:
732
"""AWS region"""
733
734
@property
735
def detail(self) -> Dict[str, Any]:
736
"""Event detail"""
737
738
@property
739
def resources(self) -> List[str]:
740
"""Event resources"""
741
```
742
743
### CloudWatch Events
744
745
Data classes for CloudWatch-specific events.
746
747
```python { .api }
748
class CloudWatchLogsEvent:
749
"""CloudWatch Logs subscription filter event"""
750
751
@property
752
def message_type(self) -> str:
753
"""Message type"""
754
755
@property
756
def owner(self) -> str:
757
"""AWS account ID"""
758
759
@property
760
def log_group(self) -> str:
761
"""CloudWatch log group name"""
762
763
@property
764
def log_stream(self) -> str:
765
"""CloudWatch log stream name"""
766
767
@property
768
def subscription_filters(self) -> List[str]:
769
"""Subscription filter names"""
770
771
@property
772
def log_events(self) -> List[Dict[str, Any]]:
773
"""List of log events"""
774
775
def parse_logs_data(self) -> Dict[str, Any]:
776
"""Parse and decompress CloudWatch Logs data"""
777
778
class CloudWatchAlarmEvent:
779
"""CloudWatch Alarm state change event"""
780
781
@property
782
def alarm_data(self) -> CloudWatchAlarmData:
783
"""Alarm data"""
784
785
class CloudWatchAlarmData:
786
"""CloudWatch Alarm data"""
787
788
@property
789
def alarm_name(self) -> str:
790
"""Alarm name"""
791
792
@property
793
def state(self) -> CloudWatchAlarmState:
794
"""Current alarm state"""
795
796
@property
797
def previous_state(self) -> CloudWatchAlarmState:
798
"""Previous alarm state"""
799
800
@property
801
def configuration(self) -> CloudWatchAlarmConfiguration:
802
"""Alarm configuration"""
803
804
class CloudWatchAlarmState:
805
"""CloudWatch Alarm state information"""
806
807
@property
808
def value(self) -> str:
809
"""State value (OK, ALARM, INSUFFICIENT_DATA)"""
810
811
@property
812
def reason(self) -> str:
813
"""State change reason"""
814
815
@property
816
def timestamp(self) -> str:
817
"""State timestamp"""
818
819
class CloudWatchAlarmConfiguration:
820
"""CloudWatch Alarm configuration"""
821
822
@property
823
def description(self) -> str | None:
824
"""Alarm description"""
825
826
@property
827
def metrics(self) -> List[CloudWatchAlarmMetric]:
828
"""Alarm metrics"""
829
830
class CloudWatchAlarmMetric:
831
"""CloudWatch Alarm metric"""
832
833
@property
834
def id(self) -> str:
835
"""Metric ID"""
836
837
@property
838
def metric_stat(self) -> CloudWatchAlarmMetricStat | None:
839
"""Metric statistics"""
840
841
class CloudWatchAlarmMetricStat:
842
"""CloudWatch Alarm metric statistics"""
843
844
@property
845
def metric(self) -> Dict[str, Any]:
846
"""Metric definition"""
847
848
@property
849
def period(self) -> int:
850
"""Metric period in seconds"""
851
852
@property
853
def stat(self) -> str:
854
"""Statistic (Average, Sum, Maximum, etc.)"""
855
856
class CloudWatchDashboardCustomWidgetEvent:
857
"""CloudWatch Dashboard custom widget event"""
858
859
@property
860
def describe(self) -> bool:
861
"""Whether this is a describe request"""
862
863
@property
864
def widget_context(self) -> Dict[str, Any]:
865
"""Widget context"""
866
```
867
868
### AWS Config Events
869
870
Data classes for AWS Config rule events.
871
872
```python { .api }
873
class AWSConfigRuleEvent:
874
"""AWS Config rule evaluation event"""
875
876
@property
877
def version(self) -> str:
878
"""Event version"""
879
880
@property
881
def invocation_event(self) -> Dict[str, Any]:
882
"""Config rule invocation event"""
883
884
@property
885
def rule_parameters(self) -> Dict[str, Any]:
886
"""Config rule parameters"""
887
888
@property
889
def result_token(self) -> str:
890
"""Result token for compliance evaluation"""
891
892
@property
893
def event_left_scope(self) -> bool:
894
"""Whether event left scope"""
895
896
@property
897
def executing_rule_name(self) -> str:
898
"""Config rule name"""
899
900
@property
901
def config_rule_arn(self) -> str:
902
"""Config rule ARN"""
903
904
@property
905
def config_rule_name(self) -> str:
906
"""Config rule name"""
907
908
@property
909
def account_id(self) -> str:
910
"""AWS account ID"""
911
```
912
913
### Secrets Manager Events
914
915
Data classes for AWS Secrets Manager rotation events.
916
917
```python { .api }
918
class SecretsManagerEvent:
919
"""Secrets Manager rotation event"""
920
921
@property
922
def secret_id(self) -> str:
923
"""Secret ARN or name"""
924
925
@property
926
def client_request_token(self) -> str:
927
"""Client request token"""
928
929
@property
930
def step(self) -> str:
931
"""Rotation step (createSecret, setSecret, testSecret, finishSecret)"""
932
```
933
934
### Connect Events
935
936
Data classes for Amazon Connect events.
937
938
```python { .api }
939
class ConnectContactFlowEvent:
940
"""Amazon Connect Contact Flow event"""
941
942
@property
943
def details(self) -> Dict[str, Any]:
944
"""Contact flow details"""
945
946
@property
947
def contact_data(self) -> Dict[str, Any]:
948
"""Contact data"""
949
950
@property
951
def parameters(self) -> Dict[str, Any]:
952
"""Contact flow parameters"""
953
```
954
955
### CodePipeline Events
956
957
Data classes for AWS CodePipeline events.
958
959
```python { .api }
960
class CodePipelineJobEvent:
961
"""CodePipeline job event"""
962
963
@property
964
def job_details(self) -> Dict[str, Any]:
965
"""CodePipeline job details"""
966
967
@property
968
def job_id(self) -> str:
969
"""CodePipeline job ID"""
970
971
@property
972
def job_data(self) -> Dict[str, Any]:
973
"""Job data"""
974
975
@property
976
def input_artifacts(self) -> List[Dict[str, Any]]:
977
"""Input artifacts"""
978
979
@property
980
def output_artifacts(self) -> List[Dict[str, Any]]:
981
"""Output artifacts"""
982
983
@property
984
def action_configuration(self) -> Dict[str, Any]:
985
"""Action configuration"""
986
```
987
988
### CodeDeploy Events
989
990
Data classes for AWS CodeDeploy events.
991
992
```python { .api }
993
class CodeDeployLifecycleHookEvent:
994
"""CodeDeploy lifecycle hook event"""
995
996
@property
997
def account_id(self) -> str:
998
"""AWS account ID"""
999
1000
@property
1001
def region(self) -> str:
1002
"""AWS region"""
1003
1004
@property
1005
def deployment_id(self) -> str:
1006
"""CodeDeploy deployment ID"""
1007
1008
@property
1009
def application_name(self) -> str:
1010
"""CodeDeploy application name"""
1011
1012
@property
1013
def deployment_group_name(self) -> str:
1014
"""Deployment group name"""
1015
1016
@property
1017
def lifecycle_event_hook_execution_id(self) -> str:
1018
"""Lifecycle hook execution ID"""
1019
```
1020
1021
### VPC Lattice Events
1022
1023
Data classes for Amazon VPC Lattice events.
1024
1025
```python { .api }
1026
class VPCLatticeEvent:
1027
"""VPC Lattice service request event"""
1028
1029
@property
1030
def body(self) -> str | None:
1031
"""Request body"""
1032
1033
@property
1034
def json_body(self) -> Any:
1035
"""Parse JSON request body"""
1036
1037
@property
1038
def headers(self) -> Dict[str, str]:
1039
"""Request headers"""
1040
1041
@property
1042
def query_string_parameters(self) -> Dict[str, str] | None:
1043
"""Query parameters"""
1044
1045
@property
1046
def path_parameters(self) -> Dict[str, str] | None:
1047
"""Path parameters"""
1048
1049
@property
1050
def request_context(self) -> Dict[str, Any]:
1051
"""VPC Lattice request context"""
1052
1053
@property
1054
def is_base64_encoded(self) -> bool:
1055
"""Whether body is base64 encoded"""
1056
1057
class VPCLatticeEventV2:
1058
"""VPC Lattice v2 service request event"""
1059
1060
@property
1061
def body(self) -> str | None:
1062
"""Request body"""
1063
1064
@property
1065
def json_body(self) -> Any:
1066
"""Parse JSON request body"""
1067
1068
@property
1069
def headers(self) -> Dict[str, str]:
1070
"""Request headers"""
1071
1072
@property
1073
def query_string_parameters(self) -> Dict[str, str] | None:
1074
"""Query parameters"""
1075
1076
@property
1077
def path_parameters(self) -> Dict[str, str] | None:
1078
"""Path parameters"""
1079
1080
@property
1081
def request_context(self) -> Dict[str, Any]:
1082
"""VPC Lattice v2 request context"""
1083
1084
@property
1085
def is_base64_encoded(self) -> bool:
1086
"""Whether body is base64 encoded"""
1087
```
1088
1089
### Bedrock Events
1090
1091
Data classes for Amazon Bedrock events.
1092
1093
```python { .api }
1094
class BedrockAgentEvent:
1095
"""Bedrock Agent invocation event"""
1096
1097
@property
1098
def message_version(self) -> str:
1099
"""Message version"""
1100
1101
@property
1102
def input_text(self) -> str:
1103
"""Agent input text"""
1104
1105
@property
1106
def session_id(self) -> str:
1107
"""Agent session ID"""
1108
1109
@property
1110
def action_group(self) -> str:
1111
"""Action group name"""
1112
1113
@property
1114
def api_path(self) -> str:
1115
"""API path"""
1116
1117
@property
1118
def http_method(self) -> str:
1119
"""HTTP method"""
1120
1121
@property
1122
def parameters(self) -> Dict[str, Any]:
1123
"""Action parameters"""
1124
1125
@property
1126
def request_body(self) -> Dict[str, Any] | None:
1127
"""Request body"""
1128
1129
@property
1130
def session_attributes(self) -> Dict[str, str]:
1131
"""Session attributes"""
1132
1133
@property
1134
def prompt_session_attributes(self) -> Dict[str, str]:
1135
"""Prompt session attributes"""
1136
1137
class BedrockAgentFunctionEvent:
1138
"""Bedrock Agent function invocation event"""
1139
1140
@property
1141
def message_version(self) -> str:
1142
"""Message version"""
1143
1144
@property
1145
def input_text(self) -> str:
1146
"""Function input text"""
1147
1148
@property
1149
def session_id(self) -> str:
1150
"""Agent session ID"""
1151
1152
@property
1153
def function(self) -> str:
1154
"""Function name"""
1155
1156
@property
1157
def parameters(self) -> Dict[str, Any]:
1158
"""Function parameters"""
1159
1160
@property
1161
def session_attributes(self) -> Dict[str, str]:
1162
"""Session attributes"""
1163
1164
@property
1165
def prompt_session_attributes(self) -> Dict[str, str]:
1166
"""Prompt session attributes"""
1167
```
1168
1169
### SES Events
1170
1171
Data classes for Amazon Simple Email Service events.
1172
1173
```python { .api }
1174
class SESEvent:
1175
"""Simple Email Service event"""
1176
1177
@property
1178
def records(self) -> List[SESRecord]:
1179
"""List of SES records"""
1180
1181
class SESRecord:
1182
"""Individual SES record"""
1183
1184
@property
1185
def ses(self) -> Dict[str, Any]:
1186
"""SES event data"""
1187
1188
@property
1189
def mail(self) -> Dict[str, Any]:
1190
"""Email message data"""
1191
1192
@property
1193
def receipt(self) -> Dict[str, Any]:
1194
"""Email receipt data"""
1195
```
1196
1197
### Kafka Events
1198
1199
Data classes for managed Kafka events.
1200
1201
```python { .api }
1202
class KafkaEvent:
1203
"""Managed Kafka event (MSK/Self-managed)"""
1204
1205
@property
1206
def event_source(self) -> str:
1207
"""Event source"""
1208
1209
@property
1210
def event_source_arn(self) -> str:
1211
"""Kafka cluster ARN"""
1212
1213
@property
1214
def records(self) -> Dict[str, List[KafkaRecord]]:
1215
"""Records grouped by topic-partition"""
1216
1217
@property
1218
def bootstrap_servers(self) -> str:
1219
"""Kafka bootstrap servers"""
1220
1221
class KafkaRecord:
1222
"""Individual Kafka record"""
1223
1224
@property
1225
def topic(self) -> str:
1226
"""Kafka topic"""
1227
1228
@property
1229
def partition(self) -> int:
1230
"""Kafka partition"""
1231
1232
@property
1233
def offset(self) -> int:
1234
"""Kafka offset"""
1235
1236
@property
1237
def timestamp(self) -> int:
1238
"""Record timestamp"""
1239
1240
@property
1241
def timestamp_type(self) -> str:
1242
"""Timestamp type"""
1243
1244
@property
1245
def key(self) -> str | None:
1246
"""Record key (base64 encoded)"""
1247
1248
@property
1249
def value(self) -> str:
1250
"""Record value (base64 encoded)"""
1251
1252
@property
1253
def headers(self) -> Dict[str, str]:
1254
"""Record headers"""
1255
1256
@property
1257
def decoded_key(self) -> bytes | None:
1258
"""Decode record key from base64"""
1259
1260
@property
1261
def decoded_value(self) -> bytes:
1262
"""Decode record value from base64"""
1263
1264
@property
1265
def json_value(self) -> Any:
1266
"""Parse record value as JSON"""
1267
```
1268
1269
### CloudFormation Events
1270
1271
Data classes for AWS CloudFormation events.
1272
1273
```python { .api }
1274
class CloudFormationCustomResourceEvent:
1275
"""CloudFormation custom resource event"""
1276
1277
@property
1278
def request_type(self) -> str:
1279
"""Request type (Create, Update, Delete)"""
1280
1281
@property
1282
def response_url(self) -> str:
1283
"""CloudFormation response URL"""
1284
1285
@property
1286
def stack_id(self) -> str:
1287
"""CloudFormation stack ID"""
1288
1289
@property
1290
def request_id(self) -> str:
1291
"""Request ID"""
1292
1293
@property
1294
def resource_type(self) -> str:
1295
"""Custom resource type"""
1296
1297
@property
1298
def logical_resource_id(self) -> str:
1299
"""Logical resource ID"""
1300
1301
@property
1302
def resource_properties(self) -> Dict[str, Any]:
1303
"""Resource properties"""
1304
1305
@property
1306
def old_resource_properties(self) -> Dict[str, Any] | None:
1307
"""Old resource properties (Update only)"""
1308
```
1309
1310
### Transfer Family Events
1311
1312
Data classes for AWS Transfer Family events.
1313
1314
```python { .api }
1315
class TransferFamilyAuthorizer:
1316
"""Transfer Family custom authorizer event"""
1317
1318
@property
1319
def username(self) -> str:
1320
"""Username attempting authentication"""
1321
1322
@property
1323
def password(self) -> str:
1324
"""Password for authentication"""
1325
1326
@property
1327
def protocol(self) -> str:
1328
"""Transfer protocol (SFTP, FTPS, FTP)"""
1329
1330
@property
1331
def server_id(self) -> str:
1332
"""Transfer Family server ID"""
1333
1334
@property
1335
def source_ip(self) -> str:
1336
"""Source IP address"""
1337
1338
class TransferFamilyAuthorizerResponse:
1339
"""Transfer Family authorizer response"""
1340
1341
def __init__(
1342
self,
1343
role: str = None,
1344
policy: str = None,
1345
home_directory: str = None,
1346
home_directory_type: str = "PATH",
1347
home_directory_details: List[Dict[str, str]] = None,
1348
posix_profile: Dict[str, int] = None,
1349
public_key_id: str = None,
1350
):
1351
"""
1352
Create Transfer Family authorizer response.
1353
1354
Parameters:
1355
- role: IAM role ARN for the user
1356
- policy: Session policy JSON
1357
- home_directory: User's home directory
1358
- home_directory_type: Type of home directory (PATH or LOGICAL)
1359
- home_directory_details: Logical directory mappings
1360
- posix_profile: POSIX profile (Uid, Gid, SecondaryGids)
1361
- public_key_id: Public key ID
1362
"""
1363
```
1364
1365
## Usage Examples
1366
1367
### API Gateway Event Processing
1368
1369
```python
1370
from aws_lambda_powertools.utilities.data_classes import APIGatewayProxyEvent, event_source
1371
from aws_lambda_powertools.utilities.typing import LambdaContext
1372
import json
1373
1374
@event_source(data_class=APIGatewayProxyEvent)
1375
def lambda_handler(event: APIGatewayProxyEvent, context: LambdaContext) -> dict:
1376
# Access request properties
1377
method = event.request_context["httpMethod"]
1378
path = event.request_context["path"]
1379
1380
# Get headers (case-insensitive)
1381
content_type = event.get_header_value("content-type", "application/json")
1382
auth_header = event.get_header_value("Authorization")
1383
1384
# Get query parameters
1385
page = event.get_query_string_value("page", "1")
1386
limit = event.get_query_string_value("limit", "10")
1387
1388
# Parse JSON body if present
1389
request_data = None
1390
if event.body:
1391
request_data = event.json_body
1392
1393
# Process based on method and path
1394
if method == "GET" and path == "/users":
1395
users = get_users(page=int(page), limit=int(limit))
1396
return {
1397
"statusCode": 200,
1398
"headers": {"Content-Type": "application/json"},
1399
"body": json.dumps({"users": users, "page": page, "limit": limit})
1400
}
1401
1402
elif method == "POST" and path == "/users":
1403
if not request_data:
1404
return {
1405
"statusCode": 400,
1406
"body": json.dumps({"error": "Request body required"})
1407
}
1408
1409
user = create_user(request_data)
1410
return {
1411
"statusCode": 201,
1412
"headers": {"Content-Type": "application/json"},
1413
"body": json.dumps(user)
1414
}
1415
1416
elif method == "GET" and event.path_parameters:
1417
user_id = event.path_parameters.get("id")
1418
if user_id:
1419
user = get_user(user_id)
1420
if user:
1421
return {
1422
"statusCode": 200,
1423
"headers": {"Content-Type": "application/json"},
1424
"body": json.dumps(user)
1425
}
1426
else:
1427
return {"statusCode": 404, "body": json.dumps({"error": "User not found"})}
1428
1429
return {"statusCode": 404, "body": json.dumps({"error": "Route not found"})}
1430
```
1431
1432
### SQS Message Processing
1433
1434
```python
1435
from aws_lambda_powertools.utilities.data_classes import SQSEvent, event_source
1436
from aws_lambda_powertools.utilities.typing import LambdaContext
1437
import json
1438
1439
@event_source(data_class=SQSEvent)
1440
def lambda_handler(event: SQSEvent, context: LambdaContext) -> dict:
1441
success_count = 0
1442
error_count = 0
1443
1444
# Process each SQS record
1445
for record in event.records:
1446
try:
1447
# Access record properties
1448
message_id = record.message_id
1449
receipt_handle = record.receipt_handle
1450
1451
# Parse message body
1452
message_data = record.json_body
1453
1454
# Check message attributes
1455
message_type = None
1456
if record.message_attributes:
1457
message_type_attr = record.message_attributes.get("MessageType")
1458
if message_type_attr:
1459
message_type = message_type_attr.get("stringValue")
1460
1461
# Process based on message type
1462
if message_type == "order":
1463
process_order(message_data)
1464
elif message_type == "payment":
1465
process_payment(message_data)
1466
else:
1467
# Default processing
1468
process_generic_message(message_data)
1469
1470
success_count += 1
1471
1472
except Exception as e:
1473
error_count += 1
1474
print(f"Failed to process message {record.message_id}: {str(e)}")
1475
# In batch processing, you might want to raise to trigger partial batch failure
1476
1477
return {
1478
"statusCode": 200,
1479
"body": json.dumps({
1480
"processed": success_count,
1481
"errors": error_count
1482
})
1483
}
1484
1485
def process_order(order_data: dict):
1486
"""Process order message"""
1487
order_id = order_data.get("orderId")
1488
customer_id = order_data.get("customerId")
1489
1490
# Order processing logic
1491
print(f"Processing order {order_id} for customer {customer_id}")
1492
1493
def process_payment(payment_data: dict):
1494
"""Process payment message"""
1495
payment_id = payment_data.get("paymentId")
1496
amount = payment_data.get("amount")
1497
1498
# Payment processing logic
1499
print(f"Processing payment {payment_id} for amount ${amount}")
1500
```
1501
1502
### S3 Event Handling
1503
1504
```python
1505
from aws_lambda_powertools.utilities.data_classes import S3Event, event_source
1506
from aws_lambda_powertools.utilities.typing import LambdaContext
1507
import boto3
1508
from urllib.parse import unquote_plus
1509
1510
s3_client = boto3.client("s3")
1511
1512
@event_source(data_class=S3Event)
1513
def lambda_handler(event: S3Event, context: LambdaContext) -> dict:
1514
processed_objects = []
1515
1516
for record in event.records:
1517
# Get S3 object information
1518
bucket_name = record.bucket_name
1519
object_key = record.object_key # Already URL decoded
1520
event_name = record.event_name
1521
object_size = record.object_size
1522
1523
print(f"Processing {event_name} event for {bucket_name}/{object_key}")
1524
print(f"Object size: {object_size} bytes")
1525
1526
# Handle different S3 events
1527
if event_name.startswith("ObjectCreated"):
1528
result = handle_object_created(bucket_name, object_key, record)
1529
elif event_name.startswith("ObjectRemoved"):
1530
result = handle_object_removed(bucket_name, object_key, record)
1531
else:
1532
result = {"status": "ignored", "event": event_name}
1533
1534
processed_objects.append({
1535
"bucket": bucket_name,
1536
"key": object_key,
1537
"event": event_name,
1538
"result": result
1539
})
1540
1541
return {
1542
"statusCode": 200,
1543
"processedObjects": processed_objects
1544
}
1545
1546
def handle_object_created(bucket: str, key: str, record) -> dict:
1547
"""Handle S3 object creation"""
1548
# Check file extension
1549
if key.lower().endswith(('.jpg', '.jpeg', '.png', '.gif')):
1550
# Process image file
1551
return process_image_file(bucket, key)
1552
elif key.lower().endswith('.json'):
1553
# Process JSON data file
1554
return process_json_file(bucket, key)
1555
elif key.lower().endswith('.csv'):
1556
# Process CSV file
1557
return process_csv_file(bucket, key)
1558
else:
1559
return {"status": "skipped", "reason": "unsupported_file_type"}
1560
1561
def handle_object_removed(bucket: str, key: str, record) -> dict:
1562
"""Handle S3 object removal"""
1563
# Cleanup related resources
1564
cleanup_related_data(bucket, key)
1565
return {"status": "cleaned_up"}
1566
1567
def process_image_file(bucket: str, key: str) -> dict:
1568
"""Process uploaded image file"""
1569
try:
1570
# Example: Generate thumbnail
1571
response = s3_client.get_object(Bucket=bucket, Key=key)
1572
image_data = response['Body'].read()
1573
1574
# Image processing logic here
1575
# thumbnail = create_thumbnail(image_data)
1576
1577
# Save thumbnail back to S3
1578
thumbnail_key = f"thumbnails/{key}"
1579
# s3_client.put_object(Bucket=bucket, Key=thumbnail_key, Body=thumbnail)
1580
1581
return {"status": "processed", "thumbnail_key": thumbnail_key}
1582
except Exception as e:
1583
return {"status": "error", "error": str(e)}
1584
```
1585
1586
### DynamoDB Streams Processing
1587
1588
```python
1589
from aws_lambda_powertools.utilities.data_classes import DynamoDBStreamEvent, event_source
1590
from aws_lambda_powertools.utilities.typing import LambdaContext
1591
import boto3
1592
import json
1593
1594
# Initialize AWS services
1595
ses_client = boto3.client("ses")
1596
sns_client = boto3.client("sns")
1597
1598
@event_source(data_class=DynamoDBStreamEvent)
1599
def lambda_handler(event: DynamoDBStreamEvent, context: LambdaContext) -> dict:
1600
processed_records = []
1601
1602
for record in event.records:
1603
event_name = record.event_name # INSERT, MODIFY, REMOVE
1604
1605
try:
1606
if event_name == "INSERT":
1607
result = handle_insert(record)
1608
elif event_name == "MODIFY":
1609
result = handle_modify(record)
1610
elif event_name == "REMOVE":
1611
result = handle_remove(record)
1612
else:
1613
result = {"status": "ignored"}
1614
1615
processed_records.append({
1616
"eventName": event_name,
1617
"eventId": record.event_id,
1618
"result": result
1619
})
1620
1621
except Exception as e:
1622
processed_records.append({
1623
"eventName": event_name,
1624
"eventId": record.event_id,
1625
"error": str(e)
1626
})
1627
1628
return {"processedRecords": processed_records}
1629
1630
def handle_insert(record) -> dict:
1631
"""Handle new item insertion"""
1632
new_image = record.dynamodb.get("NewImage", {})
1633
1634
# Extract item data (DynamoDB attribute format)
1635
item_type = new_image.get("type", {}).get("S", "")
1636
1637
if item_type == "user":
1638
return handle_new_user(new_image)
1639
elif item_type == "order":
1640
return handle_new_order(new_image)
1641
else:
1642
return {"status": "unknown_type", "type": item_type}
1643
1644
def handle_modify(record) -> dict:
1645
"""Handle item modification"""
1646
old_image = record.dynamodb.get("OldImage", {})
1647
new_image = record.dynamodb.get("NewImage", {})
1648
1649
# Compare status changes
1650
old_status = old_image.get("status", {}).get("S", "")
1651
new_status = new_image.get("status", {}).get("S", "")
1652
1653
if old_status != new_status:
1654
return handle_status_change(old_image, new_image, old_status, new_status)
1655
1656
return {"status": "no_significant_changes"}
1657
1658
def handle_remove(record) -> dict:
1659
"""Handle item removal"""
1660
old_image = record.dynamodb.get("OldImage", {})
1661
1662
# Cleanup related resources
1663
item_id = old_image.get("id", {}).get("S", "")
1664
item_type = old_image.get("type", {}).get("S", "")
1665
1666
cleanup_item(item_id, item_type)
1667
1668
return {"status": "cleaned_up", "item_id": item_id}
1669
1670
def handle_new_user(user_data: dict) -> dict:
1671
"""Send welcome email to new user"""
1672
email = user_data.get("email", {}).get("S", "")
1673
name = user_data.get("name", {}).get("S", "")
1674
1675
if email and name:
1676
send_welcome_email(email, name)
1677
return {"status": "welcome_email_sent", "email": email}
1678
1679
return {"status": "insufficient_data"}
1680
1681
def handle_new_order(order_data: dict) -> dict:
1682
"""Process new order"""
1683
order_id = order_data.get("orderId", {}).get("S", "")
1684
customer_id = order_data.get("customerId", {}).get("S", "")
1685
1686
# Send order confirmation
1687
notify_order_created(order_id, customer_id)
1688
1689
return {"status": "order_notification_sent", "order_id": order_id}
1690
1691
def handle_status_change(old_image: dict, new_image: dict, old_status: str, new_status: str) -> dict:
1692
"""Handle status changes"""
1693
item_id = new_image.get("id", {}).get("S", "")
1694
1695
if new_status == "completed":
1696
# Handle completion
1697
handle_completion(item_id, new_image)
1698
elif new_status == "cancelled":
1699
# Handle cancellation
1700
handle_cancellation(item_id, old_image)
1701
1702
return {
1703
"status": "status_change_processed",
1704
"old_status": old_status,
1705
"new_status": new_status,
1706
"item_id": item_id
1707
}
1708
```
1709
1710
### Kinesis Streams Processing
1711
1712
```python
1713
from aws_lambda_powertools.utilities.data_classes import KinesisStreamEvent, event_source
1714
from aws_lambda_powertools.utilities.typing import LambdaContext
1715
import json
1716
import base64
1717
1718
@event_source(data_class=KinesisStreamEvent)
1719
def lambda_handler(event: KinesisStreamEvent, context: LambdaContext) -> dict:
1720
processed_records = 0
1721
total_bytes = 0
1722
1723
for record in event.records:
1724
try:
1725
# Access Kinesis record properties
1726
partition_key = record.partition_key
1727
sequence_number = record.sequence_number
1728
1729
# Decode record data
1730
record_data = record.data_as_json # Automatically decodes base64 and parses JSON
1731
1732
# Process the record
1733
process_kinesis_record(record_data, partition_key, sequence_number)
1734
1735
processed_records += 1
1736
total_bytes += len(record.data_as_bytes)
1737
1738
except json.JSONDecodeError as e:
1739
print(f"Failed to parse JSON for record {record.sequence_number}: {str(e)}")
1740
# Handle non-JSON data
1741
text_data = record.data_as_text
1742
process_text_record(text_data, record.partition_key)
1743
1744
except Exception as e:
1745
print(f"Failed to process record {record.sequence_number}: {str(e)}")
1746
1747
return {
1748
"statusCode": 200,
1749
"processedRecords": processed_records,
1750
"totalBytes": total_bytes
1751
}
1752
1753
def process_kinesis_record(data: dict, partition_key: str, sequence_number: str):
1754
"""Process individual Kinesis record"""
1755
record_type = data.get("type", "unknown")
1756
timestamp = data.get("timestamp")
1757
1758
print(f"Processing {record_type} record from partition {partition_key}")
1759
1760
if record_type == "click_event":
1761
process_click_event(data)
1762
elif record_type == "page_view":
1763
process_page_view(data)
1764
elif record_type == "purchase":
1765
process_purchase_event(data)
1766
else:
1767
print(f"Unknown record type: {record_type}")
1768
1769
def process_click_event(event_data: dict):
1770
"""Process click tracking event"""
1771
user_id = event_data.get("user_id")
1772
element_id = event_data.get("element_id")
1773
page = event_data.get("page")
1774
1775
# Analytics processing
1776
print(f"Click: user {user_id} clicked {element_id} on {page}")
1777
1778
def process_page_view(event_data: dict):
1779
"""Process page view event"""
1780
user_id = event_data.get("user_id")
1781
page = event_data.get("page")
1782
referrer = event_data.get("referrer")
1783
1784
# Page view analytics
1785
print(f"Page view: user {user_id} viewed {page} from {referrer}")
1786
```
1787
1788
## Types
1789
1790
```python { .api }
1791
from typing import Dict, Any, List, Optional, Union
1792
from aws_lambda_powertools.utilities.typing import LambdaContext
1793
1794
# Event source decorator signature
1795
EventSourceDecorator = Callable[[Callable], Callable]
1796
1797
# Common property types used across data classes
1798
Headers = Dict[str, str]
1799
QueryParameters = Optional[Dict[str, str]]
1800
PathParameters = Optional[Dict[str, str]]
1801
MultiValueHeaders = Optional[Dict[str, List[str]]]
1802
MultiValueQueryParameters = Optional[Dict[str, List[str]]]
1803
1804
# Request context types (vary by service)
1805
APIGatewayRequestContext = Dict[str, Any]
1806
ALBRequestContext = Dict[str, Any]
1807
LambdaFunctionUrlRequestContext = Dict[str, Any]
1808
VPCLatticeRequestContext = Dict[str, Any]
1809
1810
# Record types for batch processing
1811
SQSRecords = List[SQSRecord]
1812
SNSRecords = List[SNSRecord]
1813
S3Records = List[S3Record]
1814
DynamoDBRecords = List[DynamoDBRecord]
1815
KinesisRecords = List[KinesisStreamRecord]
1816
```