|
21 | 21 | import enum |
22 | 22 | import functools |
23 | 23 | import logging |
| 24 | +import re |
24 | 25 | import typing |
25 | 26 | from typing import Any, Callable, FrozenSet, Optional, Union, get_args, get_origin |
26 | 27 | import uuid |
@@ -142,25 +143,38 @@ def get_value_by_path(data: Any, keys: list[str]) -> Any: |
142 | 143 | return data |
143 | 144 |
|
144 | 145 |
|
145 | | -def convert_to_dict(obj: object) -> Any: |
| 146 | +def maybe_snake_to_camel(snake_str: str, convert: bool = True) -> str: |
| 147 | + """Converts a snake_case string to CamelCase, if convert is True.""" |
| 148 | + if not convert: |
| 149 | + return snake_str |
| 150 | + return re.sub(r'_([a-zA-Z])', lambda match: match.group(1).upper(), snake_str) |
| 151 | + |
| 152 | + |
| 153 | +def convert_to_dict(obj: object, convert_keys: bool = False) -> Any: |
146 | 154 | """Recursively converts a given object to a dictionary. |
147 | 155 |
|
148 | 156 | If the object is a Pydantic model, it uses the model's `model_dump()` method. |
149 | 157 |
|
150 | 158 | Args: |
151 | 159 | obj: The object to convert. |
| 160 | + convert_keys: Whether to convert the keys from snake case to camel case. |
152 | 161 |
|
153 | 162 | Returns: |
154 | 163 | A dictionary representation of the object, a list of objects if a list is |
155 | 164 | passed, or the object itself if it is not a dictionary, list, or Pydantic |
156 | 165 | model. |
157 | 166 | """ |
158 | 167 | if isinstance(obj, pydantic.BaseModel): |
159 | | - return obj.model_dump(exclude_none=True) |
| 168 | + return convert_to_dict(obj.model_dump(exclude_none=True), convert_keys) |
160 | 169 | elif isinstance(obj, dict): |
161 | | - return {key: convert_to_dict(value) for key, value in obj.items()} |
| 170 | + return { |
| 171 | + maybe_snake_to_camel(key, convert_keys): convert_to_dict( |
| 172 | + value, convert_keys |
| 173 | + ) |
| 174 | + for key, value in obj.items() |
| 175 | + } |
162 | 176 | elif isinstance(obj, list): |
163 | | - return [convert_to_dict(item) for item in obj] |
| 177 | + return [convert_to_dict(item, convert_keys) for item in obj] |
164 | 178 | else: |
165 | 179 | return obj |
166 | 180 |
|
@@ -642,3 +656,4 @@ def recursive_dict_update( |
642 | 656 | target_dict[key] = value |
643 | 657 | else: |
644 | 658 | target_dict[key] = value |
| 659 | + |
0 commit comments