@autorest/python 5.16.0 → 5.17.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 +43 -3
- package/README.md +30 -4
- package/autorest/__init__.py +1 -1
- package/autorest/codegen/__init__.py +48 -209
- package/autorest/codegen/models/__init__.py +116 -83
- package/autorest/codegen/models/base_builder.py +49 -88
- package/autorest/codegen/models/base_model.py +1 -1
- package/autorest/codegen/models/{base_schema.py → base_type.py} +56 -40
- package/autorest/codegen/models/client.py +157 -48
- package/autorest/codegen/models/code_model.py +108 -254
- package/autorest/codegen/models/combined_type.py +107 -0
- package/autorest/codegen/models/{constant_schema.py → constant_type.py} +49 -40
- package/autorest/codegen/models/credential_types.py +224 -0
- package/autorest/codegen/models/{dictionary_schema.py → dictionary_type.py} +41 -31
- package/autorest/codegen/models/enum_type.py +195 -0
- package/autorest/codegen/models/imports.py +23 -0
- package/autorest/codegen/models/list_type.py +134 -0
- package/autorest/codegen/models/lro_operation.py +77 -156
- package/autorest/codegen/models/lro_paging_operation.py +28 -11
- package/autorest/codegen/models/model_type.py +239 -0
- package/autorest/codegen/models/operation.py +303 -269
- package/autorest/codegen/models/operation_group.py +48 -89
- package/autorest/codegen/models/paging_operation.py +80 -123
- package/autorest/codegen/models/parameter.py +289 -396
- package/autorest/codegen/models/parameter_list.py +348 -360
- package/autorest/codegen/models/primitive_types.py +544 -0
- package/autorest/codegen/models/property.py +109 -139
- package/autorest/codegen/models/request_builder.py +105 -88
- package/autorest/codegen/models/request_builder_parameter.py +112 -100
- package/autorest/codegen/models/response.py +325 -0
- package/autorest/codegen/models/utils.py +12 -19
- package/autorest/codegen/serializers/__init__.py +46 -37
- package/autorest/codegen/serializers/builder_serializer.py +604 -1146
- package/autorest/codegen/serializers/client_serializer.py +83 -88
- package/autorest/codegen/serializers/general_serializer.py +5 -64
- package/autorest/codegen/serializers/import_serializer.py +7 -4
- package/autorest/codegen/serializers/metadata_serializer.py +15 -104
- package/autorest/codegen/serializers/model_base_serializer.py +40 -32
- package/autorest/codegen/serializers/model_generic_serializer.py +8 -6
- package/autorest/codegen/serializers/model_init_serializer.py +2 -4
- package/autorest/codegen/serializers/model_python3_serializer.py +22 -16
- package/autorest/codegen/serializers/operation_groups_serializer.py +4 -13
- package/autorest/codegen/serializers/parameter_serializer.py +174 -0
- package/autorest/codegen/serializers/request_builders_serializer.py +12 -29
- package/autorest/codegen/serializers/utils.py +0 -142
- package/autorest/codegen/templates/MANIFEST.in.jinja2 +1 -0
- package/autorest/codegen/templates/{service_client.py.jinja2 → client.py.jinja2} +7 -7
- package/autorest/codegen/templates/config.py.jinja2 +13 -13
- package/autorest/codegen/templates/enum.py.jinja2 +4 -4
- package/autorest/codegen/templates/enum_container.py.jinja2 +1 -1
- package/autorest/codegen/templates/init.py.jinja2 +2 -2
- package/autorest/codegen/templates/lro_operation.py.jinja2 +4 -1
- package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +4 -1
- package/autorest/codegen/templates/metadata.json.jinja2 +33 -33
- package/autorest/codegen/templates/model.py.jinja2 +23 -24
- package/autorest/codegen/templates/model_container.py.jinja2 +2 -1
- package/autorest/codegen/templates/model_init.py.jinja2 +3 -5
- package/autorest/codegen/templates/operation.py.jinja2 +6 -8
- package/autorest/codegen/templates/operation_group.py.jinja2 +7 -7
- package/autorest/codegen/templates/operation_groups_container.py.jinja2 +1 -1
- package/autorest/codegen/templates/operation_tools.jinja2 +8 -2
- package/autorest/codegen/templates/paging_operation.py.jinja2 +2 -2
- package/autorest/codegen/templates/request_builder.py.jinja2 +13 -11
- package/autorest/codegen/templates/setup.py.jinja2 +9 -3
- package/autorest/codegen/templates/vendor.py.jinja2 +1 -1
- package/autorest/jsonrpc/server.py +15 -3
- package/autorest/m4reformatter/__init__.py +1108 -0
- package/autorest/multiapi/models/code_model.py +1 -1
- package/autorest/multiapi/serializers/__init__.py +4 -4
- package/autorest/multiapi/templates/multiapi_config.py.jinja2 +3 -3
- package/autorest/multiapi/templates/multiapi_init.py.jinja2 +2 -2
- package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +3 -3
- package/autorest/multiapi/templates/multiapi_service_client.py.jinja2 +9 -9
- package/autorest/postprocess/__init__.py +202 -0
- package/autorest/postprocess/get_all.py +19 -0
- package/autorest/postprocess/venvtools.py +73 -0
- package/autorest/preprocess/__init__.py +209 -0
- package/autorest/preprocess/helpers.py +54 -0
- package/autorest/{namer → preprocess}/python_mappings.py +21 -16
- package/package.json +2 -2
- package/autorest/codegen/models/credential_model.py +0 -55
- package/autorest/codegen/models/credential_schema.py +0 -95
- package/autorest/codegen/models/credential_schema_policy.py +0 -73
- package/autorest/codegen/models/enum_schema.py +0 -225
- package/autorest/codegen/models/list_schema.py +0 -135
- package/autorest/codegen/models/object_schema.py +0 -303
- package/autorest/codegen/models/primitive_schemas.py +0 -495
- package/autorest/codegen/models/request_builder_parameter_list.py +0 -249
- package/autorest/codegen/models/schema_request.py +0 -55
- package/autorest/codegen/models/schema_response.py +0 -141
- package/autorest/namer/__init__.py +0 -23
- package/autorest/namer/name_converter.py +0 -509
|
@@ -3,13 +3,13 @@
|
|
|
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
|
|
6
|
+
from typing import Any, Dict, Optional, TYPE_CHECKING, List
|
|
7
7
|
|
|
8
8
|
from .base_model import BaseModel
|
|
9
|
-
from .
|
|
9
|
+
from .constant_type import ConstantType
|
|
10
|
+
from .base_type import BaseType
|
|
10
11
|
from .imports import FileImport, ImportType, TypingSection
|
|
11
|
-
from .
|
|
12
|
-
from .enum_schema import EnumSchema
|
|
12
|
+
from .utils import add_to_description, add_to_pylint_disable
|
|
13
13
|
|
|
14
14
|
if TYPE_CHECKING:
|
|
15
15
|
from .code_model import CodeModel
|
|
@@ -20,173 +20,143 @@ class Property(BaseModel): # pylint: disable=too-many-instance-attributes
|
|
|
20
20
|
self,
|
|
21
21
|
yaml_data: Dict[str, Any],
|
|
22
22
|
code_model: "CodeModel",
|
|
23
|
-
|
|
24
|
-
schema: BaseSchema,
|
|
25
|
-
original_swagger_name: str,
|
|
26
|
-
*,
|
|
27
|
-
flattened_names: Optional[List[str]] = None,
|
|
28
|
-
description: Optional[str] = None,
|
|
29
|
-
client_default_value: Optional[Any] = None,
|
|
23
|
+
type: BaseType,
|
|
30
24
|
) -> None:
|
|
31
25
|
super().__init__(yaml_data, code_model)
|
|
32
|
-
self.
|
|
33
|
-
self.
|
|
34
|
-
self.
|
|
35
|
-
self.
|
|
36
|
-
|
|
37
|
-
self.required: bool = yaml_data.get("required", False)
|
|
38
|
-
self.readonly: bool = yaml_data.get("readOnly", False)
|
|
26
|
+
self.rest_api_name: str = self.yaml_data["restApiName"]
|
|
27
|
+
self.client_name: str = self.yaml_data["clientName"]
|
|
28
|
+
self.type = type
|
|
29
|
+
self.optional: bool = self.yaml_data["optional"]
|
|
30
|
+
self.readonly: bool = self.yaml_data.get("readonly", False)
|
|
39
31
|
self.is_discriminator: bool = yaml_data.get("isDiscriminator", False)
|
|
40
|
-
self.client_default_value =
|
|
41
|
-
self.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
32
|
+
self.client_default_value = yaml_data.get("clientDefaultValue", None)
|
|
33
|
+
if self.client_default_value is None:
|
|
34
|
+
self.client_default_value = self.type.client_default_value
|
|
35
|
+
self.flattened_names: List[str] = yaml_data.get("flattenedNames", [])
|
|
36
|
+
|
|
37
|
+
@property
|
|
38
|
+
def pylint_disable(self) -> str:
|
|
39
|
+
retval: str = ""
|
|
40
|
+
if self.yaml_data.get("pylintDisable"):
|
|
41
|
+
retval = add_to_pylint_disable(retval, self.yaml_data["pylintDisable"])
|
|
42
|
+
return retval
|
|
43
|
+
|
|
44
|
+
def description(self, *, is_operation_file: bool) -> str:
|
|
45
|
+
from .model_type import ModelType
|
|
46
|
+
|
|
47
|
+
description = self.yaml_data["description"]
|
|
48
|
+
if not (self.optional or self.client_default_value):
|
|
49
|
+
description = add_to_description(description, "Required.")
|
|
50
|
+
# don't want model type documentation as part of property doc
|
|
51
|
+
type_description = (
|
|
52
|
+
""
|
|
53
|
+
if isinstance(self.type, ModelType)
|
|
54
|
+
else self.type.description(is_operation_file=is_operation_file)
|
|
48
55
|
)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if self.
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
else:
|
|
59
|
-
description = "Required. "
|
|
60
|
-
elif isinstance(self.schema, ConstantSchema):
|
|
61
|
-
description += (
|
|
62
|
-
f" The only acceptable values to pass in are None and {self.constant_declaration}. "
|
|
63
|
-
+ f"The default value is {self.default_value_declaration}."
|
|
64
|
-
)
|
|
65
|
-
if self.is_discriminator:
|
|
66
|
-
description += "Constant filled by server. "
|
|
67
|
-
if isinstance(self.schema, EnumSchema):
|
|
68
|
-
values = [
|
|
69
|
-
self.schema.enum_type.get_declaration(v.value)
|
|
70
|
-
for v in self.schema.values
|
|
71
|
-
]
|
|
72
|
-
if description and description[-1] != " ":
|
|
73
|
-
description += " "
|
|
74
|
-
description += "Known values are: {}.".format(", ".join(values))
|
|
75
|
-
if self.schema.default_value:
|
|
76
|
-
description += f' Default value: "{self.schema.default_value}".'
|
|
77
|
-
return description
|
|
56
|
+
return add_to_description(description, type_description)
|
|
57
|
+
|
|
58
|
+
@property
|
|
59
|
+
def client_default_value_declaration(self) -> str:
|
|
60
|
+
if self.client_default_value is not None:
|
|
61
|
+
return self.type.get_declaration(self.client_default_value)
|
|
62
|
+
if self.type.client_default_value is not None:
|
|
63
|
+
return self.type.get_declaration(self.type.client_default_value)
|
|
64
|
+
return "None"
|
|
78
65
|
|
|
79
66
|
@property
|
|
80
67
|
def constant(self) -> bool:
|
|
81
68
|
# this bool doesn't consider you to be constant if you are a discriminator
|
|
82
69
|
# you also have to be required to be considered a constant
|
|
83
70
|
return (
|
|
84
|
-
isinstance(self.
|
|
85
|
-
and self.
|
|
71
|
+
isinstance(self.type, ConstantType)
|
|
72
|
+
and not self.optional
|
|
86
73
|
and not self.is_discriminator
|
|
87
74
|
)
|
|
88
75
|
|
|
89
76
|
@property
|
|
90
|
-
def
|
|
91
|
-
|
|
92
|
-
|
|
77
|
+
def is_input(self):
|
|
78
|
+
return not (self.constant or self.readonly or self.is_discriminator)
|
|
79
|
+
|
|
80
|
+
@property
|
|
81
|
+
def serialization_type(self) -> str:
|
|
82
|
+
return self.type.serialization_type
|
|
83
|
+
|
|
84
|
+
def type_annotation(self, *, is_operation_file: bool = False) -> str:
|
|
85
|
+
if self.optional and self.client_default_value is None:
|
|
86
|
+
return f"Optional[{self.type.type_annotation(is_operation_file=is_operation_file)}]"
|
|
87
|
+
return self.type.type_annotation(is_operation_file=is_operation_file)
|
|
88
|
+
|
|
89
|
+
def get_json_template_representation(
|
|
90
|
+
self,
|
|
91
|
+
*,
|
|
92
|
+
optional: bool = True, # pylint: disable=unused-argument
|
|
93
|
+
client_default_value_declaration: Optional[str] = None,
|
|
94
|
+
description: Optional[str] = None,
|
|
95
|
+
) -> Any:
|
|
96
|
+
if self.client_default_value:
|
|
97
|
+
client_default_value_declaration = self.type.get_declaration(
|
|
98
|
+
self.client_default_value
|
|
99
|
+
)
|
|
100
|
+
if self.description(is_operation_file=True):
|
|
101
|
+
description = self.description(is_operation_file=True)
|
|
102
|
+
return self.type.get_json_template_representation(
|
|
103
|
+
optional=self.optional,
|
|
104
|
+
client_default_value_declaration=client_default_value_declaration,
|
|
105
|
+
description=description,
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
@property
|
|
109
|
+
def validation(self) -> Optional[Dict[str, Any]]:
|
|
110
|
+
retval: Dict[str, Any] = {}
|
|
111
|
+
if not self.optional:
|
|
93
112
|
retval["required"] = True
|
|
94
113
|
if self.readonly:
|
|
95
114
|
retval["readonly"] = True
|
|
96
115
|
if self.constant:
|
|
97
116
|
retval["constant"] = True
|
|
98
|
-
|
|
99
|
-
validation_map_from_schema = cast(
|
|
100
|
-
Dict[str, Union[bool, int, str]], self.schema.validation_map
|
|
101
|
-
)
|
|
102
|
-
retval.update(validation_map_from_schema)
|
|
117
|
+
retval.update(self.type.validation or {})
|
|
103
118
|
return retval or None
|
|
104
119
|
|
|
105
120
|
@property
|
|
106
|
-
def
|
|
107
|
-
"""Return the RestAPI name correctly escaped for serialization."""
|
|
121
|
+
def attribute_map(self) -> str:
|
|
108
122
|
if self.flattened_names:
|
|
109
|
-
|
|
110
|
-
|
|
123
|
+
attribute_key = ".".join(
|
|
124
|
+
n.replace(".", "\\\\.") for n in self.flattened_names
|
|
125
|
+
)
|
|
126
|
+
else:
|
|
127
|
+
attribute_key = self.rest_api_name.replace(".", "\\\\.")
|
|
128
|
+
if self.type.xml_serialization_ctxt:
|
|
129
|
+
xml_metadata = f", 'xml': {{{self.type.xml_serialization_ctxt}}}"
|
|
130
|
+
else:
|
|
131
|
+
xml_metadata = ""
|
|
132
|
+
return f'"{self.client_name}": {{"key": "{attribute_key}", "type": "{self.serialization_type}"{xml_metadata}}},'
|
|
133
|
+
|
|
134
|
+
def imports(self) -> FileImport:
|
|
135
|
+
from .model_type import ModelType
|
|
136
|
+
|
|
137
|
+
file_import = self.type.imports(is_operation_file=False)
|
|
138
|
+
if self.optional and self.client_default_value is None:
|
|
139
|
+
file_import.add_submodule_import("typing", "Optional", ImportType.STDLIB)
|
|
140
|
+
if isinstance(self.type, ModelType):
|
|
141
|
+
file_import.add_submodule_import(
|
|
142
|
+
"..",
|
|
143
|
+
"models",
|
|
144
|
+
ImportType.LOCAL,
|
|
145
|
+
TypingSection.TYPING,
|
|
146
|
+
alias="_models",
|
|
147
|
+
)
|
|
148
|
+
return file_import
|
|
111
149
|
|
|
112
150
|
@classmethod
|
|
113
151
|
def from_yaml(
|
|
114
152
|
cls,
|
|
115
153
|
yaml_data: Dict[str, Any],
|
|
116
154
|
code_model: "CodeModel",
|
|
117
|
-
*,
|
|
118
|
-
has_additional_properties: Optional[bool] = None,
|
|
119
155
|
) -> "Property":
|
|
120
|
-
from . import
|
|
156
|
+
from . import build_type # pylint: disable=import-outside-toplevel
|
|
121
157
|
|
|
122
|
-
name = yaml_data["language"]["python"]["name"]
|
|
123
|
-
if name == "additional_properties" and has_additional_properties:
|
|
124
|
-
name = "additional_properties1"
|
|
125
|
-
schema = build_schema(yaml_data=yaml_data["schema"], code_model=code_model)
|
|
126
158
|
return cls(
|
|
127
159
|
yaml_data=yaml_data,
|
|
128
160
|
code_model=code_model,
|
|
129
|
-
|
|
130
|
-
schema=schema,
|
|
131
|
-
original_swagger_name=yaml_data["serializedName"],
|
|
132
|
-
flattened_names=yaml_data.get("flattenedNames", []),
|
|
133
|
-
client_default_value=yaml_data.get("clientDefaultValue"),
|
|
161
|
+
type=build_type(yaml_data["type"], code_model),
|
|
134
162
|
)
|
|
135
|
-
|
|
136
|
-
@property
|
|
137
|
-
def is_input(self):
|
|
138
|
-
return not (self.constant or self.readonly or self.is_discriminator)
|
|
139
|
-
|
|
140
|
-
@property
|
|
141
|
-
def constant_declaration(self) -> str:
|
|
142
|
-
if self.schema:
|
|
143
|
-
if isinstance(self.schema, ConstantSchema):
|
|
144
|
-
return self.schema.get_declaration(self.schema.value)
|
|
145
|
-
raise ValueError(
|
|
146
|
-
"Trying to get constant declaration for a schema that is not ConstantSchema"
|
|
147
|
-
)
|
|
148
|
-
raise ValueError("Trying to get a declaration for a schema that doesn't exist")
|
|
149
|
-
|
|
150
|
-
@property
|
|
151
|
-
def serialization_type(self) -> str:
|
|
152
|
-
return self.schema.serialization_type
|
|
153
|
-
|
|
154
|
-
@property
|
|
155
|
-
def xml_metadata(self) -> str:
|
|
156
|
-
if self.schema.has_xml_serialization_ctxt:
|
|
157
|
-
return f", 'xml': {{{self.schema.xml_serialization_ctxt()}}}"
|
|
158
|
-
return ""
|
|
159
|
-
|
|
160
|
-
@property
|
|
161
|
-
def default_value(self) -> Any:
|
|
162
|
-
return self.client_default_value or self.schema.default_value
|
|
163
|
-
|
|
164
|
-
@property
|
|
165
|
-
def default_value_declaration(self) -> Any:
|
|
166
|
-
if self.client_default_value:
|
|
167
|
-
return self.schema.get_declaration(self.client_default_value)
|
|
168
|
-
return self.schema.default_value_declaration
|
|
169
|
-
|
|
170
|
-
def type_annotation(self, *, is_operation_file: bool = False) -> str:
|
|
171
|
-
if self.required:
|
|
172
|
-
return self.schema.type_annotation(is_operation_file=is_operation_file)
|
|
173
|
-
return f"Optional[{self.schema.type_annotation(is_operation_file=is_operation_file)}]"
|
|
174
|
-
|
|
175
|
-
def get_json_template_representation(self, **kwargs: Any) -> Any:
|
|
176
|
-
kwargs["optional"] = not self.required
|
|
177
|
-
if self.default_value:
|
|
178
|
-
kwargs["default_value_declaration"] = self.schema.get_declaration(
|
|
179
|
-
self.default_value
|
|
180
|
-
)
|
|
181
|
-
if self.description:
|
|
182
|
-
kwargs["description"] = self.description
|
|
183
|
-
return self.schema.get_json_template_representation(**kwargs)
|
|
184
|
-
|
|
185
|
-
def model_file_imports(self) -> FileImport:
|
|
186
|
-
file_import = self.schema.model_file_imports()
|
|
187
|
-
if not self.required:
|
|
188
|
-
file_import.add_submodule_import(
|
|
189
|
-
"typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL
|
|
190
|
-
)
|
|
191
|
-
file_import.merge(self.schema.model_file_imports())
|
|
192
|
-
return file_import
|
|
@@ -3,82 +3,79 @@
|
|
|
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, List, TypeVar, Optional, TYPE_CHECKING
|
|
7
6
|
import logging
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
from typing import (
|
|
8
|
+
Any,
|
|
9
|
+
Callable,
|
|
10
|
+
Dict,
|
|
11
|
+
List,
|
|
12
|
+
TypeVar,
|
|
13
|
+
TYPE_CHECKING,
|
|
14
|
+
Union,
|
|
15
|
+
Optional,
|
|
16
|
+
)
|
|
17
|
+
from abc import abstractmethod
|
|
18
|
+
|
|
19
|
+
from .base_builder import BaseBuilder
|
|
20
|
+
from .parameter_list import (
|
|
21
|
+
RequestBuilderParameterList,
|
|
22
|
+
OverloadedRequestBuilderParameterList,
|
|
23
|
+
)
|
|
14
24
|
from .imports import FileImport, ImportType, TypingSection
|
|
15
|
-
from .
|
|
25
|
+
from .request_builder_parameter import RequestBuilderMultipartBodyParameter
|
|
16
26
|
|
|
17
27
|
if TYPE_CHECKING:
|
|
18
28
|
from .code_model import CodeModel
|
|
19
29
|
|
|
20
30
|
_LOGGER = logging.getLogger(__name__)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
31
|
+
ParameterListType = TypeVar(
|
|
32
|
+
"ParameterListType",
|
|
33
|
+
bound=Union[RequestBuilderParameterList, OverloadedRequestBuilderParameterList],
|
|
34
|
+
)
|
|
24
35
|
|
|
25
36
|
|
|
26
|
-
class
|
|
37
|
+
class RequestBuilderBase(BaseBuilder[ParameterListType]):
|
|
27
38
|
def __init__(
|
|
28
39
|
self,
|
|
29
40
|
yaml_data: Dict[str, Any],
|
|
30
41
|
code_model: "CodeModel",
|
|
31
42
|
name: str,
|
|
32
|
-
|
|
33
|
-
method: str,
|
|
34
|
-
multipart: bool,
|
|
35
|
-
schema_requests: List[SchemaRequest],
|
|
36
|
-
parameters: RequestBuilderParameterList,
|
|
37
|
-
description: str,
|
|
38
|
-
summary: str,
|
|
39
|
-
responses: Optional[List[SchemaResponse]] = None,
|
|
43
|
+
parameters: ParameterListType,
|
|
40
44
|
*,
|
|
45
|
+
overloads: Optional[List["RequestBuilder"]] = None,
|
|
41
46
|
abstract: bool = False,
|
|
42
|
-
):
|
|
47
|
+
) -> None:
|
|
43
48
|
super().__init__(
|
|
44
|
-
yaml_data=yaml_data,
|
|
45
49
|
code_model=code_model,
|
|
50
|
+
yaml_data=yaml_data,
|
|
46
51
|
name=name,
|
|
47
|
-
description=description,
|
|
48
52
|
parameters=parameters,
|
|
49
|
-
|
|
50
|
-
schema_requests=schema_requests,
|
|
51
|
-
summary=summary,
|
|
53
|
+
overloads=overloads,
|
|
52
54
|
abstract=abstract,
|
|
53
55
|
want_tracing=False,
|
|
54
56
|
)
|
|
55
|
-
self.
|
|
56
|
-
self.
|
|
57
|
-
self.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
@property
|
|
69
|
-
def operation_group_name(self) -> str:
|
|
70
|
-
return self.yaml_data["language"]["python"]["operationGroupName"]
|
|
57
|
+
self.overloads: List["RequestBuilder"] = overloads or []
|
|
58
|
+
self.url: str = yaml_data["url"]
|
|
59
|
+
self.method: str = yaml_data["method"]
|
|
60
|
+
|
|
61
|
+
def response_type_annotation(self, **kwargs) -> str:
|
|
62
|
+
return "HttpRequest"
|
|
63
|
+
|
|
64
|
+
def response_docstring_text(self, **kwargs) -> str:
|
|
65
|
+
return (
|
|
66
|
+
"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/protocol/quickstart for how to "
|
|
68
|
+
+ "incorporate this response into your code flow."
|
|
69
|
+
)
|
|
71
70
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
return self.yaml_data["language"]["python"]["builderGroupName"]
|
|
71
|
+
def response_docstring_type(self, **kwargs) -> str:
|
|
72
|
+
return "~azure.core.rest.HttpRequest"
|
|
75
73
|
|
|
76
74
|
def imports(self) -> FileImport:
|
|
77
75
|
file_import = FileImport()
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
file_import.merge(parameter.imports())
|
|
76
|
+
if not self.abstract:
|
|
77
|
+
for parameter in self.parameters.method:
|
|
78
|
+
file_import.merge(parameter.imports(async_mode=False))
|
|
82
79
|
|
|
83
80
|
file_import.add_submodule_import(
|
|
84
81
|
"azure.core.rest",
|
|
@@ -90,9 +87,9 @@ class RequestBuilder(BaseBuilder):
|
|
|
90
87
|
relative_path = ".."
|
|
91
88
|
if (
|
|
92
89
|
not self.code_model.options["builders_visibility"] == "embedded"
|
|
93
|
-
and self.
|
|
90
|
+
and self.group_name
|
|
94
91
|
):
|
|
95
|
-
relative_path = "..." if self.
|
|
92
|
+
relative_path = "..." if self.group_name else ".."
|
|
96
93
|
file_import.add_submodule_import(
|
|
97
94
|
f"{relative_path}_vendor", "_format_url_section", ImportType.LOCAL
|
|
98
95
|
)
|
|
@@ -104,70 +101,90 @@ class RequestBuilder(BaseBuilder):
|
|
|
104
101
|
"typing", "Any", ImportType.STDLIB, typing_section=TypingSection.CONDITIONAL
|
|
105
102
|
)
|
|
106
103
|
file_import.add_submodule_import("msrest", "Serializer", ImportType.THIRDPARTY)
|
|
104
|
+
if (
|
|
105
|
+
self.overloads
|
|
106
|
+
and self.code_model.options["builders_visibility"] != "embedded"
|
|
107
|
+
):
|
|
108
|
+
file_import.add_submodule_import("typing", "overload", ImportType.STDLIB)
|
|
107
109
|
return file_import
|
|
108
110
|
|
|
109
|
-
@
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
111
|
+
@staticmethod
|
|
112
|
+
@abstractmethod
|
|
113
|
+
def parameter_list_type() -> Callable[
|
|
114
|
+
[Dict[str, Any], "CodeModel"], ParameterListType
|
|
115
|
+
]:
|
|
116
|
+
...
|
|
113
117
|
|
|
114
|
-
|
|
118
|
+
@classmethod
|
|
119
|
+
def from_yaml(cls, yaml_data: Dict[str, Any], code_model: "CodeModel"):
|
|
120
|
+
# when combine embedded builders into one operation file, we need to avoid duplicated build function name.
|
|
115
121
|
# So add operation group name is effective method
|
|
116
122
|
additional_mark = ""
|
|
117
123
|
if (
|
|
118
124
|
code_model.options["combine_operation_files"]
|
|
119
125
|
and code_model.options["builders_visibility"] == "embedded"
|
|
120
126
|
):
|
|
121
|
-
additional_mark = yaml_data["
|
|
127
|
+
additional_mark = yaml_data["groupName"]
|
|
122
128
|
names = [
|
|
123
129
|
"build",
|
|
124
130
|
additional_mark,
|
|
125
|
-
yaml_data["
|
|
131
|
+
yaml_data["name"],
|
|
126
132
|
"request",
|
|
127
133
|
]
|
|
128
134
|
name = "_".join([n for n in names if n])
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
SchemaRequest.from_yaml(yaml, code_model=code_model)
|
|
133
|
-
for yaml in yaml_data["requests"]
|
|
135
|
+
overloads = [
|
|
136
|
+
RequestBuilder.from_yaml(rb_yaml_data, code_model)
|
|
137
|
+
for rb_yaml_data in yaml_data.get("overloads", [])
|
|
134
138
|
]
|
|
135
|
-
parameters, multiple_content_type_parameters = create_parameters(
|
|
136
|
-
yaml_data, code_model, RequestBuilderParameter.from_yaml
|
|
137
|
-
)
|
|
138
|
-
parameter_list = RequestBuilderParameterList(
|
|
139
|
-
code_model, parameters + multiple_content_type_parameters, schema_requests
|
|
140
|
-
)
|
|
141
139
|
abstract = False
|
|
140
|
+
parameter_list = cls.parameter_list_type()(yaml_data, code_model)
|
|
142
141
|
if (
|
|
143
142
|
code_model.options["version_tolerant"]
|
|
144
|
-
|
|
145
|
-
|
|
143
|
+
and parameter_list.has_body
|
|
144
|
+
and isinstance(
|
|
145
|
+
parameter_list.body_parameter, RequestBuilderMultipartBodyParameter
|
|
146
|
+
)
|
|
147
|
+
):
|
|
146
148
|
_LOGGER.warning(
|
|
147
|
-
'Not going to generate
|
|
148
|
-
"
|
|
149
|
-
|
|
150
|
-
"
|
|
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",
|
|
151
153
|
name,
|
|
152
154
|
)
|
|
153
155
|
abstract = True
|
|
154
156
|
|
|
155
|
-
|
|
157
|
+
return cls(
|
|
156
158
|
yaml_data=yaml_data,
|
|
157
159
|
code_model=code_model,
|
|
158
160
|
name=name,
|
|
159
|
-
url=first_request["protocol"]["http"]["path"],
|
|
160
|
-
method=first_request["protocol"]["http"]["method"].upper(),
|
|
161
|
-
multipart=first_request["protocol"]["http"].get("multipart", False),
|
|
162
|
-
schema_requests=schema_requests,
|
|
163
161
|
parameters=parameter_list,
|
|
164
|
-
|
|
165
|
-
responses=[
|
|
166
|
-
SchemaResponse.from_yaml(yaml, code_model=code_model)
|
|
167
|
-
for yaml in yaml_data.get("responses", [])
|
|
168
|
-
],
|
|
169
|
-
summary=yaml_data["language"]["python"].get("summary"),
|
|
162
|
+
overloads=overloads,
|
|
170
163
|
abstract=abstract,
|
|
171
164
|
)
|
|
172
|
-
|
|
173
|
-
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
class RequestBuilder(RequestBuilderBase[RequestBuilderParameterList]):
|
|
168
|
+
@staticmethod
|
|
169
|
+
def parameter_list_type() -> Callable[
|
|
170
|
+
[Dict[str, Any], "CodeModel"], RequestBuilderParameterList
|
|
171
|
+
]:
|
|
172
|
+
return RequestBuilderParameterList.from_yaml
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
class OverloadedRequestBuilder(
|
|
176
|
+
RequestBuilderBase[OverloadedRequestBuilderParameterList]
|
|
177
|
+
):
|
|
178
|
+
@staticmethod
|
|
179
|
+
def parameter_list_type() -> Callable[
|
|
180
|
+
[Dict[str, Any], "CodeModel"], OverloadedRequestBuilderParameterList
|
|
181
|
+
]:
|
|
182
|
+
return OverloadedRequestBuilderParameterList.from_yaml
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def get_request_builder(
|
|
186
|
+
yaml_data: Dict[str, Any], code_model: "CodeModel"
|
|
187
|
+
) -> Union[RequestBuilder, OverloadedRequestBuilder]:
|
|
188
|
+
if yaml_data.get("overloads"):
|
|
189
|
+
return OverloadedRequestBuilder.from_yaml(yaml_data, code_model)
|
|
190
|
+
return RequestBuilder.from_yaml(yaml_data, code_model)
|