File size: 4,233 Bytes
1b7e88c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
import dataclasses
import datetime
import inspect
import logging
import typing
from typing import List
from dacite import from_dict
from omagent_core.engine.configuration.configuration import Configuration
from requests.structures import CaseInsensitiveDict
logger = logging.getLogger(Configuration.get_logging_formatted_name(__name__))
simple_types = {int, float, str, bool, datetime.date, datetime.datetime, object}
dict_types = {dict, typing.Dict, CaseInsensitiveDict}
collection_types = {list, List, typing.Set}
def convert_from_dict_or_list(cls: type, data: typing.Union[dict, list]) -> object:
is_list = type(data) in collection_types
if is_list:
val_list = []
for val in data:
generic_types = typing.get_args(cls)[0]
converted = convert_from_dict(generic_types, val)
val_list.append(converted)
return val_list
return convert_from_dict(cls, data)
def convert_from_dict(cls: type, data: dict) -> object:
if data is None:
return data
if type(data) == cls:
return data
if dataclasses.is_dataclass(cls):
return from_dict(data_class=cls, data=data)
typ = type(data)
if not (
(
str(typ).startswith("dict[")
or str(typ).startswith("typing.Dict[")
or str(typ).startswith("requests.structures.CaseInsensitiveDict[")
or typ == dict
or str(typ).startswith("OrderedDict[")
)
):
data = {}
members = inspect.signature(cls.__init__).parameters
kwargs = {}
for member in members:
if "self" == member:
continue
typ = members[member].annotation
generic_types = typing.get_args(members[member].annotation)
if typ in simple_types:
if member in data:
kwargs[member] = data[member]
else:
kwargs[member] = members[member].default
elif (
str(typ).startswith("typing.List[")
or str(typ).startswith("typing.Set[")
or str(typ).startswith("list[")
):
values = []
generic_type = object
if len(generic_types) > 0:
generic_type = generic_types[0]
for val in data[member]:
values.append(get_value(generic_type, val))
kwargs[member] = values
elif (
str(typ).startswith("dict[")
or str(typ).startswith("typing.Dict[")
or str(typ).startswith("requests.structures.CaseInsensitiveDict[")
or typ == dict
or str(typ).startswith("OrderedDict[")
):
values = {}
generic_type = object
if len(generic_types) > 1:
generic_type = generic_types[1]
for k in data[member]:
v = data[member][k]
values[k] = get_value(generic_type, v)
kwargs[member] = values
elif typ == inspect.Parameter.empty:
if inspect.Parameter.VAR_KEYWORD == members[member].kind:
if type(data) in dict_types:
kwargs.update(data)
else:
kwargs.update(data[member])
else:
# kwargs[member] = data[member]
kwargs.update(data)
else:
kwargs[member] = convert_from_dict(typ, data[member])
return cls(**kwargs)
def get_value(typ: type, val: object) -> object:
if typ in simple_types:
return val
elif (
str(typ).startswith("typing.List[")
or str(typ).startswith("typing.Set[")
or str(typ).startswith("list[")
):
values = []
for val in val:
converted = get_value(type(val), val)
values.append(converted)
return values
elif (
str(typ).startswith("dict[")
or str(typ).startswith("typing.Dict[")
or str(typ).startswith("requests.structures.CaseInsensitiveDict[")
or typ == dict
):
values = {}
for k in val:
v = val[k]
values[k] = get_value(object, v)
return values
else:
return convert_from_dict(typ, val)
|