forked from OpenG2P/openg2p-erp-community-addon
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tools.py
101 lines (82 loc) · 2.8 KB
/
tools.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
# Copyright 2018 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from collections import OrderedDict
def cerberus_to_json(schema):
"""Convert a Cerberus schema to a JSON schema
"""
result = OrderedDict()
required = []
properties = OrderedDict()
result["type"] = "object"
result["required"] = required
result["properties"] = properties
for field, spec in list(schema.items()):
props = _get_field_props(spec)
properties[field] = props
if spec.get("required"):
required.append(field)
# sort required to get the same order on each run and easy comparison into
# the tests
required.sort()
return result
def _get_field_props(spec): # noqa: C901
resp = OrderedDict()
# dictionary of tuple (json type, json fromat) by cerberus type for
# cerberus types requiring a specific mapping to a json type/format
type_map = {
"dict": ("object",),
"list": ("array",),
"objectid": ("string", "objectid"),
"datetime": ("string", "date-time"),
"float": ("number", "float"),
}
_type = spec.get("type")
if _type is None:
return resp
if "description" in spec:
resp["description"] = spec["description"]
if "allowed" in spec:
resp["enum"] = spec["allowed"]
if "default" in spec:
resp["default"] = spec["default"]
if "minlength" in spec:
if _type == "string":
resp["minLength"] = spec["minlength"]
elif _type == "list":
resp["minItems"] = spec["minlength"]
if "maxlength" in spec:
if _type == "string":
resp["maxLength"] = spec["maxlength"]
elif _type == "list":
resp["maxItems"] = spec["maxlength"]
if "min" in spec:
if _type in ["number", "integer", "float"]:
resp["minimum"] = spec["min"]
if "max" in spec:
if _type in ["number", "integer", "float"]:
resp["maximum"] = spec["max"]
if "readonly" in spec:
resp["readOnly"] = spec["readonly"]
if "regex" in spec:
resp["pattern"] = spec["regex"]
if "nullable" in spec:
resp["nullable"] = spec["nullable"]
if "allowed" in spec:
resp["enum"] = spec["allowed"]
json_type = type_map.get(_type, (_type,))
resp["type"] = json_type[0]
if json_type[0] == "object":
if "schema" in spec:
resp.update(cerberus_to_json(spec["schema"]))
elif json_type[0] == "array":
if "schema" in spec:
resp["items"] = _get_field_props(spec["schema"])
else:
resp["items"] = {"type": "string"}
else:
try:
resp["format"] = json_type[1]
# pylint:disable=except-pass
except IndexError:
pass
return resp