@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.
Files changed (68) hide show
  1. package/autorest/_utils.py +2 -1
  2. package/autorest/codegen/__init__.py +23 -81
  3. package/autorest/codegen/models/__init__.py +5 -3
  4. package/autorest/codegen/models/{base_type.py → base.py} +24 -3
  5. package/autorest/codegen/models/base_builder.py +9 -5
  6. package/autorest/codegen/models/client.py +183 -13
  7. package/autorest/codegen/models/code_model.py +154 -141
  8. package/autorest/codegen/models/combined_type.py +5 -2
  9. package/autorest/codegen/models/constant_type.py +38 -4
  10. package/autorest/codegen/models/credential_types.py +1 -1
  11. package/autorest/codegen/models/dictionary_type.py +1 -1
  12. package/autorest/codegen/models/enum_type.py +5 -3
  13. package/autorest/codegen/models/imports.py +78 -29
  14. package/autorest/codegen/models/list_type.py +1 -1
  15. package/autorest/codegen/models/lro_operation.py +5 -1
  16. package/autorest/codegen/models/model_type.py +1 -2
  17. package/autorest/codegen/models/operation.py +34 -10
  18. package/autorest/codegen/models/operation_group.py +16 -5
  19. package/autorest/codegen/models/paging_operation.py +5 -4
  20. package/autorest/codegen/models/parameter.py +19 -6
  21. package/autorest/codegen/models/primitive_types.py +1 -2
  22. package/autorest/codegen/models/property.py +4 -4
  23. package/autorest/codegen/models/request_builder.py +17 -6
  24. package/autorest/codegen/models/request_builder_parameter.py +5 -2
  25. package/autorest/codegen/models/response.py +6 -3
  26. package/autorest/codegen/serializers/__init__.py +207 -135
  27. package/autorest/codegen/serializers/builder_serializer.py +2 -4
  28. package/autorest/codegen/serializers/client_serializer.py +41 -45
  29. package/autorest/codegen/serializers/general_serializer.py +80 -37
  30. package/autorest/codegen/serializers/import_serializer.py +30 -36
  31. package/autorest/codegen/serializers/metadata_serializer.py +36 -14
  32. package/autorest/codegen/serializers/model_serializer.py +34 -19
  33. package/autorest/codegen/serializers/operation_groups_serializer.py +22 -6
  34. package/autorest/codegen/serializers/operations_init_serializer.py +10 -4
  35. package/autorest/codegen/serializers/sample_serializer.py +144 -0
  36. package/autorest/codegen/templates/client.py.jinja2 +7 -15
  37. package/autorest/codegen/templates/client_container.py.jinja2 +12 -0
  38. package/autorest/codegen/templates/config.py.jinja2 +13 -26
  39. package/autorest/codegen/templates/config_container.py.jinja2 +16 -0
  40. package/autorest/codegen/templates/enum_container.py.jinja2 +1 -1
  41. package/autorest/codegen/templates/init.py.jinja2 +9 -3
  42. package/autorest/codegen/templates/lro_operation.py.jinja2 +1 -1
  43. package/autorest/codegen/templates/metadata.json.jinja2 +13 -14
  44. package/autorest/codegen/templates/model_dpg.py.jinja2 +4 -4
  45. package/autorest/codegen/templates/model_init.py.jinja2 +1 -1
  46. package/autorest/codegen/templates/operation.py.jinja2 +1 -1
  47. package/autorest/codegen/templates/operation_group.py.jinja2 +2 -2
  48. package/autorest/codegen/templates/operation_groups_container.py.jinja2 +5 -5
  49. package/autorest/codegen/templates/operation_tools.jinja2 +2 -2
  50. package/autorest/codegen/templates/operations_folder_init.py.jinja2 +4 -4
  51. package/autorest/codegen/templates/{CHANGELOG.md.jinja2 → packaging_templates/CHANGELOG.md.jinja2} +0 -0
  52. package/autorest/codegen/templates/{LICENSE.jinja2 → packaging_templates/LICENSE.jinja2} +0 -0
  53. package/autorest/codegen/templates/{MANIFEST.in.jinja2 → packaging_templates/MANIFEST.in.jinja2} +0 -0
  54. package/autorest/codegen/templates/{README.md.jinja2 → packaging_templates/README.md.jinja2} +0 -0
  55. package/autorest/codegen/templates/{dev_requirements.txt.jinja2 → packaging_templates/dev_requirements.txt.jinja2} +0 -0
  56. package/autorest/codegen/templates/{setup.py.jinja2 → packaging_templates/setup.py.jinja2} +12 -9
  57. package/autorest/codegen/templates/request_builders.py.jinja2 +2 -2
  58. package/autorest/codegen/templates/sample.py.jinja2 +44 -0
  59. package/autorest/codegen/templates/vendor.py.jinja2 +4 -2
  60. package/autorest/m4reformatter/__init__.py +18 -4
  61. package/autorest/multiapi/models/imports.py +89 -18
  62. package/autorest/multiapi/serializers/import_serializer.py +88 -7
  63. package/autorest/multiapi/utils.py +6 -0
  64. package/autorest/preprocess/__init__.py +20 -8
  65. package/package.json +1 -1
  66. package/run_cadl.py +0 -1
  67. package/autorest/cadlflags/__init__.py +0 -130
  68. 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 .base_model import BaseModel
9
- from .base_type import BaseType
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, yaml_data: Dict[str, Any], code_model: "CodeModel", type: BaseType
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
- 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
+ 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, code_model: CodeModel, *, output_folder: Union[str, Path], **kwargs: Any
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.request_builders
64
+ self.code_model.has_operations
53
65
  )
54
66
 
55
- def serialize(self) -> None:
56
- env = Environment(
57
- loader=PackageLoader("autorest.codegen", "templates"),
58
- keep_trailing_newline=True,
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
- namespace_path = (
66
- Path(".")
67
- if self.code_model.options["no_namespace_folders"]
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.code_model.options["models_mode"] and (
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.request_builders:
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
- 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))
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("autorest.codegen", "templates"),
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
- params = self.code_model.options["package_configuration"] or {}
202
- _serialize_and_write_package_files_proc(**params)
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 = {rb.group_name for rb in self.code_model.request_builders}
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 r in self.code_model.request_builders
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 operation_group in self.code_model.operation_groups:
360
- self._serialize_and_write_operations_file(
361
- env=env,
362
- namespace_path=namespace_path,
363
- operation_group=operation_group,
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, namespace_path: Path, general_serializer: GeneralSerializer
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
- if self.code_model.request_builders:
411
- self.write_file(
412
- namespace_path / Path(f"{self.code_model.client.filename}.py"),
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(og for og in self.code_model.operation_groups if og.need_validation):
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"), aio_general_serializer.serialize_init_file()
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
- if self.code_model.request_builders:
474
- self.write_file(
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, code_model=code_model, output_folder=output_folder
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)")