@autorest/python 5.16.0 → 5.17.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 (92) hide show
  1. package/ChangeLog.md +43 -3
  2. package/README.md +30 -4
  3. package/autorest/__init__.py +1 -1
  4. package/autorest/codegen/__init__.py +48 -209
  5. package/autorest/codegen/models/__init__.py +116 -83
  6. package/autorest/codegen/models/base_builder.py +49 -88
  7. package/autorest/codegen/models/base_model.py +1 -1
  8. package/autorest/codegen/models/{base_schema.py → base_type.py} +56 -40
  9. package/autorest/codegen/models/client.py +157 -48
  10. package/autorest/codegen/models/code_model.py +108 -254
  11. package/autorest/codegen/models/combined_type.py +107 -0
  12. package/autorest/codegen/models/{constant_schema.py → constant_type.py} +49 -40
  13. package/autorest/codegen/models/credential_types.py +224 -0
  14. package/autorest/codegen/models/{dictionary_schema.py → dictionary_type.py} +41 -31
  15. package/autorest/codegen/models/enum_type.py +195 -0
  16. package/autorest/codegen/models/imports.py +23 -0
  17. package/autorest/codegen/models/list_type.py +134 -0
  18. package/autorest/codegen/models/lro_operation.py +77 -156
  19. package/autorest/codegen/models/lro_paging_operation.py +28 -11
  20. package/autorest/codegen/models/model_type.py +239 -0
  21. package/autorest/codegen/models/operation.py +303 -269
  22. package/autorest/codegen/models/operation_group.py +48 -89
  23. package/autorest/codegen/models/paging_operation.py +80 -123
  24. package/autorest/codegen/models/parameter.py +289 -396
  25. package/autorest/codegen/models/parameter_list.py +348 -360
  26. package/autorest/codegen/models/primitive_types.py +544 -0
  27. package/autorest/codegen/models/property.py +109 -139
  28. package/autorest/codegen/models/request_builder.py +105 -88
  29. package/autorest/codegen/models/request_builder_parameter.py +112 -100
  30. package/autorest/codegen/models/response.py +325 -0
  31. package/autorest/codegen/models/utils.py +12 -19
  32. package/autorest/codegen/serializers/__init__.py +46 -37
  33. package/autorest/codegen/serializers/builder_serializer.py +604 -1146
  34. package/autorest/codegen/serializers/client_serializer.py +83 -88
  35. package/autorest/codegen/serializers/general_serializer.py +5 -64
  36. package/autorest/codegen/serializers/import_serializer.py +7 -4
  37. package/autorest/codegen/serializers/metadata_serializer.py +15 -104
  38. package/autorest/codegen/serializers/model_base_serializer.py +40 -32
  39. package/autorest/codegen/serializers/model_generic_serializer.py +8 -6
  40. package/autorest/codegen/serializers/model_init_serializer.py +2 -4
  41. package/autorest/codegen/serializers/model_python3_serializer.py +22 -16
  42. package/autorest/codegen/serializers/operation_groups_serializer.py +4 -13
  43. package/autorest/codegen/serializers/parameter_serializer.py +174 -0
  44. package/autorest/codegen/serializers/request_builders_serializer.py +12 -29
  45. package/autorest/codegen/serializers/utils.py +0 -142
  46. package/autorest/codegen/templates/MANIFEST.in.jinja2 +1 -0
  47. package/autorest/codegen/templates/{service_client.py.jinja2 → client.py.jinja2} +7 -7
  48. package/autorest/codegen/templates/config.py.jinja2 +13 -13
  49. package/autorest/codegen/templates/enum.py.jinja2 +4 -4
  50. package/autorest/codegen/templates/enum_container.py.jinja2 +1 -1
  51. package/autorest/codegen/templates/init.py.jinja2 +2 -2
  52. package/autorest/codegen/templates/lro_operation.py.jinja2 +4 -1
  53. package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +4 -1
  54. package/autorest/codegen/templates/metadata.json.jinja2 +33 -33
  55. package/autorest/codegen/templates/model.py.jinja2 +23 -24
  56. package/autorest/codegen/templates/model_container.py.jinja2 +2 -1
  57. package/autorest/codegen/templates/model_init.py.jinja2 +3 -5
  58. package/autorest/codegen/templates/operation.py.jinja2 +6 -8
  59. package/autorest/codegen/templates/operation_group.py.jinja2 +7 -7
  60. package/autorest/codegen/templates/operation_groups_container.py.jinja2 +1 -1
  61. package/autorest/codegen/templates/operation_tools.jinja2 +8 -2
  62. package/autorest/codegen/templates/paging_operation.py.jinja2 +2 -2
  63. package/autorest/codegen/templates/request_builder.py.jinja2 +13 -11
  64. package/autorest/codegen/templates/setup.py.jinja2 +9 -3
  65. package/autorest/codegen/templates/vendor.py.jinja2 +1 -1
  66. package/autorest/jsonrpc/server.py +15 -3
  67. package/autorest/m4reformatter/__init__.py +1108 -0
  68. package/autorest/multiapi/models/code_model.py +1 -1
  69. package/autorest/multiapi/serializers/__init__.py +4 -4
  70. package/autorest/multiapi/templates/multiapi_config.py.jinja2 +3 -3
  71. package/autorest/multiapi/templates/multiapi_init.py.jinja2 +2 -2
  72. package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +3 -3
  73. package/autorest/multiapi/templates/multiapi_service_client.py.jinja2 +9 -9
  74. package/autorest/postprocess/__init__.py +202 -0
  75. package/autorest/postprocess/get_all.py +19 -0
  76. package/autorest/postprocess/venvtools.py +73 -0
  77. package/autorest/preprocess/__init__.py +209 -0
  78. package/autorest/preprocess/helpers.py +54 -0
  79. package/autorest/{namer → preprocess}/python_mappings.py +21 -16
  80. package/package.json +2 -2
  81. package/autorest/codegen/models/credential_model.py +0 -55
  82. package/autorest/codegen/models/credential_schema.py +0 -95
  83. package/autorest/codegen/models/credential_schema_policy.py +0 -73
  84. package/autorest/codegen/models/enum_schema.py +0 -225
  85. package/autorest/codegen/models/list_schema.py +0 -135
  86. package/autorest/codegen/models/object_schema.py +0 -303
  87. package/autorest/codegen/models/primitive_schemas.py +0 -495
  88. package/autorest/codegen/models/request_builder_parameter_list.py +0 -249
  89. package/autorest/codegen/models/schema_request.py +0 -55
  90. package/autorest/codegen/models/schema_response.py +0 -141
  91. package/autorest/namer/__init__.py +0 -23
  92. package/autorest/namer/name_converter.py +0 -509
@@ -6,22 +6,23 @@
6
6
  from typing import List
7
7
 
8
8
  from . import utils
9
- from ..models import CodeModel
10
- from ..models.parameter import ParameterMethodLocation
9
+ from ..models import CodeModel, ParameterMethodLocation
10
+ from .parameter_serializer import ParameterSerializer, PopKwargType
11
11
 
12
12
 
13
13
  class ClientSerializer:
14
14
  def __init__(self, code_model: CodeModel, is_python3_file: bool) -> None:
15
15
  self.code_model = code_model
16
16
  self.is_python3_file = is_python3_file
17
+ self.parameter_serializer = ParameterSerializer()
17
18
 
18
19
  def _init_signature(self, async_mode: bool) -> str:
19
- return utils.serialize_method(
20
+ return self.parameter_serializer.serialize_method(
20
21
  function_def="def",
21
22
  method_name="__init__",
22
- is_in_class=True,
23
- method_param_signatures=self.code_model.service_client.parameters.client_method_signature(
24
- async_mode or self.is_python3_file
23
+ need_self_param=True,
24
+ method_param_signatures=self.code_model.client.parameters.method_signature(
25
+ async_mode or self.is_python3_file, async_mode
25
26
  ),
26
27
  )
27
28
 
@@ -34,50 +35,42 @@ class ClientSerializer:
34
35
  )
35
36
 
36
37
  def pop_kwargs_from_signature(self, async_mode: bool) -> List[str]:
37
- return utils.pop_kwargs_from_signature(
38
- self.code_model.service_client.parameters.kwargs_to_pop(
38
+ return self.parameter_serializer.pop_kwargs_from_signature(
39
+ self.code_model.client.parameters.kwargs_to_pop(
39
40
  async_mode or self.is_python3_file,
40
41
  ),
41
42
  check_kwarg_dict=False,
42
- pop_headers_kwarg=utils.PopKwargType.NO,
43
- pop_params_kwarg=utils.PopKwargType.NO,
43
+ pop_headers_kwarg=PopKwargType.NO,
44
+ pop_params_kwarg=PopKwargType.NO,
44
45
  )
45
46
 
46
47
  def class_definition(self, async_mode) -> str:
47
- class_name = self.code_model.class_name
48
- has_mixin_og = any(
49
- og for og in self.code_model.operation_groups if og.is_empty_operation_group
50
- )
48
+ class_name = self.code_model.client.name
49
+ has_mixin_og = any(og for og in self.code_model.operation_groups if og.is_mixin)
51
50
  base_class = ""
52
51
  if has_mixin_og:
53
52
  base_class = f"{class_name}OperationsMixin"
54
53
  elif not (async_mode or self.is_python3_file):
55
54
  base_class = "object"
56
- disable = ""
57
- if len(self.code_model.operation_groups) > 6:
58
- disable = " # pylint: disable=too-many-instance-attributes"
55
+ pylint_disable = self.code_model.client.pylint_disable
59
56
  if base_class:
60
- return f"class {class_name}({base_class}):{disable}"
61
- return f"class {class_name}:{disable}"
57
+ return f"class {class_name}({base_class}):{pylint_disable}"
58
+ return f"class {class_name}:{pylint_disable}"
62
59
 
63
60
  def property_descriptions(self, async_mode: bool) -> List[str]:
64
61
  retval: List[str] = []
65
62
  operations_folder = ".aio.operations." if async_mode else ".operations."
66
- for og in [
67
- og
68
- for og in self.code_model.operation_groups
69
- if not og.is_empty_operation_group
70
- ]:
71
- retval.append(f":ivar {og.name}: {og.class_name} operations")
63
+ for og in [og for og in self.code_model.operation_groups if not og.is_mixin]:
64
+ retval.append(f":ivar {og.property_name}: {og.class_name} operations")
72
65
  retval.append(
73
- f":vartype {og.name}: {self.code_model.namespace}{operations_folder}{og.class_name}"
66
+ f":vartype {og.property_name}: {self.code_model.namespace}{operations_folder}{og.class_name}"
74
67
  )
75
- for param in self.code_model.service_client.parameters.client_method:
68
+ for param in self.code_model.client.parameters.method:
76
69
  retval.append(
77
- f":{param.description_keyword} {param.serialized_name}: {param.description}"
70
+ f":{param.description_keyword} {param.client_name}: {param.description}"
78
71
  )
79
72
  retval.append(
80
- f":{param.docstring_type_keyword} {param.serialized_name}: {param.docstring_type}"
73
+ f":{param.docstring_type_keyword} {param.client_name}: {param.docstring_type(async_mode=async_mode)}"
81
74
  )
82
75
  if self.code_model.has_lro_operations:
83
76
  retval.append(
@@ -88,32 +81,36 @@ class ClientSerializer:
88
81
  return retval
89
82
 
90
83
  def initialize_config(self) -> str:
91
- config_name = f"{self.code_model.class_name}Configuration"
84
+ config_name = f"{self.code_model.client.name}Configuration"
92
85
  config_call = ", ".join(
93
86
  [
94
- f"{p.serialized_name}={p.serialized_name}"
95
- for p in self.code_model.service_client.parameters.config_method
96
- if not p.method_location
97
- in (ParameterMethodLocation.KWARG, ParameterMethodLocation.HIDDEN_KWARG)
87
+ f"{p.client_name}={p.client_name}"
88
+ for p in self.code_model.config.parameters.method
89
+ if p.method_location != ParameterMethodLocation.KWARG
98
90
  ]
99
91
  + ["**kwargs"]
100
92
  )
101
93
  return f"self._config = {config_name}({config_call})"
102
94
 
95
+ @property
96
+ def host_variable_name(self) -> str:
97
+ try:
98
+ return next(
99
+ p for p in self.code_model.client.parameters if p.is_host
100
+ ).client_name
101
+ except StopIteration:
102
+ return "_endpoint"
103
+
103
104
  def initialize_pipeline_client(self, async_mode: bool) -> str:
104
- host_variable_name = (
105
- self.code_model.service_client.parameters.host_variable_name
105
+ pipeline_client_name = self.code_model.client.pipeline_class(async_mode)
106
+ return (
107
+ f"self._client = {pipeline_client_name}(base_url={self.host_variable_name}, "
108
+ "config=self._config, **kwargs)"
106
109
  )
107
- if self.code_model.service_client.has_parameterized_host:
108
- host_variable_name = (
109
- "_" + host_variable_name
110
- ) # we don't want potential conflicts with input params
111
- pipeline_client_name = self.code_model.service_client.pipeline_class(async_mode)
112
- return f"self._client = {pipeline_client_name}(base_url={host_variable_name}, config=self._config, **kwargs)"
113
110
 
114
111
  def serializers_and_operation_groups_properties(self) -> List[str]:
115
112
  retval = []
116
- if self.code_model.sorted_schemas:
113
+ if self.code_model.model_types:
117
114
  client_models_value = (
118
115
  "{k: v for k, v in models.__dict__.items() if isinstance(v, type)}"
119
116
  )
@@ -129,19 +126,12 @@ class ClientSerializer:
129
126
  if not self.code_model.options["client_side_validation"]:
130
127
  retval.append("self._serialize.client_side_validation = False")
131
128
  operation_groups = [
132
- og
133
- for og in self.code_model.operation_groups
134
- if not og.is_empty_operation_group
129
+ og for og in self.code_model.operation_groups if not og.is_mixin
135
130
  ]
136
131
  for og in operation_groups:
137
- disable_check = (
138
- " # type: ignore # pylint: disable=abstract-class-instantiated"
139
- if og.has_abstract_operations
140
- else ""
141
- )
142
132
  retval.extend(
143
133
  [
144
- f"self.{og.name} = {og.class_name}({disable_check}",
134
+ f"self.{og.property_name} = {og.class_name}({og.mypy_ignore}{og.pylint_disable}",
145
135
  " self._client, self._config, self._serialize, self._deserialize",
146
136
  ")",
147
137
  ]
@@ -149,13 +139,21 @@ class ClientSerializer:
149
139
  return retval
150
140
 
151
141
  def _send_request_signature(self, async_mode: bool) -> str:
152
- return utils.serialize_method(
142
+ is_python3_file = async_mode or self.code_model.options["python3_only"]
143
+ request_signature = [
144
+ "request: HttpRequest,"
145
+ if is_python3_file
146
+ else "request, # type: HttpRequest"
147
+ ]
148
+ send_request_signature = (
149
+ request_signature
150
+ + self.code_model.client.parameters.method_signature_kwargs(is_python3_file)
151
+ )
152
+ return self.parameter_serializer.serialize_method(
153
153
  function_def="def",
154
- method_name=self.code_model.send_request_name,
155
- is_in_class=True,
156
- method_param_signatures=self.code_model.service_client.send_request_signature(
157
- async_mode or self.is_python3_file
158
- ),
154
+ method_name=self.code_model.client.send_request_name,
155
+ need_self_param=True,
156
+ method_param_signatures=send_request_signature,
159
157
  )
160
158
 
161
159
  def send_request_signature_and_response_type_annotation(
@@ -173,7 +171,7 @@ class ClientSerializer:
173
171
  def _example_make_call(self, async_mode: bool) -> List[str]:
174
172
  http_response = "AsyncHttpResponse" if async_mode else "HttpResponse"
175
173
  retval = [
176
- f">>> response = {'await ' if async_mode else ''}client.{self.code_model.send_request_name}(request)"
174
+ f">>> response = {'await ' if async_mode else ''}client.{self.code_model.client.send_request_name}(request)"
177
175
  ]
178
176
  retval.append(f"<{http_response}: 200 OK>")
179
177
  return retval
@@ -189,13 +187,11 @@ class ClientSerializer:
189
187
  retval.append("")
190
188
 
191
189
  request_builder = self.code_model.request_builders[0]
192
- request_builder_signature = ", ".join(
193
- request_builder.parameters.call(async_mode)
194
- )
195
- if request_builder.builder_group_name:
196
- rest_imported = request_builder.builder_group_name
190
+ request_builder_signature = ", ".join(request_builder.parameters.call)
191
+ if request_builder.group_name:
192
+ rest_imported = request_builder.group_name
197
193
  request_builder_name = (
198
- f"{request_builder.builder_group_name}.{request_builder.name}"
194
+ f"{request_builder.group_name}.{request_builder.name}"
199
195
  )
200
196
  else:
201
197
  rest_imported = request_builder.name
@@ -245,23 +241,24 @@ class ClientSerializer:
245
241
  return retval
246
242
 
247
243
  def serialize_path(self) -> List[str]:
248
- return utils.serialize_path(
249
- self.code_model.global_parameters.path, "self._serialize"
244
+ return self.parameter_serializer.serialize_path(
245
+ self.code_model.client.parameters.path, "self._serialize"
250
246
  )
251
247
 
252
248
 
253
249
  class ConfigSerializer:
254
250
  def __init__(self, code_model: CodeModel, is_python3_file: bool) -> None:
255
251
  self.code_model = code_model
252
+ self.parameter_serializer = ParameterSerializer()
256
253
  self.is_python3_file = is_python3_file
257
254
 
258
255
  def _init_signature(self, async_mode: bool) -> str:
259
- return utils.serialize_method(
256
+ return self.parameter_serializer.serialize_method(
260
257
  function_def="def",
261
258
  method_name="__init__",
262
- is_in_class=True,
263
- method_param_signatures=self.code_model.global_parameters.config_method_signature(
264
- async_mode or self.is_python3_file
259
+ need_self_param=True,
260
+ method_param_signatures=self.code_model.config.parameters.method_signature(
261
+ async_mode or self.is_python3_file, async_mode
265
262
  ),
266
263
  )
267
264
 
@@ -274,38 +271,36 @@ class ConfigSerializer:
274
271
  )
275
272
 
276
273
  def pop_kwargs_from_signature(self, async_mode: bool) -> List[str]:
277
- return utils.pop_kwargs_from_signature(
278
- self.code_model.global_parameters.config_kwargs_to_pop(
274
+ return self.parameter_serializer.pop_kwargs_from_signature(
275
+ self.code_model.config.parameters.kwargs_to_pop(
279
276
  async_mode or self.is_python3_file
280
277
  ),
281
278
  check_kwarg_dict=False,
282
- pop_headers_kwarg=utils.PopKwargType.NO,
283
- pop_params_kwarg=utils.PopKwargType.NO,
279
+ pop_headers_kwarg=PopKwargType.NO,
280
+ pop_params_kwarg=PopKwargType.NO,
284
281
  )
285
282
 
286
283
  def set_constants(self) -> List[str]:
287
284
  return [
288
- f"self.{p.serialized_name} = {p.constant_declaration}"
289
- for p in self.code_model.global_parameters.constant
290
- if p not in self.code_model.global_parameters.method
285
+ f"self.{p.client_name} = {p.client_default_value_declaration}"
286
+ for p in self.code_model.config.parameters.constant
287
+ if p not in self.code_model.config.parameters.method
291
288
  ]
292
289
 
293
290
  def check_required_parameters(self) -> List[str]:
294
291
  return [
295
- f"if {p.serialized_name} is None:\n"
296
- f" raise ValueError(\"Parameter '{p.serialized_name}' must not be None.\")"
297
- for p in self.code_model.global_parameters.config_method
298
- if p.required and not p.constant
292
+ f"if {p.client_name} is None:\n"
293
+ f" raise ValueError(\"Parameter '{p.client_name}' must not be None.\")"
294
+ for p in self.code_model.config.parameters.method
295
+ if not (p.optional or p.constant)
299
296
  ]
300
297
 
301
- def property_descriptions(self) -> List[str]:
298
+ def property_descriptions(self, async_mode: bool) -> List[str]:
302
299
  retval: List[str] = []
303
- for p in self.code_model.global_parameters.config_method:
304
- retval.append(
305
- f":{p.description_keyword} {p.serialized_name}: {p.description}"
306
- )
300
+ for p in self.code_model.config.parameters.method:
301
+ retval.append(f":{p.description_keyword} {p.client_name}: {p.description}")
307
302
  retval.append(
308
- f":{p.docstring_type_keyword} {p.serialized_name}: {p.docstring_type}"
303
+ f":{p.docstring_type_keyword} {p.client_name}: {p.docstring_type(async_mode=async_mode)}"
309
304
  )
310
305
  retval.append('"""')
311
306
  return retval
@@ -9,46 +9,10 @@ from ..models import (
9
9
  FileImport,
10
10
  ImportType,
11
11
  CodeModel,
12
- TokenCredentialSchema,
13
- ParameterList,
14
12
  )
15
13
  from .client_serializer import ClientSerializer, ConfigSerializer
16
14
 
17
15
 
18
- def config_imports(
19
- code_model, global_parameters: ParameterList, async_mode: bool
20
- ) -> FileImport:
21
- file_import = FileImport()
22
- file_import.add_submodule_import(
23
- "azure.core.configuration", "Configuration", ImportType.AZURECORE
24
- )
25
- file_import.add_submodule_import(
26
- "azure.core.pipeline", "policies", ImportType.AZURECORE
27
- )
28
- file_import.add_submodule_import(
29
- "typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL
30
- )
31
- if code_model.options["package_version"]:
32
- file_import.add_submodule_import(
33
- ".._version" if async_mode else "._version", "VERSION", ImportType.LOCAL
34
- )
35
- for gp in global_parameters:
36
- file_import.merge(gp.imports())
37
- if code_model.options["azure_arm"]:
38
- policy = (
39
- "AsyncARMChallengeAuthenticationPolicy"
40
- if async_mode
41
- else "ARMChallengeAuthenticationPolicy"
42
- )
43
- file_import.add_submodule_import(
44
- "azure.mgmt.core.policies", "ARMHttpLoggingPolicy", ImportType.AZURECORE
45
- )
46
- file_import.add_submodule_import(
47
- "azure.mgmt.core.policies", policy, ImportType.AZURECORE
48
- )
49
- return file_import
50
-
51
-
52
16
  class GeneralSerializer:
53
17
  def __init__(
54
18
  self, code_model: CodeModel, env: Environment, async_mode: bool
@@ -65,23 +29,9 @@ class GeneralSerializer:
65
29
  template = self.env.get_template("init.py.jinja2")
66
30
  return template.render(code_model=self.code_model, async_mode=self.async_mode)
67
31
 
68
- def _correct_credential_parameter(self):
69
- credential_param = [
70
- gp
71
- for gp in self.code_model.global_parameters.parameters
72
- if isinstance(gp.schema, TokenCredentialSchema)
73
- ][0]
74
- credential_param.schema = TokenCredentialSchema(async_mode=self.async_mode)
75
-
76
32
  def serialize_service_client_file(self) -> str:
77
33
 
78
- template = self.env.get_template("service_client.py.jinja2")
79
-
80
- if self.code_model.options["credential"] and isinstance(
81
- self.code_model.credential_model.credential_schema_policy.credential,
82
- TokenCredentialSchema,
83
- ):
84
- self._correct_credential_parameter()
34
+ template = self.env.get_template("client.py.jinja2")
85
35
 
86
36
  python3_only = self.code_model.options["python3_only"]
87
37
  return template.render(
@@ -89,7 +39,7 @@ class GeneralSerializer:
89
39
  async_mode=self.async_mode,
90
40
  serializer=ClientSerializer(self.code_model, is_python3_file=python3_only),
91
41
  imports=FileImportSerializer(
92
- self.code_model.service_client.imports(self.async_mode),
42
+ self.code_model.client.imports(self.async_mode),
93
43
  is_python3_file=self.async_mode or python3_only,
94
44
  ),
95
45
  )
@@ -120,7 +70,7 @@ class GeneralSerializer:
120
70
  )
121
71
  file_import.add_submodule_import(
122
72
  "._configuration",
123
- f"{self.code_model.class_name}Configuration",
73
+ f"{self.code_model.client.name}Configuration",
124
74
  ImportType.LOCAL,
125
75
  )
126
76
  file_import.add_submodule_import(
@@ -145,24 +95,15 @@ class GeneralSerializer:
145
95
  if package_name and package_name.startswith("azure-"):
146
96
  package_name = package_name[len("azure-") :]
147
97
  sdk_moniker = (
148
- package_name if package_name else self.code_model.class_name.lower()
98
+ package_name if package_name else self.code_model.client.name.lower()
149
99
  )
150
-
151
- if self.code_model.options["credential"] and isinstance(
152
- self.code_model.credential_model.credential_schema_policy.credential,
153
- TokenCredentialSchema,
154
- ):
155
- self._correct_credential_parameter()
156
-
157
100
  template = self.env.get_template("config.py.jinja2")
158
101
  python3_only = self.code_model.options["python3_only"]
159
102
  return template.render(
160
103
  code_model=self.code_model,
161
104
  async_mode=self.async_mode,
162
105
  imports=FileImportSerializer(
163
- config_imports(
164
- self.code_model, self.code_model.global_parameters, self.async_mode
165
- ),
106
+ self.code_model.config.imports(self.async_mode),
166
107
  is_python3_file=self.async_mode or python3_only,
167
108
  ),
168
109
  serializer=ConfigSerializer(self.code_model, is_python3_file=python3_only),
@@ -23,9 +23,10 @@ def _serialize_package(imports: List[ImportModel], delimiter: str) -> str:
23
23
  else:
24
24
  import_str = ", ".join(
25
25
  sorted(
26
- [
27
- f"{i.submodule_name} as {i.alias}" if i.alias else i.submodule_name for i in imports # type: ignore
28
- ]
26
+ set(
27
+ f"{i.submodule_name} as {i.alias}" if i.alias else i.submodule_name # type: ignore
28
+ for i in imports
29
+ )
29
30
  )
30
31
  )
31
32
  buffer.append(f"from {imports[0].module_name} import {import_str}")
@@ -130,7 +131,9 @@ class FileImportSerializer:
130
131
  )
131
132
  )
132
133
  if i > 0:
133
- ret[-1] += " # type: ignore"
134
+ ret[
135
+ -1
136
+ ] += " # type: ignore # pylint: disable=ungrouped-imports"
134
137
  ret.append("{}{} = {}".format(spacing, type_name, definition_value))
135
138
  return ret
136
139
 
@@ -4,45 +4,28 @@
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
6
  import functools
7
- import copy
8
7
  import json
9
8
  from typing import List, Optional, Set, Tuple, Dict, Union
10
9
  from jinja2 import Environment
11
- from .general_serializer import config_imports
12
10
  from ..models import (
13
11
  CodeModel,
14
- FileImport,
15
12
  OperationGroup,
16
13
  LROOperation,
17
14
  PagingOperation,
18
- TokenCredentialSchema,
19
- ParameterList,
20
15
  TypingSection,
21
16
  ImportType,
22
- GlobalParameterList,
23
17
  )
24
18
  from .builder_serializer import get_operation_serializer
25
19
 
26
20
 
27
- def _correct_credential_parameter(
28
- global_parameters: ParameterList, async_mode: bool
29
- ) -> None:
30
- credential_param = [
31
- gp
32
- for gp in global_parameters.parameters
33
- if isinstance(gp.schema, TokenCredentialSchema)
34
- ][0]
35
- credential_param.schema = TokenCredentialSchema(async_mode=async_mode)
36
-
37
-
38
21
  def _json_serialize_imports(
39
22
  imports: Dict[
40
23
  TypingSection,
41
24
  Dict[ImportType, Dict[str, Set[Optional[Union[str, Tuple[str, str]]]]]],
42
25
  ]
43
- ):
26
+ ) -> str:
44
27
  if not imports:
45
- return None
28
+ return ""
46
29
 
47
30
  json_serialize_imports = {}
48
31
  # need to make name_import set -> list to make the dictionary json serializable
@@ -106,51 +89,6 @@ class MetadataSerializer:
106
89
 
107
90
  return chosen_version, total_api_version_list
108
91
 
109
- def _make_async_copy_of_global_parameters(self) -> GlobalParameterList:
110
- global_parameters = copy.deepcopy(self.code_model.global_parameters)
111
- _correct_credential_parameter(global_parameters, True)
112
- return global_parameters
113
-
114
- def _service_client_imports(
115
- self,
116
- global_parameters: ParameterList,
117
- mixin_operation_group: Optional[OperationGroup],
118
- async_mode: bool,
119
- ) -> str:
120
- file_import = FileImport()
121
- for gp in global_parameters:
122
- file_import.merge(gp.imports())
123
- file_import.add_submodule_import(
124
- "azure.profiles", "KnownProfiles", import_type=ImportType.AZURECORE
125
- )
126
- file_import.add_submodule_import(
127
- "azure.profiles", "ProfileDefinition", import_type=ImportType.AZURECORE
128
- )
129
- file_import.add_submodule_import(
130
- "azure.profiles.multiapiclient",
131
- "MultiApiClientMixin",
132
- import_type=ImportType.AZURECORE,
133
- )
134
- file_import.add_submodule_import(
135
- "._configuration",
136
- f"{self.code_model.class_name}Configuration",
137
- ImportType.LOCAL,
138
- )
139
- # api_version and potentially endpoint require Optional typing
140
- file_import.add_submodule_import(
141
- "typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL
142
- )
143
- if mixin_operation_group:
144
- file_import.add_submodule_import(
145
- "._operations_mixin",
146
- f"{self.code_model.class_name}OperationsMixin",
147
- ImportType.LOCAL,
148
- )
149
- file_import.merge(
150
- self.code_model.service_client.imports_for_multiapi(async_mode=async_mode)
151
- )
152
- return _json_serialize_imports(file_import.to_dict())
153
-
154
92
  def serialize(self) -> str:
155
93
  def _is_lro(operation):
156
94
  return isinstance(operation, LROOperation)
@@ -162,7 +100,7 @@ class MetadataSerializer:
162
100
  (
163
101
  operation_group
164
102
  for operation_group in self.code_model.operation_groups
165
- if operation_group.is_empty_operation_group
103
+ if operation_group.is_mixin
166
104
  ),
167
105
  None,
168
106
  )
@@ -173,43 +111,15 @@ class MetadataSerializer:
173
111
 
174
112
  chosen_version, total_api_version_list = self._choose_api_version()
175
113
 
176
- # we separate out async and sync for the case of credentials.
177
- # In this case, we need two copies of the credential global parameter
178
- # for typing purposes.
179
- async_global_parameters = self.code_model.global_parameters
180
- if self.code_model.options["credential"] and isinstance(
181
- self.code_model.credential_model.credential_schema_policy.credential,
182
- TokenCredentialSchema,
183
- ):
184
- # this ensures that the TokenCredentialSchema showing up in the list of code model's global parameters
185
- # is sync. This way we only have to make a copy for an async_credential
186
- _correct_credential_parameter(self.code_model.global_parameters, False)
187
- async_global_parameters = self._make_async_copy_of_global_parameters()
188
-
189
- sync_client_imports = self._service_client_imports(
190
- self.code_model.global_parameters, mixin_operation_group, async_mode=False
191
- )
192
- async_client_imports = self._service_client_imports(
193
- async_global_parameters, mixin_operation_group, async_mode=True
194
- )
195
-
196
- template = self.env.get_template("metadata.json.jinja2")
197
-
198
114
  # setting to true, because for multiapi we always generate with a version file with version 0.1.0
199
115
  self.code_model.options["package_version"] = "0.1.0"
200
- if (
201
- self.code_model.options["azure_arm"]
202
- and not self.code_model.service_client.parameters.host
203
- ):
204
- self.code_model.service_client.parameters.add_host(
205
- "https://management.azure.com"
206
- )
116
+ template = self.env.get_template("metadata.json.jinja2")
117
+
207
118
  return template.render(
208
119
  chosen_version=chosen_version,
209
120
  total_api_version_list=total_api_version_list,
210
121
  code_model=self.code_model,
211
- sync_global_parameters=self.code_model.global_parameters,
212
- async_global_parameters=async_global_parameters,
122
+ global_parameters=self.code_model.client.parameters,
213
123
  mixin_operations=mixin_operations,
214
124
  any=any,
215
125
  is_lro=_is_lro,
@@ -217,17 +127,17 @@ class MetadataSerializer:
217
127
  str=str,
218
128
  sync_mixin_imports=sync_mixin_imports,
219
129
  async_mixin_imports=async_mixin_imports,
220
- sync_client_imports=sync_client_imports,
221
- async_client_imports=async_client_imports,
130
+ sync_client_imports=_json_serialize_imports(
131
+ self.code_model.client.imports_for_multiapi(async_mode=False).to_dict()
132
+ ),
133
+ async_client_imports=_json_serialize_imports(
134
+ self.code_model.client.imports_for_multiapi(async_mode=True).to_dict()
135
+ ),
222
136
  sync_config_imports=_json_serialize_imports(
223
- config_imports(
224
- self.code_model, self.code_model.global_parameters, async_mode=False
225
- ).to_dict()
137
+ self.code_model.config.imports(async_mode=False).to_dict()
226
138
  ),
227
139
  async_config_imports=_json_serialize_imports(
228
- config_imports(
229
- self.code_model, async_global_parameters, async_mode=True
230
- ).to_dict()
140
+ self.code_model.config.imports(async_mode=True).to_dict()
231
141
  ),
232
142
  get_async_operation_serializer=functools.partial(
233
143
  get_operation_serializer,
@@ -241,4 +151,5 @@ class MetadataSerializer:
241
151
  async_mode=False,
242
152
  is_python3_file=False,
243
153
  ),
154
+ has_credential=bool(self.code_model.credential),
244
155
  )