@autorest/python 6.1.10 → 6.2.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.
Files changed (73) hide show
  1. package/autorest/_utils.py +2 -1
  2. package/autorest/codegen/__init__.py +87 -80
  3. package/autorest/codegen/models/__init__.py +12 -9
  4. package/autorest/codegen/models/base_builder.py +11 -5
  5. package/autorest/codegen/models/base_model.py +5 -3
  6. package/autorest/codegen/models/base_type.py +7 -5
  7. package/autorest/codegen/models/client.py +131 -32
  8. package/autorest/codegen/models/code_model.py +92 -120
  9. package/autorest/codegen/models/combined_type.py +9 -6
  10. package/autorest/codegen/models/constant_type.py +6 -6
  11. package/autorest/codegen/models/credential_types.py +18 -16
  12. package/autorest/codegen/models/dictionary_type.py +8 -6
  13. package/autorest/codegen/models/enum_type.py +24 -17
  14. package/autorest/codegen/models/imports.py +4 -4
  15. package/autorest/codegen/models/list_type.py +14 -10
  16. package/autorest/codegen/models/lro_operation.py +14 -6
  17. package/autorest/codegen/models/model_type.py +19 -19
  18. package/autorest/codegen/models/operation.py +50 -33
  19. package/autorest/codegen/models/operation_group.py +23 -12
  20. package/autorest/codegen/models/paging_operation.py +15 -20
  21. package/autorest/codegen/models/parameter.py +25 -25
  22. package/autorest/codegen/models/parameter_list.py +22 -16
  23. package/autorest/codegen/models/primitive_types.py +21 -11
  24. package/autorest/codegen/models/property.py +7 -7
  25. package/autorest/codegen/models/request_builder.py +31 -20
  26. package/autorest/codegen/models/request_builder_parameter.py +18 -13
  27. package/autorest/codegen/models/response.py +29 -22
  28. package/autorest/codegen/serializers/__init__.py +196 -139
  29. package/autorest/codegen/serializers/builder_serializer.py +59 -53
  30. package/autorest/codegen/serializers/client_serializer.py +40 -46
  31. package/autorest/codegen/serializers/enum_serializer.py +4 -4
  32. package/autorest/codegen/serializers/general_serializer.py +96 -43
  33. package/autorest/codegen/serializers/metadata_serializer.py +20 -16
  34. package/autorest/codegen/serializers/model_init_serializer.py +10 -6
  35. package/autorest/codegen/serializers/model_serializer.py +8 -8
  36. package/autorest/codegen/serializers/operation_groups_serializer.py +24 -12
  37. package/autorest/codegen/serializers/operations_init_serializer.py +6 -7
  38. package/autorest/codegen/serializers/patch_serializer.py +4 -4
  39. package/autorest/codegen/serializers/request_builders_serializer.py +6 -6
  40. package/autorest/codegen/serializers/sample_serializer.py +146 -0
  41. package/autorest/codegen/templates/client.py.jinja2 +7 -15
  42. package/autorest/codegen/templates/client_container.py.jinja2 +12 -0
  43. package/autorest/codegen/templates/config.py.jinja2 +13 -26
  44. package/autorest/codegen/templates/config_container.py.jinja2 +16 -0
  45. package/autorest/codegen/templates/enum_container.py.jinja2 +3 -3
  46. package/autorest/codegen/templates/init.py.jinja2 +11 -5
  47. package/autorest/codegen/templates/lro_operation.py.jinja2 +2 -2
  48. package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +1 -1
  49. package/autorest/codegen/templates/metadata.json.jinja2 +13 -14
  50. package/autorest/codegen/templates/model_container.py.jinja2 +3 -3
  51. package/autorest/codegen/templates/model_init.py.jinja2 +4 -4
  52. package/autorest/codegen/templates/operation.py.jinja2 +2 -2
  53. package/autorest/codegen/templates/operation_group.py.jinja2 +3 -3
  54. package/autorest/codegen/templates/operation_groups_container.py.jinja2 +7 -7
  55. package/autorest/codegen/templates/operation_tools.jinja2 +3 -3
  56. package/autorest/codegen/templates/operations_folder_init.py.jinja2 +4 -4
  57. package/autorest/codegen/templates/{CHANGELOG.md.jinja2 → packaging_templates/CHANGELOG.md.jinja2} +0 -0
  58. package/autorest/codegen/templates/{LICENSE.jinja2 → packaging_templates/LICENSE.jinja2} +0 -0
  59. package/autorest/codegen/templates/{MANIFEST.in.jinja2 → packaging_templates/MANIFEST.in.jinja2} +0 -0
  60. package/autorest/codegen/templates/{README.md.jinja2 → packaging_templates/README.md.jinja2} +0 -0
  61. package/autorest/codegen/templates/{dev_requirements.txt.jinja2 → packaging_templates/dev_requirements.txt.jinja2} +0 -0
  62. package/autorest/codegen/templates/{setup.py.jinja2 → packaging_templates/setup.py.jinja2} +9 -9
  63. package/autorest/codegen/templates/paging_operation.py.jinja2 +1 -1
  64. package/autorest/codegen/templates/request_builder.py.jinja2 +1 -1
  65. package/autorest/codegen/templates/request_builders.py.jinja2 +3 -3
  66. package/autorest/codegen/templates/rest_init.py.jinja2 +1 -1
  67. package/autorest/codegen/templates/sample.py.jinja2 +44 -0
  68. package/autorest/codegen/templates/validation.py.jinja2 +1 -1
  69. package/autorest/codegen/templates/vendor.py.jinja2 +9 -7
  70. package/autorest/codegen/templates/version.py.jinja2 +2 -2
  71. package/autorest/m4reformatter/__init__.py +20 -7
  72. package/autorest/preprocess/__init__.py +38 -23
  73. package/package.json +1 -1
@@ -3,18 +3,22 @@
3
3
  # Licensed under the MIT License. See License.txt in the project root for
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
- from typing import Dict, List, Optional, Any, Union, cast
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 CodeModel, OperationGroup, RequestBuilder
15
- from ..models import TokenCredentialType
13
+ from ..models import (
14
+ OperationGroup,
15
+ RequestBuilder,
16
+ OverloadedRequestBuilder,
17
+ NamespaceModel,
18
+ CodeModel,
19
+ )
16
20
  from .enum_serializer import EnumSerializer
17
- from .general_serializer import GeneralSerializer
21
+ from .general_serializer import GeneralNamespaceSerializer, GeneralSerializer
18
22
  from .model_init_serializer import ModelInitSerializer
19
23
  from .model_serializer import DpgModelSerializer, MsrestModelSerializer
20
24
  from .operations_init_serializer import OperationsInitSerializer
@@ -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,15 +49,27 @@ _REGENERATE_FILES = {"setup.py", "MANIFEST.in"}
41
49
 
42
50
  class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
43
51
  def __init__(
44
- self, code_model: CodeModel, *, output_folder: Union[str, Path], **kwargs: Any
52
+ self,
53
+ code_model: CodeModel,
54
+ namespace_model: NamespaceModel,
55
+ *,
56
+ output_folder: Union[str, Path],
57
+ **kwargs: Any,
45
58
  ) -> None:
46
59
  super().__init__(output_folder=output_folder, **kwargs)
47
60
  self.code_model = code_model
61
+ self.namespace_model = namespace_model
48
62
 
49
63
  @property
50
64
  def has_aio_folder(self) -> bool:
51
- return not self.code_model.options["no_async"] and bool(
52
- self.code_model.request_builders
65
+ return not self.namespace_model.options["no_async"] and bool(
66
+ self.namespace_model.operation_groups
67
+ )
68
+
69
+ @property
70
+ def has_operations_folder(self) -> bool:
71
+ return self.namespace_model.options["show_operations"] and bool(
72
+ self.namespace_model.operation_groups
53
73
  )
54
74
 
55
75
  def serialize(self) -> None:
@@ -64,27 +84,24 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
64
84
 
65
85
  namespace_path = (
66
86
  Path(".")
67
- if self.code_model.options["no_namespace_folders"]
68
- else Path(*(self.code_model.namespace.split(".")))
87
+ if self.namespace_model.options["no_namespace_folders"]
88
+ else Path(*(self.namespace_model.namespace.split(".")))
69
89
  )
70
90
  # if there was a patch file before, we keep it
71
91
  self._keep_patch_file(namespace_path / Path("_patch.py"), env)
72
92
  if self.has_aio_folder:
73
93
  self._keep_patch_file(namespace_path / Path("aio") / Path("_patch.py"), env)
74
94
 
75
- if self.code_model.options["models_mode"] and (
76
- self.code_model.model_types or self.code_model.enums
95
+ if self.namespace_model.options["models_mode"] and (
96
+ self.namespace_model.model_types or self.namespace_model.enums
77
97
  ):
78
98
  self._keep_patch_file(
79
99
  namespace_path / Path("models") / Path("_patch.py"), env
80
100
  )
81
- if (
82
- self.code_model.options["show_operations"]
83
- and self.code_model.operation_groups
84
- ):
101
+ if self.has_operations_folder:
85
102
  self._keep_patch_file(
86
103
  namespace_path
87
- / Path(self.code_model.operations_folder_name)
104
+ / Path(self.namespace_model.operations_folder_name)
88
105
  / Path("_patch.py"),
89
106
  env,
90
107
  )
@@ -92,7 +109,7 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
92
109
  self._keep_patch_file(
93
110
  namespace_path
94
111
  / Path("aio")
95
- / Path(self.code_model.operations_folder_name)
112
+ / Path(self.namespace_model.operations_folder_name)
96
113
  / Path("_patch.py"),
97
114
  env,
98
115
  )
@@ -101,8 +118,8 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
101
118
  env=env, namespace_path=namespace_path
102
119
  )
103
120
 
104
- if self.code_model.request_builders:
105
- if self.code_model.options["builders_visibility"] != "embedded":
121
+ if self.namespace_model.operation_groups:
122
+ if self.namespace_model.options["builders_visibility"] != "embedded":
106
123
  self._serialize_and_write_rest_layer(
107
124
  env=env, namespace_path=namespace_path
108
125
  )
@@ -112,25 +129,22 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
112
129
  namespace_path=namespace_path,
113
130
  )
114
131
 
115
- if (
116
- self.code_model.options["show_operations"]
117
- and self.code_model.operation_groups
118
- ):
132
+ if self.has_operations_folder:
119
133
  self._serialize_and_write_operations_folder(
120
134
  env=env, namespace_path=namespace_path
121
135
  )
122
- if self.code_model.options["multiapi"]:
136
+ if self.namespace_model.options["multiapi"]:
123
137
  self._serialize_and_write_metadata(
124
138
  env=env, namespace_path=namespace_path
125
139
  )
126
140
 
127
- if self.code_model.options["models_mode"] and (
128
- self.code_model.model_types or self.code_model.enums
141
+ if self.namespace_model.options["models_mode"] and (
142
+ self.namespace_model.model_types or self.namespace_model.enums
129
143
  ):
130
144
  self._serialize_and_write_models_folder(
131
145
  env=env, namespace_path=namespace_path
132
146
  )
133
- if not self.code_model.options["models_mode"]:
147
+ if not self.namespace_model.options["models_mode"]:
134
148
  # keep models file if users ended up just writing a models file
135
149
  if self.read_file(namespace_path / Path("models.py")):
136
150
  self.write_file(
@@ -138,68 +152,49 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
138
152
  cast(str, self.read_file(namespace_path / Path("models.py"))),
139
153
  )
140
154
 
141
- if self.code_model.options["package_mode"]:
142
- self._serialize_and_write_package_files(out_path=namespace_path)
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))
185
- if self.code_model.options["package_mode"] in ("dataplane", "mgmtplane"):
155
+ if self.namespace_model.options["package_mode"]:
156
+ self._serialize_and_write_package_files(namespace_path=namespace_path)
157
+
158
+ if (
159
+ self.namespace_model.options["show_operations"]
160
+ and self.namespace_model.operation_groups
161
+ and self.namespace_model.options["generate_sample"]
162
+ and not self.namespace_model.options["multiapi"]
163
+ ):
164
+ self._serialize_and_write_sample(env, namespace_path)
165
+
166
+ def _serialize_and_write_package_files(self, namespace_path: Path) -> None:
167
+ root_of_sdk = self._package_root_folder(namespace_path)
168
+ if self.namespace_model.options["package_mode"] in ("dataplane", "mgmtplane"):
186
169
  env = Environment(
187
- loader=PackageLoader("autorest.codegen", "templates"),
170
+ loader=PackageLoader(
171
+ "autorest.codegen", "templates/packaging_templates"
172
+ ),
188
173
  undefined=StrictUndefined,
189
174
  )
175
+
190
176
  package_files = _PACKAGE_FILES
191
- _serialize_and_write_package_files_proc(**_prepare_params())
192
- elif Path(self.code_model.options["package_mode"]).exists():
177
+ elif Path(self.namespace_model.options["package_mode"]).exists():
193
178
  env = Environment(
194
179
  loader=FileSystemLoader(
195
- str(Path(self.code_model.options["package_mode"]))
180
+ str(Path(self.namespace_model.options["package_mode"]))
196
181
  ),
197
182
  keep_trailing_newline=True,
198
183
  undefined=StrictUndefined,
199
184
  )
200
185
  package_files = env.list_templates()
201
- params = self.code_model.options["package_configuration"] or {}
202
- _serialize_and_write_package_files_proc(**params)
186
+ else:
187
+ return
188
+ serializer = GeneralSerializer(self.code_model, env)
189
+ params = self.namespace_model.options["package_configuration"] or {}
190
+ for template_name in package_files:
191
+ file = template_name.replace(".jinja2", "")
192
+ output_name = root_of_sdk / file
193
+ if not self.read_file(output_name) or file in _REGENERATE_FILES:
194
+ self.write_file(
195
+ output_name,
196
+ serializer.serialize_package_file(template_name, **params),
197
+ )
203
198
 
204
199
  def _keep_patch_file(self, path_file: Path, env: Environment):
205
200
  if self.read_file(path_file):
@@ -207,7 +202,9 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
207
202
  else:
208
203
  self.write_file(
209
204
  path_file,
210
- PatchSerializer(env=env, code_model=self.code_model).serialize(),
205
+ PatchSerializer(
206
+ env=env, namespace_model=self.namespace_model
207
+ ).serialize(),
211
208
  )
212
209
 
213
210
  def _serialize_and_write_models_folder(
@@ -217,34 +214,43 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
217
214
  models_path = namespace_path / Path("models")
218
215
  serializer = (
219
216
  DpgModelSerializer
220
- if self.code_model.options["models_mode"] == "dpg"
217
+ if self.namespace_model.options["models_mode"] == "dpg"
221
218
  else MsrestModelSerializer
222
219
  )
223
- if self.code_model.model_types:
220
+ if self.namespace_model.model_types:
224
221
  self.write_file(
225
- models_path / Path(f"{self.code_model.models_filename}.py"),
226
- serializer(code_model=self.code_model, env=env).serialize(),
222
+ models_path / Path(f"{self.namespace_model.models_filename}.py"),
223
+ serializer(namespace_model=self.namespace_model, env=env).serialize(),
227
224
  )
228
- if self.code_model.enums:
225
+ if self.namespace_model.enums:
229
226
  self.write_file(
230
- models_path / Path(f"{self.code_model.enums_filename}.py"),
231
- EnumSerializer(code_model=self.code_model, env=env).serialize(),
227
+ models_path / Path(f"{self.namespace_model.enums_filename}.py"),
228
+ EnumSerializer(
229
+ namespace_model=self.namespace_model, env=env
230
+ ).serialize(),
232
231
  )
233
232
  self.write_file(
234
233
  models_path / Path("__init__.py"),
235
- ModelInitSerializer(code_model=self.code_model, env=env).serialize(),
234
+ ModelInitSerializer(
235
+ namespace_model=self.namespace_model, env=env
236
+ ).serialize(),
236
237
  )
237
238
 
238
239
  def _serialize_and_write_rest_layer(
239
240
  self, env: Environment, namespace_path: Path
240
241
  ) -> None:
241
- rest_path = namespace_path / Path(self.code_model.rest_layer_name)
242
- group_names = {rb.group_name for rb in self.code_model.request_builders}
242
+ rest_path = namespace_path / Path(self.namespace_model.rest_layer_name)
243
+ group_names = {
244
+ rb.group_name
245
+ for c in self.namespace_model.clients
246
+ for rb in c.request_builders
247
+ }
243
248
 
244
249
  for group_name in group_names:
245
250
  request_builders = [
246
251
  r
247
- for r in self.code_model.request_builders
252
+ for c in self.namespace_model.clients
253
+ for r in c.request_builders
248
254
  if r.group_name == group_name
249
255
  ]
250
256
  self._serialize_and_write_single_rest_layer(
@@ -253,7 +259,7 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
253
259
  if not "" in group_names:
254
260
  self.write_file(
255
261
  rest_path / Path("__init__.py"),
256
- self.code_model.options["license_header"],
262
+ self.namespace_model.options["license_header"],
257
263
  )
258
264
 
259
265
  def _serialize_and_write_single_rest_layer(
@@ -268,7 +274,7 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
268
274
  self.write_file(
269
275
  output_path / Path("_request_builders.py"),
270
276
  RequestBuildersSerializer(
271
- code_model=self.code_model,
277
+ namespace_model=self.namespace_model,
272
278
  env=env,
273
279
  request_builders=request_builders,
274
280
  ).serialize_request_builders(),
@@ -278,7 +284,7 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
278
284
  self.write_file(
279
285
  output_path / Path("__init__.py"),
280
286
  RequestBuildersSerializer(
281
- code_model=self.code_model,
287
+ namespace_model=self.namespace_model,
282
288
  env=env,
283
289
  request_builders=request_builders,
284
290
  ).serialize_init(),
@@ -293,14 +299,14 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
293
299
  filename = operation_group.filename if operation_group else "_operations"
294
300
  # write first sync file
295
301
  operation_group_serializer = OperationGroupsSerializer(
296
- code_model=self.code_model,
302
+ namespace_model=self.namespace_model,
297
303
  env=env,
298
304
  async_mode=False,
299
305
  operation_group=operation_group,
300
306
  )
301
307
  self.write_file(
302
308
  namespace_path
303
- / Path(self.code_model.operations_folder_name)
309
+ / Path(self.namespace_model.operations_folder_name)
304
310
  / Path(f"{filename}.py"),
305
311
  operation_group_serializer.serialize(),
306
312
  )
@@ -308,7 +314,7 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
308
314
  if self.has_aio_folder:
309
315
  # write async operation group and operation files
310
316
  operation_group_async_serializer = OperationGroupsSerializer(
311
- code_model=self.code_model,
317
+ namespace_model=self.namespace_model,
312
318
  env=env,
313
319
  async_mode=True,
314
320
  operation_group=operation_group,
@@ -317,7 +323,7 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
317
323
  (
318
324
  namespace_path
319
325
  / Path("aio")
320
- / Path(self.code_model.operations_folder_name)
326
+ / Path(self.namespace_model.operations_folder_name)
321
327
  / Path(f"{filename}.py")
322
328
  ),
323
329
  operation_group_async_serializer.serialize(),
@@ -328,11 +334,11 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
328
334
  ) -> None:
329
335
  # write sync operations init file
330
336
  operations_init_serializer = OperationsInitSerializer(
331
- code_model=self.code_model, env=env, async_mode=False
337
+ namespace_model=self.namespace_model, env=env, async_mode=False
332
338
  )
333
339
  self.write_file(
334
340
  namespace_path
335
- / Path(self.code_model.operations_folder_name)
341
+ / Path(self.namespace_model.operations_folder_name)
336
342
  / Path("__init__.py"),
337
343
  operations_init_serializer.serialize(),
338
344
  )
@@ -340,23 +346,23 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
340
346
  # write async operations init file
341
347
  if self.has_aio_folder:
342
348
  operations_async_init_serializer = OperationsInitSerializer(
343
- code_model=self.code_model, env=env, async_mode=True
349
+ namespace_model=self.namespace_model, env=env, async_mode=True
344
350
  )
345
351
  self.write_file(
346
352
  namespace_path
347
353
  / Path("aio")
348
- / Path(self.code_model.operations_folder_name)
354
+ / Path(self.namespace_model.operations_folder_name)
349
355
  / Path("__init__.py"),
350
356
  operations_async_init_serializer.serialize(),
351
357
  )
352
358
 
353
- if self.code_model.options["combine_operation_files"]:
359
+ if self.namespace_model.options["combine_operation_files"]:
354
360
  self._serialize_and_write_operations_file(
355
361
  env=env,
356
362
  namespace_path=namespace_path,
357
363
  )
358
364
  else:
359
- for operation_group in self.code_model.operation_groups:
365
+ for operation_group in self.namespace_model.operation_groups:
360
366
  self._serialize_and_write_operations_file(
361
367
  env=env,
362
368
  namespace_path=namespace_path,
@@ -364,7 +370,9 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
364
370
  )
365
371
 
366
372
  def _serialize_and_write_version_file(
367
- self, namespace_path: Path, general_serializer: GeneralSerializer
373
+ self,
374
+ namespace_path: Path,
375
+ general_namespace_serializer: GeneralNamespaceSerializer,
368
376
  ):
369
377
  def _read_version_file(original_version_file_name: str) -> str:
370
378
  return self.read_file(namespace_path / original_version_file_name)
@@ -375,135 +383,184 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
375
383
  _read_version_file(original_version_file_name),
376
384
  )
377
385
 
378
- keep_version_file = self.code_model.options["keep_version_file"]
386
+ keep_version_file = self.namespace_model.options["keep_version_file"]
379
387
  if keep_version_file and _read_version_file("_version.py"):
380
388
  _write_version_file(original_version_file_name="_version.py")
381
389
  elif keep_version_file and _read_version_file("version.py"):
382
390
  _write_version_file(original_version_file_name="version.py")
383
- elif self.code_model.options["package_version"]:
391
+ elif self.namespace_model.options["package_version"]:
384
392
  self.write_file(
385
393
  namespace_path / Path("_version.py"),
386
- general_serializer.serialize_version_file(),
394
+ general_namespace_serializer.serialize_version_file(),
387
395
  )
388
396
 
389
397
  def _serialize_and_write_top_level_folder(
390
398
  self, env: Environment, namespace_path: Path
391
399
  ) -> None:
400
+ general_namespace_serializer = GeneralNamespaceSerializer(
401
+ namespace_model=self.namespace_model, env=env, async_mode=False
402
+ )
392
403
  general_serializer = GeneralSerializer(
393
- code_model=self.code_model, env=env, async_mode=False
404
+ code_model=self.code_model,
405
+ env=env,
394
406
  )
395
407
 
396
408
  self.write_file(
397
409
  namespace_path / Path("__init__.py"),
398
- general_serializer.serialize_init_file(),
410
+ general_namespace_serializer.serialize_init_file(),
399
411
  )
400
412
  p = namespace_path.parent
401
413
  while p != Path("."):
402
414
  # write pkgutil init file
403
415
  self.write_file(
404
416
  p / Path("__init__.py"),
405
- general_serializer.serialize_pkgutil_init_file(),
417
+ general_namespace_serializer.serialize_pkgutil_init_file(),
406
418
  )
407
419
  p = p.parent
408
420
 
409
421
  # Write the service client
410
- if self.code_model.request_builders:
422
+ if self.namespace_model.operation_groups:
411
423
  self.write_file(
412
- namespace_path / Path(f"{self.code_model.client.filename}.py"),
413
- general_serializer.serialize_service_client_file(),
424
+ namespace_path / Path(f"{self.namespace_model.client_filename}.py"),
425
+ general_namespace_serializer.serialize_service_client_file(),
414
426
  )
415
427
 
416
- if self.code_model.need_vendored_code(async_mode=False):
428
+ if self.namespace_model.need_vendored_code(async_mode=False):
417
429
  self.write_file(
418
430
  namespace_path / Path("_vendor.py"),
419
- general_serializer.serialize_vendor_file(),
431
+ general_namespace_serializer.serialize_vendor_file(),
420
432
  )
421
433
 
422
- self._serialize_and_write_version_file(namespace_path, general_serializer)
434
+ self._serialize_and_write_version_file(
435
+ namespace_path, general_namespace_serializer
436
+ )
423
437
 
424
438
  # write the empty py.typed file
425
439
  self.write_file(namespace_path / Path("py.typed"), "# Marker file for PEP 561.")
426
440
 
427
441
  if (
428
- not self.code_model.options["client_side_validation"]
429
- and not self.code_model.options["multiapi"]
442
+ not self.namespace_model.options["client_side_validation"]
443
+ and not self.namespace_model.options["multiapi"]
430
444
  ):
431
445
  self.write_file(
432
446
  namespace_path / Path("_serialization.py"),
433
- general_serializer.serialize_serialization_file(),
447
+ general_namespace_serializer.serialize_serialization_file(),
434
448
  )
435
- if self.code_model.options["models_mode"] == "dpg":
449
+ if self.namespace_model.options["models_mode"] == "dpg":
436
450
  self.write_file(
437
451
  namespace_path / Path("_model_base.py"),
438
- general_serializer.serialize_model_base_file(),
452
+ general_namespace_serializer.serialize_model_base_file(),
439
453
  )
440
454
 
441
- if any(og for og in self.code_model.operation_groups if og.need_validation):
455
+ if any(
456
+ og for og in self.namespace_model.operation_groups if og.need_validation
457
+ ):
442
458
  self.write_file(
443
459
  namespace_path / Path("_validation.py"),
444
- general_serializer.serialize_validation_file(),
460
+ general_namespace_serializer.serialize_validation_file(),
445
461
  )
446
462
 
447
463
  # Write the config file
448
- if self.code_model.request_builders:
464
+ if self.namespace_model.request_builders:
449
465
  self.write_file(
450
466
  namespace_path / Path("_configuration.py"),
451
- general_serializer.serialize_config_file(),
467
+ general_namespace_serializer.serialize_config_file(),
452
468
  )
453
469
 
454
470
  # Write the setup file
455
- if self.code_model.options["basic_setup_py"]:
471
+ if self.namespace_model.options["basic_setup_py"]:
456
472
  self.write_file(Path("setup.py"), general_serializer.serialize_setup_file())
457
473
 
458
474
  def _serialize_and_write_aio_top_level_folder(
459
475
  self, env: Environment, namespace_path: Path
460
476
  ) -> None:
461
- aio_general_serializer = GeneralSerializer(
462
- code_model=self.code_model, env=env, async_mode=True
477
+ aio_general_namespace_serializer = GeneralNamespaceSerializer(
478
+ namespace_model=self.namespace_model, env=env, async_mode=True
463
479
  )
464
480
 
465
481
  aio_path = namespace_path / Path("aio")
466
482
 
467
483
  # Write the __init__ file
468
484
  self.write_file(
469
- aio_path / Path("__init__.py"), aio_general_serializer.serialize_init_file()
485
+ aio_path / Path("__init__.py"),
486
+ aio_general_namespace_serializer.serialize_init_file(),
470
487
  )
471
488
 
472
489
  # Write the service client
473
- if self.code_model.request_builders:
490
+ if self.namespace_model.request_builders:
474
491
  self.write_file(
475
- aio_path / Path(f"{self.code_model.client.filename}.py"),
476
- aio_general_serializer.serialize_service_client_file(),
492
+ aio_path / Path(f"{self.namespace_model.client_filename}.py"),
493
+ aio_general_namespace_serializer.serialize_service_client_file(),
477
494
  )
478
495
 
479
496
  # Write the config file
480
497
  self.write_file(
481
498
  aio_path / Path("_configuration.py"),
482
- aio_general_serializer.serialize_config_file(),
499
+ aio_general_namespace_serializer.serialize_config_file(),
483
500
  )
484
- if self.code_model.need_vendored_code(async_mode=True):
501
+ if self.namespace_model.need_vendored_code(async_mode=True):
485
502
  self.write_file(
486
503
  aio_path / Path("_vendor.py"),
487
- aio_general_serializer.serialize_vendor_file(),
504
+ aio_general_namespace_serializer.serialize_vendor_file(),
488
505
  )
489
506
 
490
507
  def _serialize_and_write_metadata(
491
508
  self, env: Environment, namespace_path: Path
492
509
  ) -> None:
493
- metadata_serializer = MetadataSerializer(self.code_model, env)
510
+ metadata_serializer = MetadataSerializer(self.namespace_model, env)
494
511
  self.write_file(
495
512
  namespace_path / Path("_metadata.json"), metadata_serializer.serialize()
496
513
  )
497
514
 
515
+ # find root folder where "setup.py" is
516
+ def _package_root_folder(self, namespace_path: Path) -> Path:
517
+ return namespace_path / Path(
518
+ "../" * (self.namespace_model.namespace.count(".") + 1)
519
+ )
520
+
521
+ def _serialize_and_write_sample(self, env: Environment, namespace_path: Path):
522
+ out_path = self._package_root_folder(namespace_path) / Path("generated_samples")
523
+ for op_group in self.namespace_model.operation_groups:
524
+ for operation in op_group.operations:
525
+ samples = operation.yaml_data["samples"]
526
+ if not samples:
527
+ continue
528
+ for key, value in samples.items():
529
+ file_name = to_snake_case(key) + ".py"
530
+ try:
531
+ self.write_file(
532
+ out_path / file_name,
533
+ SampleSerializer(
534
+ namespace_model=self.namespace_model,
535
+ env=env,
536
+ operation_group=op_group,
537
+ operation=operation,
538
+ sample=value,
539
+ file_name=file_name,
540
+ sample_origin_name=key,
541
+ ).serialize(),
542
+ )
543
+ except Exception as e: # pylint: disable=broad-except
544
+ # sample generation shall not block code generation, so just log error
545
+ _LOGGER.error(
546
+ "error happens when generate sample with {%s}: {%s}", key, e
547
+ )
548
+
498
549
 
499
550
  class JinjaSerializerAutorest(JinjaSerializer, ReaderAndWriterAutorest):
500
551
  def __init__(
501
552
  self,
502
553
  autorestapi: AutorestAPI,
503
554
  code_model: CodeModel,
555
+ namespace_model: NamespaceModel,
504
556
  *,
505
557
  output_folder: Union[str, Path],
558
+ **kwargs: Any,
506
559
  ) -> None:
507
560
  super().__init__(
508
- autorestapi=autorestapi, code_model=code_model, output_folder=output_folder
561
+ autorestapi=autorestapi,
562
+ code_model=code_model,
563
+ namespace_model=namespace_model,
564
+ output_folder=output_folder,
565
+ **kwargs,
509
566
  )