2
2
# Note: We shouldn't ever need to use this directly. We should go via the apispec converter
3
3
from apispec .ext .marshmallow .field_converter import DEFAULT_FIELD_MAPPING
4
4
5
- from . import fields
5
+ from labthings .server import fields
6
+ from labthings .core .utilities import rapply
7
+
8
+ from labthings .server .schema import Schema
6
9
7
10
# Extra standard library Python types
8
11
from datetime import date , datetime , time , timedelta
9
12
from decimal import Decimal
10
13
from typing import Dict , List , Tuple , Union
11
14
from uuid import UUID
12
15
16
+ import inspect
17
+ import copy
18
+
13
19
"""
14
20
TODO: Use this to convert arbitrary dictionary into its own schema, for W3C TD
15
21
@@ -59,8 +65,54 @@ def to_string(o):
59
65
"fractions.Fraction" : to_float ,
60
66
}
61
67
68
+
69
+ def make_primative (value ):
70
+ global DEFAULT_BUILTIN_CONVERSIONS , DEFAULT_TYPE_MAPPING
71
+
72
+ value_typestrings = [x .__module__ + "." + x .__name__ for x in inspect .getmro (type (value ))]
73
+
74
+ for typestring in value_typestrings :
75
+ if typestring in DEFAULT_BUILTIN_CONVERSIONS :
76
+ value = DEFAULT_BUILTIN_CONVERSIONS .get (typestring )(value )
77
+ break
78
+
79
+ # If the final type is not primative
80
+ if not type (value ) in DEFAULT_TYPE_MAPPING :
81
+ # Fall back to a string representation
82
+ value = str (value )
83
+
84
+ return value
85
+
86
+
87
+ def value_to_field (value ):
88
+ global DEFAULT_TYPE_MAPPING
89
+ if type (value ) in DEFAULT_TYPE_MAPPING :
90
+ return DEFAULT_TYPE_MAPPING .get (type (value ))(example = value )
91
+ else :
92
+ raise TypeError (f"Unsupported data type { type (value )} " )
93
+
94
+
95
+ def data_dict_to_schema (data_dict ):
96
+ working_dict = copy .deepcopy (data_dict )
97
+ working_dict = rapply (working_dict , make_primative )
98
+
99
+ working_dict = rapply (working_dict , value_to_field )
100
+ return Schema .from_dict (working_dict )
101
+
62
102
# TODO: Deserialiser with inverse defaults
63
103
# TODO: Option to switch to .npy serialisation/deserialisation (or look for a better common array format)
64
104
65
- # Use with [x.__module__+"."+x.__name__ for x in inspect.getmro(type(POSSIBLE_MATCHER))]
66
- # Resulting array will contain strings with the same format as keys in DEFAULT_BUILTIN_CONVERSIONS
105
+ """
106
+ # TODO: MOVE TO UNIT TESTS
107
+ from fractions import Fraction
108
+
109
+ d = {
110
+ "val1": Fraction(5,2),
111
+ "map1": {
112
+ "subval1": "Hello",
113
+ "subval2": False
114
+ },
115
+ "val2": 5
116
+ }
117
+
118
+ """
0 commit comments