@autorest/python 5.16.0 → 5.19.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 +79 -4
- package/README.md +30 -4
- package/autorest/__init__.py +1 -1
- package/autorest/codegen/__init__.py +55 -211
- 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} +61 -39
- package/autorest/codegen/models/client.py +165 -53
- package/autorest/codegen/models/code_model.py +122 -257
- 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_type.py +131 -0
- package/autorest/codegen/models/enum_type.py +195 -0
- package/autorest/codegen/models/imports.py +80 -2
- package/autorest/codegen/models/list_type.py +149 -0
- package/autorest/codegen/models/lro_operation.py +79 -156
- package/autorest/codegen/models/lro_paging_operation.py +28 -11
- package/autorest/codegen/models/model_type.py +262 -0
- package/autorest/codegen/models/operation.py +331 -298
- package/autorest/codegen/models/operation_group.py +54 -91
- package/autorest/codegen/models/paging_operation.py +82 -123
- package/autorest/codegen/models/parameter.py +289 -396
- package/autorest/codegen/models/parameter_list.py +355 -360
- package/autorest/codegen/models/primitive_types.py +544 -0
- package/autorest/codegen/models/property.py +123 -139
- package/autorest/codegen/models/request_builder.py +130 -102
- 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 +55 -37
- package/autorest/codegen/serializers/builder_serializer.py +695 -1144
- package/autorest/codegen/serializers/client_serializer.py +92 -89
- package/autorest/codegen/serializers/general_serializer.py +15 -69
- 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 +49 -36
- 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 +7 -13
- package/autorest/codegen/serializers/parameter_serializer.py +174 -0
- package/autorest/codegen/serializers/request_builders_serializer.py +13 -30
- package/autorest/codegen/serializers/utils.py +0 -140
- package/autorest/codegen/templates/MANIFEST.in.jinja2 +1 -0
- package/autorest/codegen/templates/{service_client.py.jinja2 → client.py.jinja2} +10 -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 +21 -8
- package/autorest/codegen/templates/operation_groups_container.py.jinja2 +2 -2
- package/autorest/codegen/templates/operation_tools.jinja2 +11 -3
- package/autorest/codegen/templates/paging_operation.py.jinja2 +2 -2
- package/autorest/codegen/templates/request_builder.py.jinja2 +10 -15
- package/autorest/codegen/templates/request_builders.py.jinja2 +1 -1
- package/autorest/codegen/templates/serialization.py.jinja2 +2006 -0
- package/autorest/codegen/templates/setup.py.jinja2 +13 -3
- package/autorest/codegen/templates/vendor.py.jinja2 +11 -1
- package/autorest/jsonrpc/server.py +15 -3
- package/autorest/m4reformatter/__init__.py +1126 -0
- package/autorest/multiapi/models/client.py +12 -2
- package/autorest/multiapi/models/code_model.py +1 -1
- package/autorest/multiapi/serializers/__init__.py +18 -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 +4 -4
- 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 +210 -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/dictionary_schema.py +0 -106
- 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,16 +3,17 @@
|
|
|
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
|
|
16
|
+
from .model_type import ModelType
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
class Property(BaseModel): # pylint: disable=too-many-instance-attributes
|
|
@@ -20,173 +21,156 @@ class Property(BaseModel): # pylint: disable=too-many-instance-attributes
|
|
|
20
21
|
self,
|
|
21
22
|
yaml_data: Dict[str, Any],
|
|
22
23
|
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,
|
|
24
|
+
type: BaseType,
|
|
30
25
|
) -> None:
|
|
31
26
|
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)
|
|
27
|
+
self.rest_api_name: str = self.yaml_data["restApiName"]
|
|
28
|
+
self.client_name: str = self.yaml_data["clientName"]
|
|
29
|
+
self.type = type
|
|
30
|
+
self.optional: bool = self.yaml_data["optional"]
|
|
31
|
+
self.readonly: bool = self.yaml_data.get("readonly", False)
|
|
39
32
|
self.is_discriminator: bool = yaml_data.get("isDiscriminator", False)
|
|
40
|
-
self.client_default_value =
|
|
41
|
-
self.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
33
|
+
self.client_default_value = yaml_data.get("clientDefaultValue", None)
|
|
34
|
+
if self.client_default_value is None:
|
|
35
|
+
self.client_default_value = self.type.client_default_value
|
|
36
|
+
self.flattened_names: List[str] = yaml_data.get("flattenedNames", [])
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def pylint_disable(self) -> str:
|
|
40
|
+
retval: str = ""
|
|
41
|
+
if self.yaml_data.get("pylintDisable"):
|
|
42
|
+
retval = add_to_pylint_disable(retval, self.yaml_data["pylintDisable"])
|
|
43
|
+
return retval
|
|
44
|
+
|
|
45
|
+
def description(self, *, is_operation_file: bool) -> str:
|
|
46
|
+
from .model_type import ModelType
|
|
47
|
+
|
|
48
|
+
description = self.yaml_data["description"]
|
|
49
|
+
if not (self.optional or self.client_default_value):
|
|
50
|
+
description = add_to_description(description, "Required.")
|
|
51
|
+
# don't want model type documentation as part of property doc
|
|
52
|
+
type_description = (
|
|
53
|
+
""
|
|
54
|
+
if isinstance(self.type, ModelType)
|
|
55
|
+
else self.type.description(is_operation_file=is_operation_file)
|
|
48
56
|
)
|
|
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
|
|
57
|
+
return add_to_description(description, type_description)
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def client_default_value_declaration(self) -> str:
|
|
61
|
+
if self.client_default_value is not None:
|
|
62
|
+
return self.type.get_declaration(self.client_default_value)
|
|
63
|
+
if self.type.client_default_value is not None:
|
|
64
|
+
return self.type.get_declaration(self.type.client_default_value)
|
|
65
|
+
return "None"
|
|
78
66
|
|
|
79
67
|
@property
|
|
80
68
|
def constant(self) -> bool:
|
|
81
69
|
# this bool doesn't consider you to be constant if you are a discriminator
|
|
82
70
|
# you also have to be required to be considered a constant
|
|
83
71
|
return (
|
|
84
|
-
isinstance(self.
|
|
85
|
-
and self.
|
|
72
|
+
isinstance(self.type, ConstantType)
|
|
73
|
+
and not self.optional
|
|
86
74
|
and not self.is_discriminator
|
|
87
75
|
)
|
|
88
76
|
|
|
89
77
|
@property
|
|
90
|
-
def
|
|
91
|
-
|
|
92
|
-
|
|
78
|
+
def is_input(self):
|
|
79
|
+
return not (self.constant or self.readonly or self.is_discriminator)
|
|
80
|
+
|
|
81
|
+
@property
|
|
82
|
+
def serialization_type(self) -> str:
|
|
83
|
+
return self.type.serialization_type
|
|
84
|
+
|
|
85
|
+
def type_annotation(self, *, is_operation_file: bool = False) -> str:
|
|
86
|
+
if self.optional and self.client_default_value is None:
|
|
87
|
+
return f"Optional[{self.type.type_annotation(is_operation_file=is_operation_file)}]"
|
|
88
|
+
return self.type.type_annotation(is_operation_file=is_operation_file)
|
|
89
|
+
|
|
90
|
+
def get_json_template_representation(
|
|
91
|
+
self,
|
|
92
|
+
*,
|
|
93
|
+
optional: bool = True, # pylint: disable=unused-argument
|
|
94
|
+
client_default_value_declaration: Optional[str] = None,
|
|
95
|
+
description: Optional[str] = None,
|
|
96
|
+
) -> Any:
|
|
97
|
+
if self.client_default_value:
|
|
98
|
+
client_default_value_declaration = self.type.get_declaration(
|
|
99
|
+
self.client_default_value
|
|
100
|
+
)
|
|
101
|
+
if self.description(is_operation_file=True):
|
|
102
|
+
description = self.description(is_operation_file=True)
|
|
103
|
+
return self.type.get_json_template_representation(
|
|
104
|
+
optional=self.optional,
|
|
105
|
+
client_default_value_declaration=client_default_value_declaration,
|
|
106
|
+
description=description,
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
def get_polymorphic_subtypes(self, polymorphic_subtypes: List["ModelType"]) -> None:
|
|
110
|
+
from .model_type import ModelType
|
|
111
|
+
|
|
112
|
+
if isinstance(self.type, ModelType):
|
|
113
|
+
is_polymorphic_subtype = (
|
|
114
|
+
self.type.discriminator_value and not self.type.discriminated_subtypes
|
|
115
|
+
)
|
|
116
|
+
if (
|
|
117
|
+
self.type.name not in (m.name for m in polymorphic_subtypes)
|
|
118
|
+
and is_polymorphic_subtype
|
|
119
|
+
):
|
|
120
|
+
polymorphic_subtypes.append(self.type)
|
|
121
|
+
|
|
122
|
+
@property
|
|
123
|
+
def validation(self) -> Optional[Dict[str, Any]]:
|
|
124
|
+
retval: Dict[str, Any] = {}
|
|
125
|
+
if not self.optional:
|
|
93
126
|
retval["required"] = True
|
|
94
127
|
if self.readonly:
|
|
95
128
|
retval["readonly"] = True
|
|
96
129
|
if self.constant:
|
|
97
130
|
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)
|
|
131
|
+
retval.update(self.type.validation or {})
|
|
103
132
|
return retval or None
|
|
104
133
|
|
|
105
134
|
@property
|
|
106
|
-
def
|
|
107
|
-
"""Return the RestAPI name correctly escaped for serialization."""
|
|
135
|
+
def attribute_map(self) -> str:
|
|
108
136
|
if self.flattened_names:
|
|
109
|
-
|
|
110
|
-
|
|
137
|
+
attribute_key = ".".join(
|
|
138
|
+
n.replace(".", "\\\\.") for n in self.flattened_names
|
|
139
|
+
)
|
|
140
|
+
else:
|
|
141
|
+
attribute_key = self.rest_api_name.replace(".", "\\\\.")
|
|
142
|
+
if self.type.xml_serialization_ctxt:
|
|
143
|
+
xml_metadata = f", 'xml': {{{self.type.xml_serialization_ctxt}}}"
|
|
144
|
+
else:
|
|
145
|
+
xml_metadata = ""
|
|
146
|
+
return f'"{self.client_name}": {{"key": "{attribute_key}", "type": "{self.serialization_type}"{xml_metadata}}},'
|
|
147
|
+
|
|
148
|
+
def imports(self) -> FileImport:
|
|
149
|
+
from .model_type import ModelType
|
|
150
|
+
|
|
151
|
+
file_import = self.type.imports(is_operation_file=False)
|
|
152
|
+
if self.optional and self.client_default_value is None:
|
|
153
|
+
file_import.add_submodule_import("typing", "Optional", ImportType.STDLIB)
|
|
154
|
+
if isinstance(self.type, ModelType):
|
|
155
|
+
file_import.add_submodule_import(
|
|
156
|
+
"..",
|
|
157
|
+
"models",
|
|
158
|
+
ImportType.LOCAL,
|
|
159
|
+
TypingSection.TYPING,
|
|
160
|
+
alias="_models",
|
|
161
|
+
)
|
|
162
|
+
return file_import
|
|
111
163
|
|
|
112
164
|
@classmethod
|
|
113
165
|
def from_yaml(
|
|
114
166
|
cls,
|
|
115
167
|
yaml_data: Dict[str, Any],
|
|
116
168
|
code_model: "CodeModel",
|
|
117
|
-
*,
|
|
118
|
-
has_additional_properties: Optional[bool] = None,
|
|
119
169
|
) -> "Property":
|
|
120
|
-
from . import
|
|
170
|
+
from . import build_type # pylint: disable=import-outside-toplevel
|
|
121
171
|
|
|
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
172
|
return cls(
|
|
127
173
|
yaml_data=yaml_data,
|
|
128
174
|
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"),
|
|
175
|
+
type=build_type(yaml_data["type"], code_model),
|
|
134
176
|
)
|
|
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,171 +3,199 @@
|
|
|
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
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
+
)
|
|
24
|
+
from .imports import FileImport, ImportType, TypingSection, MsrestImportType
|
|
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/dpcodegen/python/send_request 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()
|
|
76
|
+
if self.abstract:
|
|
77
|
+
return file_import
|
|
78
78
|
for parameter in self.parameters.method:
|
|
79
|
-
|
|
80
|
-
continue
|
|
81
|
-
file_import.merge(parameter.imports())
|
|
79
|
+
file_import.merge(parameter.imports(async_mode=False))
|
|
82
80
|
|
|
83
81
|
file_import.add_submodule_import(
|
|
84
82
|
"azure.core.rest",
|
|
85
83
|
"HttpRequest",
|
|
86
84
|
ImportType.AZURECORE,
|
|
87
85
|
)
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
86
|
+
|
|
87
|
+
if self.parameters.path:
|
|
88
|
+
relative_path = ".."
|
|
89
|
+
if (
|
|
90
|
+
not self.code_model.options["builders_visibility"] == "embedded"
|
|
91
|
+
and self.group_name
|
|
92
|
+
):
|
|
93
|
+
relative_path = "..." if self.group_name else ".."
|
|
94
|
+
file_import.add_submodule_import(
|
|
95
|
+
f"{relative_path}_vendor", "_format_url_section", ImportType.LOCAL
|
|
96
|
+
)
|
|
97
|
+
if self.parameters.headers or self.parameters.query:
|
|
98
|
+
file_import.add_submodule_import(
|
|
99
|
+
"azure.core.utils", "case_insensitive_dict", ImportType.AZURECORE
|
|
100
|
+
)
|
|
103
101
|
file_import.add_submodule_import(
|
|
104
102
|
"typing", "Any", ImportType.STDLIB, typing_section=TypingSection.CONDITIONAL
|
|
105
103
|
)
|
|
106
|
-
file_import.
|
|
104
|
+
file_import.add_msrest_import(
|
|
105
|
+
self.code_model,
|
|
106
|
+
"..."
|
|
107
|
+
if (
|
|
108
|
+
not self.code_model.options["builders_visibility"] == "embedded"
|
|
109
|
+
and self.group_name
|
|
110
|
+
)
|
|
111
|
+
else "..",
|
|
112
|
+
MsrestImportType.Serializer,
|
|
113
|
+
TypingSection.REGULAR,
|
|
114
|
+
)
|
|
115
|
+
if (
|
|
116
|
+
self.overloads
|
|
117
|
+
and self.code_model.options["builders_visibility"] != "embedded"
|
|
118
|
+
):
|
|
119
|
+
file_import.add_submodule_import("typing", "overload", ImportType.STDLIB)
|
|
107
120
|
return file_import
|
|
108
121
|
|
|
109
|
-
@
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
122
|
+
@staticmethod
|
|
123
|
+
@abstractmethod
|
|
124
|
+
def parameter_list_type() -> Callable[
|
|
125
|
+
[Dict[str, Any], "CodeModel"], ParameterListType
|
|
126
|
+
]:
|
|
127
|
+
...
|
|
113
128
|
|
|
114
|
-
|
|
129
|
+
@classmethod
|
|
130
|
+
def from_yaml(cls, yaml_data: Dict[str, Any], code_model: "CodeModel"):
|
|
131
|
+
# when combine embedded builders into one operation file, we need to avoid duplicated build function name.
|
|
115
132
|
# So add operation group name is effective method
|
|
116
133
|
additional_mark = ""
|
|
117
134
|
if (
|
|
118
135
|
code_model.options["combine_operation_files"]
|
|
119
136
|
and code_model.options["builders_visibility"] == "embedded"
|
|
120
137
|
):
|
|
121
|
-
additional_mark = yaml_data["
|
|
138
|
+
additional_mark = yaml_data["groupName"]
|
|
122
139
|
names = [
|
|
123
140
|
"build",
|
|
124
141
|
additional_mark,
|
|
125
|
-
yaml_data["
|
|
142
|
+
yaml_data["name"],
|
|
126
143
|
"request",
|
|
127
144
|
]
|
|
128
145
|
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"]
|
|
146
|
+
overloads = [
|
|
147
|
+
RequestBuilder.from_yaml(rb_yaml_data, code_model)
|
|
148
|
+
for rb_yaml_data in yaml_data.get("overloads", [])
|
|
134
149
|
]
|
|
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
150
|
abstract = False
|
|
151
|
+
parameter_list = cls.parameter_list_type()(yaml_data, code_model)
|
|
142
152
|
if (
|
|
143
153
|
code_model.options["version_tolerant"]
|
|
144
|
-
|
|
145
|
-
|
|
154
|
+
and parameter_list.has_body
|
|
155
|
+
and isinstance(
|
|
156
|
+
parameter_list.body_parameter, RequestBuilderMultipartBodyParameter
|
|
157
|
+
)
|
|
158
|
+
):
|
|
146
159
|
_LOGGER.warning(
|
|
147
|
-
'Not going to generate
|
|
148
|
-
"
|
|
149
|
-
|
|
150
|
-
"
|
|
160
|
+
'Not going to generate operation "%s" because it has multipart / urlencoded body parameters. '
|
|
161
|
+
"Multipart / urlencoded body parameters are not supported for version tolerant generation right now. "
|
|
162
|
+
'Please write your own custom operation in the "_patch.py" file '
|
|
163
|
+
"following https://aka.ms/azsdk/python/dpcodegen/python/customize",
|
|
151
164
|
name,
|
|
152
165
|
)
|
|
153
166
|
abstract = True
|
|
154
167
|
|
|
155
|
-
|
|
168
|
+
return cls(
|
|
156
169
|
yaml_data=yaml_data,
|
|
157
170
|
code_model=code_model,
|
|
158
171
|
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
172
|
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"),
|
|
173
|
+
overloads=overloads,
|
|
170
174
|
abstract=abstract,
|
|
171
175
|
)
|
|
172
|
-
|
|
173
|
-
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
class RequestBuilder(RequestBuilderBase[RequestBuilderParameterList]):
|
|
179
|
+
@staticmethod
|
|
180
|
+
def parameter_list_type() -> Callable[
|
|
181
|
+
[Dict[str, Any], "CodeModel"], RequestBuilderParameterList
|
|
182
|
+
]:
|
|
183
|
+
return RequestBuilderParameterList.from_yaml
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
class OverloadedRequestBuilder(
|
|
187
|
+
RequestBuilderBase[OverloadedRequestBuilderParameterList]
|
|
188
|
+
):
|
|
189
|
+
@staticmethod
|
|
190
|
+
def parameter_list_type() -> Callable[
|
|
191
|
+
[Dict[str, Any], "CodeModel"], OverloadedRequestBuilderParameterList
|
|
192
|
+
]:
|
|
193
|
+
return OverloadedRequestBuilderParameterList.from_yaml
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def get_request_builder(
|
|
197
|
+
yaml_data: Dict[str, Any], code_model: "CodeModel"
|
|
198
|
+
) -> Union[RequestBuilder, OverloadedRequestBuilder]:
|
|
199
|
+
if yaml_data.get("overloads"):
|
|
200
|
+
return OverloadedRequestBuilder.from_yaml(yaml_data, code_model)
|
|
201
|
+
return RequestBuilder.from_yaml(yaml_data, code_model)
|