11from dataclasses import dataclass , field
22from typing import Optional , List , Dict , Union , ClassVar
3+
34import stringcase
45
6+ from .reference import Reference
7+
58
69@dataclass
710class Property :
811 """ Describes a single property for a schema """
912
1013 name : str
1114 required : bool
15+ default : Optional [str ]
1216
1317 _type_string : ClassVar [str ]
1418
@@ -18,23 +22,33 @@ def get_type_string(self):
1822 return self ._type_string
1923 return f"Optional[{ self ._type_string } ]"
2024
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+
2139
2240@dataclass
2341class StringProperty (Property ):
2442 """ A property of type str """
2543
2644 max_length : Optional [int ] = None
27- default : Optional [str ] = None
2845 pattern : Optional [str ] = None
2946
3047 _type_string : ClassVar [str ] = "str"
3148
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 } "'
3852
3953
4054@dataclass
@@ -43,10 +57,6 @@ class DateTimeProperty(Property):
4357
4458 _type_string : ClassVar [str ] = "datetime"
4559
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-
5060
5161@dataclass
5262class FloatProperty (Property ):
@@ -55,13 +65,6 @@ class FloatProperty(Property):
5565 default : Optional [float ] = None
5666 _type_string : ClassVar [str ] = "float"
5767
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-
6568
6669@dataclass
6770class IntProperty (Property ):
@@ -70,42 +73,27 @@ class IntProperty(Property):
7073 default : Optional [int ] = None
7174 _type_string : ClassVar [str ] = "int"
7275
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-
8076
8177@dataclass
8278class BooleanProperty (Property ):
8379 """ Property for bool """
8480
8581 _type_string : ClassVar [str ] = "bool"
8682
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-
9183
9284@dataclass
9385class ListProperty (Property ):
9486 """ Property for list """
9587
9688 type : Optional [str ]
97- ref : Optional [str ]
89+ reference : Optional [Reference ]
9890
9991 def get_type_string (self ):
10092 """ Get a string representation of type that should be used when declaring this property """
10193 if self .required :
10294 return f"List[{ self .type } ]"
10395 return f"Optional[List[{ self .type } ]]"
10496
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-
10997
11098@dataclass
11199class EnumProperty (Property ):
@@ -124,10 +112,6 @@ def get_type_string(self):
124112 return self .class_name
125113 return f"Optional[{ self .class_name } ]"
126114
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-
131115 @staticmethod
132116 def values_from_list (l : List [str ], / ) -> Dict [str , str ]:
133117 """ Convert a list of values into dict of {name: value} """
@@ -148,13 +132,13 @@ def values_from_list(l: List[str], /) -> Dict[str, str]:
148132class RefProperty (Property ):
149133 """ A property which refers to another Schema """
150134
151- ref : str
135+ reference : Reference
152136
153137 def get_type_string (self ):
154138 """ Get a string representation of type that should be used when declaring this property """
155139 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 } ]"
158142
159143 def to_string (self ) -> str :
160144 """ How this should be declared in a dataclass """
@@ -186,31 +170,35 @@ def property_from_dict(
186170) -> Property :
187171 """ Generate a Property from the OpenAPI dictionary representation of it """
188172 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+ )
190179 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 )
193181 if data ["type" ] == "string" :
194182 if "format" not in data :
195183 return StringProperty (
196184 name = name , default = data .get ("default" ), required = required , pattern = data .get ("pattern" ),
197185 )
198186 elif data ["format" ] == "date-time" :
199- return DateTimeProperty (name = name , required = required )
187+ return DateTimeProperty (name = name , required = required , default = data . get ( "default" ) )
200188 elif data ["type" ] == "number" :
201189 return FloatProperty (name = name , default = data .get ("default" ), required = required )
202190 elif data ["type" ] == "integer" :
203191 return IntProperty (name = name , default = data .get ("default" ), required = required )
204192 elif data ["type" ] == "boolean" :
205- return BooleanProperty (name = name , required = required )
193+ return BooleanProperty (name = name , required = required , default = data . get ( "default" ) )
206194 elif data ["type" ] == "array" :
207- ref = None
195+ reference = None
208196 if "$ref" in data ["items" ]:
209- ref = data ["items" ]["$ref" ]. split ( "/" )[ - 1 ]
197+ reference = Reference ( data ["items" ]["$ref" ])
210198 _type = None
211199 if "type" in data ["items" ]:
212200 _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 )
214202 elif data ["type" ] == "object" :
215- return DictProperty (name = name , required = required )
203+ return DictProperty (name = name , required = required , default = None )
216204 raise ValueError (f"Did not recognize type of { data } " )
0 commit comments