@autorest/python 6.13.7 → 6.13.9
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/autorest/codegen/__init__.py +2 -0
- package/autorest/codegen/models/code_model.py +1 -0
- package/autorest/codegen/models/constant_type.py +2 -2
- package/autorest/codegen/models/enum_type.py +4 -2
- package/autorest/codegen/models/model_type.py +3 -0
- package/autorest/codegen/models/operation.py +20 -1
- package/autorest/codegen/models/parameter.py +2 -2
- package/autorest/codegen/models/response.py +3 -1
- package/autorest/codegen/serializers/__init__.py +5 -0
- package/autorest/codegen/serializers/builder_serializer.py +17 -11
- package/autorest/codegen/serializers/general_serializer.py +37 -0
- package/autorest/codegen/templates/packaging_templates/README.md.jinja2 +1 -1
- package/autorest/codegen/templates/packaging_templates/setup.py.jinja2 +3 -3
- package/autorest/preprocess/__init__.py +17 -9
- package/package.json +1 -1
|
@@ -38,6 +38,7 @@ class OptionsRetriever:
|
|
|
38
38
|
"polymorphic-examples": 5,
|
|
39
39
|
"generate-sample": False,
|
|
40
40
|
"from-typespec": False,
|
|
41
|
+
"emit-cross-language-definition-file": False,
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
@property
|
|
@@ -333,6 +334,7 @@ class CodeGenerator(Plugin):
|
|
|
333
334
|
"from_typespec",
|
|
334
335
|
"flavor",
|
|
335
336
|
"company_name",
|
|
337
|
+
"emit_cross_language_definition_file",
|
|
336
338
|
]
|
|
337
339
|
return {f: getattr(self.options_retriever, f) for f in flags}
|
|
338
340
|
|
|
@@ -75,6 +75,7 @@ class CodeModel: # pylint: disable=too-many-public-methods, disable=too-many-in
|
|
|
75
75
|
self.named_unions: List[CombinedType] = [
|
|
76
76
|
t for t in self.types_map.values() if isinstance(t, CombinedType) and t.name
|
|
77
77
|
]
|
|
78
|
+
self.cross_language_package_id = self.yaml_data.get("crossLanguagePackageId")
|
|
78
79
|
|
|
79
80
|
@property
|
|
80
81
|
def has_form_data(self) -> bool:
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
6
|
import logging
|
|
7
|
-
from typing import Dict, Any, Optional, TYPE_CHECKING
|
|
7
|
+
from typing import Dict, Any, Optional, TYPE_CHECKING, Union
|
|
8
8
|
from .base import BaseType
|
|
9
9
|
from .imports import FileImport, ImportType, TypingSection
|
|
10
10
|
from .primitive_types import IntegerType, BinaryType, StringType, BooleanType
|
|
@@ -31,7 +31,7 @@ class ConstantType(BaseType):
|
|
|
31
31
|
yaml_data: Dict[str, Any],
|
|
32
32
|
code_model: "CodeModel",
|
|
33
33
|
value_type: BaseType,
|
|
34
|
-
value: Optional[str],
|
|
34
|
+
value: Optional[Union[str, int, float]],
|
|
35
35
|
) -> None:
|
|
36
36
|
super().__init__(yaml_data=yaml_data, code_model=code_model)
|
|
37
37
|
self.value_type = value_type
|
|
@@ -101,11 +101,10 @@ class EnumValue(BaseType):
|
|
|
101
101
|
"""
|
|
102
102
|
from . import build_type
|
|
103
103
|
|
|
104
|
-
enum_type = cast(EnumType, code_model.lookup_type(id(yaml_data["enumType"])))
|
|
105
104
|
return cls(
|
|
106
105
|
yaml_data=yaml_data,
|
|
107
106
|
code_model=code_model,
|
|
108
|
-
enum_type=
|
|
107
|
+
enum_type=cast(EnumType, build_type(yaml_data["enumType"], code_model)),
|
|
109
108
|
value_type=build_type(yaml_data["valueType"], code_model),
|
|
110
109
|
)
|
|
111
110
|
|
|
@@ -134,6 +133,9 @@ class EnumType(BaseType):
|
|
|
134
133
|
self.values = values
|
|
135
134
|
self.value_type = value_type
|
|
136
135
|
self.internal: bool = self.yaml_data.get("internal", False)
|
|
136
|
+
self.cross_language_definition_id: Optional[str] = self.yaml_data.get(
|
|
137
|
+
"crossLanguageDefinitionId"
|
|
138
|
+
)
|
|
137
139
|
|
|
138
140
|
def __lt__(self, other):
|
|
139
141
|
return self.name.lower() < other.name.lower()
|
|
@@ -75,6 +75,9 @@ class ModelType( # pylint: disable=abstract-method
|
|
|
75
75
|
self.internal: bool = self.yaml_data.get("internal", False)
|
|
76
76
|
self.snake_case_name: str = self.yaml_data["snakeCaseName"]
|
|
77
77
|
self.page_result_model: bool = self.yaml_data.get("pageResultModel", False)
|
|
78
|
+
self.cross_language_definition_id: Optional[str] = self.yaml_data.get(
|
|
79
|
+
"crossLanguageDefinitionId"
|
|
80
|
+
)
|
|
78
81
|
|
|
79
82
|
@property
|
|
80
83
|
def flattened_property(self) -> Optional[Property]:
|
|
@@ -54,7 +54,7 @@ def is_internal(target: Optional[BaseType]) -> bool:
|
|
|
54
54
|
return isinstance(target, ModelType) and target.base == "dpg" and target.internal
|
|
55
55
|
|
|
56
56
|
|
|
57
|
-
class OperationBase( # pylint: disable=too-many-public-methods
|
|
57
|
+
class OperationBase( # pylint: disable=too-many-public-methods,too-many-instance-attributes
|
|
58
58
|
Generic[ResponseType], BaseBuilder[ParameterList, List["Operation"]]
|
|
59
59
|
):
|
|
60
60
|
def __init__(
|
|
@@ -91,6 +91,9 @@ class OperationBase( # pylint: disable=too-many-public-methods
|
|
|
91
91
|
if self.internal:
|
|
92
92
|
self.name = "_" + self.name
|
|
93
93
|
self.has_etag: bool = self.yaml_data.get("hasEtag", False)
|
|
94
|
+
self.cross_language_definition_id: Optional[str] = self.yaml_data.get(
|
|
95
|
+
"crossLanguageDefinitionId"
|
|
96
|
+
)
|
|
94
97
|
|
|
95
98
|
@property
|
|
96
99
|
def has_form_data_body(self):
|
|
@@ -386,6 +389,18 @@ class OperationBase( # pylint: disable=too-many-public-methods
|
|
|
386
389
|
file_import.add_submodule_import(
|
|
387
390
|
"azure.mgmt.core.exceptions", "ARMErrorFormat", ImportType.SDKCORE
|
|
388
391
|
)
|
|
392
|
+
file_import.add_submodule_import(
|
|
393
|
+
"typing",
|
|
394
|
+
"Type",
|
|
395
|
+
ImportType.STDLIB,
|
|
396
|
+
)
|
|
397
|
+
file_import.add_mutable_mapping_import()
|
|
398
|
+
if self.non_default_error_status_codes:
|
|
399
|
+
file_import.add_submodule_import(
|
|
400
|
+
"typing",
|
|
401
|
+
"cast",
|
|
402
|
+
ImportType.STDLIB,
|
|
403
|
+
)
|
|
389
404
|
|
|
390
405
|
if self.has_kwargs_to_pop_with_default(
|
|
391
406
|
self.parameters.kwargs_to_pop, ParameterLocation.HEADER # type: ignore
|
|
@@ -478,6 +493,10 @@ class OperationBase( # pylint: disable=too-many-public-methods
|
|
|
478
493
|
)
|
|
479
494
|
if self.overloads:
|
|
480
495
|
file_import.add_submodule_import("typing", "overload", ImportType.STDLIB)
|
|
496
|
+
if self.non_default_errors and self.code_model.options["models_mode"] == "dpg":
|
|
497
|
+
file_import.add_submodule_import(
|
|
498
|
+
f"{relative_path}_model_base", "_deserialize", ImportType.LOCAL
|
|
499
|
+
)
|
|
481
500
|
return file_import
|
|
482
501
|
|
|
483
502
|
def get_response_from_status(
|
|
@@ -63,7 +63,7 @@ class _ParameterBase(
|
|
|
63
63
|
type: BaseType,
|
|
64
64
|
) -> None:
|
|
65
65
|
super().__init__(yaml_data, code_model)
|
|
66
|
-
self.wire_name: str = yaml_data
|
|
66
|
+
self.wire_name: str = yaml_data.get("wireName", "")
|
|
67
67
|
self.client_name: str = self.yaml_data["clientName"]
|
|
68
68
|
self.optional: bool = self.yaml_data["optional"]
|
|
69
69
|
self.location: ParameterLocation = self.yaml_data["location"]
|
|
@@ -373,7 +373,7 @@ class Parameter(_ParameterBase):
|
|
|
373
373
|
return ParameterMethodLocation.KEYWORD_ONLY
|
|
374
374
|
if self.grouper:
|
|
375
375
|
return ParameterMethodLocation.POSITIONAL
|
|
376
|
-
if self.constant:
|
|
376
|
+
if self.constant and self.wire_name != "Content-Type":
|
|
377
377
|
return ParameterMethodLocation.KWARG
|
|
378
378
|
if self.is_content_type:
|
|
379
379
|
if self.in_overload:
|
|
@@ -37,10 +37,12 @@ class ResponseHeader(BaseModel):
|
|
|
37
37
|
def from_yaml(
|
|
38
38
|
cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
|
|
39
39
|
) -> "ResponseHeader":
|
|
40
|
+
from . import build_type
|
|
41
|
+
|
|
40
42
|
return cls(
|
|
41
43
|
yaml_data=yaml_data,
|
|
42
44
|
code_model=code_model,
|
|
43
|
-
type=
|
|
45
|
+
type=build_type(yaml_data["type"], code_model),
|
|
44
46
|
)
|
|
45
47
|
|
|
46
48
|
|
|
@@ -522,6 +522,11 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
|
|
|
522
522
|
namespace_path / Path("_validation.py"),
|
|
523
523
|
general_serializer.serialize_validation_file(),
|
|
524
524
|
)
|
|
525
|
+
if self.code_model.options.get("emit_cross_language_definition_file"):
|
|
526
|
+
self.write_file(
|
|
527
|
+
namespace_path / Path("apiview_mapping_python.json"),
|
|
528
|
+
general_serializer.serialize_cross_language_definition_file(),
|
|
529
|
+
)
|
|
525
530
|
|
|
526
531
|
# Write the setup file
|
|
527
532
|
if self.code_model.options["basic_setup_py"]:
|
|
@@ -639,6 +639,7 @@ class _OperationSerializer(
|
|
|
639
639
|
discriminator_name = cast(
|
|
640
640
|
Property, polymorphic_subtypes[0].discriminator
|
|
641
641
|
).wire_name
|
|
642
|
+
retval.append("")
|
|
642
643
|
retval.append(
|
|
643
644
|
"# The response is polymorphic. The following are possible polymorphic "
|
|
644
645
|
f'responses based off discriminator "{discriminator_name}":'
|
|
@@ -1280,7 +1281,7 @@ class _OperationSerializer(
|
|
|
1280
1281
|
return retval
|
|
1281
1282
|
|
|
1282
1283
|
def error_map(self, builder: OperationType) -> List[str]:
|
|
1283
|
-
retval = ["error_map = {"]
|
|
1284
|
+
retval = ["error_map: MutableMapping[int, Type[HttpResponseError]] = {"]
|
|
1284
1285
|
if builder.non_default_errors:
|
|
1285
1286
|
if not 401 in builder.non_default_error_status_codes:
|
|
1286
1287
|
retval.append(" 401: ClientAuthenticationError,")
|
|
@@ -1308,30 +1309,35 @@ class _OperationSerializer(
|
|
|
1308
1309
|
for status_code in excep.status_codes:
|
|
1309
1310
|
if status_code == 401:
|
|
1310
1311
|
retval.append(
|
|
1311
|
-
" 401:
|
|
1312
|
-
|
|
1312
|
+
" 401: cast(Type[HttpResponseError], "
|
|
1313
|
+
"lambda response: ClientAuthenticationError(response=response"
|
|
1314
|
+
f"{error_model_str}{error_format_str})),"
|
|
1313
1315
|
)
|
|
1314
1316
|
elif status_code == 404:
|
|
1315
1317
|
retval.append(
|
|
1316
|
-
" 404:
|
|
1317
|
-
|
|
1318
|
+
" 404: cast(Type[HttpResponseError], "
|
|
1319
|
+
"lambda response: ResourceNotFoundError(response=response"
|
|
1320
|
+
f"{error_model_str}{error_format_str})),"
|
|
1318
1321
|
)
|
|
1319
1322
|
elif status_code == 409:
|
|
1320
1323
|
retval.append(
|
|
1321
|
-
" 409:
|
|
1322
|
-
|
|
1324
|
+
" 409: cast(Type[HttpResponseError], "
|
|
1325
|
+
"lambda response: ResourceExistsError(response=response"
|
|
1326
|
+
f"{error_model_str}{error_format_str})),"
|
|
1323
1327
|
)
|
|
1324
1328
|
elif status_code == 304:
|
|
1325
1329
|
retval.append(
|
|
1326
|
-
" 304:
|
|
1327
|
-
|
|
1330
|
+
" 304: cast(Type[HttpResponseError], "
|
|
1331
|
+
"lambda response: ResourceNotModifiedError(response=response"
|
|
1332
|
+
f"{error_model_str}{error_format_str})),"
|
|
1328
1333
|
)
|
|
1329
1334
|
elif not error_model_str and not error_format_str:
|
|
1330
1335
|
retval.append(f" {status_code}: HttpResponseError,")
|
|
1331
1336
|
else:
|
|
1332
1337
|
retval.append(
|
|
1333
|
-
f" {status_code}:
|
|
1334
|
-
|
|
1338
|
+
f" {status_code}: cast(Type[HttpResponseError], "
|
|
1339
|
+
"lambda response: HttpResponseError(response=response"
|
|
1340
|
+
f"{error_model_str}{error_format_str})),"
|
|
1335
1341
|
)
|
|
1336
1342
|
else:
|
|
1337
1343
|
retval.append(
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
# Licensed under the MIT License. See License.txt in the project root for
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
|
+
import json
|
|
6
7
|
from typing import Any, List
|
|
7
8
|
from jinja2 import Environment
|
|
8
9
|
from .import_serializer import FileImportSerializer, TypingSection
|
|
@@ -196,3 +197,39 @@ class GeneralSerializer(BaseSerializer):
|
|
|
196
197
|
def serialize_validation_file(self) -> str:
|
|
197
198
|
template = self.env.get_template("validation.py.jinja2")
|
|
198
199
|
return template.render(code_model=self.code_model)
|
|
200
|
+
|
|
201
|
+
def serialize_cross_language_definition_file(self) -> str:
|
|
202
|
+
cross_langauge_def_dict = {
|
|
203
|
+
f"{self.code_model.namespace}.models.{model.name}": model.cross_language_definition_id
|
|
204
|
+
for model in self.code_model.model_types
|
|
205
|
+
}
|
|
206
|
+
cross_langauge_def_dict.update(
|
|
207
|
+
{
|
|
208
|
+
f"{self.code_model.namespace}.models.{enum.name}": enum.cross_language_definition_id
|
|
209
|
+
for enum in self.code_model.enums
|
|
210
|
+
}
|
|
211
|
+
)
|
|
212
|
+
cross_langauge_def_dict.update(
|
|
213
|
+
{
|
|
214
|
+
(
|
|
215
|
+
f"{self.code_model.namespace}.{client.name}."
|
|
216
|
+
+ (
|
|
217
|
+
""
|
|
218
|
+
if operation_group.is_mixin
|
|
219
|
+
else f"{operation_group.property_name}."
|
|
220
|
+
)
|
|
221
|
+
+ f"{operation.name}"
|
|
222
|
+
): operation.cross_language_definition_id
|
|
223
|
+
for client in self.code_model.clients
|
|
224
|
+
for operation_group in client.operation_groups
|
|
225
|
+
for operation in operation_group.operations
|
|
226
|
+
if not operation.name.startswith("_")
|
|
227
|
+
}
|
|
228
|
+
)
|
|
229
|
+
return json.dumps(
|
|
230
|
+
{
|
|
231
|
+
"CrossLanguagePackageId": self.code_model.cross_language_package_id,
|
|
232
|
+
"CrossLanguageDefinitionId": cross_langauge_def_dict,
|
|
233
|
+
},
|
|
234
|
+
indent=4,
|
|
235
|
+
)
|
|
@@ -87,12 +87,12 @@ setup(
|
|
|
87
87
|
{% if code_model.is_legacy %}
|
|
88
88
|
"msrest>=0.7.1",
|
|
89
89
|
{% else %}
|
|
90
|
-
"isodate
|
|
90
|
+
"isodate>=0.6.1",
|
|
91
91
|
{% endif %}
|
|
92
92
|
{% if azure_arm %}
|
|
93
|
-
"azure-mgmt-core
|
|
93
|
+
"azure-mgmt-core>=1.3.2",
|
|
94
94
|
{% elif code_model.is_azure_flavor %}
|
|
95
|
-
"azure-core
|
|
95
|
+
"azure-core>=1.30.0",
|
|
96
96
|
{% else %}
|
|
97
97
|
"corehttp[requests]",
|
|
98
98
|
{% endif %}
|
|
@@ -25,15 +25,18 @@ def update_overload_section(
|
|
|
25
25
|
yaml_data: Dict[str, Any],
|
|
26
26
|
section: str,
|
|
27
27
|
):
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
overload_s
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
overload_h
|
|
28
|
+
try:
|
|
29
|
+
for overload_s, original_s in zip(overload[section], yaml_data[section]):
|
|
30
|
+
if overload_s.get("type"):
|
|
31
|
+
overload_s["type"] = original_s["type"]
|
|
32
|
+
if overload_s.get("headers"):
|
|
33
|
+
for overload_h, original_h in zip(
|
|
34
|
+
overload_s["headers"], original_s["headers"]
|
|
35
|
+
):
|
|
36
|
+
if overload_h.get("type"):
|
|
37
|
+
overload_h["type"] = original_h["type"]
|
|
38
|
+
except KeyError as exc:
|
|
39
|
+
raise ValueError(overload["name"]) from exc
|
|
37
40
|
|
|
38
41
|
|
|
39
42
|
def add_overload(
|
|
@@ -390,6 +393,11 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
|
|
|
390
393
|
and wire_name_lower in HEADERS_CONVERT_IN_METHOD
|
|
391
394
|
):
|
|
392
395
|
headers_convert(yaml_data, HEADERS_CONVERT_IN_METHOD[wire_name_lower])
|
|
396
|
+
if (
|
|
397
|
+
wire_name_lower in ["$host", "content-type", "accept"]
|
|
398
|
+
and yaml_data["type"]["type"] == "constant"
|
|
399
|
+
):
|
|
400
|
+
yaml_data["clientDefaultValue"] = yaml_data["type"]["value"]
|
|
393
401
|
|
|
394
402
|
def update_operation(
|
|
395
403
|
self,
|