-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdecoders.py
117 lines (113 loc) · 5.83 KB
/
decoders.py
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
import datetime
from medium.config import myapp
import re
import dateutil.parser
def pow_json_deserializer(dct):
"""
converting json date stings to datetime.datetime for created_at and last_updated
see: https://docs.python.org/3/library/json.html
and: http://stackoverflow.com/questions/8793448/how-to-convert-to-a-python-datetime-object-with-json-loads
Nicola of course ;)
"""
if "created_at" in dct:
print("json deserializer found: created at: " + str(dct["created_at"]))
#dct["created_at"]=datetime.datetime.strptime(dct["created_at"], myapp["date_format"])
return dct
def pow_init_from_dict_deserializer(dct, schema, simple_conversion=False):
"""
takes a dict with attributes and values
and (tries) to convert them to the specified types given in the schema
Can be used in model.init_from_dict. (Which most often follows an init_from_json call)
HTTP Request (data) => init_from_json(data) => dict(data) => init_from_dict(data, schema) => Model
Reason:
json data from ajax requests has for example dates as string but you most probably want datetime.
list values come from html form text-fields as strings ..
simple_conversion = True tries to use simple logic to create
a little bit more advanced python data types.
for example "a b c" will be model.attribute = "a b c".split(myapp["list_separator"])
Mainly used for handling request from simple html form scaffolding
"""
for elem in dct:
if elem in schema.keys():
#print("converting: " + str(elem) + " : " + str(dct[elem]) + " => " + schema[elem]["type"] )
if schema[elem]["type"].lower() == "datetime":
if not isinstance(dct[elem], (datetime.datetime)):
#print(str(type(dct[elem])) + str(dct[elem]))
try:
# expecting primarily a string
dat = datetime.datetime.strptime(dct[elem], myapp["date_format"])
dat = dat.replace(tzinfo=None)
#print("date: str -> setting: {} to {}".format(elem, str(dct[elem])))
dct[elem]=dat
except Exception as e:
# give dateutil a chance .. (99% good)
try:
#print("date: dateutil setting: {} to {}".format(elem, str(dct[elem])))
dat=dateutil.parser.parse(dct[elem])
dat=dat.replace(tzinfo=None)
dct[elem]=dat
except:
# last try with epoch int
try:
dat = datetime.datetime.fromtimestamp(dct[elem])
dat=dat.replace(tzinfo=None)
dct[elem]=dat
except Exception as e1:
print(elem + "->" +str(type(dct[elem])) + str(dct[elem]))
print("Pow Decoders Exception for field: " + elem)
raise e1
elif schema[elem]["type"].lower() == "integer":
if not isinstance(dct[elem], (int)):
try:
dct[elem] = int(dct[elem])
except Exception as e:
print(elem + "->" +
str(type(dct[elem])) + str(dct[elem]))
print("Exception for field: " + elem)
raise e
elif schema[elem]["type"].lower() == "dict":
if not isinstance(dct[elem], (dict)):
try:
import ast
if isinstance(dct[elem], (str)):
# see: https://stackoverflow.com/questions/988228/convert-a-string-representation-of-a-dictionary-to-a-dictionary
dct[elem] = ast.literal_eval(dct[elem])
except Exception as e:
raise e
elif schema[elem]["type"].lower() == "boolean":
if not isinstance(dct[elem], (bool)):
try:
if isinstance(dct[elem], (str)):
dct[elem] = int(dct[elem])
dct[elem] = bool(dct[elem])
except Exception as e:
raise e
elif schema[elem]["type"].lower() == "string":
if not isinstance(dct[elem], (str)):
try:
dct[elem] = str(dct[elem])
except Exception as e:
raise e
elif schema[elem]["type"].lower() == "list":
if not isinstance(dct[elem], (list)):
try:
if simple_conversion:
# split the given input with config.list_separator
dct[elem] = dct[elem].split(myapp["list_separator"])
else:
dct[elem] = list(dct[elem])
except Exception as e:
raise e
elif schema[elem]["type"].lower() == "float":
if not isinstance(dct[elem], (float)):
try:
dct[elem] = float(dct[elem])
except Exception as e:
raise e
elif schema[elem]["type"].lower() == "set":
if not isinstance(dct[elem], (set)):
try:
dct[elem] = set(dct[elem])
except Exception as e:
raise e
return dct