|
| 1 | +from __future__ import annotations |
| 2 | + |
1 | 3 | import base64
|
| 4 | +import dataclasses |
2 | 5 | import itertools
|
3 | 6 | import logging
|
4 | 7 | import os
|
5 | 8 | import warnings
|
6 | 9 | from binascii import Error as BinAsciiError
|
7 |
| -from typing import Dict, Generator, Optional, Union, overload |
| 10 | +from typing import Any, Dict, Generator, Optional, Union, overload |
8 | 11 |
|
9 | 12 | from aws_lambda_powertools.shared import constants
|
10 | 13 |
|
@@ -121,3 +124,43 @@ def powertools_debug_is_set() -> bool:
|
121 | 124 | def slice_dictionary(data: Dict, chunk_size: int) -> Generator[Dict, None, None]:
|
122 | 125 | for _ in range(0, len(data), chunk_size):
|
123 | 126 | yield {dict_key: data[dict_key] for dict_key in itertools.islice(data, chunk_size)}
|
| 127 | + |
| 128 | + |
| 129 | +def extract_event_from_common_models(data: Any) -> Dict | Any: |
| 130 | + """Extract raw event from common types used in Powertools |
| 131 | +
|
| 132 | + If event cannot be extracted, return received data as is. |
| 133 | +
|
| 134 | + Common models: |
| 135 | +
|
| 136 | + - Event Source Data Classes (DictWrapper) |
| 137 | + - Python Dataclasses |
| 138 | + - Pydantic Models (BaseModel) |
| 139 | +
|
| 140 | + Parameters |
| 141 | + ---------- |
| 142 | + data : Any |
| 143 | + Original event, a potential instance of DictWrapper/BaseModel/Dataclass |
| 144 | +
|
| 145 | + Notes |
| 146 | + ----- |
| 147 | +
|
| 148 | + Why not using static type for function argument? |
| 149 | +
|
| 150 | + DictWrapper would cause a circular import. Pydantic BaseModel could |
| 151 | + cause a ModuleNotFound or trigger init reflection worsening cold start. |
| 152 | + """ |
| 153 | + # Short-circuit most common type first for perf |
| 154 | + if isinstance(data, dict): |
| 155 | + return data |
| 156 | + |
| 157 | + # Is it an Event Source Data Class? |
| 158 | + if getattr(data, "raw_event", None): |
| 159 | + return data.raw_event |
| 160 | + |
| 161 | + # Is it a Pydantic Model? |
| 162 | + if callable(getattr(data, "dict", None)): |
| 163 | + return data.dict() |
| 164 | + |
| 165 | + # Is it a Dataclass? If not return as is |
| 166 | + return dataclasses.asdict(data) if dataclasses.is_dataclass(data) else data |
0 commit comments