@@ -87,6 +87,67 @@ def create_schema(self, name, schema_definition):
8787 self .open_api ['components' ]['schemas' ][name ] = final_schema
8888 return f"#/components/schemas/{ name } "
8989
90+ def _clean_schema (self , schema ):
91+ if isinstance (schema , dict ):
92+ # Replace $defs with definitions and update refs
93+ if '$defs' in schema :
94+ if 'definitions' not in schema :
95+ schema ['definitions' ] = {}
96+ schema ['definitions' ].update (schema .pop ('$defs' ))
97+
98+ def update_refs (node ):
99+ if isinstance (node , dict ):
100+ if '$ref' in node and node ['$ref' ].startswith ('#/$defs/' ):
101+ node ['$ref' ] = node ['$ref' ].replace ('#/$defs/' , '#/definitions/' )
102+ for key , value in node .items ():
103+ update_refs (value )
104+ elif isinstance (node , list ):
105+ for item in node :
106+ update_refs (item )
107+ update_refs (schema )
108+
109+ # Replace const with enum
110+ if 'const' in schema :
111+ schema ['enum' ] = [schema .pop ('const' )]
112+
113+ # Remove propertyNames
114+ if 'propertyNames' in schema :
115+ del schema ['propertyNames' ]
116+
117+ # Handle nullable
118+ if 'anyOf' in schema :
119+ is_nullable = False
120+ new_any_of = []
121+ for item in schema ['anyOf' ]:
122+ if isinstance (item , dict ) and item .get ('type' ) == 'null' :
123+ is_nullable = True
124+ else :
125+ new_any_of .append (item )
126+
127+ if is_nullable :
128+ for item in new_any_of :
129+ if isinstance (item , dict ):
130+ item ['nullable' ] = True
131+
132+ if not new_any_of :
133+ del schema ['anyOf' ]
134+ schema ['nullable' ] = True
135+ elif len (new_any_of ) == 1 :
136+ for key , value in new_any_of [0 ].items ():
137+ if key not in schema :
138+ schema [key ] = value
139+ del schema ['anyOf' ]
140+ if is_nullable :
141+ schema ['nullable' ] = True
142+ else :
143+ schema ['anyOf' ] = new_any_of
144+
145+ # Recurse
146+ return {k : self ._clean_schema (v ) for k , v in schema .items ()}
147+ elif isinstance (schema , list ):
148+ return [self ._clean_schema (item ) for item in schema ]
149+ return schema
150+
90151 def _resolve_schema_references (self , schema ):
91152 schema = self ._resolve_file_references (schema )
92153 if not isinstance (schema , dict ):
@@ -100,10 +161,12 @@ def _resolve_schema_references(self, schema):
100161 else :
101162 return schema
102163
164+ schema = self ._clean_schema (schema )
165+
103166 registry = Registry ()
104167 if "definitions" in schema :
105168 for name , sub_schema in schema ["definitions" ].items ():
106- resource = Resource .from_contents (sub_schema , default_specification = DRAFT4 )
169+ resource = Resource .from_contents (self . _clean_schema ( sub_schema ) , default_specification = DRAFT4 )
107170 registry = registry .with_resource (f"#/definitions/{ name } " , resource )
108171
109172 main_resource = Resource .from_contents (schema , default_specification = DRAFT4 )
@@ -118,8 +181,11 @@ def _resolve_schema_references(self, schema):
118181 def _recursive_dereference (self , node , resolver ):
119182 if isinstance (node , dict ):
120183 if "$ref" in node :
121- resolved = resolver .lookup (node ["$ref" ])
122- return self ._recursive_dereference (resolved .contents , resolver )
184+ try :
185+ resolved = resolver .lookup (node ["$ref" ])
186+ return self ._recursive_dereference (resolved .contents , resolver )
187+ except Exception :
188+ return node
123189 return {k : self ._recursive_dereference (v , resolver ) for k , v in node .items ()}
124190 elif isinstance (node , list ):
125191 return [self ._recursive_dereference (item , resolver ) for item in node ]
0 commit comments