|
1 | 1 | from enum import Enum
|
2 |
| -from typing import Dict, Iterator, List, Optional |
| 2 | +from typing import Any, Dict, Iterator, List, Optional, Union |
3 | 3 |
|
4 | 4 | from aws_lambda_powertools.utilities.data_classes.common import DictWrapper
|
5 | 5 |
|
6 | 6 |
|
| 7 | +class AttributeValueType(Enum): |
| 8 | + Binary = "B" |
| 9 | + BinarySet = "BS" |
| 10 | + Boolean = "BOOL" |
| 11 | + List = "L" |
| 12 | + Map = "M" |
| 13 | + Number = "N" |
| 14 | + NumberSet = "NS" |
| 15 | + Null = "NULL" |
| 16 | + String = "S" |
| 17 | + StringSet = "SS" |
| 18 | + |
| 19 | + |
7 | 20 | class AttributeValue(DictWrapper):
|
8 | 21 | """Represents the data for an attribute
|
9 | 22 |
|
10 |
| - Documentation: https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_streams_AttributeValue.html |
| 23 | + Documentation: |
| 24 | + -------------- |
| 25 | + - https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_streams_AttributeValue.html |
| 26 | + - https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html |
11 | 27 | """
|
12 | 28 |
|
| 29 | + def __init__(self, data: Dict[str, Any]): |
| 30 | + """AttributeValue constructor |
| 31 | +
|
| 32 | + Parameters |
| 33 | + ---------- |
| 34 | + data: Dict[str, Any] |
| 35 | + Raw lambda event dict |
| 36 | + """ |
| 37 | + super().__init__(data) |
| 38 | + self.dynamodb_type = list(data.keys())[0] |
| 39 | + |
13 | 40 | @property
|
14 | 41 | def b_value(self) -> Optional[str]:
|
15 | 42 | """An attribute of type Base64-encoded binary data object
|
@@ -106,6 +133,29 @@ def ss_value(self) -> Optional[List[str]]:
|
106 | 133 | """
|
107 | 134 | return self.get("SS")
|
108 | 135 |
|
| 136 | + @property |
| 137 | + def get_type(self) -> AttributeValueType: |
| 138 | + """Get the attribute value type based on the contained data""" |
| 139 | + return AttributeValueType(self.dynamodb_type) |
| 140 | + |
| 141 | + @property |
| 142 | + def l_value(self) -> Optional[List["AttributeValue"]]: |
| 143 | + """Alias of list_value""" |
| 144 | + return self.list_value |
| 145 | + |
| 146 | + @property |
| 147 | + def m_value(self) -> Optional[Dict[str, "AttributeValue"]]: |
| 148 | + """Alias of map_value""" |
| 149 | + return self.map_value |
| 150 | + |
| 151 | + @property |
| 152 | + def get_value(self) -> Union[Optional[bool], Optional[str], Optional[List], Optional[Dict]]: |
| 153 | + """Get the attribute value""" |
| 154 | + try: |
| 155 | + return getattr(self, f"{self.dynamodb_type.lower()}_value") |
| 156 | + except AttributeError: |
| 157 | + raise TypeError(f"Dynamodb type {self.dynamodb_type} is not supported") |
| 158 | + |
109 | 159 |
|
110 | 160 | def _attribute_value_dict(attr_values: Dict[str, dict], key: str) -> Optional[Dict[str, AttributeValue]]:
|
111 | 161 | """A dict of type String to AttributeValue object map
|
@@ -224,6 +274,29 @@ class DynamoDBStreamEvent(DictWrapper):
|
224 | 274 | Documentation:
|
225 | 275 | -------------
|
226 | 276 | - https://docs.aws.amazon.com/lambda/latest/dg/with-ddb.html
|
| 277 | +
|
| 278 | + Example |
| 279 | + ------- |
| 280 | + **Process dynamodb stream events and use get_type and get_value for handling conversions** |
| 281 | +
|
| 282 | + from aws_lambda_powertools.utilities.data_classes import event_source, DynamoDBStreamEvent |
| 283 | + from aws_lambda_powertools.utilities.data_classes.dynamo_db_stream_event import ( |
| 284 | + AttributeValueType, |
| 285 | + AttributeValue, |
| 286 | + ) |
| 287 | + from aws_lambda_powertools.utilities.typing import LambdaContext |
| 288 | +
|
| 289 | +
|
| 290 | + @event_source(data_class=DynamoDBStreamEvent) |
| 291 | + def lambda_handler(event: DynamoDBStreamEvent, context: LambdaContext): |
| 292 | + for record in event.records: |
| 293 | + key: AttributeValue = record.dynamodb.keys["id"] |
| 294 | + if key == AttributeValueType.Number: |
| 295 | + assert key.get_value == key.n_value |
| 296 | + print(key.get_value) |
| 297 | + elif key == AttributeValueType.Map: |
| 298 | + assert key.get_value == key.map_value |
| 299 | + print(key.get_value) |
227 | 300 | """
|
228 | 301 |
|
229 | 302 | @property
|
|
0 commit comments