@autorest/python 6.27.4 → 6.28.0
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/generator/build/lib/pygen/black.py +3 -3
- package/generator/build/lib/pygen/codegen/__init__.py +2 -0
- package/generator/build/lib/pygen/codegen/_utils.py +4 -0
- package/generator/build/lib/pygen/codegen/models/base.py +2 -3
- package/generator/build/lib/pygen/codegen/models/base_builder.py +5 -3
- package/generator/build/lib/pygen/codegen/models/client.py +28 -19
- package/generator/build/lib/pygen/codegen/models/code_model.py +200 -33
- package/generator/build/lib/pygen/codegen/models/combined_type.py +8 -5
- package/generator/build/lib/pygen/codegen/models/constant_type.py +2 -3
- package/generator/build/lib/pygen/codegen/models/credential_types.py +2 -3
- package/generator/build/lib/pygen/codegen/models/dictionary_type.py +2 -3
- package/generator/build/lib/pygen/codegen/models/enum_type.py +47 -24
- package/generator/build/lib/pygen/codegen/models/imports.py +14 -12
- package/generator/build/lib/pygen/codegen/models/list_type.py +2 -3
- package/generator/build/lib/pygen/codegen/models/lro_operation.py +8 -4
- package/generator/build/lib/pygen/codegen/models/lro_paging_operation.py +2 -2
- package/generator/build/lib/pygen/codegen/models/model_type.py +34 -19
- package/generator/build/lib/pygen/codegen/models/operation.py +66 -29
- package/generator/build/lib/pygen/codegen/models/operation_group.py +56 -11
- package/generator/build/lib/pygen/codegen/models/paging_operation.py +9 -6
- package/generator/build/lib/pygen/codegen/models/parameter.py +10 -10
- package/generator/build/lib/pygen/codegen/models/parameter_list.py +7 -7
- package/generator/build/lib/pygen/codegen/models/primitive_types.py +23 -43
- package/generator/build/lib/pygen/codegen/models/property.py +7 -7
- package/generator/build/lib/pygen/codegen/models/request_builder.py +9 -15
- package/generator/build/lib/pygen/codegen/models/response.py +6 -8
- package/generator/build/lib/pygen/codegen/models/utils.py +11 -0
- package/generator/build/lib/pygen/codegen/serializers/__init__.py +219 -244
- package/generator/build/lib/pygen/codegen/serializers/base_serializer.py +19 -1
- package/generator/build/lib/pygen/codegen/serializers/builder_serializer.py +53 -35
- package/generator/build/lib/pygen/codegen/serializers/client_serializer.py +9 -5
- package/generator/build/lib/pygen/codegen/serializers/enum_serializer.py +17 -3
- package/generator/build/lib/pygen/codegen/serializers/general_serializer.py +26 -14
- package/generator/build/lib/pygen/codegen/serializers/metadata_serializer.py +26 -8
- package/generator/build/lib/pygen/codegen/serializers/model_init_serializer.py +9 -4
- package/generator/build/lib/pygen/codegen/serializers/model_serializer.py +63 -23
- package/generator/build/lib/pygen/codegen/serializers/operation_groups_serializer.py +19 -16
- package/generator/build/lib/pygen/codegen/serializers/operations_init_serializer.py +5 -10
- package/generator/build/lib/pygen/codegen/serializers/parameter_serializer.py +10 -7
- package/generator/build/lib/pygen/codegen/serializers/request_builders_serializer.py +10 -1
- package/generator/build/lib/pygen/codegen/serializers/sample_serializer.py +7 -10
- package/generator/build/lib/pygen/codegen/serializers/test_serializer.py +24 -28
- package/generator/build/lib/pygen/codegen/serializers/types_serializer.py +6 -1
- package/generator/build/lib/pygen/codegen/serializers/utils.py +1 -15
- package/generator/build/lib/pygen/codegen/templates/client_container.py.jinja2 +1 -1
- package/generator/build/lib/pygen/codegen/templates/config_container.py.jinja2 +1 -1
- package/generator/build/lib/pygen/codegen/templates/enum_container.py.jinja2 +1 -1
- package/generator/build/lib/pygen/codegen/templates/init.py.jinja2 +1 -1
- package/generator/build/lib/pygen/codegen/templates/model_container.py.jinja2 +1 -1
- package/generator/build/lib/pygen/codegen/templates/operations_folder_init.py.jinja2 +2 -4
- package/generator/build/lib/pygen/codegen/templates/test.py.jinja2 +3 -3
- package/generator/build/lib/pygen/codegen/templates/testpreparer.py.jinja2 +2 -2
- package/generator/build/lib/pygen/codegen/templates/vendor.py.jinja2 +4 -4
- package/generator/build/lib/pygen/preprocess/__init__.py +0 -4
- package/generator/component-detection-pip-report.json +2 -2
- package/generator/dev_requirements.txt +2 -2
- package/generator/dist/pygen-0.1.0-py3-none-any.whl +0 -0
- package/generator/pygen/black.py +3 -3
- package/generator/pygen/codegen/__init__.py +2 -0
- package/generator/pygen/codegen/_utils.py +4 -0
- package/generator/pygen/codegen/models/base.py +2 -3
- package/generator/pygen/codegen/models/base_builder.py +5 -3
- package/generator/pygen/codegen/models/client.py +28 -19
- package/generator/pygen/codegen/models/code_model.py +200 -33
- package/generator/pygen/codegen/models/combined_type.py +8 -5
- package/generator/pygen/codegen/models/constant_type.py +2 -3
- package/generator/pygen/codegen/models/credential_types.py +2 -3
- package/generator/pygen/codegen/models/dictionary_type.py +2 -3
- package/generator/pygen/codegen/models/enum_type.py +47 -24
- package/generator/pygen/codegen/models/imports.py +14 -12
- package/generator/pygen/codegen/models/list_type.py +2 -3
- package/generator/pygen/codegen/models/lro_operation.py +8 -4
- package/generator/pygen/codegen/models/lro_paging_operation.py +2 -2
- package/generator/pygen/codegen/models/model_type.py +34 -19
- package/generator/pygen/codegen/models/operation.py +66 -29
- package/generator/pygen/codegen/models/operation_group.py +56 -11
- package/generator/pygen/codegen/models/paging_operation.py +9 -6
- package/generator/pygen/codegen/models/parameter.py +10 -10
- package/generator/pygen/codegen/models/parameter_list.py +7 -7
- package/generator/pygen/codegen/models/primitive_types.py +23 -43
- package/generator/pygen/codegen/models/property.py +7 -7
- package/generator/pygen/codegen/models/request_builder.py +9 -15
- package/generator/pygen/codegen/models/response.py +6 -8
- package/generator/pygen/codegen/models/utils.py +11 -0
- package/generator/pygen/codegen/serializers/__init__.py +219 -244
- package/generator/pygen/codegen/serializers/base_serializer.py +19 -1
- package/generator/pygen/codegen/serializers/builder_serializer.py +53 -35
- package/generator/pygen/codegen/serializers/client_serializer.py +9 -5
- package/generator/pygen/codegen/serializers/enum_serializer.py +17 -3
- package/generator/pygen/codegen/serializers/general_serializer.py +26 -14
- package/generator/pygen/codegen/serializers/metadata_serializer.py +26 -8
- package/generator/pygen/codegen/serializers/model_init_serializer.py +9 -4
- package/generator/pygen/codegen/serializers/model_serializer.py +63 -23
- package/generator/pygen/codegen/serializers/operation_groups_serializer.py +19 -16
- package/generator/pygen/codegen/serializers/operations_init_serializer.py +5 -10
- package/generator/pygen/codegen/serializers/parameter_serializer.py +10 -7
- package/generator/pygen/codegen/serializers/request_builders_serializer.py +10 -1
- package/generator/pygen/codegen/serializers/sample_serializer.py +7 -10
- package/generator/pygen/codegen/serializers/test_serializer.py +24 -28
- package/generator/pygen/codegen/serializers/types_serializer.py +6 -1
- package/generator/pygen/codegen/serializers/utils.py +1 -15
- package/generator/pygen/codegen/templates/client_container.py.jinja2 +1 -1
- package/generator/pygen/codegen/templates/config_container.py.jinja2 +1 -1
- package/generator/pygen/codegen/templates/enum_container.py.jinja2 +1 -1
- package/generator/pygen/codegen/templates/init.py.jinja2 +1 -1
- package/generator/pygen/codegen/templates/model_container.py.jinja2 +1 -1
- package/generator/pygen/codegen/templates/operations_folder_init.py.jinja2 +2 -4
- package/generator/pygen/codegen/templates/test.py.jinja2 +3 -3
- package/generator/pygen/codegen/templates/testpreparer.py.jinja2 +2 -2
- package/generator/pygen/codegen/templates/vendor.py.jinja2 +4 -4
- package/generator/pygen/preprocess/__init__.py +0 -4
- package/generator/pygen.egg-info/PKG-INFO +10 -1
- package/package.json +2 -2
- package/scripts/__pycache__/venvtools.cpython-310.pyc +0 -0
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
6
|
import logging
|
|
7
|
-
from
|
|
7
|
+
from collections import namedtuple
|
|
8
|
+
import re
|
|
9
|
+
from typing import List, Any, Union
|
|
8
10
|
from pathlib import Path
|
|
9
11
|
from jinja2 import PackageLoader, Environment, FileSystemLoader, StrictUndefined
|
|
10
12
|
|
|
@@ -15,6 +17,8 @@ from ..models import (
|
|
|
15
17
|
OverloadedRequestBuilder,
|
|
16
18
|
CodeModel,
|
|
17
19
|
Client,
|
|
20
|
+
ModelType,
|
|
21
|
+
EnumType,
|
|
18
22
|
)
|
|
19
23
|
from .enum_serializer import EnumSerializer
|
|
20
24
|
from .general_serializer import GeneralSerializer
|
|
@@ -34,7 +38,6 @@ from .utils import (
|
|
|
34
38
|
extract_sample_name,
|
|
35
39
|
get_namespace_from_package_name,
|
|
36
40
|
get_namespace_config,
|
|
37
|
-
get_all_operation_groups_recursively,
|
|
38
41
|
)
|
|
39
42
|
|
|
40
43
|
_LOGGER = logging.getLogger(__name__)
|
|
@@ -53,6 +56,7 @@ _PACKAGE_FILES = [
|
|
|
53
56
|
]
|
|
54
57
|
|
|
55
58
|
_REGENERATE_FILES = {"setup.py", "MANIFEST.in"}
|
|
59
|
+
AsyncInfo = namedtuple("AsyncInfo", ["async_mode", "async_path"])
|
|
56
60
|
|
|
57
61
|
|
|
58
62
|
# extract sub folders. For example, source_file_path is like:
|
|
@@ -85,54 +89,24 @@ class JinjaSerializer(ReaderAndWriter):
|
|
|
85
89
|
def has_operations_folder(self) -> bool:
|
|
86
90
|
return self.code_model.options["show_operations"] and bool(self.code_model.has_operations)
|
|
87
91
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
if self.has_operations_folder:
|
|
95
|
-
self._keep_patch_file(
|
|
96
|
-
namespace_path / Path(self.code_model.operations_folder_name) / Path("_patch.py"),
|
|
97
|
-
env,
|
|
98
|
-
)
|
|
99
|
-
if self.has_aio_folder:
|
|
100
|
-
self._keep_patch_file(
|
|
101
|
-
namespace_path / Path("aio") / Path(self.code_model.operations_folder_name) / Path("_patch.py"),
|
|
102
|
-
env,
|
|
103
|
-
)
|
|
104
|
-
self._serialize_and_write_top_level_folder(env=env, namespace_path=namespace_path, clients=clients)
|
|
105
|
-
|
|
106
|
-
if any(c for c in self.code_model.clients if c.operation_groups):
|
|
107
|
-
if self.code_model.options["builders_visibility"] != "embedded":
|
|
108
|
-
self._serialize_and_write_rest_layer(env=env, namespace_path=namespace_path)
|
|
109
|
-
if self.has_aio_folder:
|
|
110
|
-
self._serialize_and_write_aio_top_level_folder(
|
|
111
|
-
env=env,
|
|
112
|
-
namespace_path=namespace_path,
|
|
113
|
-
clients=clients,
|
|
114
|
-
)
|
|
92
|
+
@property
|
|
93
|
+
def serialize_loop(self) -> List[AsyncInfo]:
|
|
94
|
+
sync_loop = AsyncInfo(async_mode=False, async_path="")
|
|
95
|
+
async_loop = AsyncInfo(async_mode=True, async_path="aio/")
|
|
96
|
+
return [sync_loop, async_loop] if self.has_aio_folder else [sync_loop]
|
|
115
97
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
self._serialize_and_write_sample(env, namespace_path)
|
|
129
|
-
|
|
130
|
-
if (
|
|
131
|
-
self.code_model.options["show_operations"]
|
|
132
|
-
and self.code_model.has_operations
|
|
133
|
-
and self.code_model.options["generate_test"]
|
|
134
|
-
):
|
|
135
|
-
self._serialize_and_write_test(env, namespace_path)
|
|
98
|
+
@property
|
|
99
|
+
def keep_version_file(self) -> bool:
|
|
100
|
+
if self.options.get("keep_version_file"):
|
|
101
|
+
return True
|
|
102
|
+
# If the version file is already there and the version is greater than the current version, keep it.
|
|
103
|
+
try:
|
|
104
|
+
serialized_version_file = self.read_file(self.exec_path(self.code_model.namespace) / "_version.py")
|
|
105
|
+
match = re.search(r'VERSION\s*=\s*"([^"]+)"', str(serialized_version_file))
|
|
106
|
+
serialized_version = match.group(1) if match else ""
|
|
107
|
+
except (FileNotFoundError, IndexError):
|
|
108
|
+
serialized_version = ""
|
|
109
|
+
return serialized_version > self.code_model.options["package_version"]
|
|
136
110
|
|
|
137
111
|
def serialize(self) -> None:
|
|
138
112
|
env = Environment(
|
|
@@ -144,54 +118,71 @@ class JinjaSerializer(ReaderAndWriter):
|
|
|
144
118
|
lstrip_blocks=True,
|
|
145
119
|
)
|
|
146
120
|
|
|
147
|
-
namespace_path = (
|
|
148
|
-
Path(".") if self.code_model.options["no_namespace_folders"] else Path(*self._name_space().split("."))
|
|
149
|
-
)
|
|
150
|
-
|
|
151
|
-
p = namespace_path.parent
|
|
152
121
|
general_serializer = GeneralSerializer(code_model=self.code_model, env=env, async_mode=False)
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
if self.read_file(namespace_path / Path("models.py")):
|
|
122
|
+
for client_namespace, client_namespace_type in self.code_model.client_namespace_types.items():
|
|
123
|
+
exec_path = self.exec_path(client_namespace)
|
|
124
|
+
if client_namespace == "":
|
|
125
|
+
# Write the setup file
|
|
126
|
+
if self.code_model.options["basic_setup_py"]:
|
|
127
|
+
self.write_file(exec_path / Path("setup.py"), general_serializer.serialize_setup_file())
|
|
128
|
+
|
|
129
|
+
# add packaging files in root namespace (e.g. setup.py, README.md, etc.)
|
|
130
|
+
if self.code_model.options["package_mode"]:
|
|
131
|
+
self._serialize_and_write_package_files(client_namespace)
|
|
132
|
+
|
|
133
|
+
# write apiview_mapping_python.json
|
|
134
|
+
if self.code_model.options.get("emit_cross_language_definition_file"):
|
|
135
|
+
self.write_file(
|
|
136
|
+
exec_path / Path("apiview_mapping_python.json"),
|
|
137
|
+
general_serializer.serialize_cross_language_definition_file(),
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
# add generated samples and generated tests
|
|
141
|
+
if self.code_model.options["show_operations"] and self.code_model.has_operations:
|
|
142
|
+
if self.code_model.options["generate_sample"]:
|
|
143
|
+
self._serialize_and_write_sample(env, namespace=client_namespace)
|
|
144
|
+
if self.code_model.options["generate_test"]:
|
|
145
|
+
self._serialize_and_write_test(env, namespace=client_namespace)
|
|
146
|
+
elif client_namespace_type.clients:
|
|
147
|
+
# add clients folder if there are clients in this namespace
|
|
148
|
+
self._serialize_client_and_config_files(client_namespace, client_namespace_type.clients, env)
|
|
149
|
+
else:
|
|
150
|
+
# add pkgutil init file if no clients in this namespace
|
|
183
151
|
self.write_file(
|
|
184
|
-
|
|
185
|
-
|
|
152
|
+
exec_path / Path("__init__.py"),
|
|
153
|
+
general_serializer.serialize_pkgutil_init_file(),
|
|
186
154
|
)
|
|
187
|
-
if self.code_model.named_unions:
|
|
188
|
-
self.write_file(
|
|
189
|
-
namespace_path / Path("_types.py"),
|
|
190
|
-
TypesSerializer(code_model=self.code_model, env=env).serialize(),
|
|
191
|
-
)
|
|
192
155
|
|
|
193
|
-
|
|
194
|
-
|
|
156
|
+
# _model_base.py/_serialization.py/_vendor.py/py.typed/_types.py/_validation.py
|
|
157
|
+
# is always put in top level namespace
|
|
158
|
+
if self.code_model.is_top_namespace(client_namespace):
|
|
159
|
+
self._serialize_and_write_top_level_folder(env=env, namespace=client_namespace)
|
|
160
|
+
|
|
161
|
+
# add models folder if there are models in this namespace
|
|
162
|
+
if (client_namespace_type.models or client_namespace_type.enums) and self.code_model.options["models_mode"]:
|
|
163
|
+
self._serialize_and_write_models_folder(
|
|
164
|
+
env=env,
|
|
165
|
+
namespace=client_namespace,
|
|
166
|
+
models=client_namespace_type.models,
|
|
167
|
+
enums=client_namespace_type.enums,
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
if not self.code_model.options["models_mode"]:
|
|
171
|
+
# keep models file if users ended up just writing a models file
|
|
172
|
+
model_path = exec_path / Path("models.py")
|
|
173
|
+
if self.read_file(model_path):
|
|
174
|
+
self.write_file(model_path, self.read_file(model_path))
|
|
175
|
+
|
|
176
|
+
# add operations folder if there are operations in this namespace
|
|
177
|
+
if client_namespace_type.operation_groups:
|
|
178
|
+
self._serialize_and_write_operations_folder(
|
|
179
|
+
client_namespace_type.operation_groups, env=env, namespace=client_namespace
|
|
180
|
+
)
|
|
181
|
+
if self.code_model.options["multiapi"]:
|
|
182
|
+
self._serialize_and_write_metadata(env=env, namespace=client_namespace)
|
|
183
|
+
|
|
184
|
+
def _serialize_and_write_package_files(self, client_namespace: str) -> None:
|
|
185
|
+
root_of_sdk = self.exec_path(client_namespace)
|
|
195
186
|
if self.code_model.options["package_mode"] in VALID_PACKAGE_MODE:
|
|
196
187
|
env = Environment(
|
|
197
188
|
loader=PackageLoader("pygen.codegen", "templates/packaging_templates"),
|
|
@@ -216,6 +207,9 @@ class JinjaSerializer(ReaderAndWriter):
|
|
|
216
207
|
file = template_name.replace(".jinja2", "")
|
|
217
208
|
output_name = root_of_sdk / file
|
|
218
209
|
if not self.read_file(output_name) or file in _REGENERATE_FILES:
|
|
210
|
+
if self.keep_version_file and file == "setup.py":
|
|
211
|
+
# don't regenerate setup.py file if the version file is more up to date
|
|
212
|
+
continue
|
|
219
213
|
self.write_file(
|
|
220
214
|
output_name,
|
|
221
215
|
serializer.serialize_package_file(template_name, **params),
|
|
@@ -230,25 +224,31 @@ class JinjaSerializer(ReaderAndWriter):
|
|
|
230
224
|
PatchSerializer(env=env, code_model=self.code_model).serialize(),
|
|
231
225
|
)
|
|
232
226
|
|
|
233
|
-
def _serialize_and_write_models_folder(
|
|
227
|
+
def _serialize_and_write_models_folder(
|
|
228
|
+
self, env: Environment, namespace: str, models: List[ModelType], enums: List[EnumType]
|
|
229
|
+
) -> None:
|
|
234
230
|
# Write the models folder
|
|
235
|
-
models_path =
|
|
231
|
+
models_path = self.exec_path(namespace + ".models")
|
|
236
232
|
serializer = DpgModelSerializer if self.code_model.options["models_mode"] == "dpg" else MsrestModelSerializer
|
|
237
|
-
if
|
|
233
|
+
if models:
|
|
238
234
|
self.write_file(
|
|
239
235
|
models_path / Path(f"{self.code_model.models_filename}.py"),
|
|
240
|
-
serializer(code_model=self.code_model, env=env).serialize(),
|
|
236
|
+
serializer(code_model=self.code_model, env=env, client_namespace=namespace, models=models).serialize(),
|
|
241
237
|
)
|
|
242
|
-
if
|
|
238
|
+
if enums:
|
|
243
239
|
self.write_file(
|
|
244
240
|
models_path / Path(f"{self.code_model.enums_filename}.py"),
|
|
245
|
-
EnumSerializer(
|
|
241
|
+
EnumSerializer(
|
|
242
|
+
code_model=self.code_model, env=env, client_namespace=namespace, enums=enums
|
|
243
|
+
).serialize(),
|
|
246
244
|
)
|
|
247
245
|
self.write_file(
|
|
248
246
|
models_path / Path("__init__.py"),
|
|
249
|
-
ModelInitSerializer(code_model=self.code_model, env=env).serialize(),
|
|
247
|
+
ModelInitSerializer(code_model=self.code_model, env=env, models=models, enums=enums).serialize(),
|
|
250
248
|
)
|
|
251
249
|
|
|
250
|
+
self._keep_patch_file(models_path / Path("_patch.py"), env)
|
|
251
|
+
|
|
252
252
|
def _serialize_and_write_rest_layer(self, env: Environment, namespace_path: Path) -> None:
|
|
253
253
|
rest_path = namespace_path / Path(self.code_model.rest_layer_name)
|
|
254
254
|
group_names = {rb.group_name for c in self.code_model.clients for rb in c.request_builders}
|
|
@@ -292,196 +292,163 @@ class JinjaSerializer(ReaderAndWriter):
|
|
|
292
292
|
).serialize_init(),
|
|
293
293
|
)
|
|
294
294
|
|
|
295
|
-
def _serialize_and_write_operations_file(
|
|
296
|
-
self,
|
|
297
|
-
env: Environment,
|
|
298
|
-
clients: List[Client],
|
|
299
|
-
namespace_path: Path,
|
|
300
|
-
operation_group: Optional[OperationGroup] = None,
|
|
301
|
-
) -> None:
|
|
302
|
-
filename = operation_group.filename if operation_group else "_operations"
|
|
303
|
-
# write first sync file
|
|
304
|
-
operation_group_serializer = OperationGroupsSerializer(
|
|
305
|
-
code_model=self.code_model,
|
|
306
|
-
clients=clients,
|
|
307
|
-
env=env,
|
|
308
|
-
async_mode=False,
|
|
309
|
-
operation_group=operation_group,
|
|
310
|
-
)
|
|
311
|
-
self.write_file(
|
|
312
|
-
namespace_path / Path(self.code_model.operations_folder_name) / Path(f"{filename}.py"),
|
|
313
|
-
operation_group_serializer.serialize(),
|
|
314
|
-
)
|
|
315
|
-
|
|
316
|
-
if self.has_aio_folder:
|
|
317
|
-
# write async operation group and operation files
|
|
318
|
-
operation_group_async_serializer = OperationGroupsSerializer(
|
|
319
|
-
code_model=self.code_model,
|
|
320
|
-
clients=clients,
|
|
321
|
-
env=env,
|
|
322
|
-
async_mode=True,
|
|
323
|
-
operation_group=operation_group,
|
|
324
|
-
)
|
|
325
|
-
self.write_file(
|
|
326
|
-
(namespace_path / Path("aio") / Path(self.code_model.operations_folder_name) / Path(f"{filename}.py")),
|
|
327
|
-
operation_group_async_serializer.serialize(),
|
|
328
|
-
)
|
|
329
|
-
|
|
330
295
|
def _serialize_and_write_operations_folder(
|
|
331
|
-
self,
|
|
296
|
+
self, operation_groups: List[OperationGroup], env: Environment, namespace: str
|
|
332
297
|
) -> None:
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
)
|
|
341
|
-
|
|
342
|
-
# write async operations init file
|
|
343
|
-
if self.has_aio_folder:
|
|
344
|
-
operations_async_init_serializer = OperationsInitSerializer(
|
|
345
|
-
code_model=self.code_model, clients=clients, env=env, async_mode=True
|
|
298
|
+
operations_folder_name = self.code_model.operations_folder_name(namespace)
|
|
299
|
+
exec_path = self.exec_path(namespace)
|
|
300
|
+
for async_mode, async_path in self.serialize_loop:
|
|
301
|
+
prefix_path = f"{async_path}{operations_folder_name}"
|
|
302
|
+
# write init file
|
|
303
|
+
operations_init_serializer = OperationsInitSerializer(
|
|
304
|
+
code_model=self.code_model, operation_groups=operation_groups, env=env, async_mode=async_mode
|
|
346
305
|
)
|
|
347
306
|
self.write_file(
|
|
348
|
-
|
|
349
|
-
|
|
307
|
+
exec_path / Path(f"{prefix_path}/__init__.py"),
|
|
308
|
+
operations_init_serializer.serialize(),
|
|
350
309
|
)
|
|
351
310
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
311
|
+
# write operations file
|
|
312
|
+
OgLoop = namedtuple("OgLoop", ["operation_groups", "filename"])
|
|
313
|
+
if self.code_model.options["combine_operation_files"]:
|
|
314
|
+
loops = [OgLoop(operation_groups, "_operations")]
|
|
315
|
+
else:
|
|
316
|
+
loops = [OgLoop([og], og.filename) for og in operation_groups]
|
|
317
|
+
for ogs, filename in loops:
|
|
318
|
+
operation_group_serializer = OperationGroupsSerializer(
|
|
319
|
+
code_model=self.code_model,
|
|
320
|
+
operation_groups=ogs,
|
|
361
321
|
env=env,
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
322
|
+
async_mode=async_mode,
|
|
323
|
+
client_namespace=namespace,
|
|
324
|
+
)
|
|
325
|
+
self.write_file(
|
|
326
|
+
exec_path / Path(f"{prefix_path}/{filename}.py"),
|
|
327
|
+
operation_group_serializer.serialize(),
|
|
365
328
|
)
|
|
366
329
|
|
|
330
|
+
# if there was a patch file before, we keep it
|
|
331
|
+
self._keep_patch_file(exec_path / Path(f"{prefix_path}/_patch.py"), env)
|
|
332
|
+
|
|
367
333
|
def _serialize_and_write_version_file(
|
|
368
334
|
self,
|
|
369
|
-
|
|
335
|
+
namespace: str,
|
|
370
336
|
general_serializer: GeneralSerializer,
|
|
371
337
|
):
|
|
338
|
+
exec_path = self.exec_path(namespace)
|
|
339
|
+
|
|
372
340
|
def _read_version_file(original_version_file_name: str) -> str:
|
|
373
|
-
return self.read_file(
|
|
341
|
+
return self.read_file(exec_path / original_version_file_name)
|
|
374
342
|
|
|
375
343
|
def _write_version_file(original_version_file_name: str) -> None:
|
|
376
344
|
self.write_file(
|
|
377
|
-
|
|
345
|
+
exec_path / Path("_version.py"),
|
|
378
346
|
_read_version_file(original_version_file_name),
|
|
379
347
|
)
|
|
380
348
|
|
|
381
|
-
keep_version_file
|
|
382
|
-
if keep_version_file and _read_version_file("_version.py"):
|
|
349
|
+
if self.keep_version_file and _read_version_file("_version.py"):
|
|
383
350
|
_write_version_file(original_version_file_name="_version.py")
|
|
384
|
-
elif keep_version_file and _read_version_file("version.py"):
|
|
351
|
+
elif self.keep_version_file and _read_version_file("version.py"):
|
|
385
352
|
_write_version_file(original_version_file_name="version.py")
|
|
386
353
|
elif self.code_model.options["package_version"]:
|
|
387
354
|
self.write_file(
|
|
388
|
-
|
|
355
|
+
exec_path / Path("_version.py"),
|
|
389
356
|
general_serializer.serialize_version_file(),
|
|
390
357
|
)
|
|
391
358
|
|
|
392
359
|
def _serialize_client_and_config_files(
|
|
393
360
|
self,
|
|
394
|
-
|
|
395
|
-
general_serializer: GeneralSerializer,
|
|
396
|
-
async_mode: bool,
|
|
361
|
+
namespace: str,
|
|
397
362
|
clients: List[Client],
|
|
363
|
+
env: Environment,
|
|
398
364
|
) -> None:
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
general_serializer.serialize_service_client_file(clients),
|
|
365
|
+
exec_path = self.exec_path(namespace)
|
|
366
|
+
for async_mode, async_path in self.serialize_loop:
|
|
367
|
+
general_serializer = GeneralSerializer(
|
|
368
|
+
code_model=self.code_model, env=env, async_mode=async_mode, client_namespace=namespace
|
|
404
369
|
)
|
|
370
|
+
# when there is client.py, there must be __init__.py
|
|
405
371
|
self.write_file(
|
|
406
|
-
|
|
407
|
-
general_serializer.
|
|
372
|
+
exec_path / Path(f"{async_path}__init__.py"),
|
|
373
|
+
general_serializer.serialize_init_file([c for c in clients if c.has_operations]),
|
|
408
374
|
)
|
|
409
375
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
) -> None:
|
|
413
|
-
general_serializer = GeneralSerializer(code_model=self.code_model, env=env, async_mode=False)
|
|
376
|
+
# if there was a patch file before, we keep it
|
|
377
|
+
self._keep_patch_file(exec_path / Path(f"{async_path}_patch.py"), env)
|
|
414
378
|
|
|
415
|
-
|
|
416
|
-
namespace_path / Path("__init__.py"),
|
|
417
|
-
general_serializer.serialize_init_file(clients),
|
|
418
|
-
)
|
|
379
|
+
if self.code_model.clients_has_operations(clients):
|
|
419
380
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
general_serializer.serialize_vendor_file(clients),
|
|
426
|
-
)
|
|
381
|
+
# write client file
|
|
382
|
+
self.write_file(
|
|
383
|
+
exec_path / Path(f"{async_path}{self.code_model.client_filename}.py"),
|
|
384
|
+
general_serializer.serialize_service_client_file(clients),
|
|
385
|
+
)
|
|
427
386
|
|
|
428
|
-
|
|
387
|
+
# write config file
|
|
388
|
+
self.write_file(
|
|
389
|
+
exec_path / Path(f"{async_path}_configuration.py"),
|
|
390
|
+
general_serializer.serialize_config_file(clients),
|
|
391
|
+
)
|
|
392
|
+
|
|
393
|
+
# sometimes we need define additional Mixin class for client in _vendor.py
|
|
394
|
+
self._serialize_and_write_vendor_file(env, namespace)
|
|
395
|
+
|
|
396
|
+
def _serialize_and_write_vendor_file(self, env: Environment, namespace: str) -> None:
|
|
397
|
+
exec_path = self.exec_path(namespace)
|
|
398
|
+
# write _vendor.py
|
|
399
|
+
for async_mode, async_path in self.serialize_loop:
|
|
400
|
+
if self.code_model.need_vendored_code(async_mode=async_mode, client_namespace=namespace):
|
|
401
|
+
self.write_file(
|
|
402
|
+
exec_path / Path(f"{async_path}_vendor.py"),
|
|
403
|
+
GeneralSerializer(
|
|
404
|
+
code_model=self.code_model, env=env, async_mode=async_mode, client_namespace=namespace
|
|
405
|
+
).serialize_vendor_file(),
|
|
406
|
+
)
|
|
407
|
+
|
|
408
|
+
def _serialize_and_write_top_level_folder(self, env: Environment, namespace: str) -> None:
|
|
409
|
+
exec_path = self.exec_path(namespace)
|
|
410
|
+
# write _vendor.py
|
|
411
|
+
self._serialize_and_write_vendor_file(env, namespace)
|
|
412
|
+
|
|
413
|
+
general_serializer = GeneralSerializer(code_model=self.code_model, env=env, async_mode=False)
|
|
414
|
+
|
|
415
|
+
# write _version.py
|
|
416
|
+
self._serialize_and_write_version_file(namespace, general_serializer)
|
|
429
417
|
|
|
430
418
|
# write the empty py.typed file
|
|
431
|
-
self.write_file(
|
|
419
|
+
self.write_file(exec_path / Path("py.typed"), "# Marker file for PEP 561.")
|
|
432
420
|
|
|
421
|
+
# write _serialization.py
|
|
433
422
|
if not self.code_model.options["client_side_validation"] and not self.code_model.options["multiapi"]:
|
|
434
423
|
self.write_file(
|
|
435
|
-
|
|
424
|
+
exec_path / Path("_serialization.py"),
|
|
436
425
|
general_serializer.serialize_serialization_file(),
|
|
437
426
|
)
|
|
427
|
+
|
|
428
|
+
# write _model_base.py
|
|
438
429
|
if self.code_model.options["models_mode"] == "dpg":
|
|
439
430
|
self.write_file(
|
|
440
|
-
|
|
431
|
+
exec_path / Path("_model_base.py"),
|
|
441
432
|
general_serializer.serialize_model_base_file(),
|
|
442
433
|
)
|
|
443
434
|
|
|
435
|
+
# write _validation.py
|
|
444
436
|
if any(og for client in self.code_model.clients for og in client.operation_groups if og.need_validation):
|
|
445
437
|
self.write_file(
|
|
446
|
-
|
|
438
|
+
exec_path / Path("_validation.py"),
|
|
447
439
|
general_serializer.serialize_validation_file(),
|
|
448
440
|
)
|
|
449
|
-
if self.code_model.options.get("emit_cross_language_definition_file"):
|
|
450
|
-
self.write_file(
|
|
451
|
-
Path("./apiview_mapping_python.json"),
|
|
452
|
-
general_serializer.serialize_cross_language_definition_file(),
|
|
453
|
-
)
|
|
454
|
-
|
|
455
|
-
# Write the setup file
|
|
456
|
-
if self.code_model.options["basic_setup_py"]:
|
|
457
|
-
self.write_file(Path("setup.py"), general_serializer.serialize_setup_file())
|
|
458
|
-
|
|
459
|
-
def _serialize_and_write_aio_top_level_folder(
|
|
460
|
-
self, env: Environment, namespace_path: Path, clients: List[Client]
|
|
461
|
-
) -> None:
|
|
462
|
-
aio_general_serializer = GeneralSerializer(code_model=self.code_model, env=env, async_mode=True)
|
|
463
|
-
|
|
464
|
-
aio_path = namespace_path / Path("aio")
|
|
465
|
-
|
|
466
|
-
# Write the __init__ file
|
|
467
|
-
self.write_file(
|
|
468
|
-
aio_path / Path("__init__.py"),
|
|
469
|
-
aio_general_serializer.serialize_init_file(clients),
|
|
470
|
-
)
|
|
471
441
|
|
|
472
|
-
#
|
|
473
|
-
self.
|
|
474
|
-
namespace_path, aio_general_serializer, async_mode=True, clients=clients
|
|
475
|
-
)
|
|
476
|
-
if self.code_model.need_vendored_code(async_mode=True):
|
|
442
|
+
# write _types.py
|
|
443
|
+
if self.code_model.named_unions:
|
|
477
444
|
self.write_file(
|
|
478
|
-
|
|
479
|
-
|
|
445
|
+
exec_path / Path("_types.py"),
|
|
446
|
+
TypesSerializer(code_model=self.code_model, env=env).serialize(),
|
|
480
447
|
)
|
|
481
448
|
|
|
482
|
-
def _serialize_and_write_metadata(self, env: Environment,
|
|
483
|
-
metadata_serializer = MetadataSerializer(self.code_model, env)
|
|
484
|
-
self.write_file(
|
|
449
|
+
def _serialize_and_write_metadata(self, env: Environment, namespace: str) -> None:
|
|
450
|
+
metadata_serializer = MetadataSerializer(self.code_model, env, client_namespace=namespace)
|
|
451
|
+
self.write_file(self.exec_path(namespace) / Path("_metadata.json"), metadata_serializer.serialize())
|
|
485
452
|
|
|
486
453
|
@property
|
|
487
454
|
def _namespace_from_package_name(self) -> str:
|
|
@@ -493,9 +460,17 @@ class JinjaSerializer(ReaderAndWriter):
|
|
|
493
460
|
|
|
494
461
|
return self._namespace_from_package_name
|
|
495
462
|
|
|
496
|
-
|
|
497
|
-
def
|
|
498
|
-
|
|
463
|
+
@property
|
|
464
|
+
def exec_path_compensation(self) -> Path:
|
|
465
|
+
"""Assume the process is running in the root folder of the package. If not, we need the path compensation."""
|
|
466
|
+
return (
|
|
467
|
+
Path("../" * (self._name_space().count(".") + 1))
|
|
468
|
+
if self.code_model.options["no_namespace_folders"]
|
|
469
|
+
else Path(".")
|
|
470
|
+
)
|
|
471
|
+
|
|
472
|
+
def exec_path(self, namespace: str) -> Path:
|
|
473
|
+
return self.exec_path_compensation / Path(*namespace.split("."))
|
|
499
474
|
|
|
500
475
|
@property
|
|
501
476
|
def _additional_folder(self) -> Path:
|
|
@@ -506,8 +481,8 @@ class JinjaSerializer(ReaderAndWriter):
|
|
|
506
481
|
return Path("/".join(namespace_config.split(".")[num_of_package_namespace:]))
|
|
507
482
|
return Path("")
|
|
508
483
|
|
|
509
|
-
def _serialize_and_write_sample(self, env: Environment,
|
|
510
|
-
out_path = self.
|
|
484
|
+
def _serialize_and_write_sample(self, env: Environment, namespace: str):
|
|
485
|
+
out_path = self.exec_path(namespace) / Path("generated_samples")
|
|
511
486
|
for client in self.code_model.clients:
|
|
512
487
|
for op_group in client.operation_groups:
|
|
513
488
|
for operation in op_group.operations:
|
|
@@ -539,15 +514,15 @@ class JinjaSerializer(ReaderAndWriter):
|
|
|
539
514
|
log_error = f"error happens in sample {file}: {e}"
|
|
540
515
|
_LOGGER.error(log_error)
|
|
541
516
|
|
|
542
|
-
def _serialize_and_write_test(self, env: Environment,
|
|
517
|
+
def _serialize_and_write_test(self, env: Environment, namespace: str):
|
|
543
518
|
self.code_model.for_test = True
|
|
544
|
-
out_path = self.
|
|
519
|
+
out_path = self.exec_path(namespace) / Path("generated_tests")
|
|
545
520
|
general_serializer = TestGeneralSerializer(code_model=self.code_model, env=env)
|
|
546
521
|
self.write_file(out_path / "conftest.py", general_serializer.serialize_conftest())
|
|
547
522
|
if not self.code_model.options["azure_arm"]:
|
|
548
|
-
for
|
|
549
|
-
async_suffix = "_async" if
|
|
550
|
-
general_serializer.
|
|
523
|
+
for async_mode in (True, False):
|
|
524
|
+
async_suffix = "_async" if async_mode else ""
|
|
525
|
+
general_serializer.async_mode = async_mode
|
|
551
526
|
self.write_file(
|
|
552
527
|
out_path / f"testpreparer{async_suffix}.py",
|
|
553
528
|
general_serializer.serialize_testpreparer(),
|
|
@@ -560,9 +535,9 @@ class JinjaSerializer(ReaderAndWriter):
|
|
|
560
535
|
):
|
|
561
536
|
continue
|
|
562
537
|
test_serializer = TestSerializer(self.code_model, env, client=client, operation_group=og)
|
|
563
|
-
for
|
|
538
|
+
for async_mode in (True, False):
|
|
564
539
|
try:
|
|
565
|
-
test_serializer.
|
|
540
|
+
test_serializer.async_mode = async_mode
|
|
566
541
|
self.write_file(
|
|
567
542
|
out_path / f"{to_snake_case(test_serializer.test_class_name)}.py",
|
|
568
543
|
test_serializer.serialize_test(),
|