@autorest/python 5.16.0 → 5.19.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 (96) hide show
  1. package/ChangeLog.md +79 -4
  2. package/README.md +30 -4
  3. package/autorest/__init__.py +1 -1
  4. package/autorest/codegen/__init__.py +55 -211
  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} +61 -39
  9. package/autorest/codegen/models/client.py +165 -53
  10. package/autorest/codegen/models/code_model.py +122 -257
  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_type.py +131 -0
  15. package/autorest/codegen/models/enum_type.py +195 -0
  16. package/autorest/codegen/models/imports.py +80 -2
  17. package/autorest/codegen/models/list_type.py +149 -0
  18. package/autorest/codegen/models/lro_operation.py +79 -156
  19. package/autorest/codegen/models/lro_paging_operation.py +28 -11
  20. package/autorest/codegen/models/model_type.py +262 -0
  21. package/autorest/codegen/models/operation.py +331 -298
  22. package/autorest/codegen/models/operation_group.py +54 -91
  23. package/autorest/codegen/models/paging_operation.py +82 -123
  24. package/autorest/codegen/models/parameter.py +289 -396
  25. package/autorest/codegen/models/parameter_list.py +355 -360
  26. package/autorest/codegen/models/primitive_types.py +544 -0
  27. package/autorest/codegen/models/property.py +123 -139
  28. package/autorest/codegen/models/request_builder.py +130 -102
  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 +55 -37
  33. package/autorest/codegen/serializers/builder_serializer.py +695 -1144
  34. package/autorest/codegen/serializers/client_serializer.py +92 -89
  35. package/autorest/codegen/serializers/general_serializer.py +15 -69
  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 +49 -36
  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 +7 -13
  43. package/autorest/codegen/serializers/parameter_serializer.py +174 -0
  44. package/autorest/codegen/serializers/request_builders_serializer.py +13 -30
  45. package/autorest/codegen/serializers/utils.py +0 -140
  46. package/autorest/codegen/templates/MANIFEST.in.jinja2 +1 -0
  47. package/autorest/codegen/templates/{service_client.py.jinja2 → client.py.jinja2} +10 -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 +21 -8
  60. package/autorest/codegen/templates/operation_groups_container.py.jinja2 +2 -2
  61. package/autorest/codegen/templates/operation_tools.jinja2 +11 -3
  62. package/autorest/codegen/templates/paging_operation.py.jinja2 +2 -2
  63. package/autorest/codegen/templates/request_builder.py.jinja2 +10 -15
  64. package/autorest/codegen/templates/request_builders.py.jinja2 +1 -1
  65. package/autorest/codegen/templates/serialization.py.jinja2 +2006 -0
  66. package/autorest/codegen/templates/setup.py.jinja2 +13 -3
  67. package/autorest/codegen/templates/vendor.py.jinja2 +11 -1
  68. package/autorest/jsonrpc/server.py +15 -3
  69. package/autorest/m4reformatter/__init__.py +1126 -0
  70. package/autorest/multiapi/models/client.py +12 -2
  71. package/autorest/multiapi/models/code_model.py +1 -1
  72. package/autorest/multiapi/serializers/__init__.py +18 -4
  73. package/autorest/multiapi/templates/multiapi_config.py.jinja2 +3 -3
  74. package/autorest/multiapi/templates/multiapi_init.py.jinja2 +2 -2
  75. package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +4 -4
  76. package/autorest/multiapi/templates/multiapi_service_client.py.jinja2 +9 -9
  77. package/autorest/postprocess/__init__.py +202 -0
  78. package/autorest/postprocess/get_all.py +19 -0
  79. package/autorest/postprocess/venvtools.py +73 -0
  80. package/autorest/preprocess/__init__.py +210 -0
  81. package/autorest/preprocess/helpers.py +54 -0
  82. package/autorest/{namer → preprocess}/python_mappings.py +21 -16
  83. package/package.json +2 -2
  84. package/autorest/codegen/models/credential_model.py +0 -55
  85. package/autorest/codegen/models/credential_schema.py +0 -95
  86. package/autorest/codegen/models/credential_schema_policy.py +0 -73
  87. package/autorest/codegen/models/dictionary_schema.py +0 -106
  88. package/autorest/codegen/models/enum_schema.py +0 -225
  89. package/autorest/codegen/models/list_schema.py +0 -135
  90. package/autorest/codegen/models/object_schema.py +0 -303
  91. package/autorest/codegen/models/primitive_schemas.py +0 -495
  92. package/autorest/codegen/models/request_builder_parameter_list.py +0 -249
  93. package/autorest/codegen/models/schema_request.py +0 -55
  94. package/autorest/codegen/models/schema_response.py +0 -141
  95. package/autorest/namer/__init__.py +0 -23
  96. 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,44 @@ 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
+
104
+ @property
105
+ def should_init_super(self) -> bool:
106
+ return any(
107
+ og
108
+ for og in self.code_model.operation_groups
109
+ if og.is_mixin and og.has_abstract_operations
110
+ )
111
+
103
112
  def initialize_pipeline_client(self, async_mode: bool) -> str:
104
- host_variable_name = (
105
- self.code_model.service_client.parameters.host_variable_name
113
+ pipeline_client_name = self.code_model.client.pipeline_class(async_mode)
114
+ return (
115
+ f"self._client = {pipeline_client_name}(base_url={self.host_variable_name}, "
116
+ "config=self._config, **kwargs)"
106
117
  )
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
118
 
114
119
  def serializers_and_operation_groups_properties(self) -> List[str]:
115
120
  retval = []
116
- if self.code_model.sorted_schemas:
121
+ if self.code_model.model_types:
117
122
  client_models_value = (
118
123
  "{k: v for k, v in models.__dict__.items() if isinstance(v, type)}"
119
124
  )
@@ -129,19 +134,12 @@ class ClientSerializer:
129
134
  if not self.code_model.options["client_side_validation"]:
130
135
  retval.append("self._serialize.client_side_validation = False")
131
136
  operation_groups = [
132
- og
133
- for og in self.code_model.operation_groups
134
- if not og.is_empty_operation_group
137
+ og for og in self.code_model.operation_groups if not og.is_mixin
135
138
  ]
136
139
  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
140
  retval.extend(
143
141
  [
144
- f"self.{og.name} = {og.class_name}({disable_check}",
142
+ f"self.{og.property_name} = {og.class_name}({og.mypy_ignore}{og.pylint_disable}",
145
143
  " self._client, self._config, self._serialize, self._deserialize",
146
144
  ")",
147
145
  ]
@@ -149,13 +147,21 @@ class ClientSerializer:
149
147
  return retval
150
148
 
151
149
  def _send_request_signature(self, async_mode: bool) -> str:
152
- return utils.serialize_method(
150
+ is_python3_file = async_mode or self.code_model.options["python3_only"]
151
+ request_signature = [
152
+ "request: HttpRequest,"
153
+ if is_python3_file
154
+ else "request, # type: HttpRequest"
155
+ ]
156
+ send_request_signature = (
157
+ request_signature
158
+ + self.code_model.client.parameters.method_signature_kwargs(is_python3_file)
159
+ )
160
+ return self.parameter_serializer.serialize_method(
153
161
  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
- ),
162
+ method_name=self.code_model.client.send_request_name,
163
+ need_self_param=True,
164
+ method_param_signatures=send_request_signature,
159
165
  )
160
166
 
161
167
  def send_request_signature_and_response_type_annotation(
@@ -173,7 +179,7 @@ class ClientSerializer:
173
179
  def _example_make_call(self, async_mode: bool) -> List[str]:
174
180
  http_response = "AsyncHttpResponse" if async_mode else "HttpResponse"
175
181
  retval = [
176
- f">>> response = {'await ' if async_mode else ''}client.{self.code_model.send_request_name}(request)"
182
+ f">>> response = {'await ' if async_mode else ''}client.{self.code_model.client.send_request_name}(request)"
177
183
  ]
178
184
  retval.append(f"<{http_response}: 200 OK>")
179
185
  return retval
@@ -189,13 +195,11 @@ class ClientSerializer:
189
195
  retval.append("")
190
196
 
191
197
  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
198
+ request_builder_signature = ", ".join(request_builder.parameters.call)
199
+ if request_builder.group_name:
200
+ rest_imported = request_builder.group_name
197
201
  request_builder_name = (
198
- f"{request_builder.builder_group_name}.{request_builder.name}"
202
+ f"{request_builder.group_name}.{request_builder.name}"
199
203
  )
200
204
  else:
201
205
  rest_imported = request_builder.name
@@ -228,7 +232,7 @@ class ClientSerializer:
228
232
  retval.extend(self._rest_request_example(async_mode))
229
233
  retval.append("")
230
234
  retval.append(
231
- "For more information on this code flow, see https://aka.ms/azsdk/python/protocol/quickstart"
235
+ "For more information on this code flow, see https://aka.ms/azsdk/dpcodegen/python/send_request"
232
236
  )
233
237
  retval.append(f"")
234
238
  retval.append(":param request: The network request you want to make. Required.")
@@ -245,23 +249,24 @@ class ClientSerializer:
245
249
  return retval
246
250
 
247
251
  def serialize_path(self) -> List[str]:
248
- return utils.serialize_path(
249
- self.code_model.global_parameters.path, "self._serialize"
252
+ return self.parameter_serializer.serialize_path(
253
+ self.code_model.client.parameters.path, "self._serialize"
250
254
  )
251
255
 
252
256
 
253
257
  class ConfigSerializer:
254
258
  def __init__(self, code_model: CodeModel, is_python3_file: bool) -> None:
255
259
  self.code_model = code_model
260
+ self.parameter_serializer = ParameterSerializer()
256
261
  self.is_python3_file = is_python3_file
257
262
 
258
263
  def _init_signature(self, async_mode: bool) -> str:
259
- return utils.serialize_method(
264
+ return self.parameter_serializer.serialize_method(
260
265
  function_def="def",
261
266
  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
267
+ need_self_param=True,
268
+ method_param_signatures=self.code_model.config.parameters.method_signature(
269
+ async_mode or self.is_python3_file, async_mode
265
270
  ),
266
271
  )
267
272
 
@@ -274,38 +279,36 @@ class ConfigSerializer:
274
279
  )
275
280
 
276
281
  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(
282
+ return self.parameter_serializer.pop_kwargs_from_signature(
283
+ self.code_model.config.parameters.kwargs_to_pop(
279
284
  async_mode or self.is_python3_file
280
285
  ),
281
286
  check_kwarg_dict=False,
282
- pop_headers_kwarg=utils.PopKwargType.NO,
283
- pop_params_kwarg=utils.PopKwargType.NO,
287
+ pop_headers_kwarg=PopKwargType.NO,
288
+ pop_params_kwarg=PopKwargType.NO,
284
289
  )
285
290
 
286
291
  def set_constants(self) -> List[str]:
287
292
  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
293
+ f"self.{p.client_name} = {p.client_default_value_declaration}"
294
+ for p in self.code_model.config.parameters.constant
295
+ if p not in self.code_model.config.parameters.method
291
296
  ]
292
297
 
293
298
  def check_required_parameters(self) -> List[str]:
294
299
  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
300
+ f"if {p.client_name} is None:\n"
301
+ f" raise ValueError(\"Parameter '{p.client_name}' must not be None.\")"
302
+ for p in self.code_model.config.parameters.method
303
+ if not (p.optional or p.constant)
299
304
  ]
300
305
 
301
- def property_descriptions(self) -> List[str]:
306
+ def property_descriptions(self, async_mode: bool) -> List[str]:
302
307
  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
- )
308
+ for p in self.code_model.config.parameters.method:
309
+ retval.append(f":{p.description_keyword} {p.client_name}: {p.description}")
307
310
  retval.append(
308
- f":{p.docstring_type_keyword} {p.serialized_name}: {p.docstring_type}"
311
+ f":{p.docstring_type_keyword} {p.client_name}: {p.docstring_type(async_mode=async_mode)}"
309
312
  )
310
313
  retval.append('"""')
311
314
  return retval
@@ -5,50 +5,15 @@
5
5
  # --------------------------------------------------------------------------
6
6
  from jinja2 import Environment
7
7
  from .import_serializer import FileImportSerializer, TypingSection
8
+ from ..models.imports import MsrestImportType
8
9
  from ..models import (
9
10
  FileImport,
10
11
  ImportType,
11
12
  CodeModel,
12
- TokenCredentialSchema,
13
- ParameterList,
14
13
  )
15
14
  from .client_serializer import ClientSerializer, ConfigSerializer
16
15
 
17
16
 
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
17
  class GeneralSerializer:
53
18
  def __init__(
54
19
  self, code_model: CodeModel, env: Environment, async_mode: bool
@@ -65,23 +30,9 @@ class GeneralSerializer:
65
30
  template = self.env.get_template("init.py.jinja2")
66
31
  return template.render(code_model=self.code_model, async_mode=self.async_mode)
67
32
 
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
33
  def serialize_service_client_file(self) -> str:
77
34
 
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()
35
+ template = self.env.get_template("client.py.jinja2")
85
36
 
86
37
  python3_only = self.code_model.options["python3_only"]
87
38
  return template.render(
@@ -89,7 +40,7 @@ class GeneralSerializer:
89
40
  async_mode=self.async_mode,
90
41
  serializer=ClientSerializer(self.code_model, is_python3_file=python3_only),
91
42
  imports=FileImportSerializer(
92
- self.code_model.service_client.imports(self.async_mode),
43
+ self.code_model.client.imports(self.async_mode),
93
44
  is_python3_file=self.async_mode or python3_only,
94
45
  ),
95
46
  )
@@ -120,14 +71,14 @@ class GeneralSerializer:
120
71
  )
121
72
  file_import.add_submodule_import(
122
73
  "._configuration",
123
- f"{self.code_model.class_name}Configuration",
74
+ f"{self.code_model.client.name}Configuration",
124
75
  ImportType.LOCAL,
125
76
  )
126
- file_import.add_submodule_import(
127
- "msrest", "Serializer", ImportType.THIRDPARTY, TypingSection.TYPING
128
- )
129
- file_import.add_submodule_import(
130
- "msrest", "Deserializer", ImportType.THIRDPARTY, TypingSection.TYPING
77
+ file_import.add_msrest_import(
78
+ self.code_model,
79
+ ".." if self.async_mode else ".",
80
+ MsrestImportType.SerializerDeserializer,
81
+ TypingSection.TYPING,
131
82
  )
132
83
 
133
84
  return template.render(
@@ -145,24 +96,15 @@ class GeneralSerializer:
145
96
  if package_name and package_name.startswith("azure-"):
146
97
  package_name = package_name[len("azure-") :]
147
98
  sdk_moniker = (
148
- package_name if package_name else self.code_model.class_name.lower()
99
+ package_name if package_name else self.code_model.client.name.lower()
149
100
  )
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
101
  template = self.env.get_template("config.py.jinja2")
158
102
  python3_only = self.code_model.options["python3_only"]
159
103
  return template.render(
160
104
  code_model=self.code_model,
161
105
  async_mode=self.async_mode,
162
106
  imports=FileImportSerializer(
163
- config_imports(
164
- self.code_model, self.code_model.global_parameters, self.async_mode
165
- ),
107
+ self.code_model.config.imports(self.async_mode),
166
108
  is_python3_file=self.async_mode or python3_only,
167
109
  ),
168
110
  serializer=ConfigSerializer(self.code_model, is_python3_file=python3_only),
@@ -179,3 +121,7 @@ class GeneralSerializer:
179
121
  params.update(self.code_model.options)
180
122
  params.update(self.code_model.package_dependency)
181
123
  return template.render(code_model=self.code_model, **params)
124
+
125
+ def serialize_serialization_file(self) -> str:
126
+ template = self.env.get_template("serialization.py.jinja2")
127
+ return template.render(code_model=self.code_model)
@@ -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
  )