1
1
from __future__ import annotations
2
2
3
- from collections import defaultdict
4
3
from dataclasses import dataclass , field
5
4
from enum import Enum
6
5
from typing import Dict , List , Optional , Set
@@ -34,23 +33,21 @@ def from_dict(d: Dict, /) -> Parameter:
34
33
)
35
34
36
35
37
- @dataclass
38
- class Endpoint :
39
- """
40
- Describes a single endpoint on the server
41
- """
36
+ def _import_string_from_ref (ref : str , prefix : str = "" ) -> str :
37
+ return f"from { prefix } .{ stringcase .snakecase (ref )} import { ref } "
42
38
43
- path : str
44
- method : str
45
- description : Optional [str ]
46
- name : str
47
- parameters : List [Parameter ]
48
- responses : List [Response ]
39
+
40
+ @dataclass
41
+ class EndpointCollection :
42
+ """ A bunch of endpoints grouped under a tag that will become a module """
43
+ tag : str
44
+ endpoints : List [Endpoint ] = field (default_factory = list )
45
+ relative_imports : Set [str ] = field (default_factory = set )
49
46
50
47
@staticmethod
51
- def get_by_tags_from_dict (d : Dict [str , Dict [str , Dict ]], / ) -> Dict [str , List [ Endpoint ] ]:
52
- """ Parse the openapi paths data to get a list of endpoints """
53
- endpoints_by_tag : Dict [str , List [ Endpoint ]] = defaultdict ( list )
48
+ def from_dict (d : Dict [str , Dict [str , Dict ]], / ) -> Dict [str , EndpointCollection ]:
49
+ """ Parse the openapi paths data to get EndpointCollections by tag """
50
+ endpoints_by_tag : Dict [str , EndpointCollection ] = {}
54
51
for path , path_data in d .items ():
55
52
for method , method_data in path_data .items ():
56
53
parameters : List [Parameter ] = []
@@ -64,18 +61,52 @@ def get_by_tags_from_dict(d: Dict[str, Dict[str, Dict]], /) -> Dict[str, List[En
64
61
data = response_dict ,
65
62
)
66
63
responses .append (response )
64
+ form_body_ref = None
65
+ if "requestBody" in method_data :
66
+ form_body_ref = Endpoint .parse_request_body (method_data ["requestBody" ])
67
+
67
68
endpoint = Endpoint (
68
69
path = path ,
69
70
method = method ,
70
71
description = method_data .get ("description" ),
71
72
name = method_data ["operationId" ],
72
73
parameters = parameters ,
73
74
responses = responses ,
75
+ form_body_ref = form_body_ref ,
74
76
)
75
- endpoints_by_tag [tag ].append (endpoint )
77
+
78
+ collection = endpoints_by_tag .setdefault (tag , EndpointCollection (tag = tag ))
79
+ collection .endpoints .append (endpoint )
80
+ if form_body_ref :
81
+ collection .relative_imports .add (_import_string_from_ref (form_body_ref , prefix = "..models" ))
76
82
return endpoints_by_tag
77
83
78
84
85
+ @dataclass
86
+ class Endpoint :
87
+ """
88
+ Describes a single endpoint on the server
89
+ """
90
+
91
+ path : str
92
+ method : str
93
+ description : Optional [str ]
94
+ name : str
95
+ parameters : List [Parameter ]
96
+ responses : List [Response ]
97
+ form_body_ref : Optional [str ]
98
+
99
+ @staticmethod
100
+ def parse_request_body (body : Dict , / ) -> Optional [str ]:
101
+ """ Return form_body_ref """
102
+ form_body_ref = None
103
+ body_content = body ["content" ]
104
+ form_body = body_content .get ("application/x-www-form-urlencoded" )
105
+ if form_body :
106
+ form_body_ref = form_body ["schema" ]["$ref" ].split ("/" )[- 1 ]
107
+ return form_body_ref
108
+
109
+
79
110
@dataclass
80
111
class Schema :
81
112
"""
@@ -99,7 +130,7 @@ def from_dict(d: Dict, /) -> Schema:
99
130
p = property_from_dict (name = key , required = key in required , data = value )
100
131
properties .append (p )
101
132
if isinstance (p , (ListProperty , RefProperty )) and p .ref :
102
- schema .relative_imports .add (f"from . { stringcase . snakecase (p .ref )} import { p . ref } " )
133
+ schema .relative_imports .add (_import_string_from_ref (p .ref ))
103
134
return schema
104
135
105
136
@staticmethod
@@ -121,7 +152,7 @@ class OpenAPI:
121
152
version : str
122
153
security_schemes : Dict
123
154
schemas : Dict [str , Schema ]
124
- endpoints_by_tag : Dict [str , List [ Endpoint ] ]
155
+ endpoint_collections_by_tag : Dict [str , EndpointCollection ]
125
156
enums : Dict [str , EnumProperty ]
126
157
127
158
@staticmethod
@@ -146,7 +177,7 @@ def from_dict(d: Dict, /) -> OpenAPI:
146
177
title = d ["info" ]["title" ],
147
178
description = d ["info" ]["description" ],
148
179
version = d ["info" ]["version" ],
149
- endpoints_by_tag = Endpoint . get_by_tags_from_dict (d ["paths" ]),
180
+ endpoint_collections_by_tag = EndpointCollection . from_dict (d ["paths" ]),
150
181
schemas = schemas ,
151
182
security_schemes = d ["components" ]["securitySchemes" ],
152
183
enums = enums ,
0 commit comments