@autorest/python 6.1.11 → 6.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/autorest/_utils.py +2 -1
  2. package/autorest/codegen/__init__.py +87 -80
  3. package/autorest/codegen/models/__init__.py +11 -8
  4. package/autorest/codegen/models/base_builder.py +11 -5
  5. package/autorest/codegen/models/base_model.py +5 -3
  6. package/autorest/codegen/models/base_type.py +7 -5
  7. package/autorest/codegen/models/client.py +131 -32
  8. package/autorest/codegen/models/code_model.py +92 -120
  9. package/autorest/codegen/models/combined_type.py +9 -6
  10. package/autorest/codegen/models/constant_type.py +6 -6
  11. package/autorest/codegen/models/credential_types.py +18 -16
  12. package/autorest/codegen/models/dictionary_type.py +8 -6
  13. package/autorest/codegen/models/enum_type.py +24 -17
  14. package/autorest/codegen/models/imports.py +4 -4
  15. package/autorest/codegen/models/list_type.py +14 -10
  16. package/autorest/codegen/models/lro_operation.py +14 -6
  17. package/autorest/codegen/models/model_type.py +19 -19
  18. package/autorest/codegen/models/operation.py +50 -33
  19. package/autorest/codegen/models/operation_group.py +23 -12
  20. package/autorest/codegen/models/paging_operation.py +14 -11
  21. package/autorest/codegen/models/parameter.py +25 -25
  22. package/autorest/codegen/models/parameter_list.py +22 -16
  23. package/autorest/codegen/models/primitive_types.py +21 -11
  24. package/autorest/codegen/models/property.py +7 -7
  25. package/autorest/codegen/models/request_builder.py +31 -20
  26. package/autorest/codegen/models/request_builder_parameter.py +18 -13
  27. package/autorest/codegen/models/response.py +29 -22
  28. package/autorest/codegen/serializers/__init__.py +196 -139
  29. package/autorest/codegen/serializers/builder_serializer.py +50 -49
  30. package/autorest/codegen/serializers/client_serializer.py +40 -46
  31. package/autorest/codegen/serializers/enum_serializer.py +4 -4
  32. package/autorest/codegen/serializers/general_serializer.py +96 -43
  33. package/autorest/codegen/serializers/metadata_serializer.py +20 -16
  34. package/autorest/codegen/serializers/model_init_serializer.py +10 -6
  35. package/autorest/codegen/serializers/model_serializer.py +8 -8
  36. package/autorest/codegen/serializers/operation_groups_serializer.py +24 -12
  37. package/autorest/codegen/serializers/operations_init_serializer.py +6 -7
  38. package/autorest/codegen/serializers/patch_serializer.py +4 -4
  39. package/autorest/codegen/serializers/request_builders_serializer.py +6 -6
  40. package/autorest/codegen/serializers/sample_serializer.py +146 -0
  41. package/autorest/codegen/templates/client.py.jinja2 +7 -15
  42. package/autorest/codegen/templates/client_container.py.jinja2 +12 -0
  43. package/autorest/codegen/templates/config.py.jinja2 +13 -26
  44. package/autorest/codegen/templates/config_container.py.jinja2 +16 -0
  45. package/autorest/codegen/templates/enum_container.py.jinja2 +3 -3
  46. package/autorest/codegen/templates/init.py.jinja2 +11 -5
  47. package/autorest/codegen/templates/lro_operation.py.jinja2 +2 -2
  48. package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +1 -1
  49. package/autorest/codegen/templates/metadata.json.jinja2 +13 -14
  50. package/autorest/codegen/templates/model_container.py.jinja2 +3 -3
  51. package/autorest/codegen/templates/model_init.py.jinja2 +4 -4
  52. package/autorest/codegen/templates/operation.py.jinja2 +2 -2
  53. package/autorest/codegen/templates/operation_group.py.jinja2 +3 -3
  54. package/autorest/codegen/templates/operation_groups_container.py.jinja2 +7 -7
  55. package/autorest/codegen/templates/operation_tools.jinja2 +3 -3
  56. package/autorest/codegen/templates/operations_folder_init.py.jinja2 +4 -4
  57. package/autorest/codegen/templates/{CHANGELOG.md.jinja2 → packaging_templates/CHANGELOG.md.jinja2} +0 -0
  58. package/autorest/codegen/templates/{LICENSE.jinja2 → packaging_templates/LICENSE.jinja2} +0 -0
  59. package/autorest/codegen/templates/{MANIFEST.in.jinja2 → packaging_templates/MANIFEST.in.jinja2} +0 -0
  60. package/autorest/codegen/templates/{README.md.jinja2 → packaging_templates/README.md.jinja2} +0 -0
  61. package/autorest/codegen/templates/{dev_requirements.txt.jinja2 → packaging_templates/dev_requirements.txt.jinja2} +0 -0
  62. package/autorest/codegen/templates/{setup.py.jinja2 → packaging_templates/setup.py.jinja2} +9 -9
  63. package/autorest/codegen/templates/paging_operation.py.jinja2 +1 -1
  64. package/autorest/codegen/templates/request_builder.py.jinja2 +1 -1
  65. package/autorest/codegen/templates/request_builders.py.jinja2 +3 -3
  66. package/autorest/codegen/templates/rest_init.py.jinja2 +1 -1
  67. package/autorest/codegen/templates/sample.py.jinja2 +44 -0
  68. package/autorest/codegen/templates/validation.py.jinja2 +1 -1
  69. package/autorest/codegen/templates/vendor.py.jinja2 +9 -7
  70. package/autorest/codegen/templates/version.py.jinja2 +2 -2
  71. package/autorest/m4reformatter/__init__.py +20 -7
  72. package/autorest/preprocess/__init__.py +38 -23
  73. package/package.json +1 -1
@@ -1,10 +1,10 @@
1
1
  {% import 'operation_tools.jinja2' as op_tools %}
2
2
  # coding=utf-8
3
- {{ code_model.options['license_header'] }}
3
+ {{ namespace_model.options['license_header'] }}
4
4
  {{ imports }}
5
5
 
6
- {{ op_tools.declare_serializer(code_model, request_builders) }}
6
+ {{ op_tools.declare_serializer(namespace_model) }}
7
7
  {% for request_builder in request_builders %}
8
8
 
9
9
  {% include "request_builder.py.jinja2" %}
10
- {% endfor %}
10
+ {% endfor %}
@@ -1,5 +1,5 @@
1
1
  # coding=utf-8
2
- {{ code_model.options['license_header'] }}
2
+ {{ client.namespace_model.options['license_header'] }}
3
3
 
4
4
  {% for request_builder in request_builders %}
5
5
  from ._request_builders import {{ request_builder.name }}
@@ -0,0 +1,44 @@
1
+ # coding=utf-8
2
+ {% set aad_token = "DefaultAzureCredential" %}
3
+ {% set azure_key = "AzureKeyCredential" %}
4
+ {{ namespace_model.options['license_header'] }}
5
+
6
+ {{ imports }}
7
+ """
8
+ # PREREQUISITES
9
+ {% if "credential" in client_params and aad_token in client_params["credential"] %}
10
+ pip install azure-identity
11
+ {% endif %}
12
+ pip install {{ (namespace_model.options["package_name"] or namespace_model.clients[0].name)|lower }}
13
+ # USAGE
14
+ python {{ file_name }}
15
+ {% if "credential" in client_params and aad_token in client_params["credential"] %}
16
+
17
+ Before run the sample, please set the values of the client ID, tenant ID and client secret
18
+ of the AAD application as environment variables: AZURE_CLIENT_ID, AZURE_TENANT_ID,
19
+ AZURE_CLIENT_SECRET. For more info about how to get the value, please see:
20
+ https://docs.microsoft.com/azure/active-directory/develop/howto-create-service-principal-portal
21
+ {% elif "credential" in client_params and azure_key in client_params["credential"] %}
22
+
23
+ Before run the sample, please set environment variables AZURE_KEY with real value
24
+ which can access your service
25
+ {% endif %}
26
+ """
27
+ def main():
28
+ client = {{ namespace_model.clients[0].name }}(
29
+ {% for key,value in client_params.items() %}
30
+ {{ key }}={{ value }},
31
+ {% endfor %}
32
+ )
33
+
34
+ response = client{{ operation_group_name }}{{ operation_name }}(
35
+ {% for key, value in operation_params.items() %}
36
+ {{ key }}={{ value|indent(8) }},
37
+ {% endfor %}
38
+ ){{ operation_result }}
39
+
40
+ {% if origin_file %}
41
+ # x-ms-original-file: {{ origin_file }}
42
+ {% endif %}
43
+ if __name__ == "__main__":
44
+ main()
@@ -1,4 +1,4 @@
1
- {{ code_model.options['license_header'] }}
1
+ {{ namespace_model.options['license_header'] }}
2
2
  import functools
3
3
 
4
4
  def api_version_validation(**kwargs):
@@ -1,9 +1,9 @@
1
1
  {% import 'keywords.jinja2' as keywords with context %}
2
- {{ code_model.options['license_header'] }}
2
+ {{ namespace_model.options['license_header'] }}
3
3
 
4
4
  {{ imports }}
5
5
 
6
- {% if code_model.need_request_converter and not async_mode %}
6
+ {% if namespace_model.need_request_converter and not async_mode %}
7
7
  def _convert_request(request, files=None):
8
8
  data = request.content if not files else None
9
9
  request = HttpRequest(method=request.method, url=request.url, headers=request.headers, data=data)
@@ -11,7 +11,7 @@ def _convert_request(request, files=None):
11
11
  request.set_formdata_body(files)
12
12
  return request
13
13
  {% endif %}
14
- {% if code_model.need_format_url and not async_mode %}
14
+ {% if namespace_model.need_format_url and not async_mode %}
15
15
 
16
16
  def _format_url_section(template, **kwargs):
17
17
  components = template.split("/")
@@ -25,16 +25,18 @@ def _format_url_section(template, **kwargs):
25
25
  ]
26
26
  template = "/".join(components)
27
27
  {% endif %}
28
- {% if code_model.need_mixin_abc %}
28
+ {% if namespace_model.need_mixin_abc %}
29
+ {% for client in namespace_model.clients | selectattr("has_mixin") %}
29
30
 
30
- class MixinABC(ABC):
31
+ class {{ client.name }}MixinABC(ABC):
31
32
  """DO NOT use this class. It is for internal typing use only."""
32
33
  _client: "{{ keywords.async_class }}PipelineClient"
33
- _config: {{ code_model.client.name }}Configuration
34
+ _config: {{ client.name }}Configuration
34
35
  _serialize: "Serializer"
35
36
  _deserialize: "Deserializer"
37
+ {% endfor %}
36
38
  {% endif %}
37
- {% if code_model.has_abstract_operations %}
39
+ {% if namespace_model.has_abstract_operations %}
38
40
 
39
41
  def raise_if_not_implemented(cls, abstract_methods):
40
42
  not_implemented = [f for f in abstract_methods if not callable(getattr(cls, f, None))]
@@ -1,4 +1,4 @@
1
1
  # coding=utf-8
2
- {{ code_model.options['license_header'] }}
2
+ {{ namespace_model.options['license_header'] }}
3
3
 
4
- VERSION = "{{ code_model.options['package_version'] }}"
4
+ VERSION = "{{ namespace_model.options['package_version'] }}"
@@ -6,6 +6,7 @@
6
6
  # --------------------------------------------------------------------------
7
7
  """The modelerfour reformatter autorest plugin.
8
8
  """
9
+ import re
9
10
  import copy
10
11
  import logging
11
12
  from typing import Callable, Dict, Any, Iterable, List, Optional, Set
@@ -421,6 +422,10 @@ def update_client_url(yaml_data: Dict[str, Any]) -> str:
421
422
  ]["uri"]
422
423
 
423
424
 
425
+ def to_lower_camel_case(name: str) -> str:
426
+ return re.sub(r"_([a-z])", lambda x: x.group(1).upper(), name)
427
+
428
+
424
429
  class M4Reformatter(
425
430
  YamlUpdatePluginAutorest
426
431
  ): # pylint: disable=too-many-public-methods
@@ -554,6 +559,7 @@ class M4Reformatter(
554
559
  operation["overloads"] = self.update_overloads(
555
560
  group_name, yaml_data, body_parameter, content_types=content_types
556
561
  )
562
+ operation["samples"] = yaml_data.get("extensions", {}).get("x-ms-examples", {})
557
563
  return operation
558
564
 
559
565
  def add_paging_information(
@@ -665,6 +671,9 @@ class M4Reformatter(
665
671
  body_param["clientDefaultValue"] = body_type["value"]
666
672
  body_param["flattened"] = flattened
667
673
  body_param["isPartialBody"] = is_partial_body
674
+ body_param["restApiName"] = body_param["restApiName"] or to_lower_camel_case(
675
+ body_param["clientName"]
676
+ )
668
677
  return body_param
669
678
 
670
679
  def update_multipart_body_parameter(
@@ -1081,12 +1090,14 @@ class M4Reformatter(
1081
1090
  "url": update_client_url(yaml_data)
1082
1091
  if yaml_data.get("globalParameters")
1083
1092
  else "",
1084
- "namespace": self._autorestapi.get_value("namespace")
1085
- or to_snake_case(yaml_data["info"]["title"].replace(" ", "")),
1086
1093
  }
1087
1094
 
1088
1095
  def update_yaml(self, yaml_data: Dict[str, Any]) -> None:
1089
1096
  """Convert in place the YAML str."""
1097
+ # there can only be one namespace and client from swagger
1098
+ namespace = self._autorestapi.get_value("namespace") or to_snake_case(
1099
+ yaml_data["info"]["title"].replace(" ", "")
1100
+ )
1090
1101
  # First we update the types, so we can access for when we're creating parameters etc.
1091
1102
  for type_group, types in yaml_data["schemas"].items():
1092
1103
  for t in types:
@@ -1097,18 +1108,20 @@ class M4Reformatter(
1097
1108
  # we don't generate cloud error
1098
1109
  continue
1099
1110
  update_type(t)
1100
- yaml_data["client"] = self.update_client(yaml_data)
1101
- yaml_data["operationGroups"] = [
1111
+ yaml_data[namespace] = {}
1112
+ yaml_data[namespace]["clients"] = [self.update_client(yaml_data)]
1113
+ yaml_data[namespace]["clients"][0]["operationGroups"] = [
1102
1114
  self.update_operation_group(og) for og in yaml_data["operationGroups"]
1103
1115
  ]
1104
- yaml_data["types"] = list(ORIGINAL_ID_TO_UPDATED_TYPE.values()) + list(
1105
- KNOWN_TYPES.values()
1106
- )
1116
+ yaml_data[namespace]["types"] = list(
1117
+ ORIGINAL_ID_TO_UPDATED_TYPE.values()
1118
+ ) + list(KNOWN_TYPES.values())
1107
1119
  if yaml_data.get("globalParameters"):
1108
1120
  del yaml_data["globalParameters"]
1109
1121
  del yaml_data["info"]
1110
1122
  del yaml_data["language"]
1111
1123
  del yaml_data["protocol"]
1124
+ del yaml_data["operationGroups"]
1112
1125
  if yaml_data.get("schemas"):
1113
1126
  del yaml_data["schemas"]
1114
1127
  if yaml_data.get("security"):
@@ -16,7 +16,9 @@ from .. import YamlUpdatePlugin, YamlUpdatePluginAutorest
16
16
  from .._utils import parse_args, get_body_type_for_description, JSON_REGEXP, KNOWN_TYPES
17
17
 
18
18
 
19
- def add_body_param_type(code_model: Dict[str, Any], body_parameter: Dict[str, Any]):
19
+ def add_body_param_type(
20
+ namespace_model: Dict[str, Any], body_parameter: Dict[str, Any]
21
+ ):
20
22
  if (
21
23
  body_parameter
22
24
  and body_parameter["type"]["type"] in ("model", "dict", "list")
@@ -30,7 +32,7 @@ def add_body_param_type(code_model: Dict[str, Any], body_parameter: Dict[str, An
30
32
  "type": "combined",
31
33
  "types": [body_parameter["type"], KNOWN_TYPES["binary"]],
32
34
  }
33
- code_model["types"].append(body_parameter["type"])
35
+ namespace_model["types"].append(body_parameter["type"])
34
36
 
35
37
 
36
38
  def update_overload_section(
@@ -133,7 +135,7 @@ def update_operation_group_class_name(
133
135
  yaml_data: Dict[str, Any], class_name: str
134
136
  ) -> str:
135
137
  if class_name == "":
136
- return yaml_data["client"]["name"] + "OperationsMixin"
138
+ return yaml_data["name"] + "OperationsMixin"
137
139
  if class_name == "Operations":
138
140
  return "Operations"
139
141
  return class_name + "Operations"
@@ -175,9 +177,13 @@ def update_client(yaml_data: Dict[str, Any]) -> None:
175
177
  yaml_data["description"] = update_description(
176
178
  yaml_data["description"], default_description=yaml_data["name"]
177
179
  )
178
- yaml_data["moduleName"] = to_snake_case(yaml_data["name"].replace(" ", "_"))
180
+ yaml_data["legacyFilename"] = to_snake_case(yaml_data["name"].replace(" ", "_"))
179
181
  for parameter in yaml_data["parameters"]:
180
182
  update_parameter(parameter)
183
+ prop_name = yaml_data["name"]
184
+ if prop_name.endswith("Client"):
185
+ prop_name = prop_name[: len(prop_name) - len("Client")]
186
+ yaml_data["builderPadName"] = to_snake_case(prop_name)
181
187
 
182
188
 
183
189
  def update_paging_response(yaml_data: Dict[str, Any]) -> None:
@@ -208,7 +214,7 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
208
214
 
209
215
  def update_operation(
210
216
  self,
211
- code_model: Dict[str, Any],
217
+ namespace_model: Dict[str, Any],
212
218
  yaml_data: Dict[str, Any],
213
219
  *,
214
220
  is_overload: bool = False,
@@ -231,12 +237,12 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
231
237
  for entry in yaml_data["bodyParameter"].get("entries", []):
232
238
  update_parameter(entry)
233
239
  for overload in yaml_data.get("overloads", []):
234
- self.update_operation(code_model, overload, is_overload=True)
240
+ self.update_operation(namespace_model, overload, is_overload=True)
235
241
  for response in yaml_data.get("responses", []):
236
242
  response["discriminator"] = "operation"
237
243
  if body_parameter and not is_overload:
238
244
  # if we have a JSON body, we add a binary overload
239
- add_body_param_type(code_model, body_parameter)
245
+ add_body_param_type(namespace_model, body_parameter)
240
246
  add_overloads_for_body_param(yaml_data)
241
247
 
242
248
  def _update_lro_operation_helper(self, yaml_data: Dict[str, Any]) -> None:
@@ -264,36 +270,40 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
264
270
 
265
271
  def update_lro_paging_operation(
266
272
  self,
267
- code_model: Dict[str, Any],
273
+ namespace_model: Dict[str, Any],
268
274
  yaml_data: Dict[str, Any],
269
275
  is_overload: bool = False,
270
276
  ) -> None:
271
- self.update_lro_operation(code_model, yaml_data, is_overload=is_overload)
272
- self.update_paging_operation(code_model, yaml_data, is_overload=is_overload)
277
+ self.update_lro_operation(namespace_model, yaml_data, is_overload=is_overload)
278
+ self.update_paging_operation(
279
+ namespace_model, yaml_data, is_overload=is_overload
280
+ )
273
281
  yaml_data["discriminator"] = "lropaging"
274
282
  for response in yaml_data.get("responses", []):
275
283
  response["discriminator"] = "lropaging"
276
284
  for overload in yaml_data.get("overloads", []):
277
- self.update_lro_paging_operation(code_model, overload, is_overload=True)
285
+ self.update_lro_paging_operation(
286
+ namespace_model, overload, is_overload=True
287
+ )
278
288
 
279
289
  def update_lro_operation(
280
290
  self,
281
- code_model: Dict[str, Any],
291
+ namespace_model: Dict[str, Any],
282
292
  yaml_data: Dict[str, Any],
283
293
  is_overload: bool = False,
284
294
  ) -> None:
285
- self.update_operation(code_model, yaml_data, is_overload=is_overload)
295
+ self.update_operation(namespace_model, yaml_data, is_overload=is_overload)
286
296
  self._update_lro_operation_helper(yaml_data)
287
297
  for overload in yaml_data.get("overloads", []):
288
298
  self._update_lro_operation_helper(overload)
289
299
 
290
300
  def update_paging_operation(
291
301
  self,
292
- code_model: Dict[str, Any],
302
+ namespace_model: Dict[str, Any],
293
303
  yaml_data: Dict[str, Any],
294
304
  is_overload: bool = False,
295
305
  ) -> None:
296
- self.update_operation(code_model, yaml_data, is_overload=is_overload)
306
+ self.update_operation(namespace_model, yaml_data, is_overload=is_overload)
297
307
  if not yaml_data.get("pagerSync"):
298
308
  yaml_data["pagerSync"] = "azure.core.paging.ItemPaged"
299
309
  if not yaml_data.get("pagerAsync"):
@@ -328,11 +338,14 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
328
338
  update_paging_response(response)
329
339
  response["itemType"] = item_type
330
340
  for overload in yaml_data.get("overloads", []):
331
- self.update_paging_operation(code_model, overload, is_overload=True)
341
+ self.update_paging_operation(namespace_model, overload, is_overload=True)
332
342
 
333
- def update_operation_groups(self, yaml_data: Dict[str, Any]) -> None:
334
- operation_groups_yaml_data = yaml_data["operationGroups"]
343
+ def update_operation_groups(
344
+ self, namespace: Dict[str, Any], client: Dict[str, Any]
345
+ ) -> None:
346
+ operation_groups_yaml_data = client["operationGroups"]
335
347
  for operation_group in operation_groups_yaml_data:
348
+ operation_group["clientName"] = client["name"]
336
349
  operation_group["propertyName"] = pad_reserved_words(
337
350
  operation_group["propertyName"], PadType.OPERATION_GROUP
338
351
  )
@@ -340,16 +353,18 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
340
353
  operation_group["propertyName"]
341
354
  )
342
355
  operation_group["className"] = update_operation_group_class_name(
343
- yaml_data, operation_group["className"]
356
+ client, operation_group["className"]
344
357
  )
345
358
  for operation in operation_group["operations"]:
346
- self.get_operation_updater(operation)(yaml_data, operation)
359
+ self.get_operation_updater(operation)(namespace, operation)
347
360
 
348
361
  def update_yaml(self, yaml_data: Dict[str, Any]) -> None:
349
362
  """Convert in place the YAML str."""
350
- update_client(yaml_data["client"])
351
- self.update_operation_groups(yaml_data)
352
- update_types(yaml_data["types"])
363
+ for namespace in yaml_data.values():
364
+ update_types(namespace["types"])
365
+ for client in namespace["clients"]:
366
+ update_client(client)
367
+ self.update_operation_groups(namespace, client)
353
368
 
354
369
 
355
370
  class PreProcessPluginAutorest(YamlUpdatePluginAutorest, PreProcessPlugin):
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autorest/python",
3
- "version": "6.1.11",
3
+ "version": "6.2.0",
4
4
  "description": "The Python extension for generators in AutoRest.",
5
5
  "repository": {
6
6
  "type": "git",