@autorest/python 6.5.1 → 6.6.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.
@@ -331,7 +331,9 @@ class OperationBase( # pylint: disable=too-many-public-methods
331
331
  )
332
332
  return file_import
333
333
 
334
- def imports(self, async_mode: bool, **kwargs: Any) -> FileImport:
334
+ def imports( # pylint: disable=too-many-branches
335
+ self, async_mode: bool, **kwargs: Any
336
+ ) -> FileImport:
335
337
  if self.abstract:
336
338
  return FileImport()
337
339
  file_import = self._imports_shared(async_mode, **kwargs)
@@ -356,6 +358,12 @@ class OperationBase( # pylint: disable=too-many-public-methods
356
358
  file_import.merge(
357
359
  self.parameters.body_parameter.type.imports(operation=self, **kwargs)
358
360
  )
361
+ if not async_mode:
362
+ for param in self.parameters.headers:
363
+ if param.wire_name.lower() == "repeatability-request-id":
364
+ file_import.add_import("uuid", ImportType.STDLIB)
365
+ elif param.wire_name.lower() == "repeatability-first-sent":
366
+ file_import.add_import("datetime", ImportType.STDLIB)
359
367
 
360
368
  # Exceptions
361
369
  errors = [
@@ -52,6 +52,9 @@ class ParameterDelimeter(str, Enum):
52
52
  COMMA = "comma"
53
53
 
54
54
 
55
+ SPECIAL_HANDLE_HEADERS = ["repeatability-request-id", "repeatability-first-sent"]
56
+
57
+
55
58
  class _ParameterBase(
56
59
  BaseModel, abc.ABC
57
60
  ): # pylint: disable=too-many-instance-attributes
@@ -90,6 +93,10 @@ class _ParameterBase(
90
93
  self.default_to_unset_sentinel: bool = self.yaml_data.get(
91
94
  "defaultToUnsetSentinel", False
92
95
  )
96
+ self.is_special_handle_header: bool = (
97
+ self.location == ParameterLocation.HEADER
98
+ and self.wire_name.lower() in SPECIAL_HANDLE_HEADERS
99
+ )
93
100
 
94
101
  @property
95
102
  def constant(self) -> bool:
@@ -213,7 +213,9 @@ class _ParameterListBase(
213
213
  method_params: List[Union[ParameterType, BodyParameterType]] = [
214
214
  p
215
215
  for p in self.parameters
216
- if p.in_method_signature and p.implementation == self.implementation
216
+ if p.in_method_signature
217
+ and p.implementation == self.implementation
218
+ and not p.is_special_handle_header
217
219
  ]
218
220
  if self._body_parameter:
219
221
  if self._body_parameter.in_method_signature:
@@ -437,6 +437,21 @@ class _BuilderBaseSerializer(Generic[BuilderType]): # pylint: disable=abstract-
437
437
  ]
438
438
  return retval
439
439
 
440
+ @staticmethod
441
+ def _serialize_special_handle_header(param: Parameter) -> List[str]:
442
+ if param.wire_name.lower() == "repeatability-request-id":
443
+ return [
444
+ """if "Repeatability-Request-ID" not in _headers:""",
445
+ """ _headers["Repeatability-Request-ID"] = str(uuid.uuid4())""",
446
+ ]
447
+ if param.wire_name.lower() == "repeatability-first-sent":
448
+ return [
449
+ """if "Repeatability-First-Sent" not in _headers:""",
450
+ """ _headers["Repeatability-First-Sent"] = _SERIALIZER.serialize_data(datetime.datetime.now(),
451
+ "rfc-1123")""",
452
+ ]
453
+ raise ValueError(f"Unsupported special header: {param}")
454
+
440
455
  def serialize_path(self, builder: BuilderType) -> List[str]:
441
456
  return self.parameter_serializer.serialize_path(
442
457
  builder.parameters.path, self.serializer_name
@@ -548,12 +563,15 @@ class RequestBuilderSerializer(
548
563
  def serialize_headers(self, builder: RequestBuilderType) -> List[str]:
549
564
  retval = ["# Construct headers"]
550
565
  for parameter in builder.parameters.headers:
551
- retval.extend(
552
- self._serialize_parameter(
553
- parameter,
554
- kwarg_name="headers",
566
+ if parameter.is_special_handle_header:
567
+ retval.extend(self._serialize_special_handle_header(parameter))
568
+ else:
569
+ retval.extend(
570
+ self._serialize_parameter(
571
+ parameter,
572
+ kwarg_name="headers",
573
+ )
555
574
  )
556
- )
557
575
  return retval
558
576
 
559
577
  def serialize_query(self, builder: RequestBuilderType) -> List[str]:
@@ -710,6 +728,7 @@ class _OperationSerializer(
710
728
  )
711
729
  else PopKwargType.SIMPLE,
712
730
  check_client_input=not self.code_model.options["multiapi"],
731
+ operation_name=f"('{builder.name}')" if builder.group_name == "" else "",
713
732
  )
714
733
  cls_annotation = builder.cls_type_annotation(async_mode=self.async_mode)
715
734
  pylint_disable = ""
@@ -150,10 +150,16 @@ class ClientSerializer:
150
150
  og for og in self.client.operation_groups if not og.is_mixin
151
151
  ]
152
152
  for og in operation_groups:
153
+ if og.code_model.options["multiapi"]:
154
+ api_version = (
155
+ f", '{og.api_versions[0]}'" if og.api_versions else ", None"
156
+ )
157
+ else:
158
+ api_version = ""
153
159
  retval.extend(
154
160
  [
155
161
  f"self.{og.property_name} = {og.class_name}({og.pylint_disable}",
156
- " self._client, self._config, self._serialize, self._deserialize",
162
+ f" self._client, self._config, self._serialize, self._deserialize{api_version}",
157
163
  ")",
158
164
  ]
159
165
  )
@@ -3,7 +3,7 @@
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 List, Sequence, Union
6
+ from typing import List, Sequence, Union, Optional
7
7
  from enum import Enum, auto
8
8
 
9
9
 
@@ -111,6 +111,7 @@ class ParameterSerializer:
111
111
  pop_headers_kwarg: PopKwargType,
112
112
  pop_params_kwarg: PopKwargType,
113
113
  check_client_input: bool = False,
114
+ operation_name: Optional[str] = None,
114
115
  ) -> List[str]:
115
116
  retval = []
116
117
 
@@ -142,9 +143,18 @@ class ParameterSerializer:
142
143
  if kwarg.location == ParameterLocation.HEADER
143
144
  else "params"
144
145
  )
146
+ if (
147
+ kwarg.client_name == "api_version"
148
+ and kwarg.code_model.options["multiapi"]
149
+ and operation_name is not None
150
+ ):
151
+ default_value = (
152
+ f"self._api_version{operation_name} or {default_value}"
153
+ )
145
154
  default_value = (
146
155
  f"_{kwarg_dict}.pop('{kwarg.wire_name}', {default_value})"
147
156
  )
157
+
148
158
  retval.append(
149
159
  f"{kwarg.client_name}: {type_annot} = kwargs.pop('{kwarg.client_name}', "
150
160
  + f"{default_value})"
@@ -30,12 +30,22 @@ class {{ operation_group.class_name }}{{ base_class }}:{{ disable }}
30
30
  self._config = input_args.pop(0) if input_args else kwargs.pop("config")
31
31
  self._serialize = input_args.pop(0) if input_args else kwargs.pop("serializer")
32
32
  self._deserialize = input_args.pop(0) if input_args else kwargs.pop("deserializer")
33
+ {% if code_model.options["multiapi"] %}
34
+ self._api_version = input_args.pop(0) if input_args else kwargs.pop("api_version")
35
+ {% endif %}
33
36
  {{ check_abstract_methods() }}
34
37
  {% elif operation_group.has_abstract_operations %}
35
38
 
36
39
  def __init__(self){{ return_none_type_annotation }}:
37
40
  {{ check_abstract_methods() }}
38
41
  {% endif %}
42
+ {% if operation_group.is_mixin and code_model.options["multiapi"] %}
43
+ def _api_version(self, op_name: str) -> str: # pylint: disable=unused-argument
44
+ try:
45
+ return self._config.api_version
46
+ except: # pylint: disable=bare-except
47
+ return ""
48
+ {% endif %}
39
49
  {% for operation in operation_group.operations if not operation.abstract %}
40
50
 
41
51
  {% set request_builder = operation.request_builder %}
@@ -87,6 +87,8 @@ class {{ code_model.client.name }}({% if code_model.operation_mixin_group.mixin_
87
87
  else:
88
88
  raise ValueError("API version {} is not available".format(api_version))
89
89
  {% endif %}
90
+ if api_version:
91
+ kwargs.setdefault('api_version', api_version)
90
92
  self._config = {{ code_model.client.name }}Configuration({{ code_model.global_parameters.call }}{{ ", " if code_model.global_parameters.call }}**kwargs)
91
93
  self._client = {{ async_prefix }}{{ code_model.client.pipeline_client }}(base_url={{ code_model.host_variable_name }}, config=self._config, **kwargs)
92
94
  super({{ code_model.client.name }}, self).__init__(
@@ -132,7 +134,7 @@ class {{ code_model.client.name }}({% if code_model.operation_mixin_group.mixin_
132
134
  else:
133
135
  raise ValueError("API version {} does not have operation group '{{ operation_group.name }}'".format(api_version))
134
136
  self._config.api_version = api_version
135
- return OperationClass(self._client, self._config, Serializer(self._models_dict(api_version)), Deserializer(self._models_dict(api_version)))
137
+ return OperationClass(self._client, self._config, Serializer(self._models_dict(api_version)), Deserializer(self._models_dict(api_version)), api_version)
136
138
  {% endfor %}
137
139
 
138
140
  {{ def }} close(self):
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autorest/python",
3
- "version": "6.5.1",
3
+ "version": "6.6.0",
4
4
  "description": "The Python extension for generators in AutoRest.",
5
5
  "main": "index.js",
6
6
  "repository": {