@autorest/python 6.1.10 → 6.2.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/autorest/_utils.py +2 -1
- package/autorest/codegen/__init__.py +87 -80
- package/autorest/codegen/models/__init__.py +12 -9
- package/autorest/codegen/models/base_builder.py +11 -5
- package/autorest/codegen/models/base_model.py +5 -3
- package/autorest/codegen/models/base_type.py +7 -5
- package/autorest/codegen/models/client.py +131 -32
- package/autorest/codegen/models/code_model.py +92 -120
- package/autorest/codegen/models/combined_type.py +9 -6
- package/autorest/codegen/models/constant_type.py +6 -6
- package/autorest/codegen/models/credential_types.py +18 -16
- package/autorest/codegen/models/dictionary_type.py +8 -6
- package/autorest/codegen/models/enum_type.py +24 -17
- package/autorest/codegen/models/imports.py +4 -4
- package/autorest/codegen/models/list_type.py +14 -10
- package/autorest/codegen/models/lro_operation.py +14 -6
- package/autorest/codegen/models/model_type.py +19 -19
- package/autorest/codegen/models/operation.py +50 -33
- package/autorest/codegen/models/operation_group.py +23 -12
- package/autorest/codegen/models/paging_operation.py +15 -20
- package/autorest/codegen/models/parameter.py +25 -25
- package/autorest/codegen/models/parameter_list.py +22 -16
- package/autorest/codegen/models/primitive_types.py +21 -11
- package/autorest/codegen/models/property.py +7 -7
- package/autorest/codegen/models/request_builder.py +31 -20
- package/autorest/codegen/models/request_builder_parameter.py +18 -13
- package/autorest/codegen/models/response.py +29 -22
- package/autorest/codegen/serializers/__init__.py +196 -139
- package/autorest/codegen/serializers/builder_serializer.py +59 -53
- package/autorest/codegen/serializers/client_serializer.py +40 -46
- package/autorest/codegen/serializers/enum_serializer.py +4 -4
- package/autorest/codegen/serializers/general_serializer.py +96 -43
- package/autorest/codegen/serializers/metadata_serializer.py +20 -16
- package/autorest/codegen/serializers/model_init_serializer.py +10 -6
- package/autorest/codegen/serializers/model_serializer.py +8 -8
- package/autorest/codegen/serializers/operation_groups_serializer.py +24 -12
- package/autorest/codegen/serializers/operations_init_serializer.py +6 -7
- package/autorest/codegen/serializers/patch_serializer.py +4 -4
- package/autorest/codegen/serializers/request_builders_serializer.py +6 -6
- package/autorest/codegen/serializers/sample_serializer.py +146 -0
- package/autorest/codegen/templates/client.py.jinja2 +7 -15
- package/autorest/codegen/templates/client_container.py.jinja2 +12 -0
- package/autorest/codegen/templates/config.py.jinja2 +13 -26
- package/autorest/codegen/templates/config_container.py.jinja2 +16 -0
- package/autorest/codegen/templates/enum_container.py.jinja2 +3 -3
- package/autorest/codegen/templates/init.py.jinja2 +11 -5
- package/autorest/codegen/templates/lro_operation.py.jinja2 +2 -2
- package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +1 -1
- package/autorest/codegen/templates/metadata.json.jinja2 +13 -14
- package/autorest/codegen/templates/model_container.py.jinja2 +3 -3
- package/autorest/codegen/templates/model_init.py.jinja2 +4 -4
- package/autorest/codegen/templates/operation.py.jinja2 +2 -2
- package/autorest/codegen/templates/operation_group.py.jinja2 +3 -3
- package/autorest/codegen/templates/operation_groups_container.py.jinja2 +7 -7
- package/autorest/codegen/templates/operation_tools.jinja2 +3 -3
- package/autorest/codegen/templates/operations_folder_init.py.jinja2 +4 -4
- package/autorest/codegen/templates/{CHANGELOG.md.jinja2 → packaging_templates/CHANGELOG.md.jinja2} +0 -0
- package/autorest/codegen/templates/{LICENSE.jinja2 → packaging_templates/LICENSE.jinja2} +0 -0
- package/autorest/codegen/templates/{MANIFEST.in.jinja2 → packaging_templates/MANIFEST.in.jinja2} +0 -0
- package/autorest/codegen/templates/{README.md.jinja2 → packaging_templates/README.md.jinja2} +0 -0
- package/autorest/codegen/templates/{dev_requirements.txt.jinja2 → packaging_templates/dev_requirements.txt.jinja2} +0 -0
- package/autorest/codegen/templates/{setup.py.jinja2 → packaging_templates/setup.py.jinja2} +9 -9
- package/autorest/codegen/templates/paging_operation.py.jinja2 +1 -1
- package/autorest/codegen/templates/request_builder.py.jinja2 +1 -1
- package/autorest/codegen/templates/request_builders.py.jinja2 +3 -3
- package/autorest/codegen/templates/rest_init.py.jinja2 +1 -1
- package/autorest/codegen/templates/sample.py.jinja2 +44 -0
- package/autorest/codegen/templates/validation.py.jinja2 +1 -1
- package/autorest/codegen/templates/vendor.py.jinja2 +9 -7
- package/autorest/codegen/templates/version.py.jinja2 +2 -2
- package/autorest/m4reformatter/__init__.py +20 -7
- package/autorest/preprocess/__init__.py +38 -23
- package/package.json +1 -1
|
@@ -3,12 +3,18 @@
|
|
|
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, TYPE_CHECKING, TypeVar, Generic, Union
|
|
6
|
+
from typing import Any, Dict, TYPE_CHECKING, TypeVar, Generic, Union, List, Optional
|
|
7
7
|
|
|
8
8
|
from .base_model import BaseModel
|
|
9
9
|
from .parameter_list import ClientGlobalParameterList, ConfigGlobalParameterList
|
|
10
10
|
from .imports import FileImport, ImportType, TypingSection, MsrestImportType
|
|
11
11
|
from .utils import add_to_pylint_disable
|
|
12
|
+
from .operation_group import OperationGroup
|
|
13
|
+
from .request_builder import (
|
|
14
|
+
RequestBuilder,
|
|
15
|
+
OverloadedRequestBuilder,
|
|
16
|
+
)
|
|
17
|
+
from .parameter import Parameter
|
|
12
18
|
|
|
13
19
|
ParameterListType = TypeVar(
|
|
14
20
|
"ParameterListType",
|
|
@@ -16,7 +22,7 @@ ParameterListType = TypeVar(
|
|
|
16
22
|
)
|
|
17
23
|
|
|
18
24
|
if TYPE_CHECKING:
|
|
19
|
-
from .code_model import
|
|
25
|
+
from .code_model import NamespaceModel
|
|
20
26
|
|
|
21
27
|
|
|
22
28
|
class _ClientConfigBase(Generic[ParameterListType], BaseModel):
|
|
@@ -25,14 +31,15 @@ class _ClientConfigBase(Generic[ParameterListType], BaseModel):
|
|
|
25
31
|
def __init__(
|
|
26
32
|
self,
|
|
27
33
|
yaml_data: Dict[str, Any],
|
|
28
|
-
|
|
34
|
+
namespace_model: "NamespaceModel",
|
|
29
35
|
parameters: ParameterListType,
|
|
30
36
|
):
|
|
31
|
-
super().__init__(yaml_data,
|
|
37
|
+
super().__init__(yaml_data, namespace_model)
|
|
32
38
|
self.parameters = parameters
|
|
33
39
|
self.url: str = self.yaml_data[
|
|
34
40
|
"url"
|
|
35
41
|
] # the base endpoint of the client. Can be parameterized or not
|
|
42
|
+
self.legacy_filename: str = self.yaml_data.get("legacyFilename", "client")
|
|
36
43
|
|
|
37
44
|
@property
|
|
38
45
|
def description(self) -> str:
|
|
@@ -46,8 +53,21 @@ class _ClientConfigBase(Generic[ParameterListType], BaseModel):
|
|
|
46
53
|
class Client(_ClientConfigBase[ClientGlobalParameterList]):
|
|
47
54
|
"""Model representing our service client"""
|
|
48
55
|
|
|
56
|
+
def __init__(
|
|
57
|
+
self,
|
|
58
|
+
yaml_data: Dict[str, Any],
|
|
59
|
+
namespace_model: "NamespaceModel",
|
|
60
|
+
parameters: ClientGlobalParameterList,
|
|
61
|
+
):
|
|
62
|
+
super().__init__(yaml_data, namespace_model, parameters)
|
|
63
|
+
self.operation_groups: List[OperationGroup] = []
|
|
64
|
+
self.request_builders: List[
|
|
65
|
+
Union[RequestBuilder, OverloadedRequestBuilder]
|
|
66
|
+
] = []
|
|
67
|
+
self.config = Config.from_yaml(yaml_data, self.namespace_model)
|
|
68
|
+
|
|
49
69
|
def pipeline_class(self, async_mode: bool) -> str:
|
|
50
|
-
if self.
|
|
70
|
+
if self.namespace_model.options["azure_arm"]:
|
|
51
71
|
if async_mode:
|
|
52
72
|
return "AsyncARMPipelineClient"
|
|
53
73
|
return "ARMPipelineClient"
|
|
@@ -55,12 +75,17 @@ class Client(_ClientConfigBase[ClientGlobalParameterList]):
|
|
|
55
75
|
return "AsyncPipelineClient"
|
|
56
76
|
return "PipelineClient"
|
|
57
77
|
|
|
78
|
+
@property
|
|
79
|
+
def credential(self) -> Optional[Parameter]:
|
|
80
|
+
"""The credential param, if one exists"""
|
|
81
|
+
return self.parameters.credential
|
|
82
|
+
|
|
58
83
|
@property
|
|
59
84
|
def send_request_name(self) -> str:
|
|
60
85
|
"""Name of the send request function"""
|
|
61
86
|
return (
|
|
62
87
|
"send_request"
|
|
63
|
-
if self.
|
|
88
|
+
if self.namespace_model.options["show_send_request"]
|
|
64
89
|
else "_send_request"
|
|
65
90
|
)
|
|
66
91
|
|
|
@@ -72,7 +97,7 @@ class Client(_ClientConfigBase[ClientGlobalParameterList]):
|
|
|
72
97
|
@property
|
|
73
98
|
def pylint_disable(self) -> str:
|
|
74
99
|
retval = add_to_pylint_disable("", "client-accepts-api-version-keyword")
|
|
75
|
-
if len(self.
|
|
100
|
+
if len(self.operation_groups) > 6:
|
|
76
101
|
retval = add_to_pylint_disable(retval, "too-many-instance-attributes")
|
|
77
102
|
return retval
|
|
78
103
|
|
|
@@ -80,11 +105,24 @@ class Client(_ClientConfigBase[ClientGlobalParameterList]):
|
|
|
80
105
|
def filename(self) -> str:
|
|
81
106
|
"""Name of the file for the client"""
|
|
82
107
|
if (
|
|
83
|
-
self.
|
|
84
|
-
or self.
|
|
108
|
+
self.namespace_model.options["version_tolerant"]
|
|
109
|
+
or self.namespace_model.options["low_level_client"]
|
|
85
110
|
):
|
|
86
111
|
return "_client"
|
|
87
|
-
return f"_{self.
|
|
112
|
+
return f"_{self.legacy_filename}"
|
|
113
|
+
|
|
114
|
+
def lookup_request_builder(
|
|
115
|
+
self, request_builder_id: int
|
|
116
|
+
) -> Union[RequestBuilder, OverloadedRequestBuilder]:
|
|
117
|
+
"""Find the request builder based off of id"""
|
|
118
|
+
try:
|
|
119
|
+
return next(
|
|
120
|
+
rb
|
|
121
|
+
for rb in self.request_builders
|
|
122
|
+
if id(rb.yaml_data) == request_builder_id
|
|
123
|
+
)
|
|
124
|
+
except StopIteration:
|
|
125
|
+
raise KeyError(f"No request builder with id {request_builder_id} found.")
|
|
88
126
|
|
|
89
127
|
def _imports_shared(self, async_mode: bool) -> FileImport:
|
|
90
128
|
file_import = FileImport()
|
|
@@ -92,7 +130,7 @@ class Client(_ClientConfigBase[ClientGlobalParameterList]):
|
|
|
92
130
|
file_import.add_submodule_import(
|
|
93
131
|
"typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL
|
|
94
132
|
)
|
|
95
|
-
if self.
|
|
133
|
+
if self.namespace_model.options["azure_arm"]:
|
|
96
134
|
file_import.add_submodule_import(
|
|
97
135
|
"azure.mgmt.core", self.pipeline_class(async_mode), ImportType.AZURECORE
|
|
98
136
|
)
|
|
@@ -105,11 +143,11 @@ class Client(_ClientConfigBase[ClientGlobalParameterList]):
|
|
|
105
143
|
file_import.merge(gp.imports(async_mode))
|
|
106
144
|
file_import.add_submodule_import(
|
|
107
145
|
"._configuration",
|
|
108
|
-
f"{self.
|
|
146
|
+
f"{self.name}Configuration",
|
|
109
147
|
ImportType.LOCAL,
|
|
110
148
|
)
|
|
111
149
|
file_import.add_msrest_import(
|
|
112
|
-
self.
|
|
150
|
+
self.namespace_model,
|
|
113
151
|
".." if async_mode else ".",
|
|
114
152
|
MsrestImportType.SerializerDeserializer,
|
|
115
153
|
TypingSection.REGULAR,
|
|
@@ -117,6 +155,58 @@ class Client(_ClientConfigBase[ClientGlobalParameterList]):
|
|
|
117
155
|
|
|
118
156
|
return file_import
|
|
119
157
|
|
|
158
|
+
@property
|
|
159
|
+
def has_mixin(self) -> bool:
|
|
160
|
+
"""Do we want a mixin ABC class for typing purposes?"""
|
|
161
|
+
return any(o for o in self.operation_groups if o.is_mixin)
|
|
162
|
+
|
|
163
|
+
@property
|
|
164
|
+
def need_format_url(self) -> bool:
|
|
165
|
+
"""Whether we need to format urls. If so, we need to vendor core."""
|
|
166
|
+
return any(rq for rq in self.request_builders if rq.parameters.path)
|
|
167
|
+
|
|
168
|
+
@property
|
|
169
|
+
def has_lro_operations(self) -> bool:
|
|
170
|
+
"""Are there any LRO operations in this SDK?"""
|
|
171
|
+
return any(
|
|
172
|
+
[
|
|
173
|
+
operation.operation_type in ("lro", "lropaging")
|
|
174
|
+
for operation_group in self.operation_groups
|
|
175
|
+
for operation in operation_group.operations
|
|
176
|
+
]
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
def format_lro_operations(self) -> None:
|
|
180
|
+
"""Adds operations and attributes needed for LROs.
|
|
181
|
+
If there are LRO functions in here, will add initial LRO function. Will also set the return
|
|
182
|
+
type of the LRO operation
|
|
183
|
+
"""
|
|
184
|
+
for operation_group in self.operation_groups:
|
|
185
|
+
i = 0
|
|
186
|
+
while i < len(operation_group.operations):
|
|
187
|
+
operation = operation_group.operations[i]
|
|
188
|
+
if operation.operation_type in ("lro", "lropaging"):
|
|
189
|
+
operation_group.operations.insert(i, operation.initial_operation) # type: ignore
|
|
190
|
+
i += 1
|
|
191
|
+
i += 1
|
|
192
|
+
|
|
193
|
+
@property
|
|
194
|
+
def need_request_converter(self) -> bool:
|
|
195
|
+
"""
|
|
196
|
+
Whether we need to convert our created azure.core.rest.HttpRequests to
|
|
197
|
+
azure.core.pipeline.transport.HttpRequests
|
|
198
|
+
"""
|
|
199
|
+
return (
|
|
200
|
+
self.namespace_model.options["show_operations"]
|
|
201
|
+
and bool(self.request_builders)
|
|
202
|
+
and not self.namespace_model.options["version_tolerant"]
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
@property
|
|
206
|
+
def has_abstract_operations(self) -> bool:
|
|
207
|
+
"""Whether there is abstract operation in any operation group."""
|
|
208
|
+
return any(og.has_abstract_operations for og in self.operation_groups)
|
|
209
|
+
|
|
120
210
|
def imports(self, async_mode: bool) -> FileImport:
|
|
121
211
|
file_import = self._imports_shared(async_mode)
|
|
122
212
|
if async_mode:
|
|
@@ -140,20 +230,20 @@ class Client(_ClientConfigBase[ClientGlobalParameterList]):
|
|
|
140
230
|
ImportType.AZURECORE,
|
|
141
231
|
TypingSection.CONDITIONAL,
|
|
142
232
|
)
|
|
143
|
-
for og in self.
|
|
233
|
+
for og in self.operation_groups:
|
|
144
234
|
file_import.add_submodule_import(
|
|
145
|
-
f".{self.
|
|
235
|
+
f".{self.namespace_model.operations_folder_name}",
|
|
146
236
|
og.class_name,
|
|
147
237
|
ImportType.LOCAL,
|
|
148
238
|
)
|
|
149
239
|
|
|
150
240
|
if (
|
|
151
|
-
self.
|
|
152
|
-
and self.
|
|
241
|
+
self.namespace_model.model_types
|
|
242
|
+
and self.namespace_model.options["models_mode"] == "msrest"
|
|
153
243
|
):
|
|
154
244
|
path_to_models = ".." if async_mode else "."
|
|
155
|
-
if len(self.
|
|
156
|
-
self.
|
|
245
|
+
if len(self.namespace_model.model_types) != len(
|
|
246
|
+
self.namespace_model.public_model_types
|
|
157
247
|
):
|
|
158
248
|
# this means we have hidden models. In that case, we import directly from the models
|
|
159
249
|
# file, not the module, bc we don't expose the hidden models in the models module
|
|
@@ -161,7 +251,7 @@ class Client(_ClientConfigBase[ClientGlobalParameterList]):
|
|
|
161
251
|
# Also in this case, we're in version tolerant, so python3 only is true
|
|
162
252
|
file_import.add_submodule_import(
|
|
163
253
|
f"{path_to_models}models",
|
|
164
|
-
self.
|
|
254
|
+
self.namespace_model.models_filename,
|
|
165
255
|
ImportType.LOCAL,
|
|
166
256
|
alias="models",
|
|
167
257
|
)
|
|
@@ -169,7 +259,7 @@ class Client(_ClientConfigBase[ClientGlobalParameterList]):
|
|
|
169
259
|
file_import.add_submodule_import(
|
|
170
260
|
path_to_models, "models", ImportType.LOCAL
|
|
171
261
|
)
|
|
172
|
-
elif self.
|
|
262
|
+
elif self.namespace_model.options["models_mode"] == "msrest":
|
|
173
263
|
# in this case, we have client_models = {} in the service client, which needs a type annotation
|
|
174
264
|
# this import will always be commented, so will always add it to the typing section
|
|
175
265
|
file_import.add_submodule_import(
|
|
@@ -184,9 +274,7 @@ class Client(_ClientConfigBase[ClientGlobalParameterList]):
|
|
|
184
274
|
"typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL
|
|
185
275
|
)
|
|
186
276
|
try:
|
|
187
|
-
mixin_operation = next(
|
|
188
|
-
og for og in self.code_model.operation_groups if og.is_mixin
|
|
189
|
-
)
|
|
277
|
+
mixin_operation = next(og for og in self.operation_groups if og.is_mixin)
|
|
190
278
|
file_import.add_submodule_import(
|
|
191
279
|
"._operations_mixin", mixin_operation.class_name, ImportType.LOCAL
|
|
192
280
|
)
|
|
@@ -206,11 +294,13 @@ class Client(_ClientConfigBase[ClientGlobalParameterList]):
|
|
|
206
294
|
return file_import
|
|
207
295
|
|
|
208
296
|
@classmethod
|
|
209
|
-
def from_yaml(
|
|
297
|
+
def from_yaml(
|
|
298
|
+
cls, yaml_data: Dict[str, Any], namespace_model: "NamespaceModel"
|
|
299
|
+
) -> "Client":
|
|
210
300
|
return cls(
|
|
211
301
|
yaml_data=yaml_data,
|
|
212
|
-
|
|
213
|
-
parameters=ClientGlobalParameterList.from_yaml(yaml_data,
|
|
302
|
+
namespace_model=namespace_model,
|
|
303
|
+
parameters=ClientGlobalParameterList.from_yaml(yaml_data, namespace_model),
|
|
214
304
|
)
|
|
215
305
|
|
|
216
306
|
|
|
@@ -224,6 +314,13 @@ class Config(_ClientConfigBase[ConfigGlobalParameterList]):
|
|
|
224
314
|
"Note that all parameters used to create this instance are saved as instance attributes."
|
|
225
315
|
)
|
|
226
316
|
|
|
317
|
+
@property
|
|
318
|
+
def sdk_moniker(self) -> str:
|
|
319
|
+
package_name = self.namespace_model.options["package_name"]
|
|
320
|
+
if package_name and package_name.startswith("azure-"):
|
|
321
|
+
package_name = package_name[len("azure-") :]
|
|
322
|
+
return package_name if package_name else self.yaml_data["name"].lower()
|
|
323
|
+
|
|
227
324
|
@property
|
|
228
325
|
def name(self) -> str:
|
|
229
326
|
return f"{super().name}Configuration"
|
|
@@ -239,13 +336,13 @@ class Config(_ClientConfigBase[ConfigGlobalParameterList]):
|
|
|
239
336
|
file_import.add_submodule_import(
|
|
240
337
|
"typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL
|
|
241
338
|
)
|
|
242
|
-
if self.
|
|
339
|
+
if self.namespace_model.options["package_version"]:
|
|
243
340
|
file_import.add_submodule_import(
|
|
244
341
|
".._version" if async_mode else "._version", "VERSION", ImportType.LOCAL
|
|
245
342
|
)
|
|
246
343
|
for gp in self.parameters:
|
|
247
344
|
file_import.merge(gp.imports(async_mode=async_mode))
|
|
248
|
-
if self.
|
|
345
|
+
if self.namespace_model.options["azure_arm"]:
|
|
249
346
|
policy = (
|
|
250
347
|
"AsyncARMChallengeAuthenticationPolicy"
|
|
251
348
|
if async_mode
|
|
@@ -260,9 +357,11 @@ class Config(_ClientConfigBase[ConfigGlobalParameterList]):
|
|
|
260
357
|
return file_import
|
|
261
358
|
|
|
262
359
|
@classmethod
|
|
263
|
-
def from_yaml(
|
|
360
|
+
def from_yaml(
|
|
361
|
+
cls, yaml_data: Dict[str, Any], namespace_model: "NamespaceModel"
|
|
362
|
+
) -> "Config":
|
|
264
363
|
return cls(
|
|
265
364
|
yaml_data=yaml_data,
|
|
266
|
-
|
|
267
|
-
parameters=ConfigGlobalParameterList.from_yaml(yaml_data,
|
|
365
|
+
namespace_model=namespace_model,
|
|
366
|
+
parameters=ConfigGlobalParameterList.from_yaml(yaml_data, namespace_model),
|
|
268
367
|
)
|
|
@@ -3,18 +3,21 @@
|
|
|
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 List, Dict,
|
|
6
|
+
from typing import List, Dict, Any, Set, Union
|
|
7
7
|
|
|
8
8
|
from .base_type import BaseType
|
|
9
9
|
from .enum_type import EnumType
|
|
10
10
|
from .model_type import ModelType
|
|
11
|
+
from .client import Client
|
|
12
|
+
from .request_builder import RequestBuilder, OverloadedRequestBuilder
|
|
11
13
|
from .operation_group import OperationGroup
|
|
12
|
-
from .client import Client, Config
|
|
13
|
-
from .request_builder import OverloadedRequestBuilder, RequestBuilder
|
|
14
|
-
from .parameter import Parameter
|
|
15
14
|
|
|
16
15
|
|
|
17
|
-
|
|
16
|
+
def _is_legacy(options) -> bool:
|
|
17
|
+
return not (options["version_tolerant"] or options["low_level_client"])
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class CodeModel:
|
|
18
21
|
"""Holds all of the information we have parsed out of the yaml file. The CodeModel is what gets
|
|
19
22
|
serialized by the serializers.
|
|
20
23
|
|
|
@@ -47,17 +50,34 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
47
50
|
) -> None:
|
|
48
51
|
self.yaml_data = yaml_data
|
|
49
52
|
self.options = options
|
|
53
|
+
self.namespace_models: List["NamespaceModel"] = [
|
|
54
|
+
NamespaceModel(namespace_yaml_data, self.options, namespace)
|
|
55
|
+
for namespace, namespace_yaml_data in yaml_data.items()
|
|
56
|
+
]
|
|
57
|
+
|
|
58
|
+
@property
|
|
59
|
+
def is_legacy(self) -> bool:
|
|
60
|
+
return _is_legacy(self.options)
|
|
61
|
+
|
|
62
|
+
@property
|
|
63
|
+
def description(self) -> str:
|
|
64
|
+
return self.namespace_models[0].clients[0].description
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class NamespaceModel:
|
|
68
|
+
def __init__(
|
|
69
|
+
self, yaml_data: Dict[str, Any], options: Dict[str, Any], namespace: str
|
|
70
|
+
):
|
|
71
|
+
self.yaml_data = yaml_data
|
|
50
72
|
self.types_map: Dict[int, BaseType] = {} # map yaml id to schema
|
|
51
|
-
self.operation_groups: List[OperationGroup] = []
|
|
52
73
|
self._model_types: List[ModelType] = []
|
|
53
|
-
self.
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
self.
|
|
59
|
-
self.namespace
|
|
60
|
-
self.module_name: str = self.yaml_data["client"]["moduleName"]
|
|
74
|
+
self.options = options
|
|
75
|
+
from . import build_type
|
|
76
|
+
|
|
77
|
+
for type_yaml in yaml_data.get("types", []):
|
|
78
|
+
build_type(yaml_data=type_yaml, namespace_model=self)
|
|
79
|
+
self.clients: List[Client] = []
|
|
80
|
+
self.namespace = namespace
|
|
61
81
|
|
|
62
82
|
def lookup_type(self, schema_id: int) -> BaseType:
|
|
63
83
|
"""Looks to see if the schema has already been created.
|
|
@@ -72,43 +92,24 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
72
92
|
except StopIteration:
|
|
73
93
|
raise KeyError(f"Couldn't find schema with id {schema_id}")
|
|
74
94
|
|
|
75
|
-
@property
|
|
76
|
-
def credential(self) -> Optional[Parameter]:
|
|
77
|
-
"""The credential param, if one exists"""
|
|
78
|
-
return self.client.parameters.credential
|
|
79
|
-
|
|
80
|
-
@property
|
|
81
|
-
def client(self) -> Client:
|
|
82
|
-
if not self._client:
|
|
83
|
-
raise ValueError("You haven't linked the client yet")
|
|
84
|
-
return self._client
|
|
85
|
-
|
|
86
|
-
@client.setter
|
|
87
|
-
def client(self, val: Client) -> None:
|
|
88
|
-
self._client = val
|
|
89
|
-
|
|
90
|
-
@property
|
|
91
|
-
def config(self) -> Config:
|
|
92
|
-
if not self._config:
|
|
93
|
-
raise ValueError("You haven't linked the config yet")
|
|
94
|
-
return self._config
|
|
95
|
-
|
|
96
|
-
@config.setter
|
|
97
|
-
def config(self, val: Config) -> None:
|
|
98
|
-
self._config = val
|
|
99
|
-
|
|
100
95
|
def lookup_request_builder(
|
|
101
96
|
self, request_builder_id: int
|
|
102
97
|
) -> Union[RequestBuilder, OverloadedRequestBuilder]:
|
|
103
98
|
"""Find the request builder based off of id"""
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
99
|
+
for client in self.clients:
|
|
100
|
+
try:
|
|
101
|
+
return client.lookup_request_builder(request_builder_id)
|
|
102
|
+
except KeyError:
|
|
103
|
+
pass
|
|
104
|
+
raise KeyError(f"No request builder with id {request_builder_id} found.")
|
|
105
|
+
|
|
106
|
+
@property
|
|
107
|
+
def operation_groups(self) -> List[OperationGroup]:
|
|
108
|
+
return [og for client in self.clients for og in client.operation_groups]
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
def request_builders(self) -> List[Union[RequestBuilder, OverloadedRequestBuilder]]:
|
|
112
|
+
return [rb for client in self.clients for rb in client.request_builders]
|
|
112
113
|
|
|
113
114
|
@property
|
|
114
115
|
def model_types(self) -> List[ModelType]:
|
|
@@ -132,9 +133,11 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
132
133
|
"""All of the enums"""
|
|
133
134
|
return [t for t in self.types_map.values() if isinstance(t, EnumType)]
|
|
134
135
|
|
|
135
|
-
@staticmethod
|
|
136
136
|
def _sort_model_types_helper(
|
|
137
|
-
|
|
137
|
+
self,
|
|
138
|
+
current: ModelType,
|
|
139
|
+
seen_schema_names: Set[str],
|
|
140
|
+
seen_schema_yaml_ids: Set[int],
|
|
138
141
|
):
|
|
139
142
|
if current.id in seen_schema_yaml_ids:
|
|
140
143
|
return []
|
|
@@ -150,7 +153,7 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
150
153
|
seen_schema_names.add(current.name)
|
|
151
154
|
seen_schema_yaml_ids.add(current.id)
|
|
152
155
|
ancestors = (
|
|
153
|
-
|
|
156
|
+
self._sort_model_types_helper(
|
|
154
157
|
parent, seen_schema_names, seen_schema_yaml_ids
|
|
155
158
|
)
|
|
156
159
|
+ ancestors
|
|
@@ -170,40 +173,38 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
170
173
|
sorted_object_schemas: List[ModelType] = []
|
|
171
174
|
for schema in sorted(self.model_types, key=lambda x: x.name.lower()):
|
|
172
175
|
sorted_object_schemas.extend(
|
|
173
|
-
|
|
176
|
+
self._sort_model_types_helper(
|
|
174
177
|
schema, seen_schema_names, seen_schema_yaml_ids
|
|
175
178
|
)
|
|
176
179
|
)
|
|
177
180
|
self.model_types = sorted_object_schemas
|
|
178
181
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
type of the LRO operation
|
|
183
|
-
"""
|
|
184
|
-
for operation_group in self.operation_groups:
|
|
185
|
-
i = 0
|
|
186
|
-
while i < len(operation_group.operations):
|
|
187
|
-
operation = operation_group.operations[i]
|
|
188
|
-
if operation.operation_type in ("lro", "lropaging"):
|
|
189
|
-
operation_group.operations.insert(i, operation.initial_operation) # type: ignore
|
|
190
|
-
i += 1
|
|
191
|
-
i += 1
|
|
182
|
+
@property
|
|
183
|
+
def is_legacy(self) -> bool:
|
|
184
|
+
return _is_legacy(self.options)
|
|
192
185
|
|
|
193
186
|
@property
|
|
194
|
-
def
|
|
195
|
-
"""
|
|
196
|
-
|
|
197
|
-
if self.options["version_tolerant"] and not any(
|
|
198
|
-
og for og in self.operation_groups if not og.is_mixin
|
|
199
|
-
):
|
|
200
|
-
name = f"_{name}"
|
|
201
|
-
return name
|
|
187
|
+
def rest_layer_name(self) -> str:
|
|
188
|
+
"""If we have a separate rest layer, what is its name?"""
|
|
189
|
+
return "rest" if self.options["builders_visibility"] == "public" else "_rest"
|
|
202
190
|
|
|
203
191
|
@property
|
|
204
|
-
def
|
|
205
|
-
"""
|
|
206
|
-
|
|
192
|
+
def models_filename(self) -> str:
|
|
193
|
+
"""Get the names of the model file(s)"""
|
|
194
|
+
if self.is_legacy:
|
|
195
|
+
return "_models_py3"
|
|
196
|
+
return "_models"
|
|
197
|
+
|
|
198
|
+
@property
|
|
199
|
+
def client_filename(self) -> str:
|
|
200
|
+
return self.clients[0].filename
|
|
201
|
+
|
|
202
|
+
@property
|
|
203
|
+
def enums_filename(self) -> str:
|
|
204
|
+
"""The name of the enums file"""
|
|
205
|
+
if self.is_legacy:
|
|
206
|
+
return f"_{self.clients[0].legacy_filename}_enums"
|
|
207
|
+
return "_enums"
|
|
207
208
|
|
|
208
209
|
def need_vendored_code(self, async_mode: bool) -> bool:
|
|
209
210
|
"""Whether we need to vendor code in the _vendor.py file for this SDK"""
|
|
@@ -217,58 +218,29 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
217
218
|
|
|
218
219
|
@property
|
|
219
220
|
def need_request_converter(self) -> bool:
|
|
220
|
-
|
|
221
|
-
Whether we need to convert our created azure.core.rest.HttpRequests to
|
|
222
|
-
azure.core.pipeline.transport.HttpRequests
|
|
223
|
-
"""
|
|
224
|
-
return (
|
|
225
|
-
self.options["show_operations"]
|
|
226
|
-
and bool(self.request_builders)
|
|
227
|
-
and not self.options["version_tolerant"]
|
|
228
|
-
)
|
|
221
|
+
return any(c for c in self.clients if c.need_request_converter)
|
|
229
222
|
|
|
230
223
|
@property
|
|
231
224
|
def need_format_url(self) -> bool:
|
|
232
|
-
|
|
233
|
-
return any(rq for rq in self.request_builders if rq.parameters.path)
|
|
225
|
+
return any(c for c in self.clients if c.need_format_url)
|
|
234
226
|
|
|
235
227
|
@property
|
|
236
228
|
def need_mixin_abc(self) -> bool:
|
|
237
|
-
|
|
238
|
-
return any(o for o in self.operation_groups if o.is_mixin)
|
|
229
|
+
return any(c for c in self.clients if c.has_mixin)
|
|
239
230
|
|
|
240
231
|
@property
|
|
241
|
-
def
|
|
242
|
-
|
|
243
|
-
return any(
|
|
244
|
-
[
|
|
245
|
-
operation.operation_type in ("lro", "lropaging")
|
|
246
|
-
for operation_group in self.operation_groups
|
|
247
|
-
for operation in operation_group.operations
|
|
248
|
-
]
|
|
249
|
-
)
|
|
250
|
-
|
|
251
|
-
@property
|
|
252
|
-
def models_filename(self) -> str:
|
|
253
|
-
"""Get the names of the model file(s)"""
|
|
254
|
-
if self.is_legacy:
|
|
255
|
-
return "_models_py3"
|
|
256
|
-
return "_models"
|
|
257
|
-
|
|
258
|
-
@property
|
|
259
|
-
def enums_filename(self) -> str:
|
|
260
|
-
"""The name of the enums file"""
|
|
261
|
-
if self.is_legacy:
|
|
262
|
-
return f"_{self.module_name}_enums"
|
|
263
|
-
return "_enums"
|
|
264
|
-
|
|
265
|
-
@property
|
|
266
|
-
def is_legacy(self) -> bool:
|
|
267
|
-
return not (
|
|
268
|
-
self.options["version_tolerant"] or self.options["low_level_client"]
|
|
269
|
-
)
|
|
232
|
+
def has_abstract_operations(self) -> bool:
|
|
233
|
+
return any(c for c in self.clients if c.has_abstract_operations)
|
|
270
234
|
|
|
271
235
|
@property
|
|
272
|
-
def
|
|
273
|
-
"""
|
|
274
|
-
|
|
236
|
+
def operations_folder_name(self) -> str:
|
|
237
|
+
"""Get the name of the operations folder that holds operations."""
|
|
238
|
+
name = "operations"
|
|
239
|
+
if self.options["version_tolerant"] and not any(
|
|
240
|
+
og
|
|
241
|
+
for client in self.clients
|
|
242
|
+
for og in client.operation_groups
|
|
243
|
+
if not og.is_mixin
|
|
244
|
+
):
|
|
245
|
+
name = f"_{name}"
|
|
246
|
+
return name
|
|
@@ -9,7 +9,7 @@ from autorest.codegen.models.imports import FileImport, ImportType
|
|
|
9
9
|
from .base_type import BaseType
|
|
10
10
|
|
|
11
11
|
if TYPE_CHECKING:
|
|
12
|
-
from .code_model import
|
|
12
|
+
from .code_model import NamespaceModel
|
|
13
13
|
from .model_type import ModelType
|
|
14
14
|
|
|
15
15
|
|
|
@@ -21,9 +21,12 @@ class CombinedType(BaseType):
|
|
|
21
21
|
"""
|
|
22
22
|
|
|
23
23
|
def __init__(
|
|
24
|
-
self,
|
|
24
|
+
self,
|
|
25
|
+
yaml_data: Dict[str, Any],
|
|
26
|
+
namespace_model: "NamespaceModel",
|
|
27
|
+
types: List[BaseType],
|
|
25
28
|
) -> None:
|
|
26
|
-
super().__init__(yaml_data,
|
|
29
|
+
super().__init__(yaml_data, namespace_model)
|
|
27
30
|
self.types = types # the types that this type is combining
|
|
28
31
|
|
|
29
32
|
@property
|
|
@@ -102,12 +105,12 @@ class CombinedType(BaseType):
|
|
|
102
105
|
|
|
103
106
|
@classmethod
|
|
104
107
|
def from_yaml(
|
|
105
|
-
cls, yaml_data: Dict[str, Any],
|
|
108
|
+
cls, yaml_data: Dict[str, Any], namespace_model: "NamespaceModel"
|
|
106
109
|
) -> "BaseType":
|
|
107
110
|
from . import build_type
|
|
108
111
|
|
|
109
112
|
return cls(
|
|
110
113
|
yaml_data,
|
|
111
|
-
|
|
112
|
-
[build_type(t,
|
|
114
|
+
namespace_model,
|
|
115
|
+
[build_type(t, namespace_model) for t in yaml_data["types"]],
|
|
113
116
|
)
|