@autorest/python 5.14.0 → 5.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ChangeLog.md +29 -0
- package/autorest/codegen/__init__.py +87 -47
- package/autorest/codegen/models/base_schema.py +2 -6
- package/autorest/codegen/models/client.py +6 -0
- package/autorest/codegen/models/code_model.py +40 -74
- package/autorest/codegen/models/constant_schema.py +7 -3
- package/autorest/codegen/models/credential_model.py +47 -0
- package/autorest/codegen/models/credential_schema.py +5 -4
- package/autorest/codegen/models/dictionary_schema.py +7 -7
- package/autorest/codegen/models/enum_schema.py +8 -39
- package/autorest/codegen/models/imports.py +3 -1
- package/autorest/codegen/models/list_schema.py +18 -8
- package/autorest/codegen/models/lro_operation.py +3 -3
- package/autorest/codegen/models/lro_paging_operation.py +3 -3
- package/autorest/codegen/models/object_schema.py +17 -13
- package/autorest/codegen/models/operation.py +27 -6
- package/autorest/codegen/models/operation_group.py +7 -2
- package/autorest/codegen/models/paging_operation.py +3 -3
- package/autorest/codegen/models/parameter.py +39 -15
- package/autorest/codegen/models/parameter_list.py +1 -1
- package/autorest/codegen/models/primitive_schemas.py +15 -25
- package/autorest/codegen/models/property.py +5 -5
- package/autorest/codegen/models/request_builder.py +4 -4
- package/autorest/codegen/models/request_builder_parameter.py +12 -5
- package/autorest/codegen/models/schema_response.py +23 -10
- package/autorest/codegen/models/utils.py +20 -0
- package/autorest/codegen/serializers/__init__.py +49 -25
- package/autorest/codegen/serializers/builder_serializer.py +79 -37
- package/autorest/codegen/serializers/client_serializer.py +16 -6
- package/autorest/codegen/serializers/general_serializer.py +24 -3
- package/autorest/codegen/serializers/import_serializer.py +1 -1
- package/autorest/codegen/serializers/metadata_serializer.py +1 -1
- package/autorest/codegen/serializers/model_base_serializer.py +8 -0
- package/autorest/codegen/serializers/model_python3_serializer.py +2 -2
- package/autorest/codegen/serializers/operation_groups_serializer.py +1 -0
- package/autorest/codegen/serializers/patch_serializer.py +12 -3
- package/autorest/codegen/serializers/utils.py +29 -4
- package/autorest/codegen/templates/config.py.jinja2 +4 -4
- package/autorest/codegen/templates/enum.py.jinja2 +1 -1
- package/autorest/codegen/templates/enum_container.py.jinja2 +0 -1
- package/autorest/codegen/templates/init.py.jinja2 +9 -6
- package/autorest/codegen/templates/keywords.jinja2 +14 -1
- package/autorest/codegen/templates/lro_operation.py.jinja2 +1 -1
- package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +1 -1
- package/autorest/codegen/templates/metadata.json.jinja2 +3 -3
- package/autorest/codegen/templates/model.py.jinja2 +1 -6
- package/autorest/codegen/templates/model_init.py.jinja2 +7 -4
- package/autorest/codegen/templates/operation.py.jinja2 +2 -3
- package/autorest/codegen/templates/operation_group.py.jinja2 +12 -5
- package/autorest/codegen/templates/operation_groups_container.py.jinja2 +0 -1
- package/autorest/codegen/templates/operations_folder_init.py.jinja2 +4 -0
- package/autorest/codegen/templates/paging_operation.py.jinja2 +1 -1
- package/autorest/codegen/templates/patch.py.jinja2 +18 -29
- package/autorest/codegen/templates/request_builder.py.jinja2 +4 -6
- package/autorest/codegen/templates/vendor.py.jinja2 +12 -2
- package/autorest/multiapi/models/imports.py +21 -11
- package/autorest/multiapi/serializers/import_serializer.py +3 -1
- package/package.json +2 -2
package/ChangeLog.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
### 2022-04-07 - 5.15.0
|
|
4
|
+
|
|
5
|
+
| Library | Min Version |
|
|
6
|
+
| ----------------------------------------------------------------------- | ----------- |
|
|
7
|
+
| `@autorest/core` | `3.6.2` |
|
|
8
|
+
| `@autorest/modelerfour` | `4.19.1` |
|
|
9
|
+
| `azure-core` dep of generated code | `1.23.0` |
|
|
10
|
+
| `msrest` dep of generated code | `0.6.21` |
|
|
11
|
+
| `azure-mgmt-core` dep of generated code (If generating mgmt plane code) | `1.3.0` |
|
|
12
|
+
|
|
13
|
+
**New Features**
|
|
14
|
+
|
|
15
|
+
- Add support for security configurations in the swagger. For more information, see https://github.com/Azure/autorest/blob/main/docs/generate/authentication.md #1161
|
|
16
|
+
- Add support for handwritten customizations of generated code. For more information, see https://aka.ms/azsdk/python/dpcodegen/python/customize #1153
|
|
17
|
+
- Allow `header` and `params` as kwargs in operation and request-build function to hand over REST Header and Query parameters case insensitively #1183
|
|
18
|
+
|
|
19
|
+
**Bug Fixes**
|
|
20
|
+
|
|
21
|
+
- Make `--version-tolerant` generated code mypy compatible in the `azure-sdk-for-python` repo. Tested only with the `--black` flag #1185
|
|
22
|
+
- Remove unnecessary vendored code in the `_vendor` file if the SDK has no operations #1196
|
|
23
|
+
- Fix the generation of the root `__init__` files for packages with only models #1195
|
|
24
|
+
- Add pylint and mypy support for `--version-tolerant` generations with `--models-mode=msrest` #1202
|
|
25
|
+
|
|
26
|
+
**Breaking Changes in Version Tolerant Generation**
|
|
27
|
+
|
|
28
|
+
- Change client filenames to `_client.py` #1206
|
|
29
|
+
- Change the models filename from `_models_py3.py` to `_models.py` #1204
|
|
30
|
+
- Change the enums filename to `_enums.py` #1204
|
|
31
|
+
|
|
3
32
|
### 2022-03-08 - 5.14.0
|
|
4
33
|
|
|
5
34
|
| Library | Min Version |
|
|
@@ -18,7 +18,11 @@ from .models.parameter_list import GlobalParameterList
|
|
|
18
18
|
from .models.rest import Rest
|
|
19
19
|
from .serializers import JinjaSerializer
|
|
20
20
|
from .models.credential_schema_policy import CredentialSchemaPolicy, get_credential_schema_policy_type
|
|
21
|
-
from .models.
|
|
21
|
+
from .models.credential_schema_policy import BearerTokenCredentialPolicy, AzureKeyCredentialPolicy
|
|
22
|
+
from .models.credential_model import CredentialModel
|
|
23
|
+
|
|
24
|
+
_AAD_TYPE = "AADToken"
|
|
25
|
+
_KEY_TYPE = "AzureKey"
|
|
22
26
|
|
|
23
27
|
def _build_convenience_layer(yaml_data: Dict[str, Any], code_model: CodeModel) -> None:
|
|
24
28
|
# Create operations
|
|
@@ -32,7 +36,6 @@ def _build_convenience_layer(yaml_data: Dict[str, Any], code_model: CodeModel) -
|
|
|
32
36
|
code_model.sort_schemas()
|
|
33
37
|
|
|
34
38
|
if code_model.options["show_operations"]:
|
|
35
|
-
code_model.add_schema_link_to_operation()
|
|
36
39
|
code_model.generate_single_parameter_from_multiple_content_types_operation()
|
|
37
40
|
code_model.link_operation_to_request_builder()
|
|
38
41
|
# LRO operation
|
|
@@ -92,6 +95,12 @@ def _validate_code_model_options(options: Dict[str, Any]) -> None:
|
|
|
92
95
|
"Please remove --reformat-next-link from your call for version tolerant generations."
|
|
93
96
|
)
|
|
94
97
|
|
|
98
|
+
if options["multiapi"] and options["version_tolerant"]:
|
|
99
|
+
raise ValueError(
|
|
100
|
+
"Can not currently generate version tolerant multiapi SDKs. "
|
|
101
|
+
"We are working on creating a new multiapi SDK for version tolerant and it is not available yet."
|
|
102
|
+
)
|
|
103
|
+
|
|
95
104
|
_LOGGER = logging.getLogger(__name__)
|
|
96
105
|
class CodeGenerator(Plugin):
|
|
97
106
|
@staticmethod
|
|
@@ -131,32 +140,53 @@ class CodeGenerator(Plugin):
|
|
|
131
140
|
def _build_package_dependency() -> Dict[str, str]:
|
|
132
141
|
return {
|
|
133
142
|
"dependency_azure_mgmt_core": "azure-mgmt-core<2.0.0,>=1.3.0",
|
|
134
|
-
"dependency_azure_core": "azure-core<2.0.0,>=1.
|
|
143
|
+
"dependency_azure_core": "azure-core<2.0.0,>=1.23.0",
|
|
135
144
|
"dependency_msrest": "msrest>=0.6.21",
|
|
136
145
|
}
|
|
137
146
|
|
|
147
|
+
@staticmethod
|
|
148
|
+
def _build_with_security_definition(yaml_data: Dict[str, Any], credential_model: CredentialModel):
|
|
149
|
+
security_yaml = yaml_data.get("security", {})
|
|
150
|
+
if security_yaml.get("authenticationRequired"):
|
|
151
|
+
for scheme in security_yaml.get("schemes"):
|
|
152
|
+
if _AAD_TYPE == scheme["type"]:
|
|
153
|
+
credential_model.credential_scopes.update(scheme["scopes"])
|
|
154
|
+
elif _KEY_TYPE == scheme["type"]:
|
|
155
|
+
# only accept the last one
|
|
156
|
+
credential_model.key_header_name = scheme["headerName"]
|
|
157
|
+
|
|
158
|
+
if credential_model.credential_scopes:
|
|
159
|
+
credential_model.policy_type = BearerTokenCredentialPolicy
|
|
160
|
+
elif credential_model.key_header_name:
|
|
161
|
+
credential_model.policy_type = AzureKeyCredentialPolicy
|
|
162
|
+
|
|
163
|
+
@staticmethod
|
|
164
|
+
def _build_credential_model(code_model: CodeModel, credential_model: CredentialModel):
|
|
165
|
+
if credential_model.policy_type:
|
|
166
|
+
code_model.options["credential"] = True
|
|
167
|
+
credential_model.build_authentication_policy()
|
|
168
|
+
code_model.credential_model = credential_model
|
|
169
|
+
|
|
170
|
+
def _handle_credential_model(self, yaml_data: Dict[str, Any], code_model: CodeModel):
|
|
171
|
+
credential_model = CredentialModel(code_model.options["azure_arm"])
|
|
172
|
+
|
|
173
|
+
# credential info with security definition will be overridded by credential flags
|
|
174
|
+
self._build_with_security_definition(yaml_data, credential_model)
|
|
175
|
+
self._build_with_credential_flags(code_model, credential_model)
|
|
176
|
+
|
|
177
|
+
self._build_credential_model(code_model, credential_model)
|
|
178
|
+
|
|
138
179
|
def _create_code_model(self, yaml_data: Dict[str, Any], options: Dict[str, Union[str, bool]]) -> CodeModel:
|
|
139
180
|
# Create a code model
|
|
140
181
|
|
|
141
182
|
code_model = CodeModel(options=options)
|
|
142
|
-
|
|
143
|
-
self._handle_default_authentication_policy(code_model)
|
|
183
|
+
self._handle_credential_model(yaml_data, code_model)
|
|
144
184
|
code_model.module_name = yaml_data["info"]["python_title"]
|
|
145
185
|
code_model.class_name = yaml_data["info"]["pascal_case_title"]
|
|
146
186
|
code_model.description = (
|
|
147
187
|
yaml_data["info"]["description"] if yaml_data["info"].get("description") else ""
|
|
148
188
|
)
|
|
149
189
|
|
|
150
|
-
# Global parameters
|
|
151
|
-
code_model.global_parameters = GlobalParameterList(
|
|
152
|
-
code_model,
|
|
153
|
-
[Parameter.from_yaml(param, code_model=code_model) for param in yaml_data.get("globalParameters", [])],
|
|
154
|
-
)
|
|
155
|
-
code_model.global_parameters.code_model = code_model
|
|
156
|
-
|
|
157
|
-
# Custom URL
|
|
158
|
-
code_model.setup_client_input_parameters(yaml_data)
|
|
159
|
-
|
|
160
190
|
# Get my namespace
|
|
161
191
|
namespace = self._autorestapi.get_value("namespace")
|
|
162
192
|
_LOGGER.debug("Namespace parameter was %s", namespace)
|
|
@@ -164,16 +194,24 @@ class CodeGenerator(Plugin):
|
|
|
164
194
|
namespace = yaml_data["info"]["python_title"]
|
|
165
195
|
code_model.namespace = namespace
|
|
166
196
|
|
|
167
|
-
code_model.rest = Rest.from_yaml(yaml_data, code_model=code_model)
|
|
168
197
|
if yaml_data.get("schemas"):
|
|
169
198
|
exceptions_set = CodeGenerator._build_exceptions_set(yaml_data=yaml_data["operationGroups"])
|
|
170
199
|
|
|
171
200
|
for type_list in yaml_data["schemas"].values():
|
|
172
201
|
for schema in type_list:
|
|
173
202
|
build_schema(yaml_data=schema, exceptions_set=exceptions_set, code_model=code_model)
|
|
174
|
-
code_model.add_schema_link_to_request_builder()
|
|
175
|
-
code_model.add_schema_link_to_global_parameters()
|
|
176
203
|
|
|
204
|
+
# Global parameters
|
|
205
|
+
code_model.global_parameters = GlobalParameterList(
|
|
206
|
+
code_model,
|
|
207
|
+
[Parameter.from_yaml(param, code_model=code_model) for param in yaml_data.get("globalParameters", [])],
|
|
208
|
+
)
|
|
209
|
+
code_model.global_parameters.code_model = code_model
|
|
210
|
+
|
|
211
|
+
# Custom URL
|
|
212
|
+
code_model.setup_client_input_parameters(yaml_data)
|
|
213
|
+
|
|
214
|
+
code_model.rest = Rest.from_yaml(yaml_data, code_model=code_model)
|
|
177
215
|
_build_convenience_layer(yaml_data=yaml_data, code_model=code_model)
|
|
178
216
|
|
|
179
217
|
if options["credential"]:
|
|
@@ -196,9 +234,13 @@ class CodeGenerator(Plugin):
|
|
|
196
234
|
)
|
|
197
235
|
return credential_scopes
|
|
198
236
|
|
|
199
|
-
def
|
|
200
|
-
self,
|
|
201
|
-
|
|
237
|
+
def _update_with_credential_flags(
|
|
238
|
+
self,
|
|
239
|
+
code_model: CodeModel,
|
|
240
|
+
credential_schema_policy: Type[CredentialSchemaPolicy],
|
|
241
|
+
credential_model: CredentialModel
|
|
242
|
+
):
|
|
243
|
+
credential_model.policy_type = credential_schema_policy
|
|
202
244
|
credential_scopes = self._get_credential_scopes(code_model.options['credential'])
|
|
203
245
|
credential_key_header_name = self._autorestapi.get_value('credential-key-header-name')
|
|
204
246
|
azure_arm = code_model.options['azure_arm']
|
|
@@ -227,38 +269,36 @@ class CodeGenerator(Plugin):
|
|
|
227
269
|
"name is tied with AzureKeyCredentialPolicy. Instead, with this policy it is recommend you "
|
|
228
270
|
"pass in --credential-scopes."
|
|
229
271
|
)
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
272
|
+
credential_model.credential_scopes = set(credential_scopes)
|
|
273
|
+
else:
|
|
274
|
+
# currently the only other credential policy is AzureKeyCredentialPolicy
|
|
275
|
+
if credential_scopes:
|
|
276
|
+
raise ValueError(
|
|
277
|
+
"You have passed in credential scopes with default credential policy type "
|
|
278
|
+
"AzureKeyCredentialPolicy. This is not allowed, since credential scopes is tied with "
|
|
279
|
+
f"{credential_model.default_authentication_policy.name()}. Instead, with this policy "
|
|
280
|
+
"you must pass in --credential-key-header-name."
|
|
281
|
+
)
|
|
282
|
+
if not credential_key_header_name:
|
|
283
|
+
credential_key_header_name = "api-key"
|
|
284
|
+
_LOGGER.info(
|
|
285
|
+
"Defaulting the AzureKeyCredentialPolicy header's name to 'api-key'"
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
credential_model.key_header_name = credential_key_header_name
|
|
289
|
+
|
|
290
|
+
def _build_with_credential_flags(self, code_model: CodeModel, credential_model: CredentialModel):
|
|
291
|
+
if not code_model.options["credential"]:
|
|
292
|
+
return
|
|
251
293
|
|
|
252
|
-
def _handle_default_authentication_policy(self, code_model: CodeModel):
|
|
253
294
|
credential_schema_policy_name = (
|
|
254
295
|
self._autorestapi.get_value("credential-default-policy-type") or
|
|
255
|
-
|
|
296
|
+
credential_model.default_authentication_policy.name()
|
|
256
297
|
)
|
|
257
298
|
credential_schema_policy_type = get_credential_schema_policy_type(credential_schema_policy_name)
|
|
258
|
-
|
|
259
|
-
code_model, credential_schema_policy_type
|
|
299
|
+
self._update_with_credential_flags(
|
|
300
|
+
code_model, credential_schema_policy_type, credential_model
|
|
260
301
|
)
|
|
261
|
-
code_model.credential_schema_policy = credential_schema_policy
|
|
262
302
|
|
|
263
303
|
def _build_code_model_options(self) -> Dict[str, Any]:
|
|
264
304
|
"""Build en options dict from the user input while running autorest.
|
|
@@ -90,18 +90,14 @@ class BaseSchema(BaseModel, ABC):
|
|
|
90
90
|
"""
|
|
91
91
|
...
|
|
92
92
|
|
|
93
|
-
@
|
|
94
|
-
def type_annotation(self) -> str:
|
|
93
|
+
@abstractmethod
|
|
94
|
+
def type_annotation(self, *, is_operation_file: bool = False) -> str:
|
|
95
95
|
"""The python type used for type annotation
|
|
96
96
|
|
|
97
97
|
Special case for enum, for instance: Union[str, "EnumName"]
|
|
98
98
|
"""
|
|
99
99
|
...
|
|
100
100
|
|
|
101
|
-
@property
|
|
102
|
-
def operation_type_annotation(self) -> str:
|
|
103
|
-
return self.type_annotation
|
|
104
|
-
|
|
105
101
|
def get_declaration(self, value: Any) -> str: # pylint: disable=no-self-use
|
|
106
102
|
"""Return the current value from YAML as a Python string that represents the constant.
|
|
107
103
|
|
|
@@ -102,3 +102,9 @@ class Client:
|
|
|
102
102
|
def send_request_signature(self, is_python3_file: bool) -> List[str]:
|
|
103
103
|
request_signature = ["request: HttpRequest," if is_python3_file else "request, # type: HttpRequest"]
|
|
104
104
|
return request_signature + self.parameters.method_signature_kwargs(is_python3_file)
|
|
105
|
+
|
|
106
|
+
@property
|
|
107
|
+
def filename(self) -> str:
|
|
108
|
+
if self.code_model.options["version_tolerant"] or self.code_model.options["low_level_client"]:
|
|
109
|
+
return "_client"
|
|
110
|
+
return f"_{self.code_model.module_name}"
|
|
@@ -3,14 +3,10 @@
|
|
|
3
3
|
# Licensed under the MIT License. See License.txt in the project root for
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
|
-
from itertools import chain
|
|
7
6
|
import logging
|
|
8
|
-
from typing import cast, List, Dict, Optional, Any, Set
|
|
7
|
+
from typing import cast, List, Dict, Optional, Any, Set
|
|
9
8
|
|
|
10
9
|
from .base_schema import BaseSchema
|
|
11
|
-
from .credential_schema_policy import (
|
|
12
|
-
ARMChallengeAuthenticationPolicy, BearerTokenCredentialPolicy, CredentialSchemaPolicy
|
|
13
|
-
)
|
|
14
10
|
from .enum_schema import EnumSchema
|
|
15
11
|
from .object_schema import ObjectSchema
|
|
16
12
|
from .operation_group import OperationGroup
|
|
@@ -20,12 +16,10 @@ from .paging_operation import PagingOperation
|
|
|
20
16
|
from .parameter import Parameter
|
|
21
17
|
from .client import Client
|
|
22
18
|
from .parameter_list import GlobalParameterList
|
|
23
|
-
from .schema_response import SchemaResponse
|
|
24
19
|
from .property import Property
|
|
25
|
-
from .primitive_schemas import IOSchema
|
|
26
20
|
from .request_builder import RequestBuilder
|
|
27
21
|
from .rest import Rest
|
|
28
|
-
|
|
22
|
+
from .credential_model import CredentialModel
|
|
29
23
|
|
|
30
24
|
_LOGGER = logging.getLogger(__name__)
|
|
31
25
|
|
|
@@ -53,6 +47,8 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
53
47
|
:type operation_groups: list[~autorest.models.OperationGroup]
|
|
54
48
|
:param package_dependency: All the dependencies needed in setup.py
|
|
55
49
|
:type package_dependency: Dict[str, str]
|
|
50
|
+
:param credential_model: The class contains all the credential info
|
|
51
|
+
:type credential_model: CredentialMode
|
|
56
52
|
"""
|
|
57
53
|
|
|
58
54
|
def __init__(
|
|
@@ -77,8 +73,8 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
77
73
|
self.service_client: Client = Client(self, params)
|
|
78
74
|
self._rest: Optional[Rest] = None
|
|
79
75
|
self.request_builder_ids: Dict[int, RequestBuilder] = {}
|
|
80
|
-
self._credential_schema_policy: Optional[CredentialSchemaPolicy] = None
|
|
81
76
|
self.package_dependency: Dict[str, str] = {}
|
|
77
|
+
self._credential_model: Optional[CredentialModel] = None
|
|
82
78
|
|
|
83
79
|
@property
|
|
84
80
|
def global_parameters(self) -> GlobalParameterList:
|
|
@@ -211,18 +207,14 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
211
207
|
return self.schemas or self.enums
|
|
212
208
|
|
|
213
209
|
@property
|
|
214
|
-
def
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
def credential_schema_policy(self) -> CredentialSchemaPolicy:
|
|
219
|
-
if not self._credential_schema_policy:
|
|
220
|
-
raise ValueError("You want to find the Credential Schema Policy, but have not given a value")
|
|
221
|
-
return self._credential_schema_policy
|
|
210
|
+
def credential_model(self) -> CredentialModel:
|
|
211
|
+
if not self._credential_model:
|
|
212
|
+
raise ValueError("You want to find the Credential Model, but have not given a value")
|
|
213
|
+
return self._credential_model
|
|
222
214
|
|
|
223
|
-
@
|
|
224
|
-
def
|
|
225
|
-
self.
|
|
215
|
+
@credential_model.setter
|
|
216
|
+
def credential_model(self, val: CredentialModel) -> None:
|
|
217
|
+
self._credential_model = val
|
|
226
218
|
|
|
227
219
|
@staticmethod
|
|
228
220
|
def _add_properties_from_inheritance_helper(schema, properties) -> List[Property]:
|
|
@@ -303,74 +295,33 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
303
295
|
return
|
|
304
296
|
raise KeyError("Didn't find the target property")
|
|
305
297
|
|
|
306
|
-
def _populate_schema(self, obj: Any) -> None:
|
|
307
|
-
schema_obj = obj.schema
|
|
308
|
-
if schema_obj and not isinstance(schema_obj, dict):
|
|
309
|
-
return
|
|
310
|
-
|
|
311
|
-
if schema_obj:
|
|
312
|
-
schema_obj_id = id(obj.schema)
|
|
313
|
-
_LOGGER.debug("Looking for id %s for member %s", schema_obj_id, obj)
|
|
314
|
-
try:
|
|
315
|
-
obj.schema = self.lookup_schema(schema_obj_id)
|
|
316
|
-
except KeyError:
|
|
317
|
-
_LOGGER.critical("Unable to ref the object")
|
|
318
|
-
raise
|
|
319
|
-
if isinstance(obj, Parameter) and obj.target_property_name:
|
|
320
|
-
self._populate_target_property(obj)
|
|
321
|
-
if isinstance(obj, SchemaResponse) and obj.is_stream_response:
|
|
322
|
-
obj.schema = IOSchema(namespace=None, yaml_data={})
|
|
323
|
-
|
|
324
|
-
def add_schema_link_to_operation(self) -> None:
|
|
325
|
-
"""Puts created schemas into operation classes `schema` property
|
|
326
|
-
|
|
327
|
-
:return: None
|
|
328
|
-
:rtype: None
|
|
329
|
-
"""
|
|
330
|
-
# Index schemas
|
|
331
|
-
for operation_group in self.operation_groups:
|
|
332
|
-
for operation in operation_group.operations:
|
|
333
|
-
for obj in chain(
|
|
334
|
-
operation.parameters,
|
|
335
|
-
operation.multiple_content_type_parameters or [],
|
|
336
|
-
operation.responses,
|
|
337
|
-
operation.exceptions,
|
|
338
|
-
chain.from_iterable(response.headers for response in operation.responses),
|
|
339
|
-
):
|
|
340
|
-
self._populate_schema(obj)
|
|
341
|
-
|
|
342
|
-
def add_schema_link_to_request_builder(self) -> None:
|
|
343
|
-
for request_builder in self.rest.request_builders:
|
|
344
|
-
for obj in chain(
|
|
345
|
-
request_builder.parameters,
|
|
346
|
-
chain.from_iterable(request.parameters for request in request_builder.schema_requests),
|
|
347
|
-
request_builder.responses,
|
|
348
|
-
):
|
|
349
|
-
self._populate_schema(obj)
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
def add_schema_link_to_global_parameters(self) -> None:
|
|
353
|
-
for parameter in self.global_parameters:
|
|
354
|
-
self._populate_schema(parameter)
|
|
355
|
-
|
|
356
298
|
def generate_single_parameter_from_multiple_content_types_operation(self) -> None:
|
|
357
299
|
for operation_group in self.operation_groups:
|
|
358
300
|
for operation in operation_group.operations:
|
|
359
301
|
if operation.multiple_content_type_parameters:
|
|
360
302
|
operation.convert_multiple_content_type_parameters()
|
|
361
303
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
304
|
+
def need_vendored_code(self, async_mode: bool) -> bool:
|
|
305
|
+
if async_mode:
|
|
306
|
+
return self.need_mixin_abc
|
|
307
|
+
return self.need_request_converter or self.need_format_url or self.need_mixin_abc
|
|
365
308
|
|
|
366
309
|
@property
|
|
367
310
|
def need_request_converter(self) -> bool:
|
|
368
|
-
return
|
|
311
|
+
return (
|
|
312
|
+
self.options["show_operations"] and
|
|
313
|
+
bool(self.rest.request_builders) and
|
|
314
|
+
not self.options["version_tolerant"]
|
|
315
|
+
)
|
|
369
316
|
|
|
370
317
|
@property
|
|
371
318
|
def need_format_url(self) -> bool:
|
|
372
319
|
return any(rq for rq in self.rest.request_builders if rq.parameters.path)
|
|
373
320
|
|
|
321
|
+
@property
|
|
322
|
+
def need_mixin_abc(self) -> bool:
|
|
323
|
+
return any(o for o in self.operation_groups if o.is_empty_operation_group and self.options["python3_only"])
|
|
324
|
+
|
|
374
325
|
@property
|
|
375
326
|
def has_lro_operations(self) -> bool:
|
|
376
327
|
return any([
|
|
@@ -400,3 +351,18 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
400
351
|
request_builder.name = request_builder.name + "_initial"
|
|
401
352
|
operation.request_builder = request_builder
|
|
402
353
|
operation.link_body_kwargs_to_body_params()
|
|
354
|
+
|
|
355
|
+
def get_models_filename(self, is_python3_file: bool) -> str:
|
|
356
|
+
if (
|
|
357
|
+
self.options["version_tolerant"] or self.options["low_level_client"]
|
|
358
|
+
) and self.options["python3_only"]:
|
|
359
|
+
return "_models"
|
|
360
|
+
if is_python3_file:
|
|
361
|
+
return "_models_py3"
|
|
362
|
+
return "_models"
|
|
363
|
+
|
|
364
|
+
@property
|
|
365
|
+
def enums_filename(self) -> str:
|
|
366
|
+
if self.options["version_tolerant"] or self.options["low_level_client"]:
|
|
367
|
+
return "_enums"
|
|
368
|
+
return f"_{self.module_name}_enums"
|
|
@@ -60,9 +60,8 @@ class ConstantSchema(BaseSchema):
|
|
|
60
60
|
"""
|
|
61
61
|
return self.schema.docstring_type
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
return self.schema.type_annotation
|
|
63
|
+
def type_annotation(self, *, is_operation_file: bool = False) -> str:
|
|
64
|
+
return self.schema.type_annotation(is_operation_file=is_operation_file)
|
|
66
65
|
|
|
67
66
|
@classmethod
|
|
68
67
|
def from_yaml(cls, namespace: str, yaml_data: Dict[str, Any], **kwargs) -> "ConstantSchema":
|
|
@@ -95,3 +94,8 @@ class ConstantSchema(BaseSchema):
|
|
|
95
94
|
file_import = FileImport()
|
|
96
95
|
file_import.merge(self.schema.imports())
|
|
97
96
|
return file_import
|
|
97
|
+
|
|
98
|
+
def model_file_imports(self) -> FileImport:
|
|
99
|
+
file_import = self.imports()
|
|
100
|
+
file_import.merge(self.schema.model_file_imports())
|
|
101
|
+
return file_import
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# -------------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
# Licensed under the MIT License. See License.txt in the project root for
|
|
4
|
+
# license information.
|
|
5
|
+
# --------------------------------------------------------------------------
|
|
6
|
+
from typing import Set, Optional, Type
|
|
7
|
+
from .credential_schema_policy import CredentialSchemaPolicy, BearerTokenCredentialPolicy
|
|
8
|
+
from .credential_schema_policy import ARMChallengeAuthenticationPolicy
|
|
9
|
+
from .credential_schema import TokenCredentialSchema, AzureKeyCredentialSchema
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class CredentialModel:
|
|
13
|
+
"""Store info about credential.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def __init__(
|
|
17
|
+
self,
|
|
18
|
+
azure_arm: bool
|
|
19
|
+
) -> None:
|
|
20
|
+
self.azure_arm: bool = azure_arm
|
|
21
|
+
self.credential_scopes: Set[str] = set()
|
|
22
|
+
self.key_header_name: str = ""
|
|
23
|
+
self.policy_type: Optional[Type[CredentialSchemaPolicy]] = None
|
|
24
|
+
self._credential_schema_policy: Optional[CredentialSchemaPolicy] = None
|
|
25
|
+
|
|
26
|
+
@property
|
|
27
|
+
def default_authentication_policy(self) -> Type[CredentialSchemaPolicy]:
|
|
28
|
+
return ARMChallengeAuthenticationPolicy if self.azure_arm else BearerTokenCredentialPolicy
|
|
29
|
+
|
|
30
|
+
@property
|
|
31
|
+
def credential_schema_policy(self) -> CredentialSchemaPolicy:
|
|
32
|
+
if not self._credential_schema_policy:
|
|
33
|
+
raise ValueError(
|
|
34
|
+
"You want to find the Credential Schema Policy, but have not given a value")
|
|
35
|
+
return self._credential_schema_policy
|
|
36
|
+
|
|
37
|
+
def build_authentication_policy(self):
|
|
38
|
+
if hasattr(self.policy_type, "credential_scopes"):
|
|
39
|
+
self._credential_schema_policy = self.policy_type( # pylint: disable=not-callable
|
|
40
|
+
credential=TokenCredentialSchema(async_mode=False),
|
|
41
|
+
credential_scopes=list(self.credential_scopes),
|
|
42
|
+
)
|
|
43
|
+
elif hasattr(self.policy_type, "credential_key_header_name"):
|
|
44
|
+
self._credential_schema_policy = self.policy_type( # pylint: disable=not-callable
|
|
45
|
+
credential=AzureKeyCredentialSchema(),
|
|
46
|
+
credential_key_header_name=self.key_header_name
|
|
47
|
+
)
|
|
@@ -11,6 +11,9 @@ class CredentialSchema(BaseSchema):
|
|
|
11
11
|
def __init__(self) -> None: # pylint: disable=super-init-not-called
|
|
12
12
|
self.default_value = None
|
|
13
13
|
|
|
14
|
+
def type_annotation(self, *, is_operation_file: bool = False) -> str:
|
|
15
|
+
raise ValueError("Children classes should set their own type annotation")
|
|
16
|
+
|
|
14
17
|
@property
|
|
15
18
|
def docstring_type(self) -> str:
|
|
16
19
|
return self.serialization_type
|
|
@@ -38,8 +41,7 @@ class AzureKeyCredentialSchema(CredentialSchema):
|
|
|
38
41
|
def serialization_type(self) -> str:
|
|
39
42
|
return "~azure.core.credentials.AzureKeyCredential"
|
|
40
43
|
|
|
41
|
-
|
|
42
|
-
def type_annotation(self) -> str:
|
|
44
|
+
def type_annotation(self, *, is_operation_file: bool = False) -> str: # pylint: disable=unused-argument
|
|
43
45
|
return "AzureKeyCredential"
|
|
44
46
|
|
|
45
47
|
def imports(self) -> FileImport:
|
|
@@ -66,8 +68,7 @@ class TokenCredentialSchema(CredentialSchema):
|
|
|
66
68
|
return self.async_type
|
|
67
69
|
return self.sync_type
|
|
68
70
|
|
|
69
|
-
|
|
70
|
-
def type_annotation(self) -> str:
|
|
71
|
+
def type_annotation(self, *, is_operation_file: bool = False) -> str: # pylint: disable=unused-argument
|
|
71
72
|
if self.async_mode:
|
|
72
73
|
return '"AsyncTokenCredential"'
|
|
73
74
|
return '"TokenCredential"'
|
|
@@ -34,18 +34,13 @@ class DictionarySchema(BaseSchema):
|
|
|
34
34
|
"""
|
|
35
35
|
return f"{{{self.element_type.serialization_type}}}"
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
def type_annotation(self) -> str:
|
|
37
|
+
def type_annotation(self, *, is_operation_file: bool = False) -> str:
|
|
39
38
|
"""The python type used for type annotation
|
|
40
39
|
|
|
41
40
|
:return: The type annotation for this schema
|
|
42
41
|
:rtype: str
|
|
43
42
|
"""
|
|
44
|
-
return f"Dict[str, {self.element_type.type_annotation}]"
|
|
45
|
-
|
|
46
|
-
@property
|
|
47
|
-
def operation_type_annotation(self) -> str:
|
|
48
|
-
return f"Dict[str, {self.element_type.operation_type_annotation}]"
|
|
43
|
+
return f"Dict[str, {self.element_type.type_annotation(is_operation_file=is_operation_file)}]"
|
|
49
44
|
|
|
50
45
|
@property
|
|
51
46
|
def docstring_text(self) -> str:
|
|
@@ -101,3 +96,8 @@ class DictionarySchema(BaseSchema):
|
|
|
101
96
|
file_import.add_submodule_import("typing", "Dict", ImportType.STDLIB, TypingSection.CONDITIONAL)
|
|
102
97
|
file_import.merge(self.element_type.imports())
|
|
103
98
|
return file_import
|
|
99
|
+
|
|
100
|
+
def model_file_imports(self) -> FileImport:
|
|
101
|
+
file_import = self.imports()
|
|
102
|
+
file_import.merge(self.element_type.model_file_imports())
|
|
103
|
+
return file_import
|