1
1
from pathlib import Path
2
+ from typing import List
2
3
from typing import Optional
3
4
from typing import Union
4
5
14
15
from openapi_pydantic .v3 .v3_0 import OpenAPI
15
16
from pydantic import ValidationError
16
17
17
- from .common import HTTPLibrary , PydanticVersion
18
+ from .common import Formatter , HTTPLibrary , PydanticVersion
18
19
from .common import library_config_dict
19
20
from .language_converters .python .generator import generator
20
21
from .language_converters .python .jinja_config import SERVICE_TEMPLATE
21
22
from .language_converters .python .jinja_config import create_jinja_env
22
23
from .models import ConversionResult
23
24
24
25
25
- def write_code (path : Path , content ) -> None :
26
+ def write_code (path : Path , content : str , formatter : Formatter ) -> None :
26
27
"""
27
28
Write the content to the file at the given path.
28
- :param autoformat: The autoformat applied to the code written.
29
29
:param path: The path to the file.
30
30
:param content: The content to write.
31
+ :param formatter: The formatter applied to the code written.
31
32
"""
32
33
try :
33
34
with open (path , "w" ) as f :
34
- try :
35
- formatted_contend = black .format_file_contents (
36
- content , fast = False , mode = black .FileMode (line_length = 120 )
37
- )
38
-
39
- except NothingChanged :
35
+ if formatter == Formatter .BLACK :
36
+ formatted_contend = format_using_black (content )
37
+ elif formatter == Formatter .NONE :
40
38
formatted_contend = content
41
- formatted_contend = isort .code (formatted_contend , line_length = 120 )
39
+ else :
40
+ raise NotImplementedError (
41
+ f"Missing implementation for formatter { formatter !r} ."
42
+ )
42
43
f .write (formatted_contend )
43
44
except Exception as e :
44
45
raise e
45
46
46
47
48
+ def format_using_black (content : str ) -> str :
49
+ try :
50
+ formatted_contend = black .format_file_contents (
51
+ content , fast = False , mode = black .FileMode (line_length = 120 )
52
+ )
53
+ except NothingChanged :
54
+ return content
55
+ return isort .code (formatted_contend , line_length = 120 )
56
+
57
+
47
58
def get_open_api (source : Union [str , Path ]) -> OpenAPI :
48
59
"""
49
60
Tries to fetch the openapi specification file from the web or load from a local file.
@@ -105,14 +116,14 @@ def get_open_api(source: Union[str, Path]) -> OpenAPI:
105
116
raise
106
117
107
118
108
- def write_data (data : ConversionResult , output : Union [str , Path ]) -> None :
119
+ def write_data (data : ConversionResult , output : Union [str , Path ], formatter : Formatter ) -> None :
109
120
"""
110
- This function will firstly create the folderstrucutre of output, if it doesn't exist. Then it will create the
121
+ This function will firstly create the folder structure of output, if it doesn't exist. Then it will create the
111
122
models from data.models into the models sub module of the output folder. After this, the services will be created
112
123
into the services sub module of the output folder.
113
- :param autoformat: The autoformat applied to the code written.
114
124
:param data: The data to write.
115
125
:param output: The path to the output folder.
126
+ :param formatter: The formatter applied to the code written.
116
127
"""
117
128
118
129
# Create the folder structure of the output folder.
@@ -126,17 +137,18 @@ def write_data(data: ConversionResult, output: Union[str, Path]) -> None:
126
137
services_path = Path (output ) / "services"
127
138
services_path .mkdir (parents = True , exist_ok = True )
128
139
129
- files = []
140
+ files : List [ str ] = []
130
141
131
142
# Write the models.
132
143
for model in data .models :
133
144
files .append (model .file_name )
134
- write_code (models_path / f"{ model .file_name } .py" , model .content )
145
+ write_code (models_path / f"{ model .file_name } .py" , model .content , formatter )
135
146
136
147
# Create models.__init__.py file containing imports to all models.
137
148
write_code (
138
149
models_path / "__init__.py" ,
139
150
"\n " .join ([f"from .{ file } import *" for file in files ]),
151
+ formatter ,
140
152
)
141
153
142
154
files = []
@@ -150,18 +162,20 @@ def write_data(data: ConversionResult, output: Union[str, Path]) -> None:
150
162
write_code (
151
163
services_path / f"{ service .file_name } .py" ,
152
164
jinja_env .get_template (SERVICE_TEMPLATE ).render (** service .dict ()),
165
+ formatter ,
153
166
)
154
167
155
168
# Create services.__init__.py file containing imports to all services.
156
- write_code (services_path / "__init__.py" , "" )
169
+ write_code (services_path / "__init__.py" , "" , formatter )
157
170
158
171
# Write the api_config.py file.
159
- write_code (Path (output ) / "api_config.py" , data .api_config .content )
172
+ write_code (Path (output ) / "api_config.py" , data .api_config .content , formatter )
160
173
161
174
# Write the __init__.py file.
162
175
write_code (
163
176
Path (output ) / "__init__.py" ,
164
177
"from .models import *\n from .services import *\n from .api_config import *" ,
178
+ formatter ,
165
179
)
166
180
167
181
@@ -173,6 +187,7 @@ def generate_data(
173
187
use_orjson : bool = False ,
174
188
custom_template_path : Optional [str ] = None ,
175
189
pydantic_version : PydanticVersion = PydanticVersion .V2 ,
190
+ formatter : Formatter = Formatter .BLACK ,
176
191
) -> None :
177
192
"""
178
193
Generate Python code from an OpenAPI 3.0 specification.
@@ -189,4 +204,4 @@ def generate_data(
189
204
pydantic_version ,
190
205
)
191
206
192
- write_data (result , output )
207
+ write_data (result , output , formatter )
0 commit comments