@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.
- package/ChangeLog.md +74 -0
- package/autorest/codegen/__init__.py +7 -7
- package/autorest/codegen/models/__init__.py +2 -1
- package/autorest/codegen/models/base_builder.py +16 -8
- package/autorest/codegen/models/client.py +5 -3
- package/autorest/codegen/models/code_model.py +19 -5
- package/autorest/codegen/models/imports.py +7 -0
- package/autorest/codegen/models/lro_operation.py +7 -3
- package/autorest/codegen/models/object_schema.py +3 -3
- package/autorest/codegen/models/operation.py +69 -38
- package/autorest/codegen/models/operation_group.py +13 -8
- package/autorest/codegen/models/paging_operation.py +5 -2
- package/autorest/codegen/models/parameter.py +46 -13
- package/autorest/codegen/models/parameter_list.py +62 -70
- package/autorest/codegen/models/primitive_schemas.py +11 -0
- package/autorest/codegen/models/request_builder.py +21 -8
- package/autorest/codegen/models/request_builder_parameter.py +9 -5
- package/autorest/codegen/models/request_builder_parameter_list.py +179 -77
- package/autorest/codegen/models/rest.py +3 -2
- package/autorest/codegen/models/schema_request.py +4 -17
- package/autorest/codegen/models/schema_response.py +4 -4
- package/autorest/codegen/serializers/__init__.py +57 -53
- package/autorest/codegen/serializers/builder_serializer.py +76 -46
- package/autorest/codegen/serializers/client_serializer.py +37 -9
- package/autorest/codegen/serializers/general_serializer.py +7 -5
- package/autorest/codegen/serializers/import_serializer.py +22 -7
- package/autorest/codegen/serializers/metadata_serializer.py +2 -2
- package/autorest/codegen/serializers/model_base_serializer.py +3 -3
- package/autorest/codegen/serializers/model_generic_serializer.py +1 -1
- package/autorest/codegen/serializers/model_python3_serializer.py +1 -1
- package/autorest/codegen/serializers/operation_groups_serializer.py +70 -0
- package/autorest/codegen/serializers/operations_init_serializer.py +34 -2
- package/autorest/codegen/serializers/patch_serializer.py +15 -0
- package/autorest/codegen/serializers/rest_serializer.py +9 -4
- package/autorest/codegen/serializers/utils.py +2 -2
- package/autorest/codegen/templates/config.py.jinja2 +1 -11
- package/autorest/codegen/templates/init.py.jinja2 +4 -7
- package/autorest/codegen/templates/metadata.json.jinja2 +2 -2
- package/autorest/codegen/templates/model_init.py.jinja2 +1 -1
- package/autorest/codegen/templates/{operations_class.py.jinja2 → operation_group.py.jinja2} +2 -0
- package/autorest/codegen/templates/operation_groups_container.py.jinja2 +26 -0
- package/autorest/codegen/templates/operation_tools.jinja2 +7 -0
- package/autorest/codegen/templates/operations_folder_init.py.jinja2 +13 -0
- package/autorest/codegen/templates/patch.py.jinja2 +31 -0
- package/autorest/codegen/templates/request_builder.py.jinja2 +7 -2
- package/autorest/codegen/templates/request_builders.py.jinja2 +3 -3
- package/autorest/codegen/templates/setup.py.jinja2 +1 -1
- package/autorest/multiapi/serializers/__init__.py +3 -3
- package/autorest/multiapi/serializers/import_serializer.py +5 -5
- package/autorest/namer/name_converter.py +48 -3
- package/package.json +2 -2
- package/setup.py +1 -0
- package/autorest/codegen/serializers/operation_group_serializer.py +0 -71
- package/autorest/codegen/templates/operations_class_mixin.py.jinja2 +0 -16
- package/autorest/codegen/templates/operations_container.py.jinja2 +0 -42
- package/autorest/codegen/templates/operations_container_init.py.jinja2 +0 -24
- 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.
|
|
92
|
-
self.
|
|
93
|
-
self.
|
|
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.
|
|
202
|
-
if
|
|
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.
|
|
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
|
-
|
|
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,
|
|
262
|
-
if
|
|
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(
|
|
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.
|
|
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,
|
|
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(
|
|
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(
|
|
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,
|
|
221
|
+
def method_signature(self, is_python3_file: bool) -> List[str]:
|
|
230
222
|
return _method_signature_helper(
|
|
231
|
-
positional=self.method_signature_positional(
|
|
232
|
-
keyword_only=self.method_signature_keyword_only(
|
|
233
|
-
kwarg_params=self.method_signature_kwargs(
|
|
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,
|
|
237
|
-
return [parameter.method_signature(
|
|
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,
|
|
240
|
-
if not (self.keyword_only and
|
|
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(
|
|
234
|
+
return ["*,"] + [parameter.method_signature(is_python3_file) for parameter in self.keyword_only]
|
|
243
235
|
|
|
244
236
|
@staticmethod
|
|
245
|
-
def method_signature_kwargs(
|
|
246
|
-
return ["**kwargs: Any"] if
|
|
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,
|
|
252
|
+
def kwargs_to_pop(self, is_python3_file: bool) -> List[Parameter]:
|
|
261
253
|
kwargs_to_pop = self.kwargs
|
|
262
|
-
if not
|
|
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,
|
|
440
|
+
def kwargs_to_pop(self, is_python3_file: bool) -> List[Parameter]:
|
|
449
441
|
return [
|
|
450
|
-
k for k in super().kwargs_to_pop(
|
|
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,
|
|
455
|
-
current_kwargs_to_pop = super().kwargs_to_pop(
|
|
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,
|
|
463
|
-
return self.method_signature(
|
|
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,
|
|
457
|
+
def config_method_signature(self, is_python3_file: bool) -> List[str]:
|
|
466
458
|
|
|
467
459
|
positional = [
|
|
468
|
-
p.method_signature(
|
|
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
|
|
466
|
+
if is_python3_file:
|
|
475
467
|
keyword_only_method_signature = (
|
|
476
468
|
["*,"] +
|
|
477
469
|
[
|
|
478
|
-
p.method_signature(
|
|
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(
|
|
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,
|
|
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(
|
|
106
|
-
|
|
107
|
-
|
|
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(
|
|
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
|
)
|