@autorest/python 5.17.0 → 6.0.0-rc.1
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 +63 -1
- package/README.md +9 -0
- package/autorest/codegen/__init__.py +24 -30
- package/autorest/codegen/models/base_builder.py +17 -6
- package/autorest/codegen/models/base_type.py +6 -0
- package/autorest/codegen/models/client.py +9 -6
- package/autorest/codegen/models/code_model.py +20 -14
- package/autorest/codegen/models/dictionary_type.py +16 -1
- package/autorest/codegen/models/imports.py +57 -2
- package/autorest/codegen/models/list_type.py +16 -1
- package/autorest/codegen/models/lro_operation.py +4 -6
- package/autorest/codegen/models/lro_paging_operation.py +3 -9
- package/autorest/codegen/models/model_type.py +34 -16
- package/autorest/codegen/models/operation.py +47 -79
- package/autorest/codegen/models/operation_group.py +10 -9
- package/autorest/codegen/models/paging_operation.py +4 -6
- package/autorest/codegen/models/parameter.py +3 -7
- package/autorest/codegen/models/parameter_list.py +26 -35
- package/autorest/codegen/models/property.py +14 -0
- package/autorest/codegen/models/request_builder.py +32 -43
- package/autorest/codegen/serializers/__init__.py +12 -50
- package/autorest/codegen/serializers/builder_serializer.py +136 -49
- package/autorest/codegen/serializers/client_serializer.py +23 -32
- package/autorest/codegen/serializers/general_serializer.py +12 -12
- package/autorest/codegen/serializers/import_serializer.py +11 -22
- package/autorest/codegen/serializers/metadata_serializer.py +0 -2
- package/autorest/codegen/serializers/{model_base_serializer.py → model_serializer.py} +58 -44
- package/autorest/codegen/serializers/operation_groups_serializer.py +3 -7
- package/autorest/codegen/serializers/operations_init_serializer.py +2 -23
- package/autorest/codegen/serializers/patch_serializer.py +1 -3
- package/autorest/codegen/serializers/request_builders_serializer.py +2 -5
- package/autorest/codegen/serializers/utils.py +3 -4
- package/autorest/codegen/templates/client.py.jinja2 +6 -3
- package/autorest/codegen/templates/config.py.jinja2 +2 -2
- package/autorest/codegen/templates/metadata.json.jinja2 +4 -4
- package/autorest/codegen/templates/model.py.jinja2 +1 -1
- package/autorest/codegen/templates/model_init.py.jinja2 +5 -12
- package/autorest/codegen/templates/operation_group.py.jinja2 +16 -3
- package/autorest/codegen/templates/operation_groups_container.py.jinja2 +2 -8
- package/autorest/codegen/templates/operation_tools.jinja2 +3 -1
- package/autorest/codegen/templates/patch.py.jinja2 +1 -2
- package/autorest/codegen/templates/request_builder.py.jinja2 +0 -7
- package/autorest/codegen/templates/request_builders.py.jinja2 +1 -4
- package/autorest/codegen/templates/rest_init.py.jinja2 +3 -8
- package/autorest/codegen/templates/serialization.py.jinja2 +2006 -0
- package/autorest/codegen/templates/setup.py.jinja2 +4 -0
- package/autorest/codegen/templates/vendor.py.jinja2 +10 -0
- package/autorest/m4reformatter/__init__.py +82 -58
- package/autorest/multiapi/models/client.py +12 -2
- package/autorest/multiapi/serializers/__init__.py +17 -8
- package/autorest/multiapi/serializers/import_serializer.py +4 -8
- package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +1 -1
- package/autorest/preprocess/__init__.py +1 -0
- package/package.json +2 -2
- package/autorest/codegen/serializers/model_generic_serializer.py +0 -32
- package/autorest/codegen/serializers/model_python3_serializer.py +0 -72
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
# Licensed under the MIT License. See License.txt in the project root for
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
|
-
import logging
|
|
7
6
|
from typing import (
|
|
8
7
|
Any,
|
|
9
8
|
Callable,
|
|
@@ -21,13 +20,11 @@ from .parameter_list import (
|
|
|
21
20
|
RequestBuilderParameterList,
|
|
22
21
|
OverloadedRequestBuilderParameterList,
|
|
23
22
|
)
|
|
24
|
-
from .imports import FileImport, ImportType, TypingSection
|
|
25
|
-
from .request_builder_parameter import RequestBuilderMultipartBodyParameter
|
|
23
|
+
from .imports import FileImport, ImportType, TypingSection, MsrestImportType
|
|
26
24
|
|
|
27
25
|
if TYPE_CHECKING:
|
|
28
26
|
from .code_model import CodeModel
|
|
29
27
|
|
|
30
|
-
_LOGGER = logging.getLogger(__name__)
|
|
31
28
|
ParameterListType = TypeVar(
|
|
32
29
|
"ParameterListType",
|
|
33
30
|
bound=Union[RequestBuilderParameterList, OverloadedRequestBuilderParameterList],
|
|
@@ -43,7 +40,6 @@ class RequestBuilderBase(BaseBuilder[ParameterListType]):
|
|
|
43
40
|
parameters: ParameterListType,
|
|
44
41
|
*,
|
|
45
42
|
overloads: Optional[List["RequestBuilder"]] = None,
|
|
46
|
-
abstract: bool = False,
|
|
47
43
|
) -> None:
|
|
48
44
|
super().__init__(
|
|
49
45
|
code_model=code_model,
|
|
@@ -51,7 +47,6 @@ class RequestBuilderBase(BaseBuilder[ParameterListType]):
|
|
|
51
47
|
name=name,
|
|
52
48
|
parameters=parameters,
|
|
53
49
|
overloads=overloads,
|
|
54
|
-
abstract=abstract,
|
|
55
50
|
want_tracing=False,
|
|
56
51
|
)
|
|
57
52
|
self.overloads: List["RequestBuilder"] = overloads or []
|
|
@@ -64,7 +59,7 @@ class RequestBuilderBase(BaseBuilder[ParameterListType]):
|
|
|
64
59
|
def response_docstring_text(self, **kwargs) -> str:
|
|
65
60
|
return (
|
|
66
61
|
"Returns an :class:`~azure.core.rest.HttpRequest` that you will pass to the client's "
|
|
67
|
-
+ "`send_request` method. See https://aka.ms/azsdk/python/
|
|
62
|
+
+ "`send_request` method. See https://aka.ms/azsdk/dpcodegen/python/send_request for how to "
|
|
68
63
|
+ "incorporate this response into your code flow."
|
|
69
64
|
)
|
|
70
65
|
|
|
@@ -73,34 +68,45 @@ class RequestBuilderBase(BaseBuilder[ParameterListType]):
|
|
|
73
68
|
|
|
74
69
|
def imports(self) -> FileImport:
|
|
75
70
|
file_import = FileImport()
|
|
76
|
-
if
|
|
77
|
-
|
|
78
|
-
|
|
71
|
+
if self.abstract:
|
|
72
|
+
return file_import
|
|
73
|
+
for parameter in self.parameters.method:
|
|
74
|
+
file_import.merge(parameter.imports(async_mode=False))
|
|
79
75
|
|
|
80
76
|
file_import.add_submodule_import(
|
|
81
77
|
"azure.core.rest",
|
|
82
78
|
"HttpRequest",
|
|
83
79
|
ImportType.AZURECORE,
|
|
84
80
|
)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
81
|
+
|
|
82
|
+
if self.parameters.path:
|
|
83
|
+
relative_path = ".."
|
|
84
|
+
if (
|
|
85
|
+
not self.code_model.options["builders_visibility"] == "embedded"
|
|
86
|
+
and self.group_name
|
|
87
|
+
):
|
|
88
|
+
relative_path = "..." if self.group_name else ".."
|
|
89
|
+
file_import.add_submodule_import(
|
|
90
|
+
f"{relative_path}_vendor", "_format_url_section", ImportType.LOCAL
|
|
91
|
+
)
|
|
92
|
+
if self.parameters.headers or self.parameters.query:
|
|
93
|
+
file_import.add_submodule_import(
|
|
94
|
+
"azure.core.utils", "case_insensitive_dict", ImportType.AZURECORE
|
|
95
|
+
)
|
|
100
96
|
file_import.add_submodule_import(
|
|
101
97
|
"typing", "Any", ImportType.STDLIB, typing_section=TypingSection.CONDITIONAL
|
|
102
98
|
)
|
|
103
|
-
file_import.
|
|
99
|
+
file_import.add_msrest_import(
|
|
100
|
+
self.code_model,
|
|
101
|
+
"..."
|
|
102
|
+
if (
|
|
103
|
+
not self.code_model.options["builders_visibility"] == "embedded"
|
|
104
|
+
and self.group_name
|
|
105
|
+
)
|
|
106
|
+
else "..",
|
|
107
|
+
MsrestImportType.Serializer,
|
|
108
|
+
TypingSection.REGULAR,
|
|
109
|
+
)
|
|
104
110
|
if (
|
|
105
111
|
self.overloads
|
|
106
112
|
and self.code_model.options["builders_visibility"] != "embedded"
|
|
@@ -136,23 +142,7 @@ class RequestBuilderBase(BaseBuilder[ParameterListType]):
|
|
|
136
142
|
RequestBuilder.from_yaml(rb_yaml_data, code_model)
|
|
137
143
|
for rb_yaml_data in yaml_data.get("overloads", [])
|
|
138
144
|
]
|
|
139
|
-
abstract = False
|
|
140
145
|
parameter_list = cls.parameter_list_type()(yaml_data, code_model)
|
|
141
|
-
if (
|
|
142
|
-
code_model.options["version_tolerant"]
|
|
143
|
-
and parameter_list.has_body
|
|
144
|
-
and isinstance(
|
|
145
|
-
parameter_list.body_parameter, RequestBuilderMultipartBodyParameter
|
|
146
|
-
)
|
|
147
|
-
):
|
|
148
|
-
_LOGGER.warning(
|
|
149
|
-
'Not going to generate operation "%s" because it has multipart / urlencoded body parameters. '
|
|
150
|
-
"Multipart / urlencoded body parameters are not supported for version tolerant generation right now. "
|
|
151
|
-
'Please write your own custom operation in the "_patch.py" file '
|
|
152
|
-
"following https://aka.ms/azsdk/python/dpcodegen/python/customize",
|
|
153
|
-
name,
|
|
154
|
-
)
|
|
155
|
-
abstract = True
|
|
156
146
|
|
|
157
147
|
return cls(
|
|
158
148
|
yaml_data=yaml_data,
|
|
@@ -160,7 +150,6 @@ class RequestBuilderBase(BaseBuilder[ParameterListType]):
|
|
|
160
150
|
name=name,
|
|
161
151
|
parameters=parameter_list,
|
|
162
152
|
overloads=overloads,
|
|
163
|
-
abstract=abstract,
|
|
164
153
|
)
|
|
165
154
|
|
|
166
155
|
|
|
@@ -14,9 +14,8 @@ from ..models import CodeModel, OperationGroup, RequestBuilder
|
|
|
14
14
|
from ..models import TokenCredentialType
|
|
15
15
|
from .enum_serializer import EnumSerializer
|
|
16
16
|
from .general_serializer import GeneralSerializer
|
|
17
|
-
from .model_generic_serializer import ModelGenericSerializer
|
|
18
17
|
from .model_init_serializer import ModelInitSerializer
|
|
19
|
-
from .
|
|
18
|
+
from .model_serializer import ModelSerializer
|
|
20
19
|
from .operations_init_serializer import OperationsInitSerializer
|
|
21
20
|
from .operation_groups_serializer import OperationGroupsSerializer
|
|
22
21
|
from .metadata_serializer import MetadataSerializer
|
|
@@ -224,22 +223,9 @@ class JinjaSerializer:
|
|
|
224
223
|
# Write the models folder
|
|
225
224
|
models_path = namespace_path / Path("models")
|
|
226
225
|
if self.code_model.model_types:
|
|
227
|
-
if not self.code_model.options["python3_only"]:
|
|
228
|
-
self._autorestapi.write_file(
|
|
229
|
-
models_path
|
|
230
|
-
/ Path(
|
|
231
|
-
f"{self.code_model.get_models_filename(is_python3_file=False)}.py"
|
|
232
|
-
),
|
|
233
|
-
ModelGenericSerializer(
|
|
234
|
-
code_model=self.code_model, env=env
|
|
235
|
-
).serialize(),
|
|
236
|
-
)
|
|
237
226
|
self._autorestapi.write_file(
|
|
238
|
-
models_path
|
|
239
|
-
|
|
240
|
-
f"{self.code_model.get_models_filename(is_python3_file=True)}.py"
|
|
241
|
-
),
|
|
242
|
-
ModelPython3Serializer(code_model=self.code_model, env=env).serialize(),
|
|
227
|
+
models_path / Path(f"{self.code_model.models_filename}.py"),
|
|
228
|
+
ModelSerializer(code_model=self.code_model, env=env).serialize(),
|
|
243
229
|
)
|
|
244
230
|
if self.code_model.enums:
|
|
245
231
|
self._autorestapi.write_file(
|
|
@@ -287,18 +273,6 @@ class JinjaSerializer:
|
|
|
287
273
|
code_model=self.code_model,
|
|
288
274
|
env=env,
|
|
289
275
|
request_builders=request_builders,
|
|
290
|
-
is_python3_file=False,
|
|
291
|
-
).serialize_request_builders(),
|
|
292
|
-
)
|
|
293
|
-
|
|
294
|
-
# write python3 request builders file
|
|
295
|
-
self._autorestapi.write_file(
|
|
296
|
-
output_path / Path("_request_builders_py3.py"),
|
|
297
|
-
RequestBuildersSerializer(
|
|
298
|
-
code_model=self.code_model,
|
|
299
|
-
env=env,
|
|
300
|
-
request_builders=request_builders,
|
|
301
|
-
is_python3_file=True,
|
|
302
276
|
).serialize_request_builders(),
|
|
303
277
|
)
|
|
304
278
|
|
|
@@ -309,7 +283,6 @@ class JinjaSerializer:
|
|
|
309
283
|
code_model=self.code_model,
|
|
310
284
|
env=env,
|
|
311
285
|
request_builders=request_builders,
|
|
312
|
-
is_python3_file=True,
|
|
313
286
|
).serialize_init(),
|
|
314
287
|
)
|
|
315
288
|
|
|
@@ -325,7 +298,6 @@ class JinjaSerializer:
|
|
|
325
298
|
code_model=self.code_model,
|
|
326
299
|
env=env,
|
|
327
300
|
async_mode=False,
|
|
328
|
-
is_python3_file=self.code_model.options["python3_only"],
|
|
329
301
|
operation_group=operation_group,
|
|
330
302
|
)
|
|
331
303
|
self._autorestapi.write_file(
|
|
@@ -335,31 +307,12 @@ class JinjaSerializer:
|
|
|
335
307
|
operation_group_serializer.serialize(),
|
|
336
308
|
)
|
|
337
309
|
|
|
338
|
-
if (
|
|
339
|
-
not self.code_model.options["python3_only"]
|
|
340
|
-
and self.code_model.options["add_python3_operation_files"]
|
|
341
|
-
):
|
|
342
|
-
# write typed second file if not python 3 only
|
|
343
|
-
operation_group_serializer = OperationGroupsSerializer(
|
|
344
|
-
code_model=self.code_model,
|
|
345
|
-
env=env,
|
|
346
|
-
async_mode=False,
|
|
347
|
-
is_python3_file=True,
|
|
348
|
-
)
|
|
349
|
-
self._autorestapi.write_file(
|
|
350
|
-
namespace_path
|
|
351
|
-
/ Path(self.code_model.operations_folder_name)
|
|
352
|
-
/ Path(f"{filename}_py3.py"),
|
|
353
|
-
operation_group_serializer.serialize(),
|
|
354
|
-
)
|
|
355
|
-
|
|
356
310
|
if self.has_aio_folder:
|
|
357
311
|
# write async operation group and operation files
|
|
358
312
|
operation_group_async_serializer = OperationGroupsSerializer(
|
|
359
313
|
code_model=self.code_model,
|
|
360
314
|
env=env,
|
|
361
315
|
async_mode=True,
|
|
362
|
-
is_python3_file=True,
|
|
363
316
|
operation_group=operation_group,
|
|
364
317
|
)
|
|
365
318
|
self._autorestapi.write_file(
|
|
@@ -477,6 +430,15 @@ class JinjaSerializer:
|
|
|
477
430
|
namespace_path / Path("py.typed"), "# Marker file for PEP 561."
|
|
478
431
|
)
|
|
479
432
|
|
|
433
|
+
if (
|
|
434
|
+
not self.code_model.options["client_side_validation"]
|
|
435
|
+
and not self.code_model.options["multiapi"]
|
|
436
|
+
):
|
|
437
|
+
self._autorestapi.write_file(
|
|
438
|
+
namespace_path / Path("_serialization.py"),
|
|
439
|
+
general_serializer.serialize_serialization_file(),
|
|
440
|
+
)
|
|
441
|
+
|
|
480
442
|
# Write the config file
|
|
481
443
|
if self.code_model.request_builders:
|
|
482
444
|
self._autorestapi.write_file(
|
|
@@ -30,6 +30,7 @@ from ..models import (
|
|
|
30
30
|
OverloadedRequestBuilder,
|
|
31
31
|
ConstantType,
|
|
32
32
|
MultipartBodyParameter,
|
|
33
|
+
Property,
|
|
33
34
|
RequestBuilderType,
|
|
34
35
|
)
|
|
35
36
|
from .parameter_serializer import ParameterSerializer, PopKwargType
|
|
@@ -83,6 +84,37 @@ def _json_dumps_template(template_representation: Any) -> Any:
|
|
|
83
84
|
)
|
|
84
85
|
|
|
85
86
|
|
|
87
|
+
def _get_polymorphic_subtype_template(polymorphic_subtype: ModelType) -> List[str]:
|
|
88
|
+
retval: List[str] = []
|
|
89
|
+
retval.append("")
|
|
90
|
+
retval.append(
|
|
91
|
+
f'# JSON input template for discriminator value "{polymorphic_subtype.discriminator_value}":'
|
|
92
|
+
)
|
|
93
|
+
subtype_template = _json_dumps_template(
|
|
94
|
+
polymorphic_subtype.get_json_template_representation(),
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
def _get_polymorphic_parent(
|
|
98
|
+
polymorphic_subtype: Optional[ModelType],
|
|
99
|
+
) -> Optional[ModelType]:
|
|
100
|
+
if not polymorphic_subtype:
|
|
101
|
+
return None
|
|
102
|
+
try:
|
|
103
|
+
return next(
|
|
104
|
+
p for p in polymorphic_subtype.parents if p.discriminated_subtypes
|
|
105
|
+
)
|
|
106
|
+
except StopIteration:
|
|
107
|
+
return None
|
|
108
|
+
|
|
109
|
+
polymorphic_parent = _get_polymorphic_parent(polymorphic_subtype)
|
|
110
|
+
while _get_polymorphic_parent(polymorphic_parent):
|
|
111
|
+
polymorphic_parent = _get_polymorphic_parent(polymorphic_parent)
|
|
112
|
+
retval.extend(
|
|
113
|
+
f"{cast(ModelType, polymorphic_parent).snake_case_name} = {subtype_template}".splitlines()
|
|
114
|
+
)
|
|
115
|
+
return retval
|
|
116
|
+
|
|
117
|
+
|
|
86
118
|
def _serialize_grouped_body(builder: BuilderType) -> List[str]:
|
|
87
119
|
retval: List[str] = []
|
|
88
120
|
for grouped_parameter in builder.parameters.grouped:
|
|
@@ -144,12 +176,9 @@ def _get_json_response_template_to_status_codes(
|
|
|
144
176
|
|
|
145
177
|
|
|
146
178
|
class _BuilderBaseSerializer(Generic[BuilderType]): # pylint: disable=abstract-method
|
|
147
|
-
def __init__(
|
|
148
|
-
self, code_model: CodeModel, async_mode: bool, is_python3_file: bool
|
|
149
|
-
) -> None:
|
|
179
|
+
def __init__(self, code_model: CodeModel, async_mode: bool) -> None:
|
|
150
180
|
self.code_model = code_model
|
|
151
181
|
self.async_mode = async_mode
|
|
152
|
-
self.is_python3_file = is_python3_file
|
|
153
182
|
self.parameter_serializer = ParameterSerializer()
|
|
154
183
|
|
|
155
184
|
@property
|
|
@@ -193,9 +222,7 @@ class _BuilderBaseSerializer(Generic[BuilderType]): # pylint: disable=abstract-
|
|
|
193
222
|
function_def=self._function_def,
|
|
194
223
|
method_name=builder.name,
|
|
195
224
|
need_self_param=self._need_self_param,
|
|
196
|
-
method_param_signatures=builder.method_signature(
|
|
197
|
-
self.async_mode or self.is_python3_file, self.async_mode
|
|
198
|
-
),
|
|
225
|
+
method_param_signatures=builder.method_signature(self.async_mode),
|
|
199
226
|
pylint_disable=builder.pylint_disable,
|
|
200
227
|
)
|
|
201
228
|
|
|
@@ -213,7 +240,6 @@ class _BuilderBaseSerializer(Generic[BuilderType]): # pylint: disable=abstract-
|
|
|
213
240
|
return (
|
|
214
241
|
decorators_str
|
|
215
242
|
+ utils.method_signature_and_response_type_annotation_template(
|
|
216
|
-
is_python3_file=self.is_python3_file,
|
|
217
243
|
method_signature=method_signature,
|
|
218
244
|
response_type_annotation=response_type_annotation,
|
|
219
245
|
)
|
|
@@ -268,6 +294,11 @@ class _BuilderBaseSerializer(Generic[BuilderType]): # pylint: disable=abstract-
|
|
|
268
294
|
return []
|
|
269
295
|
return self.param_description(builder) + self.response_docstring(builder)
|
|
270
296
|
|
|
297
|
+
@property
|
|
298
|
+
@abstractmethod
|
|
299
|
+
def _json_response_template_name(self) -> str:
|
|
300
|
+
...
|
|
301
|
+
|
|
271
302
|
def _json_input_example_template(self, builder: BuilderType) -> List[str]:
|
|
272
303
|
template: List[str] = []
|
|
273
304
|
if self.code_model.options["models_mode"]:
|
|
@@ -287,14 +318,26 @@ class _BuilderBaseSerializer(Generic[BuilderType]): # pylint: disable=abstract-
|
|
|
287
318
|
if not isinstance(body_param.type, (ListType, DictionaryType, ModelType)):
|
|
288
319
|
return template
|
|
289
320
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
321
|
+
polymorphic_subtypes: List[ModelType] = []
|
|
322
|
+
body_param.type.get_polymorphic_subtypes(polymorphic_subtypes)
|
|
323
|
+
if polymorphic_subtypes:
|
|
324
|
+
# we just assume one kind of polymorphic body for input
|
|
325
|
+
discriminator_name = cast(
|
|
326
|
+
Property, polymorphic_subtypes[0].discriminator
|
|
327
|
+
).rest_api_name
|
|
293
328
|
template.append(
|
|
294
|
-
"
|
|
295
|
-
|
|
296
|
-
)
|
|
329
|
+
"# The input is polymorphic. The following are possible polymorphic "
|
|
330
|
+
f'inputs based off discriminator "{discriminator_name}":'
|
|
297
331
|
)
|
|
332
|
+
for idx in range(
|
|
333
|
+
min(
|
|
334
|
+
self.code_model.options["polymorphic_examples"],
|
|
335
|
+
len(polymorphic_subtypes),
|
|
336
|
+
)
|
|
337
|
+
):
|
|
338
|
+
template.extend(
|
|
339
|
+
_get_polymorphic_subtype_template(polymorphic_subtypes[idx])
|
|
340
|
+
)
|
|
298
341
|
template.append("")
|
|
299
342
|
template.append(
|
|
300
343
|
"# JSON input template you can fill out and use as your body input."
|
|
@@ -337,7 +380,7 @@ class RequestBuilderSerializer(
|
|
|
337
380
|
def description_and_summary(self, builder: RequestBuilderType) -> List[str]:
|
|
338
381
|
retval = super().description_and_summary(builder)
|
|
339
382
|
retval += [
|
|
340
|
-
"See https://aka.ms/azsdk/python/
|
|
383
|
+
"See https://aka.ms/azsdk/dpcodegen/python/send_request for how to incorporate this "
|
|
341
384
|
"request builder into your code flow.",
|
|
342
385
|
"",
|
|
343
386
|
]
|
|
@@ -351,6 +394,10 @@ class RequestBuilderSerializer(
|
|
|
351
394
|
def serializer_name(self) -> str:
|
|
352
395
|
return "_SERIALIZER"
|
|
353
396
|
|
|
397
|
+
@property
|
|
398
|
+
def _json_response_template_name(self) -> str:
|
|
399
|
+
return "response.json()"
|
|
400
|
+
|
|
354
401
|
@staticmethod
|
|
355
402
|
def declare_non_inputtable_constants(builder: RequestBuilderType) -> List[str]:
|
|
356
403
|
def _get_value(param):
|
|
@@ -381,7 +428,7 @@ class RequestBuilderSerializer(
|
|
|
381
428
|
def response_docstring(self, builder: RequestBuilderType) -> List[str]:
|
|
382
429
|
response_str = (
|
|
383
430
|
f":return: Returns an :class:`~azure.core.rest.HttpRequest` that you will pass to the client's "
|
|
384
|
-
+ "`send_request` method. See https://aka.ms/azsdk/python/
|
|
431
|
+
+ "`send_request` method. See https://aka.ms/azsdk/dpcodegen/python/send_request for how to "
|
|
385
432
|
+ "incorporate this response into your code flow."
|
|
386
433
|
)
|
|
387
434
|
rtype_str = f":rtype: ~azure.core.rest.HttpRequest"
|
|
@@ -389,7 +436,7 @@ class RequestBuilderSerializer(
|
|
|
389
436
|
|
|
390
437
|
def pop_kwargs_from_signature(self, builder: RequestBuilderType) -> List[str]:
|
|
391
438
|
return self.parameter_serializer.pop_kwargs_from_signature(
|
|
392
|
-
builder.parameters.kwargs_to_pop
|
|
439
|
+
builder.parameters.kwargs_to_pop,
|
|
393
440
|
check_kwarg_dict=True,
|
|
394
441
|
pop_headers_kwarg=PopKwargType.CASE_INSENSITIVE
|
|
395
442
|
if bool(builder.parameters.headers)
|
|
@@ -399,7 +446,8 @@ class RequestBuilderSerializer(
|
|
|
399
446
|
else PopKwargType.NO,
|
|
400
447
|
)
|
|
401
448
|
|
|
402
|
-
|
|
449
|
+
@staticmethod
|
|
450
|
+
def create_http_request(builder: RequestBuilderType) -> List[str]:
|
|
403
451
|
retval = ["return HttpRequest("]
|
|
404
452
|
retval.append(f' method="{builder.method}",')
|
|
405
453
|
retval.append(" url=_url,")
|
|
@@ -412,9 +460,9 @@ class RequestBuilderSerializer(
|
|
|
412
460
|
and builder.parameters.body_parameter.in_method_signature
|
|
413
461
|
):
|
|
414
462
|
body_param = builder.parameters.body_parameter
|
|
415
|
-
if
|
|
416
|
-
|
|
417
|
-
|
|
463
|
+
if (
|
|
464
|
+
body_param.constant
|
|
465
|
+
or body_param.method_location != ParameterMethodLocation.KWARG
|
|
418
466
|
):
|
|
419
467
|
# we only need to pass it through if it's not a kwarg or it's a popped kwarg
|
|
420
468
|
retval.append(
|
|
@@ -473,10 +521,38 @@ class _OperationSerializer(
|
|
|
473
521
|
retval.append("")
|
|
474
522
|
return retval
|
|
475
523
|
|
|
524
|
+
@property
|
|
525
|
+
def _json_response_template_name(self) -> str:
|
|
526
|
+
return "response"
|
|
527
|
+
|
|
476
528
|
def example_template(self, builder: OperationType) -> List[str]:
|
|
477
529
|
retval = super().example_template(builder)
|
|
478
530
|
if self.code_model.options["models_mode"]:
|
|
479
531
|
return retval
|
|
532
|
+
for response in builder.responses:
|
|
533
|
+
polymorphic_subtypes: List[ModelType] = []
|
|
534
|
+
if not response.type:
|
|
535
|
+
continue
|
|
536
|
+
response.type.get_polymorphic_subtypes(polymorphic_subtypes)
|
|
537
|
+
if polymorphic_subtypes:
|
|
538
|
+
# we just assume one kind of polymorphic body for input
|
|
539
|
+
discriminator_name = cast(
|
|
540
|
+
Property, polymorphic_subtypes[0].discriminator
|
|
541
|
+
).rest_api_name
|
|
542
|
+
retval.append(
|
|
543
|
+
"# The response is polymorphic. The following are possible polymorphic "
|
|
544
|
+
f'responses based off discriminator "{discriminator_name}":'
|
|
545
|
+
)
|
|
546
|
+
for idx in range(
|
|
547
|
+
min(
|
|
548
|
+
self.code_model.options["polymorphic_examples"],
|
|
549
|
+
len(polymorphic_subtypes),
|
|
550
|
+
)
|
|
551
|
+
):
|
|
552
|
+
retval.extend(
|
|
553
|
+
_get_polymorphic_subtype_template(polymorphic_subtypes[idx])
|
|
554
|
+
)
|
|
555
|
+
|
|
480
556
|
if _get_json_response_template_to_status_codes(builder):
|
|
481
557
|
retval.append("")
|
|
482
558
|
for (
|
|
@@ -488,7 +564,9 @@ class _OperationSerializer(
|
|
|
488
564
|
", ".join(status_codes)
|
|
489
565
|
)
|
|
490
566
|
)
|
|
491
|
-
retval.extend(
|
|
567
|
+
retval.extend(
|
|
568
|
+
f"{self._json_response_template_name} == {response_body}".splitlines()
|
|
569
|
+
)
|
|
492
570
|
return retval
|
|
493
571
|
|
|
494
572
|
def make_pipeline_call(self, builder: OperationType) -> List[str]:
|
|
@@ -515,8 +593,6 @@ class _OperationSerializer(
|
|
|
515
593
|
def decorators(self, builder: OperationType) -> List[str]:
|
|
516
594
|
"""Decorators for the method"""
|
|
517
595
|
super_decorators = super().decorators(builder)
|
|
518
|
-
if builder.abstract:
|
|
519
|
-
super_decorators.append("@abc.abstractmethod")
|
|
520
596
|
return super_decorators
|
|
521
597
|
|
|
522
598
|
def param_description(
|
|
@@ -530,9 +606,7 @@ class _OperationSerializer(
|
|
|
530
606
|
return description_list
|
|
531
607
|
|
|
532
608
|
def pop_kwargs_from_signature(self, builder: OperationType) -> List[str]:
|
|
533
|
-
kwargs_to_pop = builder.parameters.kwargs_to_pop
|
|
534
|
-
is_python3_file=self.is_python3_file
|
|
535
|
-
)
|
|
609
|
+
kwargs_to_pop = builder.parameters.kwargs_to_pop
|
|
536
610
|
kwargs = self.parameter_serializer.pop_kwargs_from_signature(
|
|
537
611
|
kwargs_to_pop,
|
|
538
612
|
check_kwarg_dict=True,
|
|
@@ -616,6 +690,20 @@ class _OperationSerializer(
|
|
|
616
690
|
body_kwarg_name = builder.request_builder.parameters.body_parameter.client_name
|
|
617
691
|
if isinstance(body_param.type, BinaryType):
|
|
618
692
|
retval.append(f"_{body_kwarg_name} = {body_param.client_name}")
|
|
693
|
+
if (
|
|
694
|
+
not body_param.default_content_type
|
|
695
|
+
and not next(
|
|
696
|
+
p for p in builder.parameters if p.rest_api_name == "Content-Type"
|
|
697
|
+
).optional
|
|
698
|
+
):
|
|
699
|
+
content_types = "'" + "', '".join(body_param.content_types) + "'"
|
|
700
|
+
retval.extend(
|
|
701
|
+
[
|
|
702
|
+
"if not content_type:",
|
|
703
|
+
f' raise TypeError("Missing required keyword-only argument: content_type. '
|
|
704
|
+
f'Known values are:" + "{content_types}")',
|
|
705
|
+
]
|
|
706
|
+
)
|
|
619
707
|
else:
|
|
620
708
|
retval.extend(self._serialize_body_parameter(builder))
|
|
621
709
|
return retval
|
|
@@ -727,7 +815,6 @@ class _OperationSerializer(
|
|
|
727
815
|
is_next_request
|
|
728
816
|
and builder.operation_type == "paging"
|
|
729
817
|
and not bool(builder.next_request_builder) # type: ignore
|
|
730
|
-
and not self.code_model.options["reformat_next_link"]
|
|
731
818
|
and parameter.location == ParameterLocation.QUERY
|
|
732
819
|
):
|
|
733
820
|
# if we don't want to reformat query parameters for next link calls
|
|
@@ -738,10 +825,15 @@ class _OperationSerializer(
|
|
|
738
825
|
f" {parameter.client_name}={parameter.name_in_high_level_operation},"
|
|
739
826
|
)
|
|
740
827
|
if request_builder.overloads:
|
|
828
|
+
seen_body_params = set()
|
|
741
829
|
for overload in request_builder.overloads:
|
|
742
830
|
body_param = cast(
|
|
743
831
|
RequestBuilderBodyParameter, overload.parameters.body_parameter
|
|
744
832
|
)
|
|
833
|
+
if body_param.client_name in seen_body_params:
|
|
834
|
+
continue
|
|
835
|
+
seen_body_params.add(body_param.client_name)
|
|
836
|
+
|
|
745
837
|
retval.append(
|
|
746
838
|
f" {body_param.client_name}={body_param.name_in_high_level_operation},"
|
|
747
839
|
)
|
|
@@ -1008,15 +1100,12 @@ PagingOperationType = TypeVar(
|
|
|
1008
1100
|
class _PagingOperationSerializer(
|
|
1009
1101
|
_OperationSerializer[PagingOperationType]
|
|
1010
1102
|
): # pylint: disable=abstract-method
|
|
1011
|
-
def __init__(
|
|
1012
|
-
self, code_model: CodeModel, async_mode: bool, is_python3_file: bool
|
|
1013
|
-
) -> None:
|
|
1103
|
+
def __init__(self, code_model: CodeModel, async_mode: bool) -> None:
|
|
1014
1104
|
# for pylint reasons need to redefine init
|
|
1015
1105
|
# probably because inheritance is going too deep
|
|
1016
|
-
super().__init__(code_model, async_mode
|
|
1106
|
+
super().__init__(code_model, async_mode)
|
|
1017
1107
|
self.code_model = code_model
|
|
1018
1108
|
self.async_mode = async_mode
|
|
1019
|
-
self.is_python3_file = is_python3_file
|
|
1020
1109
|
self.parameter_serializer = ParameterSerializer()
|
|
1021
1110
|
|
|
1022
1111
|
def serialize_path(self, builder: PagingOperationType) -> List[str]:
|
|
@@ -1029,8 +1118,6 @@ class _PagingOperationSerializer(
|
|
|
1029
1118
|
retval: List[str] = []
|
|
1030
1119
|
if self.code_model.options["tracing"] and builder.want_tracing:
|
|
1031
1120
|
retval.append("@distributed_trace")
|
|
1032
|
-
if builder.abstract:
|
|
1033
|
-
retval.append("@abc.abstractmethod")
|
|
1034
1121
|
return retval
|
|
1035
1122
|
|
|
1036
1123
|
def call_next_link_request_builder(self, builder: PagingOperationType) -> List[str]:
|
|
@@ -1046,9 +1133,16 @@ class _PagingOperationSerializer(
|
|
|
1046
1133
|
template_url = "next_link"
|
|
1047
1134
|
|
|
1048
1135
|
request_builder = builder.next_request_builder or builder.request_builder
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1136
|
+
if builder.next_request_builder or self.code_model.is_legacy:
|
|
1137
|
+
return self._call_request_builder_helper(
|
|
1138
|
+
builder,
|
|
1139
|
+
request_builder,
|
|
1140
|
+
template_url=template_url,
|
|
1141
|
+
is_next_request=True,
|
|
1142
|
+
)
|
|
1143
|
+
retval = ['request = HttpRequest("GET", next_link)']
|
|
1144
|
+
retval.extend(self._postprocess_http_request(builder, "request.url"))
|
|
1145
|
+
return retval
|
|
1052
1146
|
|
|
1053
1147
|
def _prepare_request_callback(self, builder: PagingOperationType) -> List[str]:
|
|
1054
1148
|
retval = ["def prepare_request(next_link=None):"]
|
|
@@ -1061,10 +1155,7 @@ class _PagingOperationSerializer(
|
|
|
1061
1155
|
retval.extend(
|
|
1062
1156
|
[f" {line}" for line in self.call_next_link_request_builder(builder)]
|
|
1063
1157
|
)
|
|
1064
|
-
if not builder.next_request_builder and
|
|
1065
|
-
retval.append("")
|
|
1066
|
-
retval.extend([f" {line}" for line in self.serialize_path(builder)])
|
|
1067
|
-
if not builder.next_request_builder:
|
|
1158
|
+
if not builder.next_request_builder and self.code_model.is_legacy:
|
|
1068
1159
|
retval.append(' request.method = "GET"')
|
|
1069
1160
|
else:
|
|
1070
1161
|
retval.append("")
|
|
@@ -1142,15 +1233,12 @@ LROOperationType = TypeVar(
|
|
|
1142
1233
|
|
|
1143
1234
|
|
|
1144
1235
|
class _LROOperationSerializer(_OperationSerializer[LROOperationType]):
|
|
1145
|
-
def __init__(
|
|
1146
|
-
self, code_model: CodeModel, async_mode: bool, is_python3_file: bool
|
|
1147
|
-
) -> None:
|
|
1236
|
+
def __init__(self, code_model: CodeModel, async_mode: bool) -> None:
|
|
1148
1237
|
# for pylint reasons need to redefine init
|
|
1149
1238
|
# probably because inheritance is going too deep
|
|
1150
|
-
super().__init__(code_model, async_mode
|
|
1239
|
+
super().__init__(code_model, async_mode)
|
|
1151
1240
|
self.code_model = code_model
|
|
1152
1241
|
self.async_mode = async_mode
|
|
1153
|
-
self.is_python3_file = is_python3_file
|
|
1154
1242
|
self.parameter_serializer = ParameterSerializer()
|
|
1155
1243
|
|
|
1156
1244
|
def param_description(self, builder: LROOperationType) -> List[str]:
|
|
@@ -1330,7 +1418,6 @@ def get_operation_serializer(
|
|
|
1330
1418
|
builder: Operation,
|
|
1331
1419
|
code_model,
|
|
1332
1420
|
async_mode: bool,
|
|
1333
|
-
is_python3_file: bool,
|
|
1334
1421
|
) -> Union[
|
|
1335
1422
|
OperationSerializer,
|
|
1336
1423
|
PagingOperationSerializer,
|
|
@@ -1349,4 +1436,4 @@ def get_operation_serializer(
|
|
|
1349
1436
|
retcls = LROOperationSerializer
|
|
1350
1437
|
elif builder.operation_type == "paging":
|
|
1351
1438
|
retcls = PagingOperationSerializer
|
|
1352
|
-
return retcls(code_model, async_mode
|
|
1439
|
+
return retcls(code_model, async_mode)
|