@autorest/python 5.10.0 → 5.12.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 (57) hide show
  1. package/ChangeLog.md +74 -0
  2. package/autorest/codegen/__init__.py +7 -7
  3. package/autorest/codegen/models/__init__.py +2 -1
  4. package/autorest/codegen/models/base_builder.py +16 -8
  5. package/autorest/codegen/models/client.py +5 -3
  6. package/autorest/codegen/models/code_model.py +19 -5
  7. package/autorest/codegen/models/imports.py +7 -0
  8. package/autorest/codegen/models/lro_operation.py +7 -3
  9. package/autorest/codegen/models/object_schema.py +3 -3
  10. package/autorest/codegen/models/operation.py +69 -38
  11. package/autorest/codegen/models/operation_group.py +13 -8
  12. package/autorest/codegen/models/paging_operation.py +5 -2
  13. package/autorest/codegen/models/parameter.py +46 -13
  14. package/autorest/codegen/models/parameter_list.py +62 -70
  15. package/autorest/codegen/models/primitive_schemas.py +11 -0
  16. package/autorest/codegen/models/request_builder.py +21 -8
  17. package/autorest/codegen/models/request_builder_parameter.py +9 -5
  18. package/autorest/codegen/models/request_builder_parameter_list.py +179 -77
  19. package/autorest/codegen/models/rest.py +3 -2
  20. package/autorest/codegen/models/schema_request.py +4 -17
  21. package/autorest/codegen/models/schema_response.py +4 -4
  22. package/autorest/codegen/serializers/__init__.py +57 -53
  23. package/autorest/codegen/serializers/builder_serializer.py +76 -46
  24. package/autorest/codegen/serializers/client_serializer.py +37 -9
  25. package/autorest/codegen/serializers/general_serializer.py +7 -5
  26. package/autorest/codegen/serializers/import_serializer.py +22 -7
  27. package/autorest/codegen/serializers/metadata_serializer.py +2 -2
  28. package/autorest/codegen/serializers/model_base_serializer.py +3 -3
  29. package/autorest/codegen/serializers/model_generic_serializer.py +1 -1
  30. package/autorest/codegen/serializers/model_python3_serializer.py +1 -1
  31. package/autorest/codegen/serializers/operation_groups_serializer.py +70 -0
  32. package/autorest/codegen/serializers/operations_init_serializer.py +34 -2
  33. package/autorest/codegen/serializers/patch_serializer.py +15 -0
  34. package/autorest/codegen/serializers/rest_serializer.py +9 -4
  35. package/autorest/codegen/serializers/utils.py +2 -2
  36. package/autorest/codegen/templates/config.py.jinja2 +1 -11
  37. package/autorest/codegen/templates/init.py.jinja2 +4 -7
  38. package/autorest/codegen/templates/metadata.json.jinja2 +2 -2
  39. package/autorest/codegen/templates/model_init.py.jinja2 +1 -1
  40. package/autorest/codegen/templates/{operations_class.py.jinja2 → operation_group.py.jinja2} +2 -0
  41. package/autorest/codegen/templates/operation_groups_container.py.jinja2 +26 -0
  42. package/autorest/codegen/templates/operation_tools.jinja2 +7 -0
  43. package/autorest/codegen/templates/operations_folder_init.py.jinja2 +13 -0
  44. package/autorest/codegen/templates/patch.py.jinja2 +31 -0
  45. package/autorest/codegen/templates/request_builder.py.jinja2 +7 -2
  46. package/autorest/codegen/templates/request_builders.py.jinja2 +3 -3
  47. package/autorest/codegen/templates/setup.py.jinja2 +1 -1
  48. package/autorest/multiapi/serializers/__init__.py +3 -3
  49. package/autorest/multiapi/serializers/import_serializer.py +5 -5
  50. package/autorest/namer/name_converter.py +48 -3
  51. package/package.json +2 -2
  52. package/setup.py +1 -0
  53. package/autorest/codegen/serializers/operation_group_serializer.py +0 -71
  54. package/autorest/codegen/templates/operations_class_mixin.py.jinja2 +0 -16
  55. package/autorest/codegen/templates/operations_container.py.jinja2 +0 -42
  56. package/autorest/codegen/templates/operations_container_init.py.jinja2 +0 -24
  57. package/autorest/codegen/templates/operations_container_mixin.py.jinja2 +0 -23
@@ -69,6 +69,7 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
69
69
  original_parameter: Optional["Parameter"] = None,
70
70
  client_default_value: Optional[Any] = None,
71
71
  keyword_only: bool = False,
72
+ content_types: Optional[List[str]] = None,
72
73
  ) -> None:
73
74
  super().__init__(yaml_data)
74
75
  self.code_model = code_model
@@ -88,12 +89,15 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
88
89
  self.grouped_by = grouped_by
89
90
  self.original_parameter = original_parameter
90
91
  self.client_default_value = client_default_value
91
- self.has_multiple_media_types: bool = False
92
- self.multiple_media_types_type_annot: Optional[str] = None
93
- self.multiple_media_types_docstring_type: Optional[str] = None
92
+ self.has_multiple_content_types: bool = False
93
+ self.multiple_content_types_type_annot: Optional[str] = None
94
+ self.multiple_content_types_docstring_type: Optional[str] = None
94
95
  self._keyword_only = keyword_only
95
96
  self.is_multipart = yaml_data.get("language", {}).get("python", {}).get("multipart", False)
96
97
  self.is_data_input = yaml_data.get("isPartialBody", False) and not self.is_multipart
98
+ self.content_types = content_types or []
99
+ self.body_kwargs: List[Parameter] = []
100
+ self.is_body_kwarg = False
97
101
 
98
102
  def __hash__(self) -> int:
99
103
  return hash(self.serialized_name)
@@ -121,8 +125,6 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
121
125
  def is_json_parameter(self) -> bool:
122
126
  if self.is_multipart or self.is_data_input:
123
127
  return False
124
- if isinstance(self.schema, IOSchema):
125
- return False
126
128
  if self.style == ParameterStyle.xml:
127
129
  return False
128
130
  return True
@@ -151,6 +153,10 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
151
153
  )
152
154
  raise ValueError("Trying to get a declaration for a schema that doesn't exist")
153
155
 
156
+ @property
157
+ def serialization_formats(self) -> List[str]:
158
+ return self.yaml_data.get('serializationFormats', [])
159
+
154
160
  @property
155
161
  def xml_serialization_ctxt(self) -> str:
156
162
  return self.schema.xml_serialization_ctxt() or ""
@@ -159,6 +165,13 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
159
165
  def is_body(self) -> bool:
160
166
  return self.location == ParameterLocation.Body
161
167
 
168
+ @property
169
+ def pre_semicolon_content_types(self) -> List[str]:
170
+ """Splits on semicolon of media types and returns the first half.
171
+ I.e. ["text/plain; charset=UTF-8"] -> ["text/plain"]
172
+ """
173
+ return [content_type.split(";")[0] for content_type in self.content_types]
174
+
162
175
  @property
163
176
  def in_method_signature(self) -> bool:
164
177
  return not(
@@ -197,15 +210,24 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
197
210
  return "Method"
198
211
  return self._implementation
199
212
 
213
+ @property
214
+ def _is_io_json(self):
215
+ return any(
216
+ k for k in self.body_kwargs if k.serialized_name == "json"
217
+ ) and isinstance(self.schema, IOSchema)
218
+
200
219
  def _default_value(self) -> Tuple[Optional[Any], str, str]:
201
- type_annot = self.multiple_media_types_type_annot or self.schema.operation_type_annotation
202
- if not self.required and not type_annot == "Any":
220
+ type_annot = self.multiple_content_types_type_annot or self.schema.operation_type_annotation
221
+ if self._is_io_json:
222
+ type_annot = f"Union[{type_annot}, JSONType]"
223
+ any_types = ["Any", "JSONType"]
224
+ if not self.required and type_annot not in any_types and not self._is_io_json:
203
225
  type_annot = f"Optional[{type_annot}]"
204
226
 
205
227
  if self.client_default_value is not None:
206
228
  return self.client_default_value, self.schema.get_declaration(self.client_default_value), type_annot
207
229
 
208
- if self.multiple_media_types_type_annot:
230
+ if self.multiple_content_types_type_annot:
209
231
  # means this parameter has multiple media types. We force default value to be None.
210
232
  default_value = None
211
233
  default_value_declaration = "None"
@@ -252,14 +274,17 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
252
274
 
253
275
  @property
254
276
  def docstring_type(self) -> str:
255
- return self.multiple_media_types_docstring_type or self.schema.docstring_type
277
+ retval = self.multiple_content_types_docstring_type or self.schema.docstring_type
278
+ if self._is_io_json:
279
+ retval += " or JSONType"
280
+ return retval
256
281
 
257
282
  @property
258
283
  def has_default_value(self):
259
284
  return self.default_value is not None or not self.required
260
285
 
261
- def method_signature(self, is_python_3_file: bool) -> str:
262
- if is_python_3_file:
286
+ def method_signature(self, is_python3_file: bool) -> str:
287
+ if is_python3_file:
263
288
  if self.has_default_value:
264
289
  return f"{self.serialized_name}: {self.type_annotation} = {self.default_value_declaration},"
265
290
  return f"{self.serialized_name}: {self.type_annotation},"
@@ -295,7 +320,13 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
295
320
  return self.in_method_signature and not (self.is_keyword_only or self.is_kwarg)
296
321
 
297
322
  @classmethod
298
- def from_yaml(cls, yaml_data: Dict[str, Any], *, code_model) -> "Parameter":
323
+ def from_yaml(
324
+ cls,
325
+ yaml_data: Dict[str, Any],
326
+ *,
327
+ code_model,
328
+ content_types: Optional[List[str]] = None
329
+ ) -> "Parameter":
299
330
  http_protocol = yaml_data["protocol"].get("http", {"in": ParameterLocation.Other})
300
331
  return cls(
301
332
  code_model=code_model,
@@ -319,14 +350,16 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
319
350
  original_parameter=yaml_data.get("originalParameter", None),
320
351
  flattened=yaml_data.get("flattened", False),
321
352
  client_default_value=yaml_data.get("clientDefaultValue"),
353
+ content_types=content_types
322
354
  )
323
355
 
324
356
  def imports(self) -> FileImport:
325
357
  file_import = self.schema.imports()
326
358
  if not self.required:
327
359
  file_import.add_from_import("typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL)
328
- if self.has_multiple_media_types:
360
+ if self.has_multiple_content_types or self._is_io_json:
329
361
  file_import.add_from_import("typing", "Union", ImportType.STDLIB, TypingSection.CONDITIONAL)
362
+
330
363
  return file_import
331
364
 
332
365
  class ParameterOnlyPathAndBodyPositional(Parameter):
@@ -6,15 +6,16 @@
6
6
  from collections.abc import MutableSequence
7
7
  from copy import copy
8
8
  import logging
9
- from typing import cast, List, Callable, Optional, TypeVar, Dict
9
+ from typing import cast, List, Callable, Optional, TypeVar, Dict, TYPE_CHECKING
10
10
 
11
11
  from .parameter import Parameter, ParameterLocation
12
- from .constant_schema import ConstantSchema
13
12
  from .base_schema import BaseSchema
14
- from .enum_schema import EnumSchema
15
13
  from .dictionary_schema import DictionarySchema
16
14
  from .primitive_schemas import AnySchema, StringSchema
17
15
 
16
+ if TYPE_CHECKING:
17
+ from .schema_request import SchemaRequest
18
+
18
19
  T = TypeVar('T')
19
20
  OrderedSet = Dict[T, None]
20
21
 
@@ -27,12 +28,15 @@ def _method_signature_helper(positional: List[str], keyword_only: Optional[List[
27
28
 
28
29
  class ParameterList(MutableSequence): # pylint: disable=too-many-public-methods
29
30
  def __init__(
30
- self, code_model, parameters: Optional[List[Parameter]] = None
31
+ self,
32
+ code_model,
33
+ parameters: Optional[List[Parameter]] = None,
34
+ schema_requests: Optional[List["SchemaRequest"]] = None,
31
35
  ) -> None:
32
36
  self.code_model = code_model
37
+ self.schema_requests = schema_requests or []
33
38
  self.parameters = parameters or []
34
39
  self._json_body: Optional[BaseSchema] = None
35
- self._content_types: Optional[List[str]] = None
36
40
 
37
41
  # MutableSequence
38
42
 
@@ -64,6 +68,30 @@ class ParameterList(MutableSequence): # pylint: disable=too-many-public-methods
64
68
  def get_from_location(self, location: ParameterLocation) -> List[Parameter]:
65
69
  return self.get_from_predicate(lambda parameter: parameter.location == location)
66
70
 
71
+ @property
72
+ def content_types(self) -> List[str]:
73
+ ordered_set = {
74
+ m: None
75
+ for request in self.schema_requests
76
+ for m in request.content_types
77
+ }
78
+ return list(ordered_set.keys())
79
+
80
+ @property
81
+ def default_content_type(self) -> str:
82
+ json_content_types = [c for c in self.content_types if "json" in c]
83
+ if json_content_types:
84
+ if "application/json" in json_content_types:
85
+ return "application/json"
86
+ return json_content_types[0]
87
+
88
+ xml_content_types = [c for c in self.content_types if "xml" in c]
89
+ if xml_content_types:
90
+ if "application/xml" in xml_content_types:
91
+ return "application/xml"
92
+ return xml_content_types[0]
93
+ return self.content_types[0]
94
+
67
95
  @property
68
96
  def json_body(self) -> BaseSchema:
69
97
  if not self._json_body:
@@ -144,51 +172,15 @@ class ParameterList(MutableSequence): # pylint: disable=too-many-public-methods
144
172
 
145
173
  @property
146
174
  def multipart(self) -> List[Parameter]:
147
- return self.get_from_predicate(lambda parameter: parameter.is_multipart)
175
+ return self.get_from_predicate(
176
+ lambda parameter: parameter.is_multipart and not parameter.is_body_kwarg
177
+ )
148
178
 
149
179
  @property
150
180
  def data_inputs(self) -> List[Parameter]:
151
- return self.get_from_predicate(lambda parameter: parameter.is_data_input)
152
-
153
- @property
154
- def content_types(self) -> List[str]:
155
- if self._content_types is not None:
156
- return self._content_types
157
- content_type_params = self.get_from_predicate(
158
- lambda parameter: parameter.serialized_name == "content_type"
181
+ return self.get_from_predicate(
182
+ lambda parameter: parameter.is_data_input and not parameter.is_body_kwarg
159
183
  )
160
- content_types: OrderedSet[str] = {}
161
- for param in content_type_params:
162
- if isinstance(param.schema, dict):
163
- if param.schema.get("value"):
164
- content_types[param.schema["value"]["value"]] = None
165
- if param.schema.get("choices"):
166
- for choice in param.schema['choices']:
167
- content_types[choice['value']] = None
168
- elif isinstance(param.schema, ConstantSchema) and param.schema.value:
169
- content_types[param.schema.value] = None
170
- elif isinstance(param.schema, EnumSchema):
171
- # enums
172
- content_types.update({v.value: None for v in param.schema.values})
173
- if param.client_default_value:
174
- content_types.update({param.client_default_value: None})
175
- self._content_types = [k for k in content_types if k is not None]
176
- return self._content_types
177
-
178
- @property
179
- def default_content_type(self) -> str:
180
- json_content_types = [c for c in self.content_types if "json" in c]
181
- if json_content_types:
182
- if "application/json" in json_content_types:
183
- return "application/json"
184
- return json_content_types[0]
185
-
186
- xml_content_types = [c for c in self.content_types if "xml" in c]
187
- if xml_content_types:
188
- if "application/xml" in xml_content_types:
189
- return "application/xml"
190
- return xml_content_types[0]
191
- return self.content_types[0]
192
184
 
193
185
  def _filter_out_multiple_content_type(self, kwarg_params):
194
186
  """We don't want multiple content type kwargs in the method signature"""
@@ -226,24 +218,24 @@ class ParameterList(MutableSequence): # pylint: disable=too-many-public-methods
226
218
  return signature_parameters
227
219
 
228
220
 
229
- def method_signature(self, is_python_3_file: bool) -> List[str]:
221
+ def method_signature(self, is_python3_file: bool) -> List[str]:
230
222
  return _method_signature_helper(
231
- positional=self.method_signature_positional(is_python_3_file),
232
- keyword_only=self.method_signature_keyword_only(is_python_3_file),
233
- kwarg_params=self.method_signature_kwargs(is_python_3_file)
223
+ positional=self.method_signature_positional(is_python3_file),
224
+ keyword_only=self.method_signature_keyword_only(is_python3_file),
225
+ kwarg_params=self.method_signature_kwargs(is_python3_file)
234
226
  )
235
227
 
236
- def method_signature_positional(self, is_python_3_file: bool) -> List[str]:
237
- return [parameter.method_signature(is_python_3_file) for parameter in self.positional]
228
+ def method_signature_positional(self, is_python3_file: bool) -> List[str]:
229
+ return [parameter.method_signature(is_python3_file) for parameter in self.positional]
238
230
 
239
- def method_signature_keyword_only(self, is_python_3_file: bool) -> List[str]:
240
- if not (self.keyword_only and is_python_3_file):
231
+ def method_signature_keyword_only(self, is_python3_file: bool) -> List[str]:
232
+ if not (self.keyword_only and is_python3_file):
241
233
  return []
242
- return ["*,"] + [parameter.method_signature(is_python_3_file) for parameter in self.keyword_only]
234
+ return ["*,"] + [parameter.method_signature(is_python3_file) for parameter in self.keyword_only]
243
235
 
244
236
  @staticmethod
245
- def method_signature_kwargs(is_python_3_file: bool) -> List[str]:
246
- return ["**kwargs: Any"] if is_python_3_file else ["**kwargs # type: Any"]
237
+ def method_signature_kwargs(is_python3_file: bool) -> List[str]:
238
+ return ["**kwargs: Any"] if is_python3_file else ["**kwargs # type: Any"]
247
239
 
248
240
  @property
249
241
  def positional(self) -> List[Parameter]:
@@ -257,9 +249,9 @@ class ParameterList(MutableSequence): # pylint: disable=too-many-public-methods
257
249
  def kwargs(self) -> List[Parameter]:
258
250
  return [p for p in self.method if p.is_kwarg]
259
251
 
260
- def kwargs_to_pop(self, is_python_3_file: bool) -> List[Parameter]:
252
+ def kwargs_to_pop(self, is_python3_file: bool) -> List[Parameter]:
261
253
  kwargs_to_pop = self.kwargs
262
- if not is_python_3_file:
254
+ if not is_python3_file:
263
255
  kwargs_to_pop += self.keyword_only
264
256
  return kwargs_to_pop
265
257
 
@@ -445,41 +437,41 @@ class GlobalParameterList(ParameterList):
445
437
  return True
446
438
  return serialized_name != self.host_variable_name
447
439
 
448
- def kwargs_to_pop(self, is_python_3_file: bool) -> List[Parameter]:
440
+ def kwargs_to_pop(self, is_python3_file: bool) -> List[Parameter]:
449
441
  return [
450
- k for k in super().kwargs_to_pop(is_python_3_file)
442
+ k for k in super().kwargs_to_pop(is_python3_file)
451
443
  if not self._param_is_in_config_method(k.serialized_name)
452
444
  ]
453
445
 
454
- def config_kwargs_to_pop(self, is_python_3_file: bool) -> List[Parameter]:
455
- current_kwargs_to_pop = super().kwargs_to_pop(is_python_3_file)
446
+ def config_kwargs_to_pop(self, is_python3_file: bool) -> List[Parameter]:
447
+ current_kwargs_to_pop = super().kwargs_to_pop(is_python3_file)
456
448
  return [k for k in current_kwargs_to_pop if self._param_is_in_config_method(k.serialized_name)]
457
449
 
458
450
  @property
459
451
  def config_method(self) -> List[Parameter]:
460
452
  return [p for p in self.method if self._param_is_in_config_method(p.serialized_name)]
461
453
 
462
- def client_method_signature(self, is_python_3_file: bool) -> List[str]:
463
- return self.method_signature(is_python_3_file)
454
+ def client_method_signature(self, is_python3_file: bool) -> List[str]:
455
+ return self.method_signature(is_python3_file)
464
456
 
465
- def config_method_signature(self, is_python_3_file: bool) -> List[str]:
457
+ def config_method_signature(self, is_python3_file: bool) -> List[str]:
466
458
 
467
459
  positional = [
468
- p.method_signature(is_python_3_file)
460
+ p.method_signature(is_python3_file)
469
461
  for p in self.positional
470
462
  if self._param_is_in_config_method(p.serialized_name)
471
463
  ]
472
464
  keyword_only_params = [p for p in self.keyword_only if self._param_is_in_config_method(p.serialized_name)]
473
465
  keyword_only_method_signature = []
474
- if is_python_3_file:
466
+ if is_python3_file:
475
467
  keyword_only_method_signature = (
476
468
  ["*,"] +
477
469
  [
478
- p.method_signature(is_python_3_file) for p in keyword_only_params
470
+ p.method_signature(is_python3_file) for p in keyword_only_params
479
471
  ]
480
472
  ) if keyword_only_params else []
481
473
  return _method_signature_helper(
482
474
  positional=positional,
483
475
  keyword_only=keyword_only_method_signature,
484
- kwarg_params=self.method_signature_kwargs(is_python_3_file)
476
+ kwarg_params=self.method_signature_kwargs(is_python3_file)
485
477
  )
@@ -141,6 +141,17 @@ class AnySchema(PrimitiveSchema):
141
141
  file_import.add_from_import("typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL)
142
142
  return file_import
143
143
 
144
+ class JSONSchema(AnySchema):
145
+
146
+ @property
147
+ def docstring_type(self) -> str:
148
+ return "JSONType"
149
+
150
+ @property
151
+ def type_annotation(self) -> str:
152
+ return "JSONType"
153
+
154
+
144
155
  class NumberSchema(PrimitiveSchema):
145
156
  def __init__(self, namespace: str, yaml_data: Dict[str, Any]) -> None:
146
157
  super(NumberSchema, self).__init__(namespace=namespace, yaml_data=yaml_data)
@@ -11,6 +11,7 @@ from .request_builder_parameter_list import RequestBuilderParameterList
11
11
  from .schema_request import SchemaRequest
12
12
  from .schema_response import SchemaResponse
13
13
  from .imports import FileImport, ImportType, TypingSection
14
+ from .parameter import Parameter
14
15
 
15
16
 
16
17
  T = TypeVar('T')
@@ -38,18 +39,22 @@ class RequestBuilder(BaseBuilder):
38
39
  description=description,
39
40
  parameters=parameters,
40
41
  responses=responses,
42
+ schema_requests=schema_requests,
41
43
  summary=summary,
42
44
  )
43
45
  self.url = url
44
46
  self.method = method
45
47
  self.multipart = multipart
46
- self.schema_requests = schema_requests
47
48
 
48
49
  @property
49
50
  def is_stream(self) -> bool:
50
51
  """Is the request we're preparing a stream, like an upload."""
51
52
  return any(request.is_stream_request for request in self.schema_requests)
52
53
 
54
+ @property
55
+ def body_kwargs_to_get(self) -> List[Parameter]:
56
+ return self.parameters.body_kwargs_to_get
57
+
53
58
  @property
54
59
  def operation_group_name(self) -> str:
55
60
  return self.yaml_data["language"]["python"]["operationGroupName"]
@@ -75,10 +80,19 @@ class RequestBuilder(BaseBuilder):
75
80
  file_import.add_from_import(
76
81
  f"{relative_path}_vendor", "_format_url_section", ImportType.LOCAL
77
82
  )
83
+ if self.parameters.headers or self.parameters.query:
84
+ file_import.add_from_import(
85
+ "typing", "Dict", ImportType.STDLIB, typing_section=TypingSection.CONDITIONAL
86
+ )
78
87
  file_import.add_from_import(
79
88
  "typing", "Any", ImportType.STDLIB, typing_section=TypingSection.CONDITIONAL
80
89
  )
81
90
  file_import.add_from_import("msrest", "Serializer", ImportType.AZURECORE)
91
+ if self.parameters.has_body and (
92
+ self.code_model.options["builders_visibility"] != "embedded" or
93
+ self.code_model.options["add_python3_operation_files"]
94
+ ):
95
+ file_import.define_mypy_type("JSONType", "Any")
82
96
  return file_import
83
97
 
84
98
  @classmethod
@@ -98,15 +112,13 @@ class RequestBuilder(BaseBuilder):
98
112
  name = "_".join([n for n in names if n])
99
113
 
100
114
  first_request = yaml_data["requests"][0]
101
-
102
- parameters, multiple_media_type_parameters = (
115
+ schema_requests = [SchemaRequest.from_yaml(yaml, code_model=code_model) for yaml in yaml_data["requests"]]
116
+ parameters, multiple_content_type_parameters = (
103
117
  create_parameters(yaml_data, code_model, RequestBuilderParameter.from_yaml)
104
118
  )
105
- parameter_list = RequestBuilderParameterList(code_model, parameters + multiple_media_type_parameters)
106
-
107
- schema_requests = [SchemaRequest.from_yaml(yaml, code_model=code_model) for yaml in yaml_data["requests"]]
108
- parameter_list.add_body_kwargs(schema_requests)
109
-
119
+ parameter_list = RequestBuilderParameterList(
120
+ code_model, parameters + multiple_content_type_parameters, schema_requests
121
+ )
110
122
  request_builder_class = cls(
111
123
  code_model=code_model,
112
124
  yaml_data=yaml_data,
@@ -121,4 +133,5 @@ class RequestBuilder(BaseBuilder):
121
133
  summary=yaml_data["language"]["python"].get("summary"),
122
134
  )
123
135
  code_model.request_builder_ids[id(yaml_data)] = request_builder_class
136
+ parameter_list.add_body_kwargs()
124
137
  return request_builder_class
@@ -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 Any, Dict, Optional
6
+ from typing import Any, Dict, List, Optional
7
7
  from .parameter import ParameterOnlyPathAndBodyPositional, ParameterLocation, ParameterStyle
8
8
 
9
9
  def _make_public(name):
@@ -29,12 +29,13 @@ class RequestBuilderParameter(ParameterOnlyPathAndBodyPositional):
29
29
 
30
30
  @property
31
31
  def name_in_high_level_operation(self) -> str:
32
+ template = "{}" if self.code_model.options["version_tolerant"] else "_{}"
32
33
  if self.is_multipart:
33
- return "files"
34
+ return template.format("files")
34
35
  if self.is_data_input:
35
- return "data"
36
+ return template.format("data")
36
37
  if self.is_body and not self.constant:
37
- return self.serialized_name
38
+ return f"_{self.serialized_name}"
38
39
  name = self.yaml_data["language"]["python"]["name"]
39
40
  if self.implementation == "Client" and self.in_method_code:
40
41
  # for these, we're passing the client params to the request builder.
@@ -68,7 +69,9 @@ class RequestBuilderParameter(ParameterOnlyPathAndBodyPositional):
68
69
  return self.serialized_name
69
70
 
70
71
  @classmethod
71
- def from_yaml(cls, yaml_data: Dict[str, Any], *, code_model) -> "RequestBuilderParameter":
72
+ def from_yaml(
73
+ cls, yaml_data: Dict[str, Any], *, code_model, content_types: Optional[List[str]] = None
74
+ ) -> "RequestBuilderParameter":
72
75
  http_protocol = yaml_data["protocol"].get("http", {"in": ParameterLocation.Other})
73
76
  name = yaml_data["language"]["python"]["name"]
74
77
  location = ParameterLocation(http_protocol["in"])
@@ -94,4 +97,5 @@ class RequestBuilderParameter(ParameterOnlyPathAndBodyPositional):
94
97
  original_parameter=yaml_data.get("originalParameter", None),
95
98
  flattened=yaml_data.get("flattened", False),
96
99
  client_default_value=yaml_data.get("clientDefaultValue"),
100
+ content_types=content_types,
97
101
  )