modmex-lambda 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. modmex_lambda/__init__.py +62 -0
  2. modmex_lambda/data_classes/__init__.py +49 -0
  3. modmex_lambda/data_classes/api_gateway_authorizer_event.py +38 -0
  4. modmex_lambda/data_classes/api_gateway_proxy_event.py +328 -0
  5. modmex_lambda/data_classes/api_gateway_websocket_event.py +40 -0
  6. modmex_lambda/data_classes/cognito_user_pool_event.py +599 -0
  7. modmex_lambda/data_classes/common.py +441 -0
  8. modmex_lambda/event_handler/__init__.py +45 -0
  9. modmex_lambda/event_handler/api_gateway.py +331 -0
  10. modmex_lambda/event_handler/constants.py +3 -0
  11. modmex_lambda/event_handler/content_types.py +13 -0
  12. modmex_lambda/event_handler/cors.py +97 -0
  13. modmex_lambda/event_handler/dependencies/__init__.py +0 -0
  14. modmex_lambda/event_handler/dependencies/compat.py +231 -0
  15. modmex_lambda/event_handler/dependencies/dependant.py +279 -0
  16. modmex_lambda/event_handler/dependencies/dependency_middleware.py +423 -0
  17. modmex_lambda/event_handler/dependencies/depends.py +184 -0
  18. modmex_lambda/event_handler/dependencies/params.py +317 -0
  19. modmex_lambda/event_handler/dependencies/types.py +14 -0
  20. modmex_lambda/event_handler/exception_handler.py +70 -0
  21. modmex_lambda/event_handler/exceptions.py +72 -0
  22. modmex_lambda/event_handler/gateway_response.py +96 -0
  23. modmex_lambda/event_handler/middlewares.py +33 -0
  24. modmex_lambda/event_handler/params.py +44 -0
  25. modmex_lambda/event_handler/request.py +70 -0
  26. modmex_lambda/event_handler/response.py +60 -0
  27. modmex_lambda/event_handler/routing.py +507 -0
  28. modmex_lambda/event_handler/routing_fallbacks.py +92 -0
  29. modmex_lambda/event_handler/types.py +31 -0
  30. modmex_lambda/event_sources.py +53 -0
  31. modmex_lambda/exceptions.py +3 -0
  32. modmex_lambda/logging.py +99 -0
  33. modmex_lambda/params.py +3 -0
  34. modmex_lambda/parser.py +47 -0
  35. modmex_lambda/request.py +3 -0
  36. modmex_lambda/resolver.py +3 -0
  37. modmex_lambda/response.py +3 -0
  38. modmex_lambda/routing.py +3 -0
  39. modmex_lambda/shared/__init__.py +0 -0
  40. modmex_lambda/shared/cookies.py +84 -0
  41. modmex_lambda/shared/headers_serializer.py +65 -0
  42. modmex_lambda/shared/json_encoder.py +53 -0
  43. modmex_lambda/shared/types.py +4 -0
  44. modmex_lambda/validation.py +178 -0
  45. modmex_lambda-0.1.0.dist-info/METADATA +375 -0
  46. modmex_lambda-0.1.0.dist-info/RECORD +48 -0
  47. modmex_lambda-0.1.0.dist-info/WHEEL +4 -0
  48. modmex_lambda-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,599 @@
1
+ """Cognito User Pool trigger event data classes."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from modmex_lambda.data_classes.common import DictWrapper
8
+
9
+
10
+ class CallerContext(DictWrapper):
11
+ @property
12
+ def aws_sdk_version(self) -> str:
13
+ return str(self.get("awsSdkVersion") or "")
14
+
15
+ @property
16
+ def client_id(self) -> str:
17
+ return str(self.get("clientId") or "")
18
+
19
+
20
+ class BaseTriggerEvent(DictWrapper):
21
+ @property
22
+ def version(self) -> str:
23
+ return str(self.get("version") or "")
24
+
25
+ @property
26
+ def trigger_source(self) -> str:
27
+ return str(self.get("triggerSource") or "")
28
+
29
+ @property
30
+ def region(self) -> str:
31
+ return str(self.get("region") or "")
32
+
33
+ @property
34
+ def user_pool_id(self) -> str:
35
+ return str(self.get("userPoolId") or "")
36
+
37
+ @property
38
+ def user_name(self) -> str:
39
+ return str(self.get("userName") or "")
40
+
41
+ @property
42
+ def caller_context(self) -> CallerContext:
43
+ return CallerContext(self.get("callerContext") or {})
44
+
45
+ @property
46
+ def request(self) -> dict[str, Any]:
47
+ return dict(self.get("request") or {})
48
+
49
+ @property
50
+ def response(self) -> dict[str, Any]:
51
+ return dict(self.get("response") or {})
52
+
53
+
54
+ class PreSignUpTriggerEventRequest(DictWrapper):
55
+ @property
56
+ def user_attributes(self) -> dict[str, Any]:
57
+ return dict(self.get("userAttributes") or {})
58
+
59
+ @property
60
+ def validation_data(self) -> dict[str, Any]:
61
+ return dict(self.get("validationData") or {})
62
+
63
+ @property
64
+ def client_metadata(self) -> dict[str, Any]:
65
+ return dict(self.get("clientMetadata") or {})
66
+
67
+
68
+ class PreSignUpTriggerEventResponse(DictWrapper):
69
+ @property
70
+ def auto_confirm_user(self) -> bool:
71
+ return bool(self.get("autoConfirmUser"))
72
+
73
+ @auto_confirm_user.setter
74
+ def auto_confirm_user(self, value: bool) -> None:
75
+ self._data["autoConfirmUser"] = value
76
+
77
+ @property
78
+ def auto_verify_email(self) -> bool:
79
+ return bool(self.get("autoVerifyEmail"))
80
+
81
+ @auto_verify_email.setter
82
+ def auto_verify_email(self, value: bool) -> None:
83
+ self._data["autoVerifyEmail"] = value
84
+
85
+ @property
86
+ def auto_verify_phone(self) -> bool:
87
+ return bool(self.get("autoVerifyPhone"))
88
+
89
+ @auto_verify_phone.setter
90
+ def auto_verify_phone(self, value: bool) -> None:
91
+ self._data["autoVerifyPhone"] = value
92
+
93
+
94
+ class PreSignUpTriggerEvent(BaseTriggerEvent):
95
+ @property
96
+ def request(self) -> PreSignUpTriggerEventRequest:
97
+ return PreSignUpTriggerEventRequest(self._data.setdefault("request", {}))
98
+
99
+ @property
100
+ def response(self) -> PreSignUpTriggerEventResponse:
101
+ return PreSignUpTriggerEventResponse(self._data.setdefault("response", {}))
102
+
103
+
104
+ class PostConfirmationTriggerEventRequest(DictWrapper):
105
+ @property
106
+ def user_attributes(self) -> dict[str, Any]:
107
+ return dict(self.get("userAttributes") or {})
108
+
109
+ @property
110
+ def client_metadata(self) -> dict[str, Any]:
111
+ return dict(self.get("clientMetadata") or {})
112
+
113
+
114
+ class PostConfirmationTriggerEvent(BaseTriggerEvent):
115
+ @property
116
+ def request(self) -> PostConfirmationTriggerEventRequest:
117
+ return PostConfirmationTriggerEventRequest(self.get("request") or {})
118
+
119
+
120
+ class UserMigrationTriggerEventRequest(DictWrapper):
121
+ @property
122
+ def password(self) -> str:
123
+ return str(self.get("password") or "")
124
+
125
+ @property
126
+ def validation_data(self) -> dict[str, Any]:
127
+ return dict(self.get("validationData") or {})
128
+
129
+ @property
130
+ def client_metadata(self) -> dict[str, Any]:
131
+ return dict(self.get("clientMetadata") or {})
132
+
133
+
134
+ class UserMigrationTriggerEventResponse(DictWrapper):
135
+ @property
136
+ def user_attributes(self) -> dict[str, Any]:
137
+ return dict(self.get("userAttributes") or {})
138
+
139
+ @user_attributes.setter
140
+ def user_attributes(self, value: dict[str, Any]) -> None:
141
+ self._data["userAttributes"] = value
142
+
143
+ @property
144
+ def final_user_status(self) -> str | None:
145
+ value = self.get("finalUserStatus")
146
+ return None if value is None else str(value)
147
+
148
+ @final_user_status.setter
149
+ def final_user_status(self, value: str) -> None:
150
+ self._data["finalUserStatus"] = value
151
+
152
+ @property
153
+ def message_action(self) -> str | None:
154
+ value = self.get("messageAction")
155
+ return None if value is None else str(value)
156
+
157
+ @message_action.setter
158
+ def message_action(self, value: str) -> None:
159
+ self._data["messageAction"] = value
160
+
161
+ @property
162
+ def desired_delivery_mediums(self) -> list[str]:
163
+ return [str(item) for item in (self.get("desiredDeliveryMediums") or [])]
164
+
165
+ @desired_delivery_mediums.setter
166
+ def desired_delivery_mediums(self, value: list[str]) -> None:
167
+ self._data["desiredDeliveryMediums"] = value
168
+
169
+ @property
170
+ def force_alias_creation(self) -> bool | None:
171
+ value = self.get("forceAliasCreation")
172
+ return None if value is None else bool(value)
173
+
174
+ @force_alias_creation.setter
175
+ def force_alias_creation(self, value: bool) -> None:
176
+ self._data["forceAliasCreation"] = value
177
+
178
+ @property
179
+ def enable_sms_mfa(self) -> bool | None:
180
+ value = self.get("enableSMSMFA")
181
+ return None if value is None else bool(value)
182
+
183
+ @enable_sms_mfa.setter
184
+ def enable_sms_mfa(self, value: bool) -> None:
185
+ self._data["enableSMSMFA"] = value
186
+
187
+
188
+ class UserMigrationTriggerEvent(BaseTriggerEvent):
189
+ @property
190
+ def request(self) -> UserMigrationTriggerEventRequest:
191
+ return UserMigrationTriggerEventRequest(self.get("request") or {})
192
+
193
+ @property
194
+ def response(self) -> UserMigrationTriggerEventResponse:
195
+ return UserMigrationTriggerEventResponse(self._data.setdefault("response", {}))
196
+
197
+
198
+ class CustomMessageTriggerEventRequest(DictWrapper):
199
+ @property
200
+ def code_parameter(self) -> str:
201
+ return str(self.get("codeParameter") or "")
202
+
203
+ @property
204
+ def link_parameter(self) -> str:
205
+ return str(self.get("linkParameter") or "")
206
+
207
+ @property
208
+ def username_parameter(self) -> str:
209
+ return str(self.get("usernameParameter") or "")
210
+
211
+ @property
212
+ def user_attributes(self) -> dict[str, Any]:
213
+ return dict(self.get("userAttributes") or {})
214
+
215
+ @property
216
+ def client_metadata(self) -> dict[str, Any]:
217
+ return dict(self.get("clientMetadata") or {})
218
+
219
+
220
+ class CustomMessageTriggerEventResponse(DictWrapper):
221
+ @property
222
+ def sms_message(self) -> str:
223
+ return str(self.get("smsMessage") or "")
224
+
225
+ @sms_message.setter
226
+ def sms_message(self, value: str) -> None:
227
+ self._data["smsMessage"] = value
228
+
229
+ @property
230
+ def email_message(self) -> str:
231
+ return str(self.get("emailMessage") or "")
232
+
233
+ @email_message.setter
234
+ def email_message(self, value: str) -> None:
235
+ self._data["emailMessage"] = value
236
+
237
+ @property
238
+ def email_subject(self) -> str:
239
+ return str(self.get("emailSubject") or "")
240
+
241
+ @email_subject.setter
242
+ def email_subject(self, value: str) -> None:
243
+ self._data["emailSubject"] = value
244
+
245
+
246
+ class CustomMessageTriggerEvent(BaseTriggerEvent):
247
+ @property
248
+ def request(self) -> CustomMessageTriggerEventRequest:
249
+ return CustomMessageTriggerEventRequest(self.get("request") or {})
250
+
251
+ @property
252
+ def response(self) -> CustomMessageTriggerEventResponse:
253
+ return CustomMessageTriggerEventResponse(self._data.setdefault("response", {}))
254
+
255
+
256
+ class PreAuthenticationTriggerEventRequest(DictWrapper):
257
+ @property
258
+ def user_not_found(self) -> bool | None:
259
+ value = self.get("userNotFound")
260
+ return None if value is None else bool(value)
261
+
262
+ @property
263
+ def user_attributes(self) -> dict[str, Any]:
264
+ return dict(self.get("userAttributes") or {})
265
+
266
+ @property
267
+ def validation_data(self) -> dict[str, Any]:
268
+ return dict(self.get("validationData") or {})
269
+
270
+
271
+ class PreAuthenticationTriggerEvent(BaseTriggerEvent):
272
+ @property
273
+ def request(self) -> PreAuthenticationTriggerEventRequest:
274
+ return PreAuthenticationTriggerEventRequest(self.get("request") or {})
275
+
276
+
277
+ class PostAuthenticationTriggerEventRequest(DictWrapper):
278
+ @property
279
+ def new_device_used(self) -> bool:
280
+ return bool(self.get("newDeviceUsed"))
281
+
282
+ @property
283
+ def user_attributes(self) -> dict[str, Any]:
284
+ return dict(self.get("userAttributes") or {})
285
+
286
+ @property
287
+ def client_metadata(self) -> dict[str, Any]:
288
+ return dict(self.get("clientMetadata") or {})
289
+
290
+
291
+ class PostAuthenticationTriggerEvent(BaseTriggerEvent):
292
+ @property
293
+ def request(self) -> PostAuthenticationTriggerEventRequest:
294
+ return PostAuthenticationTriggerEventRequest(self.get("request") or {})
295
+
296
+
297
+ class GroupOverrideDetails(DictWrapper):
298
+ @property
299
+ def groups_to_override(self) -> list[str]:
300
+ return [str(item) for item in (self.get("groupsToOverride") or [])]
301
+
302
+ @groups_to_override.setter
303
+ def groups_to_override(self, value: list[str]) -> None:
304
+ self._data["groupsToOverride"] = value
305
+
306
+ @property
307
+ def iam_roles_to_override(self) -> list[str]:
308
+ return [str(item) for item in (self.get("iamRolesToOverride") or [])]
309
+
310
+ @iam_roles_to_override.setter
311
+ def iam_roles_to_override(self, value: list[str]) -> None:
312
+ self._data["iamRolesToOverride"] = value
313
+
314
+ @property
315
+ def preferred_role(self) -> str:
316
+ return str(self.get("preferredRole") or "")
317
+
318
+ @preferred_role.setter
319
+ def preferred_role(self, value: str) -> None:
320
+ self._data["preferredRole"] = value
321
+
322
+
323
+ class PreTokenGenerationTriggerEventRequest(DictWrapper):
324
+ @property
325
+ def group_configuration(self) -> GroupOverrideDetails:
326
+ return GroupOverrideDetails(self.get("groupConfiguration") or {})
327
+
328
+ @property
329
+ def user_attributes(self) -> dict[str, Any]:
330
+ return dict(self.get("userAttributes") or {})
331
+
332
+ @property
333
+ def client_metadata(self) -> dict[str, Any]:
334
+ return dict(self.get("clientMetadata") or {})
335
+
336
+
337
+ class PreTokenGenerationTriggerV2EventRequest(PreTokenGenerationTriggerEventRequest):
338
+ @property
339
+ def scopes(self) -> list[str]:
340
+ return [str(item) for item in (self.get("scopes") or [])]
341
+
342
+
343
+ class PreTokenGenerationTriggerEventResponse(DictWrapper):
344
+ @property
345
+ def claims_override_details(self) -> dict[str, Any]:
346
+ return dict(self.get("claimsOverrideDetails") or {})
347
+
348
+
349
+ class PreTokenGenerationTriggerV2EventResponse(DictWrapper):
350
+ @property
351
+ def claims_and_scope_override_details(self) -> dict[str, Any]:
352
+ return dict(self.get("claimsAndScopeOverrideDetails") or {})
353
+
354
+
355
+ class PreTokenGenerationTriggerEvent(BaseTriggerEvent):
356
+ @property
357
+ def request(self) -> PreTokenGenerationTriggerEventRequest:
358
+ return PreTokenGenerationTriggerEventRequest(self.get("request") or {})
359
+
360
+ @property
361
+ def response(self) -> PreTokenGenerationTriggerEventResponse:
362
+ return PreTokenGenerationTriggerEventResponse(self._data.setdefault("response", {}))
363
+
364
+
365
+ class PreTokenGenerationV2TriggerEvent(BaseTriggerEvent):
366
+ @property
367
+ def request(self) -> PreTokenGenerationTriggerV2EventRequest:
368
+ return PreTokenGenerationTriggerV2EventRequest(self.get("request") or {})
369
+
370
+ @property
371
+ def response(self) -> PreTokenGenerationTriggerV2EventResponse:
372
+ return PreTokenGenerationTriggerV2EventResponse(self._data.setdefault("response", {}))
373
+
374
+
375
+ class PreTokenGenerationV3TriggerEvent(PreTokenGenerationV2TriggerEvent):
376
+ """Alias for V3 payloads, which currently follow the V2 shape."""
377
+
378
+
379
+ class ChallengeResult(DictWrapper):
380
+ @property
381
+ def challenge_name(self) -> str:
382
+ return str(self.get("challengeName") or "")
383
+
384
+ @property
385
+ def challenge_result(self) -> bool:
386
+ return bool(self.get("challengeResult"))
387
+
388
+ @property
389
+ def challenge_metadata(self) -> str:
390
+ return str(self.get("challengeMetadata") or "")
391
+
392
+
393
+ class DefineAuthChallengeTriggerEventRequest(DictWrapper):
394
+ @property
395
+ def user_attributes(self) -> dict[str, Any]:
396
+ return dict(self.get("userAttributes") or {})
397
+
398
+ @property
399
+ def user_not_found(self) -> bool | None:
400
+ value = self.get("userNotFound")
401
+ return None if value is None else bool(value)
402
+
403
+ @property
404
+ def session(self) -> list[ChallengeResult]:
405
+ return [ChallengeResult(item) for item in (self.get("session") or [])]
406
+
407
+ @property
408
+ def client_metadata(self) -> dict[str, Any]:
409
+ return dict(self.get("clientMetadata") or {})
410
+
411
+
412
+ class DefineAuthChallengeTriggerEventResponse(DictWrapper):
413
+ @property
414
+ def challenge_name(self) -> str:
415
+ return str(self.get("challengeName") or "")
416
+
417
+ @challenge_name.setter
418
+ def challenge_name(self, value: str) -> None:
419
+ self._data["challengeName"] = value
420
+
421
+ @property
422
+ def fail_authentication(self) -> bool:
423
+ return bool(self.get("failAuthentication"))
424
+
425
+ @fail_authentication.setter
426
+ def fail_authentication(self, value: bool) -> None:
427
+ self._data["failAuthentication"] = value
428
+
429
+ @property
430
+ def issue_tokens(self) -> bool:
431
+ return bool(self.get("issueTokens"))
432
+
433
+ @issue_tokens.setter
434
+ def issue_tokens(self, value: bool) -> None:
435
+ self._data["issueTokens"] = value
436
+
437
+
438
+ class DefineAuthChallengeTriggerEvent(BaseTriggerEvent):
439
+ @property
440
+ def request(self) -> DefineAuthChallengeTriggerEventRequest:
441
+ return DefineAuthChallengeTriggerEventRequest(self.get("request") or {})
442
+
443
+ @property
444
+ def response(self) -> DefineAuthChallengeTriggerEventResponse:
445
+ return DefineAuthChallengeTriggerEventResponse(self._data.setdefault("response", {}))
446
+
447
+
448
+ class CreateAuthChallengeTriggerEventRequest(DictWrapper):
449
+ @property
450
+ def user_attributes(self) -> dict[str, Any]:
451
+ return dict(self.get("userAttributes") or {})
452
+
453
+ @property
454
+ def user_not_found(self) -> bool | None:
455
+ value = self.get("userNotFound")
456
+ return None if value is None else bool(value)
457
+
458
+ @property
459
+ def challenge_name(self) -> str:
460
+ return str(self.get("challengeName") or "")
461
+
462
+ @property
463
+ def session(self) -> list[ChallengeResult]:
464
+ return [ChallengeResult(item) for item in (self.get("session") or [])]
465
+
466
+ @property
467
+ def client_metadata(self) -> dict[str, Any]:
468
+ return dict(self.get("clientMetadata") or {})
469
+
470
+
471
+ class CreateAuthChallengeTriggerEventResponse(DictWrapper):
472
+ @property
473
+ def public_challenge_parameters(self) -> dict[str, Any]:
474
+ return dict(self.get("publicChallengeParameters") or {})
475
+
476
+ @public_challenge_parameters.setter
477
+ def public_challenge_parameters(self, value: dict[str, Any]) -> None:
478
+ self._data["publicChallengeParameters"] = value
479
+
480
+ @property
481
+ def private_challenge_parameters(self) -> dict[str, Any]:
482
+ return dict(self.get("privateChallengeParameters") or {})
483
+
484
+ @private_challenge_parameters.setter
485
+ def private_challenge_parameters(self, value: dict[str, Any]) -> None:
486
+ self._data["privateChallengeParameters"] = value
487
+
488
+ @property
489
+ def challenge_metadata(self) -> str:
490
+ return str(self.get("challengeMetadata") or "")
491
+
492
+ @challenge_metadata.setter
493
+ def challenge_metadata(self, value: str) -> None:
494
+ self._data["challengeMetadata"] = value
495
+
496
+
497
+ class CreateAuthChallengeTriggerEvent(BaseTriggerEvent):
498
+ @property
499
+ def request(self) -> CreateAuthChallengeTriggerEventRequest:
500
+ return CreateAuthChallengeTriggerEventRequest(self.get("request") or {})
501
+
502
+ @property
503
+ def response(self) -> CreateAuthChallengeTriggerEventResponse:
504
+ return CreateAuthChallengeTriggerEventResponse(self._data.setdefault("response", {}))
505
+
506
+
507
+ class VerifyAuthChallengeResponseTriggerEventRequest(DictWrapper):
508
+ @property
509
+ def user_attributes(self) -> dict[str, Any]:
510
+ return dict(self.get("userAttributes") or {})
511
+
512
+ @property
513
+ def private_challenge_parameters(self) -> dict[str, Any]:
514
+ return dict(self.get("privateChallengeParameters") or {})
515
+
516
+ @property
517
+ def challenge_answer(self) -> Any:
518
+ return self.get("challengeAnswer")
519
+
520
+ @property
521
+ def client_metadata(self) -> dict[str, Any]:
522
+ return dict(self.get("clientMetadata") or {})
523
+
524
+ @property
525
+ def user_not_found(self) -> bool | None:
526
+ value = self.get("userNotFound")
527
+ return None if value is None else bool(value)
528
+
529
+
530
+ class VerifyAuthChallengeResponseTriggerEventResponse(DictWrapper):
531
+ @property
532
+ def answer_correct(self) -> bool:
533
+ return bool(self.get("answerCorrect"))
534
+
535
+ @answer_correct.setter
536
+ def answer_correct(self, value: bool) -> None:
537
+ self._data["answerCorrect"] = value
538
+
539
+
540
+ class VerifyAuthChallengeResponseTriggerEvent(BaseTriggerEvent):
541
+ @property
542
+ def request(self) -> VerifyAuthChallengeResponseTriggerEventRequest:
543
+ return VerifyAuthChallengeResponseTriggerEventRequest(self.get("request") or {})
544
+
545
+ @property
546
+ def response(self) -> VerifyAuthChallengeResponseTriggerEventResponse:
547
+ return VerifyAuthChallengeResponseTriggerEventResponse(self._data.setdefault("response", {}))
548
+
549
+
550
+ class CustomEmailSenderTriggerEventRequest(DictWrapper):
551
+ @property
552
+ def type(self) -> str:
553
+ return str(self.get("type") or "")
554
+
555
+ @property
556
+ def code(self) -> str:
557
+ return str(self.get("code") or "")
558
+
559
+ @property
560
+ def user_attributes(self) -> dict[str, Any]:
561
+ return dict(self.get("userAttributes") or {})
562
+
563
+ @property
564
+ def client_metadata(self) -> dict[str, Any]:
565
+ return dict(self.get("clientMetadata") or {})
566
+
567
+
568
+ class CustomEmailSenderTriggerEvent(BaseTriggerEvent):
569
+ @property
570
+ def request(self) -> CustomEmailSenderTriggerEventRequest:
571
+ return CustomEmailSenderTriggerEventRequest(self.get("request") or {})
572
+
573
+
574
+ class CustomSMSSenderTriggerEventRequest(DictWrapper):
575
+ @property
576
+ def type(self) -> str:
577
+ return str(self.get("type") or "")
578
+
579
+ @property
580
+ def code(self) -> str:
581
+ return str(self.get("code") or "")
582
+
583
+ @property
584
+ def user_attributes(self) -> dict[str, Any]:
585
+ return dict(self.get("userAttributes") or {})
586
+
587
+ @property
588
+ def client_metadata(self) -> dict[str, Any]:
589
+ return dict(self.get("clientMetadata") or {})
590
+
591
+
592
+ class CustomSMSSenderTriggerEvent(BaseTriggerEvent):
593
+ @property
594
+ def request(self) -> CustomSMSSenderTriggerEventRequest:
595
+ return CustomSMSSenderTriggerEventRequest(self.get("request") or {})
596
+
597
+
598
+ class CognitoUserPoolEvent(BaseTriggerEvent):
599
+ """Generic Cognito User Pool event wrapper kept for compatibility."""