1
1
from dataclasses import dataclass , field
2
2
from typing import Optional , List , Dict , Union , ClassVar
3
+
3
4
import stringcase
4
5
6
+ from .reference import Reference
7
+
5
8
6
9
@dataclass
7
10
class Property :
8
11
""" Describes a single property for a schema """
9
12
10
13
name : str
11
14
required : bool
15
+ default : Optional [str ]
12
16
13
17
_type_string : ClassVar [str ]
14
18
@@ -18,23 +22,33 @@ def get_type_string(self):
18
22
return self ._type_string
19
23
return f"Optional[{ self ._type_string } ]"
20
24
25
+ def to_string (self ) -> str :
26
+ """ How this should be declared in a dataclass """
27
+ if self .default :
28
+ default = self .default
29
+ elif not self .required :
30
+ default = "None"
31
+ else :
32
+ default = None
33
+
34
+ if default is not None :
35
+ return f"{ self .name } : { self .get_type_string ()} = { self .default } "
36
+ else :
37
+ return f"{ self .name } : { self .get_type_string ()} "
38
+
21
39
22
40
@dataclass
23
41
class StringProperty (Property ):
24
42
""" A property of type str """
25
43
26
44
max_length : Optional [int ] = None
27
- default : Optional [str ] = None
28
45
pattern : Optional [str ] = None
29
46
30
47
_type_string : ClassVar [str ] = "str"
31
48
32
- def to_string (self ) -> str :
33
- """ How this should be declared in a dataclass """
34
- if self .default :
35
- return f"{ self .name } : { self .get_type_string ()} = { self .default } "
36
- else :
37
- return f"{ self .name } : { self .get_type_string ()} "
49
+ def __post_init__ (self ):
50
+ if self .default is not None :
51
+ self .default = f'"{ self .default } "'
38
52
39
53
40
54
@dataclass
@@ -43,10 +57,6 @@ class DateTimeProperty(Property):
43
57
44
58
_type_string : ClassVar [str ] = "datetime"
45
59
46
- def to_string (self ) -> str :
47
- """ How this should be declared in a dataclass """
48
- return f"{ self .name } : { self .get_type_string ()} "
49
-
50
60
51
61
@dataclass
52
62
class FloatProperty (Property ):
@@ -55,13 +65,6 @@ class FloatProperty(Property):
55
65
default : Optional [float ] = None
56
66
_type_string : ClassVar [str ] = "float"
57
67
58
- def to_string (self ) -> str :
59
- """ How this should be declared in a dataclass """
60
- if self .default :
61
- return f"{ self .name } : { self .get_type_string ()} = { self .default } "
62
- else :
63
- return f"{ self .name } : { self .get_type_string ()} "
64
-
65
68
66
69
@dataclass
67
70
class IntProperty (Property ):
@@ -70,42 +73,27 @@ class IntProperty(Property):
70
73
default : Optional [int ] = None
71
74
_type_string : ClassVar [str ] = "int"
72
75
73
- def to_string (self ) -> str :
74
- """ How this should be declared in a dataclass """
75
- if self .default :
76
- return f"{ self .name } : { self .get_type_string ()} = { self .default } "
77
- else :
78
- return f"{ self .name } : { self .get_type_string ()} "
79
-
80
76
81
77
@dataclass
82
78
class BooleanProperty (Property ):
83
79
""" Property for bool """
84
80
85
81
_type_string : ClassVar [str ] = "bool"
86
82
87
- def to_string (self ) -> str :
88
- """ How this should be declared in a dataclass """
89
- return f"{ self .name } : { self .get_type_string ()} "
90
-
91
83
92
84
@dataclass
93
85
class ListProperty (Property ):
94
86
""" Property for list """
95
87
96
88
type : Optional [str ]
97
- ref : Optional [str ]
89
+ reference : Optional [Reference ]
98
90
99
91
def get_type_string (self ):
100
92
""" Get a string representation of type that should be used when declaring this property """
101
93
if self .required :
102
94
return f"List[{ self .type } ]"
103
95
return f"Optional[List[{ self .type } ]]"
104
96
105
- def to_string (self ) -> str :
106
- """ How this should be declared in a dataclass """
107
- return f"{ self .name } : { self .get_type_string ()} "
108
-
109
97
110
98
@dataclass
111
99
class EnumProperty (Property ):
@@ -124,10 +112,6 @@ def get_type_string(self):
124
112
return self .class_name
125
113
return f"Optional[{ self .class_name } ]"
126
114
127
- def to_string (self ) -> str :
128
- """ How this should be declared in a dataclass """
129
- return f"{ self .name } : { self .get_type_string ()} "
130
-
131
115
@staticmethod
132
116
def values_from_list (l : List [str ], / ) -> Dict [str , str ]:
133
117
""" Convert a list of values into dict of {name: value} """
@@ -148,13 +132,13 @@ def values_from_list(l: List[str], /) -> Dict[str, str]:
148
132
class RefProperty (Property ):
149
133
""" A property which refers to another Schema """
150
134
151
- ref : str
135
+ reference : Reference
152
136
153
137
def get_type_string (self ):
154
138
""" Get a string representation of type that should be used when declaring this property """
155
139
if self .required :
156
- return self .ref
157
- return f"Optional[{ self .ref } ]"
140
+ return self .reference . class_name
141
+ return f"Optional[{ self .reference . class_name } ]"
158
142
159
143
def to_string (self ) -> str :
160
144
""" How this should be declared in a dataclass """
@@ -186,31 +170,35 @@ def property_from_dict(
186
170
) -> Property :
187
171
""" Generate a Property from the OpenAPI dictionary representation of it """
188
172
if "enum" in data :
189
- return EnumProperty (name = name , required = required , values = EnumProperty .values_from_list (data ["enum" ]))
173
+ return EnumProperty (
174
+ name = name ,
175
+ required = required ,
176
+ values = EnumProperty .values_from_list (data ["enum" ]),
177
+ default = data .get ("default" ),
178
+ )
190
179
if "$ref" in data :
191
- ref = data ["$ref" ].split ("/" )[- 1 ]
192
- return RefProperty (name = name , required = required , ref = ref )
180
+ return RefProperty (name = name , required = required , reference = Reference (data ["$ref" ]), default = None )
193
181
if data ["type" ] == "string" :
194
182
if "format" not in data :
195
183
return StringProperty (
196
184
name = name , default = data .get ("default" ), required = required , pattern = data .get ("pattern" ),
197
185
)
198
186
elif data ["format" ] == "date-time" :
199
- return DateTimeProperty (name = name , required = required )
187
+ return DateTimeProperty (name = name , required = required , default = data . get ( "default" ) )
200
188
elif data ["type" ] == "number" :
201
189
return FloatProperty (name = name , default = data .get ("default" ), required = required )
202
190
elif data ["type" ] == "integer" :
203
191
return IntProperty (name = name , default = data .get ("default" ), required = required )
204
192
elif data ["type" ] == "boolean" :
205
- return BooleanProperty (name = name , required = required )
193
+ return BooleanProperty (name = name , required = required , default = data . get ( "default" ) )
206
194
elif data ["type" ] == "array" :
207
- ref = None
195
+ reference = None
208
196
if "$ref" in data ["items" ]:
209
- ref = data ["items" ]["$ref" ]. split ( "/" )[ - 1 ]
197
+ reference = Reference ( data ["items" ]["$ref" ])
210
198
_type = None
211
199
if "type" in data ["items" ]:
212
200
_type = _openapi_types_to_python_type_strings [data ["items" ]["type" ]]
213
- return ListProperty (name = name , required = required , type = _type , ref = ref )
201
+ return ListProperty (name = name , required = required , type = _type , reference = reference , default = None )
214
202
elif data ["type" ] == "object" :
215
- return DictProperty (name = name , required = required )
203
+ return DictProperty (name = name , required = required , default = None )
216
204
raise ValueError (f"Did not recognize type of { data } " )
0 commit comments