@autorest/python 5.14.0 → 5.15.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 +29 -0
- package/autorest/codegen/__init__.py +87 -47
- package/autorest/codegen/models/base_schema.py +2 -6
- package/autorest/codegen/models/client.py +6 -0
- package/autorest/codegen/models/code_model.py +40 -74
- package/autorest/codegen/models/constant_schema.py +7 -3
- package/autorest/codegen/models/credential_model.py +47 -0
- package/autorest/codegen/models/credential_schema.py +5 -4
- package/autorest/codegen/models/dictionary_schema.py +7 -7
- package/autorest/codegen/models/enum_schema.py +8 -39
- package/autorest/codegen/models/imports.py +3 -1
- package/autorest/codegen/models/list_schema.py +18 -8
- package/autorest/codegen/models/lro_operation.py +3 -3
- package/autorest/codegen/models/lro_paging_operation.py +3 -3
- package/autorest/codegen/models/object_schema.py +17 -13
- package/autorest/codegen/models/operation.py +27 -6
- package/autorest/codegen/models/operation_group.py +7 -2
- package/autorest/codegen/models/paging_operation.py +3 -3
- package/autorest/codegen/models/parameter.py +39 -15
- package/autorest/codegen/models/parameter_list.py +1 -1
- package/autorest/codegen/models/primitive_schemas.py +15 -25
- package/autorest/codegen/models/property.py +5 -5
- package/autorest/codegen/models/request_builder.py +4 -4
- package/autorest/codegen/models/request_builder_parameter.py +12 -5
- package/autorest/codegen/models/schema_response.py +23 -10
- package/autorest/codegen/models/utils.py +20 -0
- package/autorest/codegen/serializers/__init__.py +49 -25
- package/autorest/codegen/serializers/builder_serializer.py +79 -37
- package/autorest/codegen/serializers/client_serializer.py +16 -6
- package/autorest/codegen/serializers/general_serializer.py +24 -3
- package/autorest/codegen/serializers/import_serializer.py +1 -1
- package/autorest/codegen/serializers/metadata_serializer.py +1 -1
- package/autorest/codegen/serializers/model_base_serializer.py +8 -0
- package/autorest/codegen/serializers/model_python3_serializer.py +2 -2
- package/autorest/codegen/serializers/operation_groups_serializer.py +1 -0
- package/autorest/codegen/serializers/patch_serializer.py +12 -3
- package/autorest/codegen/serializers/utils.py +29 -4
- package/autorest/codegen/templates/config.py.jinja2 +4 -4
- package/autorest/codegen/templates/enum.py.jinja2 +1 -1
- package/autorest/codegen/templates/enum_container.py.jinja2 +0 -1
- package/autorest/codegen/templates/init.py.jinja2 +9 -6
- package/autorest/codegen/templates/keywords.jinja2 +14 -1
- package/autorest/codegen/templates/lro_operation.py.jinja2 +1 -1
- package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +1 -1
- package/autorest/codegen/templates/metadata.json.jinja2 +3 -3
- package/autorest/codegen/templates/model.py.jinja2 +1 -6
- package/autorest/codegen/templates/model_init.py.jinja2 +7 -4
- package/autorest/codegen/templates/operation.py.jinja2 +2 -3
- package/autorest/codegen/templates/operation_group.py.jinja2 +12 -5
- package/autorest/codegen/templates/operation_groups_container.py.jinja2 +0 -1
- package/autorest/codegen/templates/operations_folder_init.py.jinja2 +4 -0
- package/autorest/codegen/templates/paging_operation.py.jinja2 +1 -1
- package/autorest/codegen/templates/patch.py.jinja2 +18 -29
- package/autorest/codegen/templates/request_builder.py.jinja2 +4 -6
- package/autorest/codegen/templates/vendor.py.jinja2 +12 -2
- package/autorest/multiapi/models/imports.py +21 -11
- package/autorest/multiapi/serializers/import_serializer.py +3 -1
- package/package.json +2 -2
|
@@ -110,12 +110,6 @@ def _serialize_files_and_data_body(builder, param_name: str) -> List[str]:
|
|
|
110
110
|
retval.append("}")
|
|
111
111
|
return retval
|
|
112
112
|
|
|
113
|
-
def _pop_parameters_kwarg(
|
|
114
|
-
function_name: str,
|
|
115
|
-
kwarg_name: str,
|
|
116
|
-
) -> str:
|
|
117
|
-
return f'_{function_name}_parameters = kwargs.pop("{kwarg_name}", {{}}) # type: Dict[str, Any]'
|
|
118
|
-
|
|
119
113
|
def _serialize_grouped_body(builder) -> List[str]:
|
|
120
114
|
retval: List[str] = []
|
|
121
115
|
for grouped_parameter in builder.parameters.grouped:
|
|
@@ -165,7 +159,7 @@ def _content_type_docstring(builder) -> str:
|
|
|
165
159
|
).default_value_declaration
|
|
166
160
|
return (
|
|
167
161
|
":keyword content_type: Media type of the body sent to the API. " +
|
|
168
|
-
f"
|
|
162
|
+
f"Known values are: {possible_values_str}. " +
|
|
169
163
|
f"Default value is {default_value}."
|
|
170
164
|
)
|
|
171
165
|
|
|
@@ -411,10 +405,11 @@ class _BuilderBaseSerializer(_BuilderSerializerProtocol): # pylint: disable=abs
|
|
|
411
405
|
...
|
|
412
406
|
|
|
413
407
|
def _serialize_parameter(
|
|
414
|
-
self, param: Parameter,
|
|
408
|
+
self, param: Parameter, kwarg_name: str
|
|
415
409
|
) -> List[str]:
|
|
416
|
-
|
|
417
|
-
|
|
410
|
+
function_name = "header" if kwarg_name == "headers" else "query"
|
|
411
|
+
set_parameter = "_{}['{}'] = {}".format(
|
|
412
|
+
kwarg_name,
|
|
418
413
|
param.rest_api_name,
|
|
419
414
|
utils.build_serialize_data_call(param, function_name, self.serializer_name)
|
|
420
415
|
)
|
|
@@ -434,10 +429,6 @@ class _BuilderBaseSerializer(_BuilderSerializerProtocol): # pylint: disable=abs
|
|
|
434
429
|
template.extend(f"response.json() == {response_body}".splitlines())
|
|
435
430
|
return template
|
|
436
431
|
|
|
437
|
-
|
|
438
|
-
def pop_kwargs_from_signature(self, builder) -> List[str]:
|
|
439
|
-
return utils.pop_kwargs_from_signature(self._get_kwargs_to_pop(builder))
|
|
440
|
-
|
|
441
432
|
def serialize_path(self, builder) -> List[str]:
|
|
442
433
|
return utils.serialize_path(builder.parameters.path, self.serializer_name)
|
|
443
434
|
|
|
@@ -463,6 +454,21 @@ class _RequestBuilderBaseSerializer(_BuilderBaseSerializer): # pylint: disable=
|
|
|
463
454
|
def serializer_name(self) -> str:
|
|
464
455
|
return "_SERIALIZER"
|
|
465
456
|
|
|
457
|
+
@staticmethod
|
|
458
|
+
def declare_non_inputtable_constants(builder) -> List[str]:
|
|
459
|
+
def _get_value(param: Parameter):
|
|
460
|
+
if param.location in [ParameterLocation.Header, ParameterLocation.Query]:
|
|
461
|
+
kwarg_dict = "headers" if param.location == ParameterLocation.Header else "params"
|
|
462
|
+
return f"_{kwarg_dict}.pop('{param.rest_api_name}', {param.constant_declaration})"
|
|
463
|
+
return f"{param.constant_declaration}"
|
|
464
|
+
return [
|
|
465
|
+
f"{p.serialized_name} = {_get_value(p)}"
|
|
466
|
+
for p in builder.parameters.constant
|
|
467
|
+
if p.original_parameter is None and
|
|
468
|
+
p.in_method_code and
|
|
469
|
+
not p.in_method_signature
|
|
470
|
+
]
|
|
471
|
+
|
|
466
472
|
def want_example_template(self, builder) -> bool:
|
|
467
473
|
if self.code_model.options["builders_visibility"] != "public":
|
|
468
474
|
return False # if we're not exposing rest layer, don't need to generate
|
|
@@ -507,14 +513,24 @@ class _RequestBuilderBaseSerializer(_BuilderBaseSerializer): # pylint: disable=
|
|
|
507
513
|
def _body_params_to_pass_to_request_creation(self, builder) -> List[str]:
|
|
508
514
|
...
|
|
509
515
|
|
|
516
|
+
def pop_kwargs_from_signature(self, builder) -> List[str]:
|
|
517
|
+
return utils.pop_kwargs_from_signature(
|
|
518
|
+
self._get_kwargs_to_pop(builder),
|
|
519
|
+
check_kwarg_dict=True,
|
|
520
|
+
pop_headers_kwarg=utils.PopKwargType.CASE_INSENSITIVE if bool(builder.parameters.headers)
|
|
521
|
+
else utils.PopKwargType.NO,
|
|
522
|
+
pop_params_kwarg=utils.PopKwargType.CASE_INSENSITIVE if bool(builder.parameters.query)
|
|
523
|
+
else utils.PopKwargType.NO,
|
|
524
|
+
)
|
|
525
|
+
|
|
510
526
|
def create_http_request(self, builder) -> List[str]:
|
|
511
527
|
retval = ["return HttpRequest("]
|
|
512
528
|
retval.append(f' method="{builder.method}",')
|
|
513
529
|
retval.append(" url=_url,")
|
|
514
530
|
if builder.parameters.query:
|
|
515
|
-
retval.append(" params=
|
|
531
|
+
retval.append(" params=_params,")
|
|
516
532
|
if builder.parameters.headers:
|
|
517
|
-
retval.append(" headers=
|
|
533
|
+
retval.append(" headers=_headers,")
|
|
518
534
|
if builder.parameters.has_body:
|
|
519
535
|
retval.extend([
|
|
520
536
|
f" {body_kwarg}={body_kwarg},"
|
|
@@ -526,21 +542,19 @@ class _RequestBuilderBaseSerializer(_BuilderBaseSerializer): # pylint: disable=
|
|
|
526
542
|
|
|
527
543
|
def serialize_headers(self, builder) -> List[str]:
|
|
528
544
|
retval = ["# Construct headers"]
|
|
529
|
-
retval.append(_pop_parameters_kwarg("header", "headers"))
|
|
530
545
|
for parameter in builder.parameters.headers:
|
|
531
546
|
retval.extend(self._serialize_parameter(
|
|
532
547
|
parameter,
|
|
533
|
-
|
|
548
|
+
kwarg_name="headers",
|
|
534
549
|
))
|
|
535
550
|
return retval
|
|
536
551
|
|
|
537
552
|
def serialize_query(self, builder) -> List[str]:
|
|
538
553
|
retval = ["# Construct parameters"]
|
|
539
|
-
retval.append(_pop_parameters_kwarg("query", "params"))
|
|
540
554
|
for parameter in builder.parameters.query:
|
|
541
555
|
retval.extend(self._serialize_parameter(
|
|
542
556
|
parameter,
|
|
543
|
-
|
|
557
|
+
kwarg_name="params",
|
|
544
558
|
))
|
|
545
559
|
return retval
|
|
546
560
|
|
|
@@ -644,7 +658,7 @@ class _OperationBaseSerializer(_BuilderBaseSerializer): # pylint: disable=abstr
|
|
|
644
658
|
return "bool"
|
|
645
659
|
response_body_annotations: OrderedSet[str] = {}
|
|
646
660
|
for response in [r for r in builder.responses if r.has_body]:
|
|
647
|
-
response_body_annotations[response.
|
|
661
|
+
response_body_annotations[response.type_annotation(is_operation_file=True)] = None
|
|
648
662
|
response_str = ", ".join(response_body_annotations.keys()) or "None"
|
|
649
663
|
if len(response_body_annotations) > 1:
|
|
650
664
|
response_str = f"Union[{response_str}]"
|
|
@@ -652,6 +666,19 @@ class _OperationBaseSerializer(_BuilderBaseSerializer): # pylint: disable=abstr
|
|
|
652
666
|
response_str = f"Optional[{response_str}]"
|
|
653
667
|
return response_str
|
|
654
668
|
|
|
669
|
+
def pop_kwargs_from_signature(self, builder) -> List[str]:
|
|
670
|
+
kwargs_to_pop = self._get_kwargs_to_pop(builder)
|
|
671
|
+
kwargs = utils.pop_kwargs_from_signature(
|
|
672
|
+
kwargs_to_pop,
|
|
673
|
+
check_kwarg_dict=True,
|
|
674
|
+
pop_headers_kwarg=utils.PopKwargType.CASE_INSENSITIVE if builder.has_kwargs_to_pop_with_default(
|
|
675
|
+
kwargs_to_pop, ParameterLocation.Header) else utils.PopKwargType.SIMPLE,
|
|
676
|
+
pop_params_kwarg=utils.PopKwargType.CASE_INSENSITIVE if builder.has_kwargs_to_pop_with_default(
|
|
677
|
+
kwargs_to_pop, ParameterLocation.Query) else utils.PopKwargType.SIMPLE,
|
|
678
|
+
)
|
|
679
|
+
kwargs.append(f"cls = kwargs.pop('cls', None) {self.cls_type_annotation(builder)}")
|
|
680
|
+
return kwargs
|
|
681
|
+
|
|
655
682
|
def cls_type_annotation(self, builder) -> str:
|
|
656
683
|
return f"# type: ClsType[{self._response_type_annotation(builder, modify_if_head_as_boolean=False)}]"
|
|
657
684
|
|
|
@@ -780,6 +807,7 @@ class _OperationBaseSerializer(_BuilderBaseSerializer): # pylint: disable=abstr
|
|
|
780
807
|
if len(body_kwargs) == 1:
|
|
781
808
|
retval.extend(self._set_body_content_kwarg(builder, builder.parameters.body[0], body_kwargs[0]))
|
|
782
809
|
else:
|
|
810
|
+
retval.append('content_type = content_type or ""')
|
|
783
811
|
for idx, body_kwarg in enumerate(body_kwargs):
|
|
784
812
|
body_param = next(
|
|
785
813
|
b for b in builder_params
|
|
@@ -854,6 +882,8 @@ class _OperationBaseSerializer(_BuilderBaseSerializer): # pylint: disable=abstr
|
|
|
854
882
|
if not self.code_model.options["version_tolerant"]:
|
|
855
883
|
template_url = template_url or f"self.{builder.name}.metadata['url']"
|
|
856
884
|
retval.append(f" template_url={template_url},")
|
|
885
|
+
retval.append(' headers=_headers,')
|
|
886
|
+
retval.append(' params=_params,')
|
|
857
887
|
retval.append(f")")
|
|
858
888
|
if not self.code_model.options["version_tolerant"]:
|
|
859
889
|
pass_files = ""
|
|
@@ -866,7 +896,7 @@ class _OperationBaseSerializer(_BuilderBaseSerializer): # pylint: disable=abstr
|
|
|
866
896
|
if self.code_model.options["version_tolerant"] and template_url:
|
|
867
897
|
url_to_format = template_url
|
|
868
898
|
retval.append(
|
|
869
|
-
"request.url = self._client.format_url({}{})".format(
|
|
899
|
+
"request.url = self._client.format_url({}{}) # type: ignore".format(
|
|
870
900
|
url_to_format,
|
|
871
901
|
", **path_format_arguments" if builder.parameters.path else ""
|
|
872
902
|
)
|
|
@@ -901,12 +931,11 @@ class _OperationBaseSerializer(_BuilderBaseSerializer): # pylint: disable=abstr
|
|
|
901
931
|
retval.append(f"deserialized = self._deserialize('{response.serialization_type}', pipeline_response)")
|
|
902
932
|
else:
|
|
903
933
|
is_xml = any(["xml" in ct for ct in response.content_types])
|
|
904
|
-
deserialized_value = ""
|
|
905
934
|
deserialized_value = "ET.fromstring(response.text())" if is_xml else "response.json()"
|
|
906
935
|
retval.append(f"if response.content:")
|
|
907
936
|
retval.append(f" deserialized = {deserialized_value}")
|
|
908
937
|
retval.append("else:")
|
|
909
|
-
retval.append(" deserialized = None")
|
|
938
|
+
retval.append(f" deserialized = None")
|
|
910
939
|
return retval
|
|
911
940
|
|
|
912
941
|
@property
|
|
@@ -954,14 +983,18 @@ class _OperationBaseSerializer(_BuilderBaseSerializer): # pylint: disable=abstr
|
|
|
954
983
|
builder.responses[0]
|
|
955
984
|
))
|
|
956
985
|
retval.append("")
|
|
986
|
+
if builder.has_optional_return_type or self.code_model.options["models_mode"]:
|
|
987
|
+
deserialized = "deserialized"
|
|
988
|
+
else:
|
|
989
|
+
deserialized = f"cast({self._response_type_annotation(builder)}, deserialized)"
|
|
957
990
|
retval.append("if cls:")
|
|
958
991
|
retval.append(" return cls(pipeline_response, {}, {})".format(
|
|
959
|
-
|
|
992
|
+
deserialized if builder.has_response_body else "None",
|
|
960
993
|
"response_headers" if builder.any_response_has_headers else '{}'
|
|
961
994
|
))
|
|
962
995
|
if builder.has_response_body:
|
|
963
996
|
retval.append("")
|
|
964
|
-
retval.append("return deserialized")
|
|
997
|
+
retval.append(f"return {deserialized}")
|
|
965
998
|
if builder.request_builder.method == 'HEAD' and self.code_model.options['head_as_boolean']:
|
|
966
999
|
retval.append("return 200 <= response.status_code <= 299")
|
|
967
1000
|
return retval
|
|
@@ -1010,7 +1043,7 @@ class _OperationBaseSerializer(_BuilderBaseSerializer): # pylint: disable=abstr
|
|
|
1010
1043
|
else:
|
|
1011
1044
|
retval.append(" 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError")
|
|
1012
1045
|
retval.append("}")
|
|
1013
|
-
retval.append("error_map.update(kwargs.pop('error_map', {}))")
|
|
1046
|
+
retval.append("error_map.update(kwargs.pop('error_map', {}) or {})")
|
|
1014
1047
|
return retval
|
|
1015
1048
|
|
|
1016
1049
|
@staticmethod
|
|
@@ -1185,7 +1218,7 @@ class _PagingOperationBaseSerializer(_OperationBaseSerializer): # pylint: disab
|
|
|
1185
1218
|
return retval
|
|
1186
1219
|
|
|
1187
1220
|
def set_up_params_for_pager(self, builder) -> List[str]:
|
|
1188
|
-
retval = [
|
|
1221
|
+
retval = []
|
|
1189
1222
|
retval.extend(self.error_map(builder))
|
|
1190
1223
|
retval.extend(self._prepare_request_callback(builder))
|
|
1191
1224
|
retval.append("")
|
|
@@ -1276,19 +1309,20 @@ class _LROOperationBaseSerializer(_OperationBaseSerializer): # pylint: disable=
|
|
|
1276
1309
|
|
|
1277
1310
|
def initial_call(self, builder) -> List[str]:
|
|
1278
1311
|
retval = [f"polling = kwargs.pop('polling', True) # type: Union[bool, {self._polling_method_type}]"]
|
|
1279
|
-
retval.append(f"cls = kwargs.pop('cls', None) {self.cls_type_annotation(builder)}")
|
|
1280
1312
|
retval.append("lro_delay = kwargs.pop(")
|
|
1281
1313
|
retval.append(" 'polling_interval',")
|
|
1282
1314
|
retval.append(" self._config.polling_interval")
|
|
1283
1315
|
retval.append(")")
|
|
1284
1316
|
retval.append("cont_token = kwargs.pop('continuation_token', None) # type: Optional[str]")
|
|
1285
1317
|
retval.append("if cont_token is None:")
|
|
1286
|
-
retval.append(f" raw_result = {self._call_method}self.{builder.initial_operation.name}(")
|
|
1318
|
+
retval.append(f" raw_result = {self._call_method}self.{builder.initial_operation.name}( # type: ignore")
|
|
1287
1319
|
retval.extend([
|
|
1288
1320
|
f" {parameter.serialized_name}={parameter.serialized_name},"
|
|
1289
1321
|
for parameter in builder.parameters.method
|
|
1290
1322
|
])
|
|
1291
1323
|
retval.append(" cls=lambda x,y,z: x,")
|
|
1324
|
+
retval.append(" headers=_headers,")
|
|
1325
|
+
retval.append(" params=_params,")
|
|
1292
1326
|
retval.append(" **kwargs")
|
|
1293
1327
|
retval.append(" )")
|
|
1294
1328
|
retval.append("kwargs.pop('error_map', None)")
|
|
@@ -1297,20 +1331,27 @@ class _LROOperationBaseSerializer(_OperationBaseSerializer): # pylint: disable=
|
|
|
1297
1331
|
def return_lro_poller(self, builder) -> List[str]:
|
|
1298
1332
|
retval = []
|
|
1299
1333
|
lro_options_str = (
|
|
1300
|
-
"
|
|
1334
|
+
"lro_options={'final-state-via': '" + builder.lro_options['final-state-via'] + "'},"
|
|
1301
1335
|
if builder.lro_options else ""
|
|
1302
1336
|
)
|
|
1303
1337
|
path_format_arguments_str = ""
|
|
1304
1338
|
if builder.parameters.path:
|
|
1305
|
-
path_format_arguments_str = "
|
|
1339
|
+
path_format_arguments_str = "path_format_arguments=path_format_arguments,"
|
|
1306
1340
|
retval.extend(self.serialize_path(builder))
|
|
1307
1341
|
retval.append("")
|
|
1308
|
-
retval.
|
|
1309
|
-
|
|
1310
|
-
f"(
|
|
1342
|
+
retval.extend([
|
|
1343
|
+
"if polling is True:",
|
|
1344
|
+
f" polling_method = cast({self._polling_method_type}, {self._default_polling_method(builder)}(",
|
|
1345
|
+
" lro_delay,",
|
|
1346
|
+
f" {lro_options_str}",
|
|
1347
|
+
f" {path_format_arguments_str}",
|
|
1348
|
+
" **kwargs",
|
|
1349
|
+
f")) # type: {self._polling_method_type}",
|
|
1350
|
+
]
|
|
1311
1351
|
)
|
|
1312
1352
|
retval.append(
|
|
1313
|
-
f"elif polling is False: polling_method = {self.
|
|
1353
|
+
f"elif polling is False: polling_method = cast({self._polling_method_type}, "
|
|
1354
|
+
f"{self._default_no_polling_method(builder)}())"
|
|
1314
1355
|
)
|
|
1315
1356
|
retval.append("else: polling_method = polling")
|
|
1316
1357
|
retval.append("if cont_token:")
|
|
@@ -1331,7 +1372,8 @@ class _LROOperationBaseSerializer(_OperationBaseSerializer): # pylint: disable=
|
|
|
1331
1372
|
if builder.lro_response:
|
|
1332
1373
|
if builder.lro_response.has_headers:
|
|
1333
1374
|
retval.append(" response_headers = {}")
|
|
1334
|
-
|
|
1375
|
+
if not self.code_model.options["models_mode"] or builder.lro_response.has_headers:
|
|
1376
|
+
retval.append(" response = pipeline_response.http_response")
|
|
1335
1377
|
retval.extend([
|
|
1336
1378
|
f" {line}"
|
|
1337
1379
|
for line in self.response_headers_and_deserialization(builder.lro_response)
|
|
@@ -32,9 +32,14 @@ class ClientSerializer:
|
|
|
32
32
|
)
|
|
33
33
|
|
|
34
34
|
def pop_kwargs_from_signature(self, async_mode: bool) -> List[str]:
|
|
35
|
-
return utils.pop_kwargs_from_signature(
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
return utils.pop_kwargs_from_signature(
|
|
36
|
+
self.code_model.service_client.parameters.kwargs_to_pop(
|
|
37
|
+
async_mode or self.is_python3_file,
|
|
38
|
+
),
|
|
39
|
+
check_kwarg_dict=False,
|
|
40
|
+
pop_headers_kwarg=utils.PopKwargType.NO,
|
|
41
|
+
pop_params_kwarg=utils.PopKwargType.NO,
|
|
42
|
+
)
|
|
38
43
|
|
|
39
44
|
def class_definition(self, async_mode) -> str:
|
|
40
45
|
class_name = self.code_model.class_name
|
|
@@ -212,9 +217,14 @@ class ConfigSerializer:
|
|
|
212
217
|
)
|
|
213
218
|
|
|
214
219
|
def pop_kwargs_from_signature(self, async_mode: bool) -> List[str]:
|
|
215
|
-
return utils.pop_kwargs_from_signature(
|
|
216
|
-
|
|
217
|
-
|
|
220
|
+
return utils.pop_kwargs_from_signature(
|
|
221
|
+
self.code_model.global_parameters.config_kwargs_to_pop(
|
|
222
|
+
async_mode or self.is_python3_file
|
|
223
|
+
),
|
|
224
|
+
check_kwarg_dict=False,
|
|
225
|
+
pop_headers_kwarg=utils.PopKwargType.NO,
|
|
226
|
+
pop_params_kwarg=utils.PopKwargType.NO,
|
|
227
|
+
)
|
|
218
228
|
|
|
219
229
|
def set_constants(self) -> List[str]:
|
|
220
230
|
return [
|
|
@@ -50,7 +50,7 @@ class GeneralSerializer:
|
|
|
50
50
|
|
|
51
51
|
if (
|
|
52
52
|
self.code_model.options['credential'] and
|
|
53
|
-
isinstance(self.code_model.credential_schema_policy.credential, TokenCredentialSchema)
|
|
53
|
+
isinstance(self.code_model.credential_model.credential_schema_policy.credential, TokenCredentialSchema)
|
|
54
54
|
):
|
|
55
55
|
self._correct_credential_parameter()
|
|
56
56
|
|
|
@@ -77,12 +77,33 @@ class GeneralSerializer:
|
|
|
77
77
|
ImportType.AZURECORE,
|
|
78
78
|
)
|
|
79
79
|
|
|
80
|
+
if self.code_model.need_mixin_abc:
|
|
81
|
+
file_import.add_submodule_import(
|
|
82
|
+
"abc",
|
|
83
|
+
"ABC",
|
|
84
|
+
ImportType.STDLIB,
|
|
85
|
+
)
|
|
86
|
+
file_import.add_submodule_import(
|
|
87
|
+
"azure.core",
|
|
88
|
+
f"{'Async' if self.async_mode else ''}PipelineClient",
|
|
89
|
+
ImportType.AZURECORE,
|
|
90
|
+
TypingSection.TYPING,
|
|
91
|
+
)
|
|
92
|
+
file_import.add_submodule_import(
|
|
93
|
+
"._configuration",
|
|
94
|
+
f"{self.code_model.class_name}Configuration",
|
|
95
|
+
ImportType.LOCAL
|
|
96
|
+
)
|
|
97
|
+
file_import.add_submodule_import("msrest", "Serializer", ImportType.THIRDPARTY, TypingSection.TYPING)
|
|
98
|
+
file_import.add_submodule_import("msrest", "Deserializer", ImportType.THIRDPARTY, TypingSection.TYPING)
|
|
99
|
+
|
|
80
100
|
return template.render(
|
|
81
101
|
code_model=self.code_model,
|
|
82
102
|
imports=FileImportSerializer(
|
|
83
103
|
file_import,
|
|
84
104
|
is_python3_file=self.async_mode,
|
|
85
|
-
)
|
|
105
|
+
),
|
|
106
|
+
async_mode=self.async_mode,
|
|
86
107
|
)
|
|
87
108
|
|
|
88
109
|
|
|
@@ -95,7 +116,7 @@ class GeneralSerializer:
|
|
|
95
116
|
|
|
96
117
|
if (
|
|
97
118
|
self.code_model.options['credential'] and
|
|
98
|
-
isinstance(self.code_model.credential_schema_policy.credential, TokenCredentialSchema)
|
|
119
|
+
isinstance(self.code_model.credential_model.credential_schema_policy.credential, TokenCredentialSchema)
|
|
99
120
|
):
|
|
100
121
|
self._correct_credential_parameter()
|
|
101
122
|
|
|
@@ -12,7 +12,7 @@ def _serialize_package(
|
|
|
12
12
|
) -> str:
|
|
13
13
|
buffer = []
|
|
14
14
|
if any(i for i in imports if i.submodule_name is None):
|
|
15
|
-
buffer.append(f"import {imports[0].module_name}")
|
|
15
|
+
buffer.append(f"import {imports[0].module_name}{f' as {imports[0].alias}' if imports[0].alias else ''}")
|
|
16
16
|
else:
|
|
17
17
|
import_str = ", ".join(sorted([
|
|
18
18
|
f"{i.submodule_name} as {i.alias}" if i.alias else i.submodule_name for i in imports # type: ignore
|
|
@@ -145,7 +145,7 @@ class MetadataSerializer:
|
|
|
145
145
|
async_global_parameters = self.code_model.global_parameters
|
|
146
146
|
if (
|
|
147
147
|
self.code_model.options['credential'] and
|
|
148
|
-
isinstance(self.code_model.credential_schema_policy.credential, TokenCredentialSchema)
|
|
148
|
+
isinstance(self.code_model.credential_model.credential_schema_policy.credential, TokenCredentialSchema)
|
|
149
149
|
):
|
|
150
150
|
# this ensures that the TokenCredentialSchema showing up in the list of code model's global parameters
|
|
151
151
|
# is sync. This way we only have to make a copy for an async_credential
|
|
@@ -40,6 +40,7 @@ class ModelBaseSerializer:
|
|
|
40
40
|
init_args=self.init_args,
|
|
41
41
|
input_documentation_string=ModelBaseSerializer.input_documentation_string,
|
|
42
42
|
variable_documentation_string=ModelBaseSerializer.variable_documentation_string,
|
|
43
|
+
declare_model=ModelBaseSerializer.declare_model,
|
|
43
44
|
)
|
|
44
45
|
|
|
45
46
|
def imports(self) -> FileImport:
|
|
@@ -62,6 +63,13 @@ class ModelBaseSerializer:
|
|
|
62
63
|
properties_to_initialize = model.properties
|
|
63
64
|
return properties_to_initialize
|
|
64
65
|
|
|
66
|
+
@staticmethod
|
|
67
|
+
def declare_model(model: ObjectSchema) -> str:
|
|
68
|
+
basename = "msrest.serialization.Model"
|
|
69
|
+
if model.base_models:
|
|
70
|
+
basename = ", ".join([cast(ObjectSchema, m).name for m in model.base_models])
|
|
71
|
+
return f"class {model.name}({basename}):"
|
|
72
|
+
|
|
65
73
|
@staticmethod
|
|
66
74
|
def input_documentation_string(prop: Property) -> List[str]:
|
|
67
75
|
# building the param line of the property doc
|
|
@@ -46,11 +46,11 @@ class ModelPython3Serializer(ModelBaseSerializer):
|
|
|
46
46
|
return ", ".join(properties_to_pass_to_super)
|
|
47
47
|
|
|
48
48
|
def required_property_no_default_init(self, prop: Property) -> str:
|
|
49
|
-
return f"{prop.name}: {prop.type_annotation}"
|
|
49
|
+
return f"{prop.name}: {prop.type_annotation()}"
|
|
50
50
|
|
|
51
51
|
def optional_property_init(self, prop: Property) -> str:
|
|
52
52
|
default = prop.default_value_declaration
|
|
53
|
-
return f"{prop.name}: {prop.type_annotation} = {default}"
|
|
53
|
+
return f"{prop.name}: {prop.type_annotation()} = {default}"
|
|
54
54
|
|
|
55
55
|
def initialize_standard_arg(self, prop: Property) -> str:
|
|
56
56
|
return f"self.{prop.name} = {prop.name}"
|
|
@@ -43,6 +43,7 @@ class OperationGroupsSerializer:
|
|
|
43
43
|
for operation_group in operation_groups:
|
|
44
44
|
imports.merge(operation_group.imports(
|
|
45
45
|
async_mode=self.async_mode,
|
|
46
|
+
is_python3_file=self.is_python3_file,
|
|
46
47
|
))
|
|
47
48
|
|
|
48
49
|
template = self.env.get_or_select_template("operation_groups_container.py.jinja2")
|
|
@@ -4,12 +4,21 @@
|
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
6
|
from jinja2 import Environment
|
|
7
|
-
|
|
7
|
+
from .import_serializer import FileImportSerializer
|
|
8
|
+
from ..models import CodeModel, FileImport, ImportType, TypingSection
|
|
8
9
|
|
|
9
10
|
class PatchSerializer:
|
|
10
|
-
def __init__(self, env: Environment) -> None:
|
|
11
|
+
def __init__(self, env: Environment, code_model: CodeModel) -> None:
|
|
11
12
|
self.env = env
|
|
13
|
+
self.code_model = code_model
|
|
12
14
|
|
|
13
15
|
def serialize(self) -> str:
|
|
14
16
|
template = self.env.get_template("patch.py.jinja2")
|
|
15
|
-
|
|
17
|
+
imports = FileImport()
|
|
18
|
+
imports.add_submodule_import("typing", "List", ImportType.STDLIB, TypingSection.CONDITIONAL)
|
|
19
|
+
is_python3_file = self.code_model.options["python3_only"]
|
|
20
|
+
return template.render(
|
|
21
|
+
code_model=self.code_model,
|
|
22
|
+
imports=FileImportSerializer(imports, is_python3_file=is_python3_file),
|
|
23
|
+
is_python3_file=is_python3_file,
|
|
24
|
+
)
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
# Licensed under the MIT License. See License.txt in the project root for
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
|
+
from enum import Enum, auto
|
|
6
7
|
from typing import List
|
|
7
|
-
from ..models import ParameterStyle, ListSchema, Parameter
|
|
8
|
+
from ..models import ParameterStyle, ListSchema, Parameter, ParameterLocation
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
def serialize_method(
|
|
@@ -102,16 +103,40 @@ def method_signature_and_response_type_annotation_template(
|
|
|
102
103
|
return f"{method_signature} -> {response_type_annotation}:"
|
|
103
104
|
return f"{method_signature}:\n # type: (...) -> {response_type_annotation}"
|
|
104
105
|
|
|
105
|
-
|
|
106
|
+
class PopKwargType(Enum):
|
|
107
|
+
NO = auto()
|
|
108
|
+
SIMPLE = auto()
|
|
109
|
+
CASE_INSENSITIVE = auto()
|
|
110
|
+
|
|
111
|
+
def pop_kwargs_from_signature(
|
|
112
|
+
kwargs_to_pop: List[Parameter],
|
|
113
|
+
check_kwarg_dict: bool,
|
|
114
|
+
pop_headers_kwarg: PopKwargType,
|
|
115
|
+
pop_params_kwarg: PopKwargType,
|
|
116
|
+
) -> List[str]:
|
|
106
117
|
retval = []
|
|
118
|
+
def append_pop_kwarg(key: str, pop_type: PopKwargType) -> None:
|
|
119
|
+
if PopKwargType.CASE_INSENSITIVE == pop_type:
|
|
120
|
+
retval.append(f'_{key} = case_insensitive_dict(kwargs.pop("{key}", {{}}) or {{}})')
|
|
121
|
+
elif PopKwargType.SIMPLE == pop_type:
|
|
122
|
+
retval.append(f'_{key} = kwargs.pop("{key}", {{}}) or {{}}')
|
|
123
|
+
append_pop_kwarg("headers", pop_headers_kwarg)
|
|
124
|
+
append_pop_kwarg("params", pop_params_kwarg)
|
|
125
|
+
if pop_headers_kwarg != PopKwargType.NO or pop_params_kwarg != PopKwargType.NO:
|
|
126
|
+
retval.append("")
|
|
107
127
|
for kwarg in kwargs_to_pop:
|
|
108
128
|
if kwarg.has_default_value:
|
|
129
|
+
default_value = kwarg.default_value_declaration
|
|
130
|
+
if check_kwarg_dict and (kwarg.location in [ParameterLocation.Header, ParameterLocation.Query]):
|
|
131
|
+
kwarg_dict = "headers" if kwarg.location == ParameterLocation.Header else "params"
|
|
132
|
+
default_value = f"_{kwarg_dict}.pop('{kwarg.rest_api_name}', {default_value})"
|
|
109
133
|
retval.append(
|
|
110
134
|
f"{kwarg.serialized_name} = kwargs.pop('{kwarg.serialized_name}', "
|
|
111
|
-
+ f"{
|
|
135
|
+
+ f"{default_value}) # type: {kwarg.type_annotation(is_operation_file=True)}"
|
|
112
136
|
)
|
|
113
137
|
else:
|
|
138
|
+
type_annot = kwarg.type_annotation(is_operation_file=True)
|
|
114
139
|
retval.append(
|
|
115
|
-
f"{kwarg.serialized_name} = kwargs.pop('{kwarg.serialized_name}') # type: {
|
|
140
|
+
f"{kwarg.serialized_name} = kwargs.pop('{kwarg.serialized_name}') # type: {type_annot}"
|
|
116
141
|
)
|
|
117
142
|
return retval
|
|
@@ -35,8 +35,8 @@ class {{ code_model.class_name }}Configuration(Configuration): # pylint: disabl
|
|
|
35
35
|
{% if serializer.set_constants() %}
|
|
36
36
|
{{ op_tools.serialize(serializer.set_constants()) | indent(8) -}}
|
|
37
37
|
{% endif %}
|
|
38
|
-
{% if code_model.options['credential'] and code_model.credential_schema_policy.credential_scopes is defined %}
|
|
39
|
-
self.credential_scopes = kwargs.pop('credential_scopes', {{ code_model.credential_schema_policy.credential_scopes }})
|
|
38
|
+
{% if code_model.options['credential'] and code_model.credential_model.credential_schema_policy.credential_scopes is defined %}
|
|
39
|
+
self.credential_scopes = kwargs.pop('credential_scopes', {{ code_model.credential_model.credential_schema_policy.credential_scopes }})
|
|
40
40
|
{% endif %}
|
|
41
41
|
kwargs.setdefault('sdk_moniker', '{{ sdk_moniker }}/{}'.format(VERSION))
|
|
42
42
|
self._configure(**kwargs)
|
|
@@ -59,10 +59,10 @@ class {{ code_model.class_name }}Configuration(Configuration): # pylint: disabl
|
|
|
59
59
|
self.authentication_policy = kwargs.get('authentication_policy')
|
|
60
60
|
{% if code_model.options['credential'] %}
|
|
61
61
|
{# only adding this if credential_scopes is not passed during code generation #}
|
|
62
|
-
{% if code_model.credential_schema_policy.credential_scopes is defined and code_model.credential_schema_policy.credential_scopes|length == 0 %}
|
|
62
|
+
{% if code_model.credential_model.credential_schema_policy.credential_scopes is defined and code_model.credential_model.credential_schema_policy.credential_scopes|length == 0 %}
|
|
63
63
|
if not self.credential_scopes and not self.authentication_policy:
|
|
64
64
|
raise ValueError("You must provide either credential_scopes or authentication_policy as kwargs")
|
|
65
65
|
{% endif %}
|
|
66
66
|
if self.credential and not self.authentication_policy:
|
|
67
|
-
self.authentication_policy = {{ code_model.credential_schema_policy.call(async_mode) }}
|
|
67
|
+
self.authentication_policy = {{ code_model.credential_model.credential_schema_policy.call(async_mode) }}
|
|
68
68
|
{% endif %}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
class {{ enum.name }}(
|
|
2
|
+
class {{ enum.name }}({{ enum.enum_type.type_annotation() }}, Enum, metaclass=CaseInsensitiveEnumMeta):
|
|
3
3
|
{% if enum.description %}
|
|
4
4
|
"""{{ enum.description | wordwrap(width=95, break_long_words=False, break_on_hyphens=False, wrapstring='\n ') }}
|
|
5
5
|
"""
|
|
@@ -1,15 +1,18 @@
|
|
|
1
|
+
{% import 'keywords.jinja2' as keywords %}
|
|
1
2
|
# coding=utf-8
|
|
2
3
|
{{ code_model.options['license_header'] }}
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
{% if code_model.rest.request_builders %}
|
|
6
|
+
from .{{ code_model.service_client.filename }} import {{ code_model.class_name }}
|
|
7
|
+
{% endif %}
|
|
5
8
|
{% if not async_mode and code_model.options['package_version']%}
|
|
6
9
|
from ._version import VERSION
|
|
7
10
|
|
|
8
11
|
__version__ = VERSION
|
|
9
12
|
{% endif %}
|
|
10
|
-
__all__ = ['{{ code_model.class_name }}']
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
{{ keywords.patch_imports(try_except=True) }}
|
|
15
|
+
__all__ = [{{("'" + code_model.class_name + "'") if code_model.rest.request_builders else ""}}]
|
|
16
|
+
{{ keywords.extend_all }}
|
|
17
|
+
|
|
18
|
+
_patch_sdk()
|
|
@@ -3,4 +3,17 @@
|
|
|
3
3
|
{% set await = "await " if async_mode else "" %}
|
|
4
4
|
{% set async_class = "Async" if async_mode else "" %}
|
|
5
5
|
{% macro escape_str(s) %}'{{ s|replace("'", "\\'") }}'{% endmacro %}
|
|
6
|
-
{% set kwargs_declaration = "**kwargs: Any" if async_mode else "**kwargs # type: Any" %}
|
|
6
|
+
{% set kwargs_declaration = "**kwargs: Any" if async_mode else "**kwargs # type: Any" %}
|
|
7
|
+
{% set extend_all = "__all__.extend([p for p in _patch_all if p not in __all__])" %}
|
|
8
|
+
{% macro patch_imports(try_except=False) %}
|
|
9
|
+
{% set indentation = " " if try_except else "" %}
|
|
10
|
+
{% if try_except %}
|
|
11
|
+
try:
|
|
12
|
+
{% endif %}
|
|
13
|
+
{{ indentation }}from ._patch import __all__ as _patch_all
|
|
14
|
+
{{ indentation }}from ._patch import * # type: ignore # pylint: disable=unused-wildcard-import
|
|
15
|
+
{% if try_except %}
|
|
16
|
+
except ImportError:
|
|
17
|
+
_patch_all = []
|
|
18
|
+
{% endif %}
|
|
19
|
+
from ._patch import patch_sdk as _patch_sdk{% endmacro %}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
{% endif %}
|
|
7
7
|
{{ operation_serializer.method_signature_and_response_type_annotation(operation) }}
|
|
8
8
|
{{ op_tools.description(operation, operation_serializer) | indent -}}
|
|
9
|
-
{% if
|
|
9
|
+
{% if operation_serializer.pop_kwargs_from_signature(operation) %}
|
|
10
10
|
{{ op_tools.serialize(operation_serializer.pop_kwargs_from_signature(operation)) | indent }}
|
|
11
11
|
{%- endif %}
|
|
12
12
|
{{ op_tools.serialize(operation_serializer.initial_call(operation)) | indent }}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
{% endif %}
|
|
8
8
|
{{ operation_serializer.method_signature_and_response_type_annotation(operation) }}
|
|
9
9
|
{{ op_tools.description(operation, operation_serializer) | indent }}
|
|
10
|
-
{% if
|
|
10
|
+
{% if operation_serializer.pop_kwargs_from_signature(operation) %}
|
|
11
11
|
{{ op_tools.serialize(operation_serializer.pop_kwargs_from_signature(operation)) | indent }}
|
|
12
12
|
{% endif %}
|
|
13
13
|
{{ op_tools.serialize(operation_serializer.set_up_params_for_pager(operation)) | indent }}
|