@autorest/python 6.1.11 → 6.2.1
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/autorest/_utils.py +2 -1
- package/autorest/codegen/__init__.py +23 -81
- package/autorest/codegen/models/__init__.py +5 -3
- package/autorest/codegen/models/{base_type.py → base.py} +24 -3
- package/autorest/codegen/models/base_builder.py +9 -5
- package/autorest/codegen/models/client.py +183 -13
- package/autorest/codegen/models/code_model.py +154 -141
- package/autorest/codegen/models/combined_type.py +5 -2
- package/autorest/codegen/models/constant_type.py +38 -4
- package/autorest/codegen/models/credential_types.py +1 -1
- package/autorest/codegen/models/dictionary_type.py +1 -1
- package/autorest/codegen/models/enum_type.py +5 -3
- package/autorest/codegen/models/imports.py +78 -29
- package/autorest/codegen/models/list_type.py +1 -1
- package/autorest/codegen/models/lro_operation.py +5 -1
- package/autorest/codegen/models/model_type.py +1 -2
- package/autorest/codegen/models/operation.py +34 -10
- package/autorest/codegen/models/operation_group.py +16 -5
- package/autorest/codegen/models/paging_operation.py +5 -4
- package/autorest/codegen/models/parameter.py +19 -6
- package/autorest/codegen/models/primitive_types.py +1 -2
- package/autorest/codegen/models/property.py +4 -4
- package/autorest/codegen/models/request_builder.py +17 -6
- package/autorest/codegen/models/request_builder_parameter.py +5 -2
- package/autorest/codegen/models/response.py +6 -3
- package/autorest/codegen/serializers/__init__.py +207 -135
- package/autorest/codegen/serializers/builder_serializer.py +2 -4
- package/autorest/codegen/serializers/client_serializer.py +41 -45
- package/autorest/codegen/serializers/general_serializer.py +80 -37
- package/autorest/codegen/serializers/import_serializer.py +30 -36
- package/autorest/codegen/serializers/metadata_serializer.py +36 -14
- package/autorest/codegen/serializers/model_serializer.py +34 -19
- package/autorest/codegen/serializers/operation_groups_serializer.py +22 -6
- package/autorest/codegen/serializers/operations_init_serializer.py +10 -4
- package/autorest/codegen/serializers/sample_serializer.py +144 -0
- package/autorest/codegen/templates/client.py.jinja2 +7 -15
- package/autorest/codegen/templates/client_container.py.jinja2 +12 -0
- package/autorest/codegen/templates/config.py.jinja2 +13 -26
- package/autorest/codegen/templates/config_container.py.jinja2 +16 -0
- package/autorest/codegen/templates/enum_container.py.jinja2 +1 -1
- package/autorest/codegen/templates/init.py.jinja2 +9 -3
- package/autorest/codegen/templates/lro_operation.py.jinja2 +1 -1
- package/autorest/codegen/templates/metadata.json.jinja2 +13 -14
- package/autorest/codegen/templates/model_dpg.py.jinja2 +4 -4
- package/autorest/codegen/templates/model_init.py.jinja2 +1 -1
- package/autorest/codegen/templates/operation.py.jinja2 +1 -1
- package/autorest/codegen/templates/operation_group.py.jinja2 +2 -2
- package/autorest/codegen/templates/operation_groups_container.py.jinja2 +5 -5
- package/autorest/codegen/templates/operation_tools.jinja2 +2 -2
- package/autorest/codegen/templates/operations_folder_init.py.jinja2 +4 -4
- package/autorest/codegen/templates/{CHANGELOG.md.jinja2 → packaging_templates/CHANGELOG.md.jinja2} +0 -0
- package/autorest/codegen/templates/{LICENSE.jinja2 → packaging_templates/LICENSE.jinja2} +0 -0
- package/autorest/codegen/templates/{MANIFEST.in.jinja2 → packaging_templates/MANIFEST.in.jinja2} +0 -0
- package/autorest/codegen/templates/{README.md.jinja2 → packaging_templates/README.md.jinja2} +0 -0
- package/autorest/codegen/templates/{dev_requirements.txt.jinja2 → packaging_templates/dev_requirements.txt.jinja2} +0 -0
- package/autorest/codegen/templates/{setup.py.jinja2 → packaging_templates/setup.py.jinja2} +12 -9
- package/autorest/codegen/templates/request_builders.py.jinja2 +2 -2
- package/autorest/codegen/templates/sample.py.jinja2 +44 -0
- package/autorest/codegen/templates/vendor.py.jinja2 +4 -2
- package/autorest/m4reformatter/__init__.py +18 -4
- package/autorest/multiapi/models/imports.py +89 -18
- package/autorest/multiapi/serializers/import_serializer.py +88 -7
- package/autorest/multiapi/utils.py +6 -0
- package/autorest/preprocess/__init__.py +20 -8
- package/package.json +1 -1
- package/run_cadl.py +0 -1
- package/autorest/cadlflags/__init__.py +0 -130
- package/autorest/codegen/models/base_model.py +0 -28
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
6
|
from typing import Dict, Optional, List, Any, TYPE_CHECKING, Union
|
|
7
7
|
|
|
8
|
-
from .
|
|
9
|
-
from .
|
|
8
|
+
from .base import BaseModel
|
|
9
|
+
from .base import BaseType
|
|
10
10
|
from .imports import FileImport, ImportType
|
|
11
11
|
from .primitive_types import BinaryType, BinaryIteratorType
|
|
12
12
|
from .dictionary_type import DictionaryType
|
|
@@ -19,7 +19,10 @@ if TYPE_CHECKING:
|
|
|
19
19
|
|
|
20
20
|
class ResponseHeader(BaseModel):
|
|
21
21
|
def __init__(
|
|
22
|
-
self,
|
|
22
|
+
self,
|
|
23
|
+
yaml_data: Dict[str, Any],
|
|
24
|
+
code_model: "CodeModel",
|
|
25
|
+
type: BaseType,
|
|
23
26
|
) -> None:
|
|
24
27
|
super().__init__(yaml_data, code_model)
|
|
25
28
|
self.rest_api_name: str = yaml_data["restApiName"]
|
|
@@ -3,16 +3,20 @@
|
|
|
3
3
|
# Licensed under the MIT License. See License.txt in the project root for
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
|
-
|
|
6
|
+
import logging
|
|
7
|
+
from typing import List, Optional, Any, Union, cast
|
|
7
8
|
from pathlib import Path
|
|
8
9
|
from jinja2 import PackageLoader, Environment, FileSystemLoader, StrictUndefined
|
|
9
|
-
from autorest.codegen.models.operation_group import OperationGroup
|
|
10
|
-
from autorest.codegen.models.request_builder import OverloadedRequestBuilder
|
|
11
10
|
|
|
12
11
|
from ... import ReaderAndWriter, ReaderAndWriterAutorest
|
|
13
12
|
from ...jsonrpc import AutorestAPI
|
|
14
|
-
from ..models import
|
|
15
|
-
|
|
13
|
+
from ..models import (
|
|
14
|
+
OperationGroup,
|
|
15
|
+
RequestBuilder,
|
|
16
|
+
OverloadedRequestBuilder,
|
|
17
|
+
CodeModel,
|
|
18
|
+
Client,
|
|
19
|
+
)
|
|
16
20
|
from .enum_serializer import EnumSerializer
|
|
17
21
|
from .general_serializer import GeneralSerializer
|
|
18
22
|
from .model_init_serializer import ModelInitSerializer
|
|
@@ -22,6 +26,10 @@ from .operation_groups_serializer import OperationGroupsSerializer
|
|
|
22
26
|
from .metadata_serializer import MetadataSerializer
|
|
23
27
|
from .request_builders_serializer import RequestBuildersSerializer
|
|
24
28
|
from .patch_serializer import PatchSerializer
|
|
29
|
+
from .sample_serializer import SampleSerializer
|
|
30
|
+
from ..._utils import to_snake_case
|
|
31
|
+
|
|
32
|
+
_LOGGER = logging.getLogger(__name__)
|
|
25
33
|
|
|
26
34
|
__all__ = [
|
|
27
35
|
"JinjaSerializer",
|
|
@@ -41,7 +49,11 @@ _REGENERATE_FILES = {"setup.py", "MANIFEST.in"}
|
|
|
41
49
|
|
|
42
50
|
class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
|
|
43
51
|
def __init__(
|
|
44
|
-
self,
|
|
52
|
+
self,
|
|
53
|
+
code_model: CodeModel,
|
|
54
|
+
*,
|
|
55
|
+
output_folder: Union[str, Path],
|
|
56
|
+
**kwargs: Any,
|
|
45
57
|
) -> None:
|
|
46
58
|
super().__init__(output_folder=output_folder, **kwargs)
|
|
47
59
|
self.code_model = code_model
|
|
@@ -49,39 +61,24 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
|
|
|
49
61
|
@property
|
|
50
62
|
def has_aio_folder(self) -> bool:
|
|
51
63
|
return not self.code_model.options["no_async"] and bool(
|
|
52
|
-
self.code_model.
|
|
64
|
+
self.code_model.has_operations
|
|
53
65
|
)
|
|
54
66
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
line_statement_prefix="##",
|
|
60
|
-
line_comment_prefix="###",
|
|
61
|
-
trim_blocks=True,
|
|
62
|
-
lstrip_blocks=True,
|
|
67
|
+
@property
|
|
68
|
+
def has_operations_folder(self) -> bool:
|
|
69
|
+
return self.code_model.options["show_operations"] and bool(
|
|
70
|
+
self.code_model.has_operations
|
|
63
71
|
)
|
|
64
72
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
else Path(*(self.code_model.namespace.split(".")))
|
|
69
|
-
)
|
|
73
|
+
def _serialize_namespace_level(
|
|
74
|
+
self, env: Environment, namespace_path: Path, clients: List[Client]
|
|
75
|
+
) -> None:
|
|
70
76
|
# if there was a patch file before, we keep it
|
|
71
77
|
self._keep_patch_file(namespace_path / Path("_patch.py"), env)
|
|
72
78
|
if self.has_aio_folder:
|
|
73
79
|
self._keep_patch_file(namespace_path / Path("aio") / Path("_patch.py"), env)
|
|
74
80
|
|
|
75
|
-
if self.
|
|
76
|
-
self.code_model.model_types or self.code_model.enums
|
|
77
|
-
):
|
|
78
|
-
self._keep_patch_file(
|
|
79
|
-
namespace_path / Path("models") / Path("_patch.py"), env
|
|
80
|
-
)
|
|
81
|
-
if (
|
|
82
|
-
self.code_model.options["show_operations"]
|
|
83
|
-
and self.code_model.operation_groups
|
|
84
|
-
):
|
|
81
|
+
if self.has_operations_folder:
|
|
85
82
|
self._keep_patch_file(
|
|
86
83
|
namespace_path
|
|
87
84
|
/ Path(self.code_model.operations_folder_name)
|
|
@@ -96,12 +93,11 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
|
|
|
96
93
|
/ Path("_patch.py"),
|
|
97
94
|
env,
|
|
98
95
|
)
|
|
99
|
-
|
|
100
96
|
self._serialize_and_write_top_level_folder(
|
|
101
|
-
env=env, namespace_path=namespace_path
|
|
97
|
+
env=env, namespace_path=namespace_path, clients=clients
|
|
102
98
|
)
|
|
103
99
|
|
|
104
|
-
if self.code_model.
|
|
100
|
+
if any(c for c in self.code_model.clients if c.operation_groups):
|
|
105
101
|
if self.code_model.options["builders_visibility"] != "embedded":
|
|
106
102
|
self._serialize_and_write_rest_layer(
|
|
107
103
|
env=env, namespace_path=namespace_path
|
|
@@ -110,19 +106,78 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
|
|
|
110
106
|
self._serialize_and_write_aio_top_level_folder(
|
|
111
107
|
env=env,
|
|
112
108
|
namespace_path=namespace_path,
|
|
109
|
+
clients=clients,
|
|
113
110
|
)
|
|
114
111
|
|
|
115
|
-
if
|
|
116
|
-
self.code_model.options["show_operations"]
|
|
117
|
-
and self.code_model.operation_groups
|
|
118
|
-
):
|
|
112
|
+
if self.has_operations_folder:
|
|
119
113
|
self._serialize_and_write_operations_folder(
|
|
120
|
-
env=env, namespace_path=namespace_path
|
|
114
|
+
clients, env=env, namespace_path=namespace_path
|
|
121
115
|
)
|
|
122
116
|
if self.code_model.options["multiapi"]:
|
|
123
117
|
self._serialize_and_write_metadata(
|
|
124
118
|
env=env, namespace_path=namespace_path
|
|
125
119
|
)
|
|
120
|
+
if self.code_model.options["package_mode"]:
|
|
121
|
+
self._serialize_and_write_package_files(namespace_path=namespace_path)
|
|
122
|
+
|
|
123
|
+
if (
|
|
124
|
+
self.code_model.options["show_operations"]
|
|
125
|
+
and self.code_model.has_operations
|
|
126
|
+
and self.code_model.options["generate_sample"]
|
|
127
|
+
and not self.code_model.options["multiapi"]
|
|
128
|
+
):
|
|
129
|
+
self._serialize_and_write_sample(env, namespace_path)
|
|
130
|
+
|
|
131
|
+
def serialize(self) -> None:
|
|
132
|
+
env = Environment(
|
|
133
|
+
loader=PackageLoader("autorest.codegen", "templates"),
|
|
134
|
+
keep_trailing_newline=True,
|
|
135
|
+
line_statement_prefix="##",
|
|
136
|
+
line_comment_prefix="###",
|
|
137
|
+
trim_blocks=True,
|
|
138
|
+
lstrip_blocks=True,
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
namespace_path = (
|
|
142
|
+
Path(".")
|
|
143
|
+
if self.code_model.options["no_namespace_folders"]
|
|
144
|
+
else Path(*(self.code_model.namespace.split(".")))
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
p = namespace_path.parent
|
|
148
|
+
general_serializer = GeneralSerializer(
|
|
149
|
+
code_model=self.code_model, env=env, async_mode=False
|
|
150
|
+
)
|
|
151
|
+
while p != Path("."):
|
|
152
|
+
# write pkgutil init file
|
|
153
|
+
self.write_file(
|
|
154
|
+
p / Path("__init__.py"),
|
|
155
|
+
general_serializer.serialize_pkgutil_init_file(),
|
|
156
|
+
)
|
|
157
|
+
p = p.parent
|
|
158
|
+
|
|
159
|
+
# serialize main module
|
|
160
|
+
self._serialize_namespace_level(
|
|
161
|
+
env,
|
|
162
|
+
namespace_path,
|
|
163
|
+
[c for c in self.code_model.clients if c.has_operations],
|
|
164
|
+
)
|
|
165
|
+
# serialize sub modules
|
|
166
|
+
for (
|
|
167
|
+
subnamespace,
|
|
168
|
+
clients,
|
|
169
|
+
) in self.code_model.subnamespace_to_clients.items():
|
|
170
|
+
subnamespace_path = namespace_path / Path(subnamespace)
|
|
171
|
+
self._serialize_namespace_level(
|
|
172
|
+
env, subnamespace_path, [c for c in clients if c.has_operations]
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
if self.code_model.options["models_mode"] and (
|
|
176
|
+
self.code_model.model_types or self.code_model.enums
|
|
177
|
+
):
|
|
178
|
+
self._keep_patch_file(
|
|
179
|
+
namespace_path / Path("models") / Path("_patch.py"), env
|
|
180
|
+
)
|
|
126
181
|
|
|
127
182
|
if self.code_model.options["models_mode"] and (
|
|
128
183
|
self.code_model.model_types or self.code_model.enums
|
|
@@ -138,57 +193,17 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
|
|
|
138
193
|
cast(str, self.read_file(namespace_path / Path("models.py"))),
|
|
139
194
|
)
|
|
140
195
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
def _serialize_and_write_package_files(self, out_path: Path) -> None:
|
|
145
|
-
def _serialize_and_write_package_files_proc(**kwargs: Any):
|
|
146
|
-
for template_name in package_files:
|
|
147
|
-
file = template_name.replace(".jinja2", "")
|
|
148
|
-
output_name = out_path / file
|
|
149
|
-
if not self.read_file(output_name) or file in _REGENERATE_FILES:
|
|
150
|
-
template = env.get_template(template_name)
|
|
151
|
-
render_result = template.render(**kwargs)
|
|
152
|
-
self.write_file(output_name, render_result)
|
|
153
|
-
|
|
154
|
-
def _prepare_params() -> Dict[Any, Any]:
|
|
155
|
-
package_parts = (self.code_model.options["package_name"] or "").split("-")[
|
|
156
|
-
:-1
|
|
157
|
-
]
|
|
158
|
-
token_cred = isinstance(
|
|
159
|
-
getattr(self.code_model.credential, "type", None), TokenCredentialType
|
|
160
|
-
)
|
|
161
|
-
version = self.code_model.options["package_version"]
|
|
162
|
-
if any(x in version for x in ["a", "b", "rc"]) or version[0] == "0":
|
|
163
|
-
dev_status = "4 - Beta"
|
|
164
|
-
else:
|
|
165
|
-
dev_status = "5 - Production/Stable"
|
|
166
|
-
params = {
|
|
167
|
-
"token_credential": token_cred,
|
|
168
|
-
"pkgutil_names": [
|
|
169
|
-
".".join(package_parts[: i + 1]) for i in range(len(package_parts))
|
|
170
|
-
],
|
|
171
|
-
"init_names": [
|
|
172
|
-
"/".join(package_parts[: i + 1]) + "/__init__.py"
|
|
173
|
-
for i in range(len(package_parts))
|
|
174
|
-
],
|
|
175
|
-
"dev_status": dev_status,
|
|
176
|
-
"client_name": self.code_model.client.name,
|
|
177
|
-
"namespace": self.code_model.namespace,
|
|
178
|
-
"code_model": self.code_model,
|
|
179
|
-
}
|
|
180
|
-
params.update(self.code_model.options)
|
|
181
|
-
params.update(self.code_model.package_dependency)
|
|
182
|
-
return params
|
|
183
|
-
|
|
184
|
-
out_path = out_path / Path("../" * (self.code_model.namespace.count(".") + 1))
|
|
196
|
+
def _serialize_and_write_package_files(self, namespace_path: Path) -> None:
|
|
197
|
+
root_of_sdk = self._package_root_folder(namespace_path)
|
|
185
198
|
if self.code_model.options["package_mode"] in ("dataplane", "mgmtplane"):
|
|
186
199
|
env = Environment(
|
|
187
|
-
loader=PackageLoader(
|
|
200
|
+
loader=PackageLoader(
|
|
201
|
+
"autorest.codegen", "templates/packaging_templates"
|
|
202
|
+
),
|
|
188
203
|
undefined=StrictUndefined,
|
|
189
204
|
)
|
|
205
|
+
|
|
190
206
|
package_files = _PACKAGE_FILES
|
|
191
|
-
_serialize_and_write_package_files_proc(**_prepare_params())
|
|
192
207
|
elif Path(self.code_model.options["package_mode"]).exists():
|
|
193
208
|
env = Environment(
|
|
194
209
|
loader=FileSystemLoader(
|
|
@@ -198,8 +213,18 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
|
|
|
198
213
|
undefined=StrictUndefined,
|
|
199
214
|
)
|
|
200
215
|
package_files = env.list_templates()
|
|
201
|
-
|
|
202
|
-
|
|
216
|
+
else:
|
|
217
|
+
return
|
|
218
|
+
serializer = GeneralSerializer(self.code_model, env, async_mode=False)
|
|
219
|
+
params = self.code_model.options["package_configuration"] or {}
|
|
220
|
+
for template_name in package_files:
|
|
221
|
+
file = template_name.replace(".jinja2", "")
|
|
222
|
+
output_name = root_of_sdk / file
|
|
223
|
+
if not self.read_file(output_name) or file in _REGENERATE_FILES:
|
|
224
|
+
self.write_file(
|
|
225
|
+
output_name,
|
|
226
|
+
serializer.serialize_package_file(template_name, **params),
|
|
227
|
+
)
|
|
203
228
|
|
|
204
229
|
def _keep_patch_file(self, path_file: Path, env: Environment):
|
|
205
230
|
if self.read_file(path_file):
|
|
@@ -239,12 +264,15 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
|
|
|
239
264
|
self, env: Environment, namespace_path: Path
|
|
240
265
|
) -> None:
|
|
241
266
|
rest_path = namespace_path / Path(self.code_model.rest_layer_name)
|
|
242
|
-
group_names = {
|
|
267
|
+
group_names = {
|
|
268
|
+
rb.group_name for c in self.code_model.clients for rb in c.request_builders
|
|
269
|
+
}
|
|
243
270
|
|
|
244
271
|
for group_name in group_names:
|
|
245
272
|
request_builders = [
|
|
246
273
|
r
|
|
247
|
-
for
|
|
274
|
+
for c in self.code_model.clients
|
|
275
|
+
for r in c.request_builders
|
|
248
276
|
if r.group_name == group_name
|
|
249
277
|
]
|
|
250
278
|
self._serialize_and_write_single_rest_layer(
|
|
@@ -287,6 +315,7 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
|
|
|
287
315
|
def _serialize_and_write_operations_file(
|
|
288
316
|
self,
|
|
289
317
|
env: Environment,
|
|
318
|
+
clients: List[Client],
|
|
290
319
|
namespace_path: Path,
|
|
291
320
|
operation_group: Optional[OperationGroup] = None,
|
|
292
321
|
) -> None:
|
|
@@ -294,6 +323,7 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
|
|
|
294
323
|
# write first sync file
|
|
295
324
|
operation_group_serializer = OperationGroupsSerializer(
|
|
296
325
|
code_model=self.code_model,
|
|
326
|
+
clients=clients,
|
|
297
327
|
env=env,
|
|
298
328
|
async_mode=False,
|
|
299
329
|
operation_group=operation_group,
|
|
@@ -309,6 +339,7 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
|
|
|
309
339
|
# write async operation group and operation files
|
|
310
340
|
operation_group_async_serializer = OperationGroupsSerializer(
|
|
311
341
|
code_model=self.code_model,
|
|
342
|
+
clients=clients,
|
|
312
343
|
env=env,
|
|
313
344
|
async_mode=True,
|
|
314
345
|
operation_group=operation_group,
|
|
@@ -324,11 +355,11 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
|
|
|
324
355
|
)
|
|
325
356
|
|
|
326
357
|
def _serialize_and_write_operations_folder(
|
|
327
|
-
self, env: Environment, namespace_path: Path
|
|
358
|
+
self, clients: List[Client], env: Environment, namespace_path: Path
|
|
328
359
|
) -> None:
|
|
329
360
|
# write sync operations init file
|
|
330
361
|
operations_init_serializer = OperationsInitSerializer(
|
|
331
|
-
code_model=self.code_model, env=env, async_mode=False
|
|
362
|
+
code_model=self.code_model, clients=clients, env=env, async_mode=False
|
|
332
363
|
)
|
|
333
364
|
self.write_file(
|
|
334
365
|
namespace_path
|
|
@@ -340,7 +371,7 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
|
|
|
340
371
|
# write async operations init file
|
|
341
372
|
if self.has_aio_folder:
|
|
342
373
|
operations_async_init_serializer = OperationsInitSerializer(
|
|
343
|
-
code_model=self.code_model, env=env, async_mode=True
|
|
374
|
+
code_model=self.code_model, clients=clients, env=env, async_mode=True
|
|
344
375
|
)
|
|
345
376
|
self.write_file(
|
|
346
377
|
namespace_path
|
|
@@ -354,17 +385,22 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
|
|
|
354
385
|
self._serialize_and_write_operations_file(
|
|
355
386
|
env=env,
|
|
356
387
|
namespace_path=namespace_path,
|
|
388
|
+
clients=clients,
|
|
357
389
|
)
|
|
358
390
|
else:
|
|
359
|
-
for
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
391
|
+
for client in self.code_model.clients:
|
|
392
|
+
for operation_group in client.operation_groups:
|
|
393
|
+
self._serialize_and_write_operations_file(
|
|
394
|
+
env=env,
|
|
395
|
+
namespace_path=namespace_path,
|
|
396
|
+
operation_group=operation_group,
|
|
397
|
+
clients=self.code_model.clients,
|
|
398
|
+
)
|
|
365
399
|
|
|
366
400
|
def _serialize_and_write_version_file(
|
|
367
|
-
self,
|
|
401
|
+
self,
|
|
402
|
+
namespace_path: Path,
|
|
403
|
+
general_serializer: GeneralSerializer,
|
|
368
404
|
):
|
|
369
405
|
def _read_version_file(original_version_file_name: str) -> str:
|
|
370
406
|
return self.read_file(namespace_path / original_version_file_name)
|
|
@@ -386,8 +422,28 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
|
|
|
386
422
|
general_serializer.serialize_version_file(),
|
|
387
423
|
)
|
|
388
424
|
|
|
425
|
+
def _serialize_client_and_config_files(
|
|
426
|
+
self,
|
|
427
|
+
namespace_path: Path,
|
|
428
|
+
general_serializer: GeneralSerializer,
|
|
429
|
+
async_mode: bool,
|
|
430
|
+
clients: List[Client],
|
|
431
|
+
) -> None:
|
|
432
|
+
if self.code_model.has_operations:
|
|
433
|
+
namespace_path = (
|
|
434
|
+
namespace_path / Path("aio") if async_mode else namespace_path
|
|
435
|
+
)
|
|
436
|
+
self.write_file(
|
|
437
|
+
namespace_path / Path(f"{self.code_model.client_filename}.py"),
|
|
438
|
+
general_serializer.serialize_service_client_file(clients),
|
|
439
|
+
)
|
|
440
|
+
self.write_file(
|
|
441
|
+
namespace_path / Path("_configuration.py"),
|
|
442
|
+
general_serializer.serialize_config_file(clients),
|
|
443
|
+
)
|
|
444
|
+
|
|
389
445
|
def _serialize_and_write_top_level_folder(
|
|
390
|
-
self, env: Environment, namespace_path: Path
|
|
446
|
+
self, env: Environment, namespace_path: Path, clients: List[Client]
|
|
391
447
|
) -> None:
|
|
392
448
|
general_serializer = GeneralSerializer(
|
|
393
449
|
code_model=self.code_model, env=env, async_mode=False
|
|
@@ -395,24 +451,13 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
|
|
|
395
451
|
|
|
396
452
|
self.write_file(
|
|
397
453
|
namespace_path / Path("__init__.py"),
|
|
398
|
-
general_serializer.serialize_init_file(),
|
|
454
|
+
general_serializer.serialize_init_file(clients),
|
|
399
455
|
)
|
|
400
|
-
p = namespace_path.parent
|
|
401
|
-
while p != Path("."):
|
|
402
|
-
# write pkgutil init file
|
|
403
|
-
self.write_file(
|
|
404
|
-
p / Path("__init__.py"),
|
|
405
|
-
general_serializer.serialize_pkgutil_init_file(),
|
|
406
|
-
)
|
|
407
|
-
p = p.parent
|
|
408
456
|
|
|
409
457
|
# Write the service client
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
general_serializer.serialize_service_client_file(),
|
|
414
|
-
)
|
|
415
|
-
|
|
458
|
+
self._serialize_client_and_config_files(
|
|
459
|
+
namespace_path, general_serializer, async_mode=False, clients=clients
|
|
460
|
+
)
|
|
416
461
|
if self.code_model.need_vendored_code(async_mode=False):
|
|
417
462
|
self.write_file(
|
|
418
463
|
namespace_path / Path("_vendor.py"),
|
|
@@ -438,25 +483,23 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
|
|
|
438
483
|
general_serializer.serialize_model_base_file(),
|
|
439
484
|
)
|
|
440
485
|
|
|
441
|
-
if any(
|
|
486
|
+
if any(
|
|
487
|
+
og
|
|
488
|
+
for client in self.code_model.clients
|
|
489
|
+
for og in client.operation_groups
|
|
490
|
+
if og.need_validation
|
|
491
|
+
):
|
|
442
492
|
self.write_file(
|
|
443
493
|
namespace_path / Path("_validation.py"),
|
|
444
494
|
general_serializer.serialize_validation_file(),
|
|
445
495
|
)
|
|
446
496
|
|
|
447
|
-
# Write the config file
|
|
448
|
-
if self.code_model.request_builders:
|
|
449
|
-
self.write_file(
|
|
450
|
-
namespace_path / Path("_configuration.py"),
|
|
451
|
-
general_serializer.serialize_config_file(),
|
|
452
|
-
)
|
|
453
|
-
|
|
454
497
|
# Write the setup file
|
|
455
498
|
if self.code_model.options["basic_setup_py"]:
|
|
456
499
|
self.write_file(Path("setup.py"), general_serializer.serialize_setup_file())
|
|
457
500
|
|
|
458
501
|
def _serialize_and_write_aio_top_level_folder(
|
|
459
|
-
self, env: Environment, namespace_path: Path
|
|
502
|
+
self, env: Environment, namespace_path: Path, clients: List[Client]
|
|
460
503
|
) -> None:
|
|
461
504
|
aio_general_serializer = GeneralSerializer(
|
|
462
505
|
code_model=self.code_model, env=env, async_mode=True
|
|
@@ -466,20 +509,13 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
|
|
|
466
509
|
|
|
467
510
|
# Write the __init__ file
|
|
468
511
|
self.write_file(
|
|
469
|
-
aio_path / Path("__init__.py"),
|
|
512
|
+
aio_path / Path("__init__.py"),
|
|
513
|
+
aio_general_serializer.serialize_init_file(clients),
|
|
470
514
|
)
|
|
471
515
|
|
|
472
516
|
# Write the service client
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
aio_path / Path(f"{self.code_model.client.filename}.py"),
|
|
476
|
-
aio_general_serializer.serialize_service_client_file(),
|
|
477
|
-
)
|
|
478
|
-
|
|
479
|
-
# Write the config file
|
|
480
|
-
self.write_file(
|
|
481
|
-
aio_path / Path("_configuration.py"),
|
|
482
|
-
aio_general_serializer.serialize_config_file(),
|
|
517
|
+
self._serialize_client_and_config_files(
|
|
518
|
+
namespace_path, aio_general_serializer, async_mode=True, clients=clients
|
|
483
519
|
)
|
|
484
520
|
if self.code_model.need_vendored_code(async_mode=True):
|
|
485
521
|
self.write_file(
|
|
@@ -495,6 +531,38 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
|
|
|
495
531
|
namespace_path / Path("_metadata.json"), metadata_serializer.serialize()
|
|
496
532
|
)
|
|
497
533
|
|
|
534
|
+
# find root folder where "setup.py" is
|
|
535
|
+
def _package_root_folder(self, namespace_path: Path) -> Path:
|
|
536
|
+
return namespace_path / Path("../" * (self.code_model.namespace.count(".") + 1))
|
|
537
|
+
|
|
538
|
+
def _serialize_and_write_sample(self, env: Environment, namespace_path: Path):
|
|
539
|
+
out_path = self._package_root_folder(namespace_path) / Path("generated_samples")
|
|
540
|
+
for client in self.code_model.clients:
|
|
541
|
+
for op_group in client.operation_groups:
|
|
542
|
+
for operation in op_group.operations:
|
|
543
|
+
samples = operation.yaml_data["samples"]
|
|
544
|
+
if not samples or operation.name.startswith("_"):
|
|
545
|
+
continue
|
|
546
|
+
for key, value in samples.items():
|
|
547
|
+
file_name = to_snake_case(key) + ".py"
|
|
548
|
+
try:
|
|
549
|
+
self.write_file(
|
|
550
|
+
out_path / file_name,
|
|
551
|
+
SampleSerializer(
|
|
552
|
+
code_model=self.code_model,
|
|
553
|
+
env=env,
|
|
554
|
+
operation_group=op_group,
|
|
555
|
+
operation=operation,
|
|
556
|
+
sample=value,
|
|
557
|
+
file_name=file_name,
|
|
558
|
+
sample_origin_name=key,
|
|
559
|
+
).serialize(),
|
|
560
|
+
)
|
|
561
|
+
except Exception as e: # pylint: disable=broad-except
|
|
562
|
+
# sample generation shall not block code generation, so just log error
|
|
563
|
+
log_error = f"error happens in sample {key}: {e}"
|
|
564
|
+
_LOGGER.error(log_error)
|
|
565
|
+
|
|
498
566
|
|
|
499
567
|
class JinjaSerializerAutorest(JinjaSerializer, ReaderAndWriterAutorest):
|
|
500
568
|
def __init__(
|
|
@@ -503,7 +571,11 @@ class JinjaSerializerAutorest(JinjaSerializer, ReaderAndWriterAutorest):
|
|
|
503
571
|
code_model: CodeModel,
|
|
504
572
|
*,
|
|
505
573
|
output_folder: Union[str, Path],
|
|
574
|
+
**kwargs: Any,
|
|
506
575
|
) -> None:
|
|
507
576
|
super().__init__(
|
|
508
|
-
autorestapi=autorestapi,
|
|
577
|
+
autorestapi=autorestapi,
|
|
578
|
+
code_model=code_model,
|
|
579
|
+
output_folder=output_folder,
|
|
580
|
+
**kwargs,
|
|
509
581
|
)
|
|
@@ -12,8 +12,8 @@ from typing import Any, Generic, List, Type, TypeVar, Dict, Union, Optional, cas
|
|
|
12
12
|
|
|
13
13
|
from ..models import (
|
|
14
14
|
Operation,
|
|
15
|
-
CodeModel,
|
|
16
15
|
PagingOperation,
|
|
16
|
+
CodeModel,
|
|
17
17
|
LROOperation,
|
|
18
18
|
LROPagingOperation,
|
|
19
19
|
ModelType,
|
|
@@ -1203,9 +1203,7 @@ class _PagingOperationSerializer(
|
|
|
1203
1203
|
next_link_str = "next_link"
|
|
1204
1204
|
try:
|
|
1205
1205
|
api_version_param = next(
|
|
1206
|
-
p
|
|
1207
|
-
for p in self.code_model.client.parameters
|
|
1208
|
-
if p.rest_api_name == "api-version"
|
|
1206
|
+
p for p in builder.client.parameters if p.rest_api_name == "api-version"
|
|
1209
1207
|
)
|
|
1210
1208
|
retval.append("# make call to next link with the client's api-version")
|
|
1211
1209
|
retval.append("_parsed_next_link = urllib.parse.urlparse(next_link)")
|