11import re
2+ from typing import Any
23from typing import Dict
34from typing import List
45from typing import Literal
78from typing import Union
89
910import click
10- from openapi_pydantic .v3 .v3_0 import Reference , Schema , Operation , Parameter , RequestBody , Response , MediaType , PathItem
11+ from openapi_pydantic .v3 import (
12+ Reference ,
13+ Schema ,
14+ Operation ,
15+ Parameter ,
16+ RequestBody ,
17+ Response ,
18+ PathItem ,
19+ )
20+
21+ # Import version-specific types for isinstance checks
22+ from openapi_pydantic .v3 .v3_0 import (
23+ Reference as Reference30 ,
24+ Schema as Schema30 ,
25+ Response as Response30 ,
26+ MediaType as MediaType30 ,
27+ )
28+ from openapi_pydantic .v3 .v3_1 import (
29+ Reference as Reference31 ,
30+ Schema as Schema31 ,
31+ Response as Response31 ,
32+ MediaType as MediaType31 ,
33+ )
1134
1235from openapi_python_generator .language_converters .python import common
1336from openapi_python_generator .language_converters .python .common import normalize_symbol
2447from openapi_python_generator .models import TypeConversion
2548
2649
50+ # Helper functions for isinstance checks across OpenAPI versions
51+ def is_response_type (obj ) -> bool :
52+ """Check if object is a Response from any OpenAPI version"""
53+ return isinstance (obj , (Response30 , Response31 ))
54+
55+
56+ def create_media_type_for_reference (reference_obj ):
57+ """Create a MediaType wrapper for a reference object, using the correct version"""
58+ # Check which version the reference object belongs to
59+ if isinstance (reference_obj , Reference30 ):
60+ return MediaType30 (schema = reference_obj )
61+ elif isinstance (reference_obj , Reference31 ):
62+ return MediaType31 (schema = reference_obj )
63+ else :
64+ # Fallback to v3.0 for generic Reference
65+ return MediaType30 (schema = reference_obj )
66+
67+
68+ def is_media_type (obj ) -> bool :
69+ """Check if object is a MediaType from any OpenAPI version"""
70+ return isinstance (obj , (MediaType30 , MediaType31 ))
71+
72+
73+ def is_reference_type (obj : Any ) -> bool :
74+ """Check if object is a Reference type across different versions."""
75+ return isinstance (obj , (Reference , Reference30 , Reference31 ))
76+
77+
78+ def is_schema_type (obj : Any ) -> bool :
79+ """Check if object is a Schema type across different versions."""
80+ return isinstance (obj , (Schema , Schema30 , Schema31 ))
81+
82+
83+ def is_schema_type (obj ) -> bool :
84+ """Check if object is a Schema from any OpenAPI version"""
85+ return isinstance (obj , (Schema30 , Schema31 ))
86+
87+
2788HTTP_OPERATIONS = ["get" , "post" , "put" , "delete" , "options" , "head" , "patch" , "trace" ]
2889
2990
@@ -45,9 +106,14 @@ def generate_body_param(operation: Operation) -> Union[str, None]:
45106 if media_type is None :
46107 return None # pragma: no cover
47108
48- if isinstance (media_type .media_type_schema , Reference ):
109+ if isinstance (
110+ media_type .media_type_schema , (Reference , Reference30 , Reference31 )
111+ ):
49112 return "data.dict()"
50- elif isinstance (media_type .media_type_schema , Schema ):
113+ elif hasattr (media_type .media_type_schema , "ref" ):
114+ # Handle Reference objects from different OpenAPI versions
115+ return "data.dict()"
116+ elif isinstance (media_type .media_type_schema , (Schema , Schema30 , Schema31 )):
51117 schema = media_type .media_type_schema
52118 if schema .type == "array" :
53119 return "[i.dict() for i in data]"
@@ -109,11 +175,13 @@ def _generate_params_from_content(content: Union[Reference, Schema]):
109175 "application/json" ,
110176 "text/plain" ,
111177 "multipart/form-data" ,
178+ "application/octet-stream" ,
112179 ]
113180
114181 if operation .requestBody is not None :
182+ # Check if this is a RequestBody (either v3.0 or v3.1) by checking for content attribute
115183 if (
116- isinstance (operation .requestBody , RequestBody )
184+ hasattr (operation .requestBody , "content" )
117185 and isinstance (operation .requestBody .content , dict )
118186 and any (
119187 [
@@ -129,8 +197,11 @@ def _generate_params_from_content(content: Union[Reference, Schema]):
129197 ][0 ]
130198 content = operation .requestBody .content .get (get_keyword )
131199 if content is not None and (
132- isinstance (content .media_type_schema , Schema )
133- or isinstance (content .media_type_schema , Reference )
200+ hasattr (content , "media_type_schema" )
201+ and (
202+ hasattr (content .media_type_schema , "type" )
203+ or hasattr (content .media_type_schema , "ref" )
204+ )
134205 ):
135206 params += (
136207 f"{ _generate_params_from_content (content .media_type_schema )} , "
@@ -199,20 +270,22 @@ def generate_return_type(operation: Operation) -> OpReturnType:
199270 return OpReturnType (type = None , status_code = 200 , complex_type = False )
200271
201272 chosen_response = good_responses [0 ][1 ]
273+ media_type_schema = None
202274
203- if isinstance (chosen_response , Response ) and chosen_response .content is not None :
204- media_type_schema = chosen_response .content .get ("application/json" )
205- elif isinstance (chosen_response , Reference ):
206- media_type_schema = MediaType (
207- media_type_schema = chosen_response
208- ) # pragma: no cover
209- else :
275+ if is_response_type (chosen_response ):
276+ # It's a Response type, access content safely
277+ if hasattr (chosen_response , "content" ) and chosen_response .content is not None :
278+ media_type_schema = chosen_response .content .get ("application/json" )
279+ elif is_reference_type (chosen_response ):
280+ media_type_schema = create_media_type_for_reference (chosen_response )
281+
282+ if media_type_schema is None :
210283 return OpReturnType (
211284 type = None , status_code = good_responses [0 ][0 ], complex_type = False
212285 )
213286
214- if isinstance (media_type_schema , MediaType ):
215- if isinstance (media_type_schema .media_type_schema , Reference ):
287+ if is_media_type (media_type_schema ):
288+ if is_reference_type (media_type_schema .media_type_schema ):
216289 type_conv = TypeConversion (
217290 original_type = media_type_schema .media_type_schema .ref ,
218291 converted_type = media_type_schema .media_type_schema .ref .split ("/" )[- 1 ],
@@ -223,7 +296,7 @@ def generate_return_type(operation: Operation) -> OpReturnType:
223296 status_code = good_responses [0 ][0 ],
224297 complex_type = True ,
225298 )
226- elif isinstance (media_type_schema .media_type_schema , Schema ):
299+ elif is_schema_type (media_type_schema .media_type_schema ):
227300 converted_result = type_converter (media_type_schema .media_type_schema , True )
228301 if "array" in converted_result .original_type and isinstance (
229302 converted_result .import_types , list
@@ -293,7 +366,7 @@ def generate_service_operation(
293366 )
294367
295368 so .content = jinja_env .get_template (library_config .template_name ).render (
296- ** so .dict ()
369+ ** so .model_dump ()
297370 )
298371
299372 if op .tags is not None and len (op .tags ) > 0 :
0 commit comments