@autorest/python 6.0.1 → 6.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ChangeLog.md +57 -0
- package/README.md +22 -3
- package/autorest/__init__.py +52 -14
- package/autorest/_utils.py +75 -0
- package/autorest/black/__init__.py +15 -8
- package/autorest/cadlflags/__init__.py +128 -0
- package/autorest/codegen/__init__.py +14 -21
- package/autorest/codegen/_utils.py +12 -0
- package/autorest/codegen/models/__init__.py +10 -1
- package/autorest/codegen/models/combined_type.py +4 -0
- package/autorest/codegen/models/model_type.py +18 -1
- package/autorest/codegen/models/parameter.py +5 -1
- package/autorest/codegen/models/property.py +1 -8
- package/autorest/codegen/models/request_builder_parameter.py +1 -1
- package/autorest/codegen/models/response.py +7 -0
- package/autorest/codegen/models/utils.py +0 -3
- package/autorest/codegen/serializers/__init__.py +20 -15
- package/autorest/codegen/serializers/builder_serializer.py +5 -5
- package/autorest/codegen/templates/README.md.jinja2 +3 -3
- package/autorest/codegen/templates/setup.py.jinja2 +1 -2
- package/autorest/jsonrpc/server.py +7 -1
- package/autorest/m2r/__init__.py +11 -4
- package/autorest/m4reformatter/__init__.py +13 -37
- package/autorest/multiapi/__init__.py +5 -6
- package/autorest/multiapi/serializers/__init__.py +5 -3
- package/autorest/multiapi/templates/multiapi_init.py.jinja2 +4 -0
- package/autorest/multiclient/__init__.py +50 -0
- package/autorest/multiclient/templates/init.py.jinja2 +8 -0
- package/autorest/multiclient/templates/version.py.jinja2 +8 -0
- package/autorest/postprocess/__init__.py +1 -1
- package/autorest/preprocess/__init__.py +138 -17
- package/autorest/preprocess/helpers.py +0 -30
- package/install.py +3 -3
- package/package.json +3 -2
- package/prepare.py +2 -2
- package/requirements.txt +8 -9
- package/run-python3.js +2 -2
- package/run_cadl.py +27 -0
- package/setup.py +2 -3
- package/start.py +2 -2
- package/autorest/multiapi/serializers/multiapi_serializer.py +0 -121
|
@@ -5,11 +5,107 @@
|
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
6
|
"""The preprocessing autorest plugin.
|
|
7
7
|
"""
|
|
8
|
+
import copy
|
|
8
9
|
from typing import Callable, Dict, Any, List, Optional
|
|
9
|
-
|
|
10
|
+
|
|
11
|
+
from .._utils import to_snake_case
|
|
12
|
+
from .helpers import pad_reserved_words, add_redefined_builtin_info
|
|
10
13
|
from .python_mappings import PadType
|
|
11
14
|
|
|
12
|
-
from .. import YamlUpdatePlugin,
|
|
15
|
+
from .. import YamlUpdatePlugin, YamlUpdatePluginAutorest
|
|
16
|
+
from .._utils import parse_args, get_body_type_for_description, JSON_REGEXP, KNOWN_TYPES
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def add_body_param_type(code_model: Dict[str, Any], body_parameter: Dict[str, Any]):
|
|
20
|
+
if (
|
|
21
|
+
body_parameter
|
|
22
|
+
and body_parameter["type"]["type"] in ("model", "dict", "list")
|
|
23
|
+
and any(
|
|
24
|
+
ct for ct in body_parameter.get("contentTypes", []) if JSON_REGEXP.match(ct)
|
|
25
|
+
)
|
|
26
|
+
and not body_parameter["type"].get("xmlMetadata")
|
|
27
|
+
and not any(t for t in ["flattened", "groupedBy"] if body_parameter.get(t))
|
|
28
|
+
):
|
|
29
|
+
body_parameter["type"] = {
|
|
30
|
+
"type": "combined",
|
|
31
|
+
"types": [body_parameter["type"], KNOWN_TYPES["binary"]],
|
|
32
|
+
}
|
|
33
|
+
code_model["types"].append(body_parameter["type"])
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def update_overload_section(
|
|
37
|
+
overload: Dict[str, Any],
|
|
38
|
+
yaml_data: Dict[str, Any],
|
|
39
|
+
section: str,
|
|
40
|
+
):
|
|
41
|
+
for overload_s, original_s in zip(overload[section], yaml_data[section]):
|
|
42
|
+
if overload_s.get("type"):
|
|
43
|
+
overload_s["type"] = original_s["type"]
|
|
44
|
+
if overload_s.get("headers"):
|
|
45
|
+
for overload_h, original_h in zip(
|
|
46
|
+
overload_s["headers"], original_s["headers"]
|
|
47
|
+
):
|
|
48
|
+
if overload_h.get("type"):
|
|
49
|
+
overload_h["type"] = original_h["type"]
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def add_overload(yaml_data: Dict[str, Any], body_type: Dict[str, Any]):
|
|
53
|
+
overload = copy.deepcopy(yaml_data)
|
|
54
|
+
overload["isOverload"] = True
|
|
55
|
+
overload["bodyParameter"]["type"] = body_type
|
|
56
|
+
|
|
57
|
+
overload["overloads"] = []
|
|
58
|
+
|
|
59
|
+
# for yaml sync, we need to make sure all of the responses, parameters, and exceptions' types have the same yaml id
|
|
60
|
+
for overload_p, original_p in zip(overload["parameters"], yaml_data["parameters"]):
|
|
61
|
+
overload_p["type"] = original_p["type"]
|
|
62
|
+
update_overload_section(overload, yaml_data, "responses")
|
|
63
|
+
update_overload_section(overload, yaml_data, "exceptions")
|
|
64
|
+
|
|
65
|
+
# update content type to be an overloads content type
|
|
66
|
+
content_type_param = next(
|
|
67
|
+
p for p in overload["parameters"] if p["restApiName"].lower() == "content-type"
|
|
68
|
+
)
|
|
69
|
+
content_type_param["inOverload"] = True
|
|
70
|
+
content_type_param["inDocstring"] = True
|
|
71
|
+
body_type_description = get_body_type_for_description(overload["bodyParameter"])
|
|
72
|
+
content_type_param[
|
|
73
|
+
"description"
|
|
74
|
+
] = f"Body Parameter content-type. Content type parameter for {body_type_description} body."
|
|
75
|
+
content_types = yaml_data["bodyParameter"]["contentTypes"]
|
|
76
|
+
if body_type["type"] == "binary" and len(content_types) > 1:
|
|
77
|
+
content_types = "'" + "', '".join(content_types) + "'"
|
|
78
|
+
content_type_param["description"] += f" Known values are: {content_types}."
|
|
79
|
+
return overload
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def add_overloads_for_body_param(yaml_data: Dict[str, Any]) -> None:
|
|
83
|
+
"""If we added a body parameter type, add overloads for that type"""
|
|
84
|
+
body_parameter = yaml_data["bodyParameter"]
|
|
85
|
+
if not (
|
|
86
|
+
body_parameter["type"]["type"] == "combined"
|
|
87
|
+
and len(yaml_data["bodyParameter"]["type"]["types"])
|
|
88
|
+
> len(yaml_data["overloads"])
|
|
89
|
+
):
|
|
90
|
+
return
|
|
91
|
+
for body_type in body_parameter["type"]["types"]:
|
|
92
|
+
if any(
|
|
93
|
+
o
|
|
94
|
+
for o in yaml_data["overloads"]
|
|
95
|
+
if id(o["bodyParameter"]["type"]) == id(body_type)
|
|
96
|
+
):
|
|
97
|
+
continue
|
|
98
|
+
yaml_data["overloads"].append(add_overload(yaml_data, body_type))
|
|
99
|
+
content_type_param = next(
|
|
100
|
+
p for p in yaml_data["parameters"] if p["restApiName"].lower() == "content-type"
|
|
101
|
+
)
|
|
102
|
+
content_type_param["inOverload"] = False
|
|
103
|
+
content_type_param["inOverriden"] = True
|
|
104
|
+
content_type_param["inDocstring"] = True
|
|
105
|
+
content_type_param[
|
|
106
|
+
"clientDefaultValue"
|
|
107
|
+
] = None # make it none bc it will be overriden, we depend on default of overloads
|
|
108
|
+
content_type_param["optional"] = True
|
|
13
109
|
|
|
14
110
|
|
|
15
111
|
def _remove_paging_maxpagesize(yaml_data: Dict[str, Any]) -> None:
|
|
@@ -101,7 +197,7 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
|
|
|
101
197
|
|
|
102
198
|
def get_operation_updater(
|
|
103
199
|
self, yaml_data: Dict[str, Any]
|
|
104
|
-
) -> Callable[[Dict[str, Any]], None]:
|
|
200
|
+
) -> Callable[[Dict[str, Any], Dict[str, Any]], None]:
|
|
105
201
|
if yaml_data["discriminator"] == "lropaging":
|
|
106
202
|
return self.update_lro_paging_operation
|
|
107
203
|
if yaml_data["discriminator"] == "lro":
|
|
@@ -110,7 +206,13 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
|
|
|
110
206
|
return self.update_paging_operation
|
|
111
207
|
return self.update_operation
|
|
112
208
|
|
|
113
|
-
def update_operation(
|
|
209
|
+
def update_operation(
|
|
210
|
+
self,
|
|
211
|
+
code_model: Dict[str, Any],
|
|
212
|
+
yaml_data: Dict[str, Any],
|
|
213
|
+
*,
|
|
214
|
+
is_overload: bool = False,
|
|
215
|
+
) -> None:
|
|
114
216
|
yaml_data["groupName"] = pad_reserved_words(
|
|
115
217
|
yaml_data["groupName"], PadType.OPERATION_GROUP
|
|
116
218
|
)
|
|
@@ -121,6 +223,7 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
|
|
|
121
223
|
yaml_data["description"], yaml_data["name"]
|
|
122
224
|
)
|
|
123
225
|
yaml_data["summary"] = update_description(yaml_data.get("summary", ""))
|
|
226
|
+
body_parameter = yaml_data.get("bodyParameter")
|
|
124
227
|
for parameter in yaml_data["parameters"]:
|
|
125
228
|
update_parameter(parameter)
|
|
126
229
|
if yaml_data.get("bodyParameter"):
|
|
@@ -128,9 +231,13 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
|
|
|
128
231
|
for entry in yaml_data["bodyParameter"].get("entries", []):
|
|
129
232
|
update_parameter(entry)
|
|
130
233
|
for overload in yaml_data.get("overloads", []):
|
|
131
|
-
self.update_operation(overload)
|
|
234
|
+
self.update_operation(code_model, overload, is_overload=True)
|
|
132
235
|
for response in yaml_data.get("responses", []):
|
|
133
236
|
response["discriminator"] = "operation"
|
|
237
|
+
if body_parameter and not is_overload:
|
|
238
|
+
# if we have a JSON body, we add a binary overload
|
|
239
|
+
add_body_param_type(code_model, body_parameter)
|
|
240
|
+
add_overloads_for_body_param(yaml_data)
|
|
134
241
|
|
|
135
242
|
def _update_lro_operation_helper(self, yaml_data: Dict[str, Any]) -> None:
|
|
136
243
|
azure_arm = self.options.get("azure-arm", False)
|
|
@@ -155,23 +262,29 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
|
|
|
155
262
|
else "azure.core.polling.async_base_polling.AsyncLROBasePolling"
|
|
156
263
|
)
|
|
157
264
|
|
|
158
|
-
def update_lro_paging_operation(
|
|
159
|
-
self
|
|
160
|
-
|
|
265
|
+
def update_lro_paging_operation(
|
|
266
|
+
self, code_model: Dict[str, Any], yaml_data: Dict[str, Any]
|
|
267
|
+
) -> None:
|
|
268
|
+
self.update_lro_operation(code_model, yaml_data)
|
|
269
|
+
self.update_paging_operation(code_model, yaml_data)
|
|
161
270
|
yaml_data["discriminator"] = "lropaging"
|
|
162
271
|
for response in yaml_data.get("responses", []):
|
|
163
272
|
response["discriminator"] = "lropaging"
|
|
164
273
|
for overload in yaml_data.get("overloads", []):
|
|
165
|
-
self.update_lro_paging_operation(overload)
|
|
274
|
+
self.update_lro_paging_operation(code_model, overload)
|
|
166
275
|
|
|
167
|
-
def update_lro_operation(
|
|
168
|
-
self
|
|
276
|
+
def update_lro_operation(
|
|
277
|
+
self, code_model: Dict[str, Any], yaml_data: Dict[str, Any]
|
|
278
|
+
) -> None:
|
|
279
|
+
self.update_operation(code_model, yaml_data)
|
|
169
280
|
self._update_lro_operation_helper(yaml_data)
|
|
170
281
|
for overload in yaml_data.get("overloads", []):
|
|
171
282
|
self._update_lro_operation_helper(overload)
|
|
172
283
|
|
|
173
|
-
def update_paging_operation(
|
|
174
|
-
self
|
|
284
|
+
def update_paging_operation(
|
|
285
|
+
self, code_model: Dict[str, Any], yaml_data: Dict[str, Any]
|
|
286
|
+
) -> None:
|
|
287
|
+
self.update_operation(code_model, yaml_data)
|
|
175
288
|
if not yaml_data.get("pagerSync"):
|
|
176
289
|
yaml_data["pagerSync"] = "azure.core.paging.ItemPaged"
|
|
177
290
|
if not yaml_data.get("pagerAsync"):
|
|
@@ -206,7 +319,7 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
|
|
|
206
319
|
update_paging_response(response)
|
|
207
320
|
response["itemType"] = item_type
|
|
208
321
|
for overload in yaml_data.get("overloads", []):
|
|
209
|
-
self.update_paging_operation(overload)
|
|
322
|
+
self.update_paging_operation(code_model, overload)
|
|
210
323
|
|
|
211
324
|
def update_operation_groups(self, yaml_data: Dict[str, Any]) -> None:
|
|
212
325
|
operation_groups_yaml_data = yaml_data["operationGroups"]
|
|
@@ -221,19 +334,27 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
|
|
|
221
334
|
yaml_data, operation_group["className"]
|
|
222
335
|
)
|
|
223
336
|
for operation in operation_group["operations"]:
|
|
224
|
-
self.get_operation_updater(operation)(operation)
|
|
337
|
+
self.get_operation_updater(operation)(yaml_data, operation)
|
|
225
338
|
|
|
226
339
|
def update_yaml(self, yaml_data: Dict[str, Any]) -> None:
|
|
227
340
|
"""Convert in place the YAML str."""
|
|
228
341
|
update_client(yaml_data["client"])
|
|
229
|
-
update_types(yaml_data["types"])
|
|
230
342
|
self.update_operation_groups(yaml_data)
|
|
343
|
+
update_types(yaml_data["types"])
|
|
231
344
|
|
|
232
345
|
|
|
233
|
-
class PreProcessPluginAutorest(
|
|
346
|
+
class PreProcessPluginAutorest(YamlUpdatePluginAutorest, PreProcessPlugin):
|
|
234
347
|
def get_options(self) -> Dict[str, Any]:
|
|
235
348
|
options = {
|
|
236
349
|
"version-tolerant": self._autorestapi.get_boolean_value("version-tolerant"),
|
|
237
350
|
"azure-arm": self._autorestapi.get_boolean_value("azure-arm"),
|
|
238
351
|
}
|
|
239
352
|
return {k: v for k, v in options.items() if v is not None}
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
if __name__ == "__main__":
|
|
356
|
+
# CADL pipeline will call this
|
|
357
|
+
args = parse_args()
|
|
358
|
+
PreProcessPlugin(
|
|
359
|
+
output_folder=args.output_folder, cadl_file=args.cadl_file
|
|
360
|
+
).process()
|
|
@@ -4,39 +4,9 @@
|
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
6
|
from typing import Any, Dict
|
|
7
|
-
import re
|
|
8
7
|
from .python_mappings import PadType, RESERVED_WORDS, REDEFINED_BUILTINS
|
|
9
8
|
|
|
10
9
|
|
|
11
|
-
def to_snake_case(name: str) -> str:
|
|
12
|
-
def replace_upper_characters(m) -> str:
|
|
13
|
-
match_str = m.group().lower()
|
|
14
|
-
if m.start() > 0 and name[m.start() - 1] == "_":
|
|
15
|
-
# we are good if a '_' already exists
|
|
16
|
-
return match_str
|
|
17
|
-
# the first letter should not have _
|
|
18
|
-
prefix = "_" if m.start() > 0 else ""
|
|
19
|
-
|
|
20
|
-
# we will add an extra _ if there are multiple upper case chars together
|
|
21
|
-
next_non_upper_case_char_location = m.start() + len(match_str)
|
|
22
|
-
if (
|
|
23
|
-
len(match_str) > 2
|
|
24
|
-
and len(name) - next_non_upper_case_char_location > 1
|
|
25
|
-
and name[next_non_upper_case_char_location].isalpha()
|
|
26
|
-
):
|
|
27
|
-
|
|
28
|
-
return (
|
|
29
|
-
prefix
|
|
30
|
-
+ match_str[: len(match_str) - 1]
|
|
31
|
-
+ "_"
|
|
32
|
-
+ match_str[len(match_str) - 1]
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
return prefix + match_str
|
|
36
|
-
|
|
37
|
-
return re.sub("[A-Z]+", replace_upper_characters, name)
|
|
38
|
-
|
|
39
|
-
|
|
40
10
|
def pad_reserved_words(name: str, pad_type: PadType):
|
|
41
11
|
# we want to pad hidden variables as well
|
|
42
12
|
if not name:
|
package/install.py
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
# license information.
|
|
7
7
|
# --------------------------------------------------------------------------
|
|
8
8
|
import sys
|
|
9
|
-
if not sys.version_info >= (3,
|
|
10
|
-
raise Exception("Autorest for Python extension requires Python 3.
|
|
9
|
+
if not sys.version_info >= (3, 7, 0):
|
|
10
|
+
raise Exception("Autorest for Python extension requires Python 3.7 at least")
|
|
11
11
|
|
|
12
12
|
try:
|
|
13
13
|
import pip
|
|
@@ -20,7 +20,7 @@ except ImportError:
|
|
|
20
20
|
raise Exception("Your Python installation doesn't have venv available")
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
# Now we have pip and Py >= 3.
|
|
23
|
+
# Now we have pip and Py >= 3.7, go to work
|
|
24
24
|
|
|
25
25
|
import subprocess
|
|
26
26
|
from pathlib import Path
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autorest/python",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.1.2",
|
|
4
4
|
"description": "The Python extension for generators in AutoRest.",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"prepare": "node run-python3.js prepare.py",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"start.py",
|
|
39
39
|
"venvtools.py",
|
|
40
40
|
"run-python3.js",
|
|
41
|
-
"requirements.txt"
|
|
41
|
+
"requirements.txt",
|
|
42
|
+
"run_cadl.py"
|
|
42
43
|
]
|
|
43
44
|
}
|
package/prepare.py
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
# license information.
|
|
7
7
|
# --------------------------------------------------------------------------
|
|
8
8
|
import sys
|
|
9
|
-
if not sys.version_info >= (3,
|
|
10
|
-
raise Exception("Autorest for Python extension requires Python 3.
|
|
9
|
+
if not sys.version_info >= (3, 7, 0):
|
|
10
|
+
raise Exception("Autorest for Python extension requires Python 3.7 at least")
|
|
11
11
|
|
|
12
12
|
from pathlib import Path
|
|
13
13
|
import venv
|
package/requirements.txt
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
black==
|
|
2
|
-
click==8.
|
|
3
|
-
docutils==0.18
|
|
4
|
-
Jinja2==3.
|
|
1
|
+
black==22.6.0
|
|
2
|
+
click==8.1.3
|
|
3
|
+
docutils==0.18
|
|
4
|
+
Jinja2==3.1.2
|
|
5
5
|
json-rpc==1.13.0
|
|
6
|
-
|
|
7
|
-
MarkupSafe==2.
|
|
6
|
+
m2r2==0.3.2
|
|
7
|
+
MarkupSafe==2.1.1
|
|
8
8
|
mistune==0.8.4
|
|
9
9
|
mypy-extensions==0.4.3
|
|
10
10
|
pathspec==0.9.0
|
|
11
|
-
platformdirs==2.
|
|
11
|
+
platformdirs==2.5.2
|
|
12
12
|
PyYAML==6.0
|
|
13
|
-
tomli==
|
|
14
|
-
typing-extensions==4.0.1
|
|
13
|
+
tomli==2.0.1
|
package/run-python3.js
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
const cp = require("child_process");
|
|
10
10
|
const extension = require("@autorest/system-requirements");
|
|
11
11
|
|
|
12
|
-
async function runPython3(scriptName,
|
|
13
|
-
const command = await extension.patchPythonPath(["python", scriptName,
|
|
12
|
+
async function runPython3(scriptName, ...args) {
|
|
13
|
+
const command = await extension.patchPythonPath(["python", scriptName, ...args], { version: ">=3.7", environmentVariable: "AUTOREST_PYTHON_EXE" });
|
|
14
14
|
cp.execSync(command.join(" "), {
|
|
15
15
|
stdio: [0, 1, 2]
|
|
16
16
|
});
|
package/run_cadl.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# -------------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
# Licensed under the MIT License. See License.txt in the project root for
|
|
4
|
+
# license information.
|
|
5
|
+
# --------------------------------------------------------------------------
|
|
6
|
+
import sys
|
|
7
|
+
import venv
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from venvtools import python_run
|
|
10
|
+
|
|
11
|
+
_ROOT_DIR = Path(__file__).parent
|
|
12
|
+
|
|
13
|
+
if __name__ == "__main__":
|
|
14
|
+
venv_path = _ROOT_DIR / "venv"
|
|
15
|
+
venv_prexists = venv_path.exists()
|
|
16
|
+
|
|
17
|
+
assert venv_prexists # Otherwise install was not done
|
|
18
|
+
|
|
19
|
+
env_builder = venv.EnvBuilder(with_pip=True)
|
|
20
|
+
venv_context = env_builder.ensure_directories(venv_path)
|
|
21
|
+
|
|
22
|
+
# run m2r
|
|
23
|
+
python_run(venv_context, "autorest.m2r.__init__", command=sys.argv[1:])
|
|
24
|
+
python_run(venv_context, "autorest.preprocess.__init__", command=sys.argv[1:])
|
|
25
|
+
python_run(venv_context, "autorest.cadlflags.__init__", command=sys.argv[1:])
|
|
26
|
+
python_run(venv_context, "autorest.codegen.__init__", command=sys.argv[1:])
|
|
27
|
+
python_run(venv_context, "autorest.black.__init__", command=sys.argv[1:])
|
package/setup.py
CHANGED
|
@@ -36,7 +36,6 @@ setup(
|
|
|
36
36
|
'Development Status :: 4 - Beta',
|
|
37
37
|
'Programming Language :: Python',
|
|
38
38
|
'Programming Language :: Python :: 3',
|
|
39
|
-
'Programming Language :: Python :: 3.6',
|
|
40
39
|
'Programming Language :: Python :: 3.7',
|
|
41
40
|
'Programming Language :: Python :: 3.8',
|
|
42
41
|
'License :: OSI Approved :: MIT License',
|
|
@@ -48,8 +47,8 @@ setup(
|
|
|
48
47
|
"json-rpc",
|
|
49
48
|
"Jinja2 >= 2.11", # I need "include" and auto-context + blank line are not indented by default
|
|
50
49
|
"pyyaml",
|
|
51
|
-
"
|
|
52
|
-
"m2r",
|
|
50
|
+
"m2r2",
|
|
53
51
|
"black",
|
|
52
|
+
"docutils<0.19", # m2r2 fails with docutils 0.19
|
|
54
53
|
],
|
|
55
54
|
)
|
package/start.py
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
# license information.
|
|
7
7
|
# --------------------------------------------------------------------------
|
|
8
8
|
import sys
|
|
9
|
-
if not sys.version_info >= (3,
|
|
10
|
-
raise Exception("Autorest for Python extension requires Python 3.
|
|
9
|
+
if not sys.version_info >= (3, 7, 0):
|
|
10
|
+
raise Exception("Autorest for Python extension requires Python 3.7 at least")
|
|
11
11
|
|
|
12
12
|
from pathlib import Path
|
|
13
13
|
import venv
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
# -------------------------------------------------------------------------
|
|
2
|
-
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
-
# Licensed under the MIT License. See License.txt in the project root for
|
|
4
|
-
# license information.
|
|
5
|
-
# --------------------------------------------------------------------------
|
|
6
|
-
from typing import Any, Dict
|
|
7
|
-
from pathlib import Path
|
|
8
|
-
from jinja2 import Environment, PackageLoader
|
|
9
|
-
|
|
10
|
-
from ...jsonrpc import AutorestAPI
|
|
11
|
-
from ... import ReaderAndWriter, ReaderAndWriterAutorest
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class MultiAPISerializer(ReaderAndWriter): # pylint: disable=abstract-method
|
|
15
|
-
def __init__(
|
|
16
|
-
self,
|
|
17
|
-
conf: Dict[str, Any],
|
|
18
|
-
async_mode: bool,
|
|
19
|
-
service_client_filename: str,
|
|
20
|
-
**kwargs: Any
|
|
21
|
-
):
|
|
22
|
-
super().__init__(**kwargs)
|
|
23
|
-
self.conf = conf
|
|
24
|
-
self.async_mode = async_mode
|
|
25
|
-
self.service_client_filename = service_client_filename
|
|
26
|
-
self.env = Environment(
|
|
27
|
-
loader=PackageLoader("autorest.multiapi", "templates"),
|
|
28
|
-
keep_trailing_newline=True,
|
|
29
|
-
line_statement_prefix="##",
|
|
30
|
-
line_comment_prefix="###",
|
|
31
|
-
trim_blocks=True,
|
|
32
|
-
lstrip_blocks=True,
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
def _get_file_path(self, filename: str) -> Path:
|
|
36
|
-
if self.async_mode:
|
|
37
|
-
return Path("aio") / filename
|
|
38
|
-
return Path(filename)
|
|
39
|
-
|
|
40
|
-
def serialize(self):
|
|
41
|
-
self.write_file(
|
|
42
|
-
self._get_file_path("__init__.py"), self.serialize_multiapi_init()
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
service_client_filename_with_py_extension = self.service_client_filename + ".py"
|
|
46
|
-
self.write_file(
|
|
47
|
-
self._get_file_path(service_client_filename_with_py_extension),
|
|
48
|
-
self.serialize_multiapi_client(),
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
configuration_filename = "_configuration.py"
|
|
52
|
-
self.write_file(
|
|
53
|
-
self._get_file_path(configuration_filename),
|
|
54
|
-
self.serialize_multiapi_config(),
|
|
55
|
-
)
|
|
56
|
-
|
|
57
|
-
operation_mixins_filename = "_operations_mixin.py"
|
|
58
|
-
if self.conf["mixin_operations"]:
|
|
59
|
-
self.write_file(
|
|
60
|
-
self._get_file_path(operation_mixins_filename),
|
|
61
|
-
self.serialize_multiapi_operation_mixins(),
|
|
62
|
-
)
|
|
63
|
-
|
|
64
|
-
if self.read_file("_version.py"):
|
|
65
|
-
self.write_file("_version.py", self.read_file("_version.py"))
|
|
66
|
-
elif self.read_file("version.py"):
|
|
67
|
-
self.write_file("_version.py", self.read_file("version.py"))
|
|
68
|
-
else:
|
|
69
|
-
self.write_file(Path("_version.py"), self.serialize_multiapi_version())
|
|
70
|
-
|
|
71
|
-
# don't erase patch file
|
|
72
|
-
if self.read_file("_patch.py"):
|
|
73
|
-
self.write_file("_patch.py", self.read_file("_patch.py"))
|
|
74
|
-
|
|
75
|
-
self.write_file(Path("models.py"), self.serialize_multiapi_models())
|
|
76
|
-
|
|
77
|
-
self.write_file(Path("py.typed"), "# Marker file for PEP 561.")
|
|
78
|
-
|
|
79
|
-
def serialize_multiapi_init(self) -> str:
|
|
80
|
-
template = self.env.get_template("multiapi_init.py.jinja2")
|
|
81
|
-
return template.render(
|
|
82
|
-
service_client_filename=self.service_client_filename,
|
|
83
|
-
client_name=self.conf["client_name"],
|
|
84
|
-
async_mode=self.async_mode,
|
|
85
|
-
)
|
|
86
|
-
|
|
87
|
-
def serialize_multiapi_client(self) -> str:
|
|
88
|
-
template = self.env.get_template("multiapi_service_client.py.jinja2")
|
|
89
|
-
return template.render(**self.conf, async_mode=self.async_mode)
|
|
90
|
-
|
|
91
|
-
def serialize_multiapi_config(self) -> str:
|
|
92
|
-
template = self.env.get_template("multiapi_config.py.jinja2")
|
|
93
|
-
return template.render(**self.conf, async_mode=self.async_mode)
|
|
94
|
-
|
|
95
|
-
def serialize_multiapi_models(self) -> str:
|
|
96
|
-
template = self.env.get_template("multiapi_models.py.jinja2")
|
|
97
|
-
return template.render(**self.conf)
|
|
98
|
-
|
|
99
|
-
def serialize_multiapi_version(self) -> str:
|
|
100
|
-
template = self.env.get_template("multiapi_version.py.jinja2")
|
|
101
|
-
return template.render()
|
|
102
|
-
|
|
103
|
-
def serialize_multiapi_operation_mixins(self) -> str:
|
|
104
|
-
template = self.env.get_template("multiapi_operations_mixin.py.jinja2")
|
|
105
|
-
return template.render(**self.conf, async_mode=self.async_mode)
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
class MultiAPISerializerAutorest(MultiAPISerializer, ReaderAndWriterAutorest):
|
|
109
|
-
def __init__(
|
|
110
|
-
self,
|
|
111
|
-
autorestapi: AutorestAPI,
|
|
112
|
-
conf: Dict[str, Any],
|
|
113
|
-
async_mode: bool,
|
|
114
|
-
service_client_filename: str,
|
|
115
|
-
):
|
|
116
|
-
super().__init__(
|
|
117
|
-
autorestapi=autorestapi,
|
|
118
|
-
conf=conf,
|
|
119
|
-
async_mode=async_mode,
|
|
120
|
-
service_client_filename=service_client_filename,
|
|
121
|
-
)
|