@autorest/python 5.15.0 → 5.16.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 +20 -0
- package/autorest/__init__.py +1 -2
- package/autorest/black/__init__.py +12 -5
- package/autorest/codegen/__init__.py +145 -73
- package/autorest/codegen/models/__init__.py +29 -18
- package/autorest/codegen/models/base_builder.py +48 -11
- package/autorest/codegen/models/base_model.py +6 -4
- package/autorest/codegen/models/base_schema.py +19 -18
- package/autorest/codegen/models/client.py +65 -21
- package/autorest/codegen/models/code_model.py +107 -61
- package/autorest/codegen/models/constant_schema.py +25 -13
- package/autorest/codegen/models/credential_model.py +23 -15
- package/autorest/codegen/models/credential_schema.py +18 -14
- package/autorest/codegen/models/credential_schema_policy.py +11 -15
- package/autorest/codegen/models/dictionary_schema.py +20 -17
- package/autorest/codegen/models/enum_schema.py +35 -25
- package/autorest/codegen/models/imports.py +70 -41
- package/autorest/codegen/models/list_schema.py +25 -13
- package/autorest/codegen/models/lro_operation.py +58 -22
- package/autorest/codegen/models/lro_paging_operation.py +2 -3
- package/autorest/codegen/models/object_schema.py +99 -49
- package/autorest/codegen/models/operation.py +236 -117
- package/autorest/codegen/models/operation_group.py +64 -34
- package/autorest/codegen/models/paging_operation.py +45 -18
- package/autorest/codegen/models/parameter.py +151 -83
- package/autorest/codegen/models/parameter_list.py +183 -162
- package/autorest/codegen/models/primitive_schemas.py +84 -55
- package/autorest/codegen/models/property.py +44 -26
- package/autorest/codegen/models/request_builder.py +65 -30
- package/autorest/codegen/models/request_builder_parameter.py +47 -23
- package/autorest/codegen/models/request_builder_parameter_list.py +77 -108
- package/autorest/codegen/models/schema_request.py +16 -6
- package/autorest/codegen/models/schema_response.py +18 -13
- package/autorest/codegen/models/utils.py +5 -2
- package/autorest/codegen/serializers/__init__.py +182 -91
- package/autorest/codegen/serializers/builder_serializer.py +667 -331
- package/autorest/codegen/serializers/client_serializer.py +98 -37
- package/autorest/codegen/serializers/general_serializer.py +61 -26
- package/autorest/codegen/serializers/import_serializer.py +93 -31
- package/autorest/codegen/serializers/metadata_serializer.py +73 -24
- package/autorest/codegen/serializers/model_base_serializer.py +35 -15
- package/autorest/codegen/serializers/model_generic_serializer.py +1 -4
- package/autorest/codegen/serializers/model_init_serializer.py +5 -1
- package/autorest/codegen/serializers/model_python3_serializer.py +7 -6
- package/autorest/codegen/serializers/operation_groups_serializer.py +20 -9
- package/autorest/codegen/serializers/operations_init_serializer.py +23 -11
- package/autorest/codegen/serializers/patch_serializer.py +4 -1
- package/autorest/codegen/serializers/{rest_serializer.py → request_builders_serializer.py} +29 -12
- package/autorest/codegen/serializers/utils.py +35 -21
- package/autorest/codegen/templates/init.py.jinja2 +2 -2
- package/autorest/codegen/templates/lro_operation.py.jinja2 +5 -7
- package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +5 -7
- package/autorest/codegen/templates/metadata.json.jinja2 +7 -6
- package/autorest/codegen/templates/operation.py.jinja2 +7 -9
- package/autorest/codegen/templates/operation_group.py.jinja2 +2 -8
- package/autorest/codegen/templates/operation_groups_container.py.jinja2 +1 -1
- package/autorest/codegen/templates/paging_operation.py.jinja2 +7 -8
- package/autorest/codegen/templates/request_builder.py.jinja2 +18 -11
- package/autorest/jsonrpc/__init__.py +7 -12
- package/autorest/jsonrpc/localapi.py +4 -3
- package/autorest/jsonrpc/server.py +13 -6
- package/autorest/jsonrpc/stdstream.py +13 -6
- package/autorest/m2r/__init__.py +5 -8
- package/autorest/multiapi/__init__.py +24 -14
- package/autorest/multiapi/models/client.py +21 -11
- package/autorest/multiapi/models/code_model.py +23 -10
- package/autorest/multiapi/models/config.py +4 -1
- package/autorest/multiapi/models/constant_global_parameter.py +1 -0
- package/autorest/multiapi/models/global_parameter.py +2 -1
- package/autorest/multiapi/models/global_parameters.py +14 -8
- package/autorest/multiapi/models/imports.py +24 -17
- package/autorest/multiapi/models/mixin_operation.py +5 -5
- package/autorest/multiapi/models/operation_group.py +2 -1
- package/autorest/multiapi/models/operation_mixin_group.py +21 -10
- package/autorest/multiapi/serializers/__init__.py +18 -23
- package/autorest/multiapi/serializers/import_serializer.py +47 -17
- package/autorest/multiapi/serializers/multiapi_serializer.py +17 -17
- package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +1 -1
- package/autorest/multiapi/utils.py +3 -3
- package/autorest/namer/__init__.py +2 -4
- package/autorest/namer/name_converter.py +200 -103
- package/autorest/namer/python_mappings.py +10 -22
- package/package.json +2 -2
- package/run-python3.js +2 -3
- package/venvtools.py +1 -1
- package/autorest/codegen/models/rest.py +0 -42
|
@@ -18,11 +18,11 @@ from .client import Client
|
|
|
18
18
|
from .parameter_list import GlobalParameterList
|
|
19
19
|
from .property import Property
|
|
20
20
|
from .request_builder import RequestBuilder
|
|
21
|
-
from .rest import Rest
|
|
22
21
|
from .credential_model import CredentialModel
|
|
23
22
|
|
|
24
23
|
_LOGGER = logging.getLogger(__name__)
|
|
25
24
|
|
|
25
|
+
|
|
26
26
|
class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-public-methods
|
|
27
27
|
"""Holds all of the information we have parsed out of the yaml file. The CodeModel is what gets
|
|
28
28
|
serialized by the serializers.
|
|
@@ -53,10 +53,16 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
53
53
|
|
|
54
54
|
def __init__(
|
|
55
55
|
self,
|
|
56
|
+
yaml_data: Dict[str, Any],
|
|
56
57
|
options: Dict[str, Any],
|
|
57
58
|
) -> None:
|
|
58
|
-
self.
|
|
59
|
-
self.
|
|
59
|
+
self.yaml_data = yaml_data
|
|
60
|
+
self.send_request_name = (
|
|
61
|
+
"send_request" if options["show_send_request"] else "_send_request"
|
|
62
|
+
)
|
|
63
|
+
self.rest_layer_name = (
|
|
64
|
+
"rest" if options["builders_visibility"] == "public" else "_rest"
|
|
65
|
+
)
|
|
60
66
|
self.options = options
|
|
61
67
|
self.module_name: str = ""
|
|
62
68
|
self.class_name: str = ""
|
|
@@ -71,8 +77,7 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
71
77
|
params = GlobalParameterList(self)
|
|
72
78
|
params.code_model = self
|
|
73
79
|
self.service_client: Client = Client(self, params)
|
|
74
|
-
self.
|
|
75
|
-
self.request_builder_ids: Dict[int, RequestBuilder] = {}
|
|
80
|
+
self.request_builders: List[RequestBuilder] = []
|
|
76
81
|
self.package_dependency: Dict[str, str] = {}
|
|
77
82
|
self._credential_model: Optional[CredentialModel] = None
|
|
78
83
|
|
|
@@ -84,16 +89,6 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
84
89
|
def global_parameters(self, val: GlobalParameterList) -> None:
|
|
85
90
|
self.service_client.parameters = val
|
|
86
91
|
|
|
87
|
-
@property
|
|
88
|
-
def rest(self) -> Rest:
|
|
89
|
-
if not self._rest:
|
|
90
|
-
raise ValueError("rest is None. Can not call it, you first have to set it.")
|
|
91
|
-
return self._rest
|
|
92
|
-
|
|
93
|
-
@rest.setter
|
|
94
|
-
def rest(self, p: Rest) -> None:
|
|
95
|
-
self._rest = p
|
|
96
|
-
|
|
97
92
|
def lookup_schema(self, schema_id: int) -> BaseSchema:
|
|
98
93
|
"""Looks to see if the schema has already been created.
|
|
99
94
|
|
|
@@ -108,6 +103,30 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
108
103
|
return elt_value
|
|
109
104
|
raise KeyError("Didn't find it!!!!!")
|
|
110
105
|
|
|
106
|
+
def lookup_request_builder(self, request_builder_id: int) -> RequestBuilder:
|
|
107
|
+
"""Find the request builder based off of id"""
|
|
108
|
+
try:
|
|
109
|
+
return next(
|
|
110
|
+
rb
|
|
111
|
+
for rb in self.request_builders
|
|
112
|
+
if id(rb.yaml_data) == request_builder_id
|
|
113
|
+
)
|
|
114
|
+
except StopIteration:
|
|
115
|
+
raise KeyError(f"No request builder with id {request_builder_id} found.")
|
|
116
|
+
|
|
117
|
+
@property
|
|
118
|
+
def exception_ids(self) -> Set[int]:
|
|
119
|
+
exceptions_set = set()
|
|
120
|
+
for group in self.yaml_data["operationGroups"]:
|
|
121
|
+
for operation in group["operations"]:
|
|
122
|
+
if not operation.get("exceptions"):
|
|
123
|
+
continue
|
|
124
|
+
for exception in operation["exceptions"]:
|
|
125
|
+
if not exception.get("schema"):
|
|
126
|
+
continue
|
|
127
|
+
exceptions_set.add(id(exception["schema"]))
|
|
128
|
+
return exceptions_set
|
|
129
|
+
|
|
111
130
|
@staticmethod
|
|
112
131
|
def _sort_schemas_helper(current, seen_schema_names, seen_schema_yaml_ids):
|
|
113
132
|
if current.id in seen_schema_yaml_ids:
|
|
@@ -124,12 +143,16 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
124
143
|
continue
|
|
125
144
|
seen_schema_names.add(current.name)
|
|
126
145
|
seen_schema_yaml_ids.add(current.id)
|
|
127
|
-
ancestors =
|
|
146
|
+
ancestors = (
|
|
147
|
+
CodeModel._sort_schemas_helper(
|
|
148
|
+
parent, seen_schema_names, seen_schema_yaml_ids
|
|
149
|
+
)
|
|
150
|
+
+ ancestors
|
|
151
|
+
)
|
|
128
152
|
seen_schema_names.add(current.name)
|
|
129
153
|
seen_schema_yaml_ids.add(current.id)
|
|
130
154
|
return ancestors
|
|
131
155
|
|
|
132
|
-
|
|
133
156
|
def sort_schemas(self) -> None:
|
|
134
157
|
"""Sorts the final object schemas by inheritance and by alphabetical order.
|
|
135
158
|
|
|
@@ -140,12 +163,17 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
140
163
|
seen_schema_yaml_ids: Set[int] = set()
|
|
141
164
|
sorted_schemas: List[ObjectSchema] = []
|
|
142
165
|
for schema in sorted(self.schemas.values(), key=lambda x: x.name.lower()):
|
|
143
|
-
sorted_schemas.extend(
|
|
166
|
+
sorted_schemas.extend(
|
|
167
|
+
CodeModel._sort_schemas_helper(
|
|
168
|
+
schema, seen_schema_names, seen_schema_yaml_ids
|
|
169
|
+
)
|
|
170
|
+
)
|
|
144
171
|
self.sorted_schemas = sorted_schemas
|
|
145
172
|
|
|
146
173
|
def setup_client_input_parameters(self, yaml_data: Dict[str, Any]):
|
|
147
174
|
dollar_host = [
|
|
148
|
-
parameter
|
|
175
|
+
parameter
|
|
176
|
+
for parameter in self.global_parameters
|
|
149
177
|
if parameter.rest_api_name == "$host"
|
|
150
178
|
]
|
|
151
179
|
if not dollar_host:
|
|
@@ -153,14 +181,18 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
153
181
|
# So far now, let's get the first one in the first operation
|
|
154
182
|
# UGLY as hell.....
|
|
155
183
|
if yaml_data.get("operationGroups"):
|
|
156
|
-
first_req_of_first_op_of_first_grp = yaml_data["operationGroups"][0][
|
|
184
|
+
first_req_of_first_op_of_first_grp = yaml_data["operationGroups"][0][
|
|
185
|
+
"operations"
|
|
186
|
+
][0]["requests"][0]
|
|
157
187
|
self.service_client.parameterized_host_template = (
|
|
158
188
|
first_req_of_first_op_of_first_grp["protocol"]["http"]["uri"]
|
|
159
189
|
)
|
|
160
190
|
else:
|
|
161
191
|
for host in dollar_host:
|
|
162
192
|
self.global_parameters.remove(host)
|
|
163
|
-
self.service_client.parameters.add_host(
|
|
193
|
+
self.service_client.parameters.add_host(
|
|
194
|
+
dollar_host[0].yaml_data["clientDefaultValue"]
|
|
195
|
+
)
|
|
164
196
|
|
|
165
197
|
def format_lro_operations(self) -> None:
|
|
166
198
|
"""Adds operations and attributes needed for LROs.
|
|
@@ -177,8 +209,8 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
177
209
|
i += 1
|
|
178
210
|
|
|
179
211
|
def remove_next_operation(self) -> None:
|
|
180
|
-
"""Linking paging operations together.
|
|
181
|
-
|
|
212
|
+
"""Linking paging operations together."""
|
|
213
|
+
|
|
182
214
|
def _lookup_operation(yaml_id: int) -> Operation:
|
|
183
215
|
for operation_group in self.operation_groups:
|
|
184
216
|
for operation in operation_group.operations:
|
|
@@ -191,15 +223,21 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
191
223
|
for operation in operation_group.operations:
|
|
192
224
|
# when we add in "LRO" functions we don't include yaml_data, so yaml_data can be empty in these cases
|
|
193
225
|
next_link_yaml = None
|
|
194
|
-
if operation.yaml_data and operation.yaml_data[
|
|
195
|
-
|
|
226
|
+
if operation.yaml_data and operation.yaml_data["language"][
|
|
227
|
+
"python"
|
|
228
|
+
].get("paging"):
|
|
229
|
+
next_link_yaml = operation.yaml_data["language"]["python"][
|
|
230
|
+
"paging"
|
|
231
|
+
].get("nextLinkOperation")
|
|
196
232
|
if isinstance(operation, PagingOperation) and next_link_yaml:
|
|
197
233
|
next_operation = _lookup_operation(id(next_link_yaml))
|
|
198
234
|
operation.next_operation = next_operation
|
|
199
235
|
next_operations.append(next_operation)
|
|
200
236
|
|
|
201
237
|
operation_group.operations = [
|
|
202
|
-
operation
|
|
238
|
+
operation
|
|
239
|
+
for operation in operation_group.operations
|
|
240
|
+
if operation not in next_operations
|
|
203
241
|
]
|
|
204
242
|
|
|
205
243
|
@property
|
|
@@ -209,7 +247,9 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
209
247
|
@property
|
|
210
248
|
def credential_model(self) -> CredentialModel:
|
|
211
249
|
if not self._credential_model:
|
|
212
|
-
raise ValueError(
|
|
250
|
+
raise ValueError(
|
|
251
|
+
"You want to find the Credential Model, but have not given a value"
|
|
252
|
+
)
|
|
213
253
|
return self._credential_model
|
|
214
254
|
|
|
215
255
|
@credential_model.setter
|
|
@@ -225,14 +265,17 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
225
265
|
parent = cast(ObjectSchema, base_model)
|
|
226
266
|
# need to make sure that the properties we choose from our parent also don't contain
|
|
227
267
|
# any of our own properties
|
|
228
|
-
schema_property_names = set(
|
|
268
|
+
schema_property_names = set(
|
|
269
|
+
[p.name for p in properties] + [p.name for p in schema.properties]
|
|
270
|
+
)
|
|
229
271
|
chosen_parent_properties = [
|
|
230
|
-
p for p in parent.properties
|
|
231
|
-
if p.name not in schema_property_names
|
|
272
|
+
p for p in parent.properties if p.name not in schema_property_names
|
|
232
273
|
]
|
|
233
274
|
properties = (
|
|
234
|
-
CodeModel._add_properties_from_inheritance_helper(
|
|
235
|
-
|
|
275
|
+
CodeModel._add_properties_from_inheritance_helper(
|
|
276
|
+
parent, chosen_parent_properties
|
|
277
|
+
)
|
|
278
|
+
+ properties
|
|
236
279
|
)
|
|
237
280
|
|
|
238
281
|
return properties
|
|
@@ -253,7 +296,9 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
253
296
|
:rtype: None
|
|
254
297
|
"""
|
|
255
298
|
for schema in self.schemas.values():
|
|
256
|
-
schema.properties = CodeModel._add_properties_from_inheritance_helper(
|
|
299
|
+
schema.properties = CodeModel._add_properties_from_inheritance_helper(
|
|
300
|
+
schema, schema.properties
|
|
301
|
+
)
|
|
257
302
|
|
|
258
303
|
@staticmethod
|
|
259
304
|
def _add_exceptions_from_inheritance_helper(schema) -> bool:
|
|
@@ -262,7 +307,9 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
262
307
|
parent_is_exception: List[bool] = []
|
|
263
308
|
for base_model in schema.base_models:
|
|
264
309
|
parent = cast(ObjectSchema, base_model)
|
|
265
|
-
parent_is_exception.append(
|
|
310
|
+
parent_is_exception.append(
|
|
311
|
+
CodeModel._add_exceptions_from_inheritance_helper(parent)
|
|
312
|
+
)
|
|
266
313
|
return any(parent_is_exception)
|
|
267
314
|
|
|
268
315
|
def _add_exceptions_from_inheritance(self) -> None:
|
|
@@ -272,7 +319,9 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
272
319
|
:rtype: None
|
|
273
320
|
"""
|
|
274
321
|
for schema in self.schemas.values():
|
|
275
|
-
schema.is_exception = CodeModel._add_exceptions_from_inheritance_helper(
|
|
322
|
+
schema.is_exception = CodeModel._add_exceptions_from_inheritance_helper(
|
|
323
|
+
schema
|
|
324
|
+
)
|
|
276
325
|
|
|
277
326
|
def add_inheritance_to_models(self) -> None:
|
|
278
327
|
"""Adds base classes and properties from base classes to schemas with parents.
|
|
@@ -283,7 +332,9 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
283
332
|
for schema in self.schemas.values():
|
|
284
333
|
if schema.base_models:
|
|
285
334
|
# right now, the base model property just holds the name of the parent class
|
|
286
|
-
schema.base_models = [
|
|
335
|
+
schema.base_models = [
|
|
336
|
+
b for b in self.schemas.values() if b.id in schema.base_models
|
|
337
|
+
]
|
|
287
338
|
self._add_properties_from_inheritance()
|
|
288
339
|
self._add_exceptions_from_inheritance()
|
|
289
340
|
|
|
@@ -304,49 +355,44 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
304
355
|
def need_vendored_code(self, async_mode: bool) -> bool:
|
|
305
356
|
if async_mode:
|
|
306
357
|
return self.need_mixin_abc
|
|
307
|
-
return
|
|
358
|
+
return (
|
|
359
|
+
self.need_request_converter or self.need_format_url or self.need_mixin_abc
|
|
360
|
+
)
|
|
308
361
|
|
|
309
362
|
@property
|
|
310
363
|
def need_request_converter(self) -> bool:
|
|
311
364
|
return (
|
|
312
|
-
self.options["show_operations"]
|
|
313
|
-
bool(self.
|
|
314
|
-
not self.options["version_tolerant"]
|
|
365
|
+
self.options["show_operations"]
|
|
366
|
+
and bool(self.request_builders)
|
|
367
|
+
and not self.options["version_tolerant"]
|
|
315
368
|
)
|
|
316
369
|
|
|
317
370
|
@property
|
|
318
371
|
def need_format_url(self) -> bool:
|
|
319
|
-
return any(rq for rq in self.
|
|
372
|
+
return any(rq for rq in self.request_builders if rq.parameters.path)
|
|
320
373
|
|
|
321
374
|
@property
|
|
322
375
|
def need_mixin_abc(self) -> bool:
|
|
323
|
-
return any(
|
|
376
|
+
return any(
|
|
377
|
+
o
|
|
378
|
+
for o in self.operation_groups
|
|
379
|
+
if o.is_empty_operation_group and self.options["python3_only"]
|
|
380
|
+
)
|
|
324
381
|
|
|
325
382
|
@property
|
|
326
383
|
def has_lro_operations(self) -> bool:
|
|
327
|
-
return any(
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
"""Looks to see if the schema has already been created.
|
|
335
|
-
|
|
336
|
-
:param int schema_id: The yaml id of the schema
|
|
337
|
-
:return: If created, we return the created schema, otherwise, we throw.
|
|
338
|
-
:rtype: ~autorest.models.RequestBuilder
|
|
339
|
-
:raises: KeyError if schema is not found
|
|
340
|
-
"""
|
|
341
|
-
for elt_key, elt_value in self.request_builder_ids.items(): # type: ignore
|
|
342
|
-
if schema_id == elt_key:
|
|
343
|
-
return elt_value
|
|
344
|
-
raise KeyError("Didn't find it!!!!!")
|
|
384
|
+
return any(
|
|
385
|
+
[
|
|
386
|
+
isinstance(operation, LROOperation)
|
|
387
|
+
for operation_group in self.operation_groups
|
|
388
|
+
for operation in operation_group.operations
|
|
389
|
+
]
|
|
390
|
+
)
|
|
345
391
|
|
|
346
392
|
def link_operation_to_request_builder(self) -> None:
|
|
347
393
|
for operation_group in self.operation_groups:
|
|
348
394
|
for operation in operation_group.operations:
|
|
349
|
-
request_builder =
|
|
395
|
+
request_builder = operation.request_builder
|
|
350
396
|
if isinstance(operation, LROOperation):
|
|
351
397
|
request_builder.name = request_builder.name + "_initial"
|
|
352
398
|
operation.request_builder = request_builder
|
|
@@ -4,11 +4,14 @@
|
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
6
|
import logging
|
|
7
|
-
from typing import Dict, Any, Optional
|
|
7
|
+
from typing import Dict, Any, Optional, TYPE_CHECKING
|
|
8
8
|
from .base_schema import BaseSchema
|
|
9
9
|
from .primitive_schemas import get_primitive_schema, PrimitiveSchema
|
|
10
10
|
from .imports import FileImport
|
|
11
11
|
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from .code_model import CodeModel
|
|
14
|
+
|
|
12
15
|
_LOGGER = logging.getLogger(__name__)
|
|
13
16
|
|
|
14
17
|
|
|
@@ -23,9 +26,13 @@ class ConstantSchema(BaseSchema):
|
|
|
23
26
|
"""
|
|
24
27
|
|
|
25
28
|
def __init__(
|
|
26
|
-
self,
|
|
29
|
+
self,
|
|
30
|
+
yaml_data: Dict[str, Any],
|
|
31
|
+
code_model: "CodeModel",
|
|
32
|
+
schema: PrimitiveSchema,
|
|
33
|
+
value: Optional[str],
|
|
27
34
|
) -> None:
|
|
28
|
-
super(
|
|
35
|
+
super().__init__(yaml_data=yaml_data, code_model=code_model)
|
|
29
36
|
self.value = value
|
|
30
37
|
self.schema = schema
|
|
31
38
|
|
|
@@ -33,7 +40,8 @@ class ConstantSchema(BaseSchema):
|
|
|
33
40
|
if value != self.value:
|
|
34
41
|
_LOGGER.warning(
|
|
35
42
|
"Passed in value of %s differs from constant value of %s. Choosing constant value",
|
|
36
|
-
str(value),
|
|
43
|
+
str(value),
|
|
44
|
+
str(self.value),
|
|
37
45
|
)
|
|
38
46
|
if self.value is None:
|
|
39
47
|
return "None"
|
|
@@ -64,7 +72,9 @@ class ConstantSchema(BaseSchema):
|
|
|
64
72
|
return self.schema.type_annotation(is_operation_file=is_operation_file)
|
|
65
73
|
|
|
66
74
|
@classmethod
|
|
67
|
-
def from_yaml(
|
|
75
|
+
def from_yaml(
|
|
76
|
+
cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
|
|
77
|
+
) -> "ConstantSchema":
|
|
68
78
|
"""Constructs a ConstantSchema from yaml data.
|
|
69
79
|
|
|
70
80
|
:param yaml_data: the yaml data from which we will construct this schema
|
|
@@ -73,23 +83,25 @@ class ConstantSchema(BaseSchema):
|
|
|
73
83
|
:return: A created ConstantSchema
|
|
74
84
|
:rtype: ~autorest.models.ConstantSchema
|
|
75
85
|
"""
|
|
76
|
-
name =
|
|
86
|
+
name = (
|
|
87
|
+
yaml_data["language"]["python"]["name"]
|
|
88
|
+
if yaml_data["language"]["python"].get("name")
|
|
89
|
+
else ""
|
|
90
|
+
)
|
|
77
91
|
_LOGGER.debug("Parsing %s constant", name)
|
|
78
92
|
return cls(
|
|
79
|
-
namespace=namespace,
|
|
80
93
|
yaml_data=yaml_data,
|
|
81
|
-
|
|
94
|
+
code_model=code_model,
|
|
95
|
+
schema=get_primitive_schema(
|
|
96
|
+
yaml_data=yaml_data["valueType"], code_model=code_model
|
|
97
|
+
),
|
|
82
98
|
value=yaml_data.get("value", {}).get("value", None),
|
|
83
99
|
)
|
|
84
100
|
|
|
85
101
|
def get_json_template_representation(self, **kwargs: Any) -> Any:
|
|
86
|
-
kwargs[
|
|
102
|
+
kwargs["default_value_declaration"] = self.schema.get_declaration(self.value)
|
|
87
103
|
return self.schema.get_json_template_representation(**kwargs)
|
|
88
104
|
|
|
89
|
-
def get_files_and_data_template_representation(self, **kwargs: Any) -> Any:
|
|
90
|
-
kwargs['default_value_declaration'] = self.schema.get_declaration(self.value)
|
|
91
|
-
return self.schema.get_files_and_data_template_representation(**kwargs)
|
|
92
|
-
|
|
93
105
|
def imports(self) -> FileImport:
|
|
94
106
|
file_import = FileImport()
|
|
95
107
|
file_import.merge(self.schema.imports())
|
|
@@ -4,19 +4,18 @@
|
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
6
|
from typing import Set, Optional, Type
|
|
7
|
-
from .credential_schema_policy import
|
|
7
|
+
from .credential_schema_policy import (
|
|
8
|
+
CredentialSchemaPolicy,
|
|
9
|
+
BearerTokenCredentialPolicy,
|
|
10
|
+
)
|
|
8
11
|
from .credential_schema_policy import ARMChallengeAuthenticationPolicy
|
|
9
12
|
from .credential_schema import TokenCredentialSchema, AzureKeyCredentialSchema
|
|
10
13
|
|
|
11
14
|
|
|
12
15
|
class CredentialModel:
|
|
13
|
-
"""Store info about credential.
|
|
14
|
-
"""
|
|
16
|
+
"""Store info about credential."""
|
|
15
17
|
|
|
16
|
-
def __init__(
|
|
17
|
-
self,
|
|
18
|
-
azure_arm: bool
|
|
19
|
-
) -> None:
|
|
18
|
+
def __init__(self, azure_arm: bool) -> None:
|
|
20
19
|
self.azure_arm: bool = azure_arm
|
|
21
20
|
self.credential_scopes: Set[str] = set()
|
|
22
21
|
self.key_header_name: str = ""
|
|
@@ -25,23 +24,32 @@ class CredentialModel:
|
|
|
25
24
|
|
|
26
25
|
@property
|
|
27
26
|
def default_authentication_policy(self) -> Type[CredentialSchemaPolicy]:
|
|
28
|
-
return
|
|
27
|
+
return (
|
|
28
|
+
ARMChallengeAuthenticationPolicy
|
|
29
|
+
if self.azure_arm
|
|
30
|
+
else BearerTokenCredentialPolicy
|
|
31
|
+
)
|
|
29
32
|
|
|
30
33
|
@property
|
|
31
34
|
def credential_schema_policy(self) -> CredentialSchemaPolicy:
|
|
32
35
|
if not self._credential_schema_policy:
|
|
33
36
|
raise ValueError(
|
|
34
|
-
"You want to find the Credential Schema Policy, but have not given a value"
|
|
37
|
+
"You want to find the Credential Schema Policy, but have not given a value"
|
|
38
|
+
)
|
|
35
39
|
return self._credential_schema_policy
|
|
36
40
|
|
|
37
41
|
def build_authentication_policy(self):
|
|
38
42
|
if hasattr(self.policy_type, "credential_scopes"):
|
|
39
|
-
self._credential_schema_policy =
|
|
40
|
-
|
|
41
|
-
|
|
43
|
+
self._credential_schema_policy = (
|
|
44
|
+
self.policy_type( # pylint: disable=not-callable
|
|
45
|
+
credential=TokenCredentialSchema(async_mode=False),
|
|
46
|
+
credential_scopes=list(self.credential_scopes),
|
|
47
|
+
)
|
|
42
48
|
)
|
|
43
49
|
elif hasattr(self.policy_type, "credential_key_header_name"):
|
|
44
|
-
self._credential_schema_policy =
|
|
45
|
-
|
|
46
|
-
|
|
50
|
+
self._credential_schema_policy = (
|
|
51
|
+
self.policy_type( # pylint: disable=not-callable
|
|
52
|
+
credential=AzureKeyCredentialSchema(),
|
|
53
|
+
credential_key_header_name=self.key_header_name,
|
|
54
|
+
)
|
|
47
55
|
)
|
|
@@ -7,6 +7,7 @@ from typing import Any
|
|
|
7
7
|
from .base_schema import BaseSchema
|
|
8
8
|
from .imports import FileImport, ImportType, TypingSection
|
|
9
9
|
|
|
10
|
+
|
|
10
11
|
class CredentialSchema(BaseSchema):
|
|
11
12
|
def __init__(self) -> None: # pylint: disable=super-init-not-called
|
|
12
13
|
self.default_value = None
|
|
@@ -29,19 +30,19 @@ class CredentialSchema(BaseSchema):
|
|
|
29
30
|
pass
|
|
30
31
|
|
|
31
32
|
def get_json_template_representation(self, **kwargs: Any) -> Any:
|
|
32
|
-
raise TypeError(
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
raise TypeError("You should not try to get a files template representation of a CredentialSchema")
|
|
33
|
+
raise TypeError(
|
|
34
|
+
"You should not try to get a JSON template representation of a CredentialSchema"
|
|
35
|
+
)
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
class AzureKeyCredentialSchema(CredentialSchema):
|
|
39
|
-
|
|
40
39
|
@property
|
|
41
40
|
def serialization_type(self) -> str:
|
|
42
41
|
return "~azure.core.credentials.AzureKeyCredential"
|
|
43
42
|
|
|
44
|
-
def type_annotation(
|
|
43
|
+
def type_annotation(
|
|
44
|
+
self, *, is_operation_file: bool = False # pylint: disable=unused-argument
|
|
45
|
+
) -> str:
|
|
45
46
|
return "AzureKeyCredential"
|
|
46
47
|
|
|
47
48
|
def imports(self) -> FileImport:
|
|
@@ -50,14 +51,14 @@ class AzureKeyCredentialSchema(CredentialSchema):
|
|
|
50
51
|
"azure.core.credentials",
|
|
51
52
|
"AzureKeyCredential",
|
|
52
53
|
ImportType.AZURECORE,
|
|
53
|
-
typing_section=TypingSection.CONDITIONAL
|
|
54
|
+
typing_section=TypingSection.CONDITIONAL,
|
|
54
55
|
)
|
|
55
56
|
return file_import
|
|
56
57
|
|
|
57
58
|
|
|
58
59
|
class TokenCredentialSchema(CredentialSchema):
|
|
59
60
|
def __init__(self, async_mode) -> None:
|
|
60
|
-
super(
|
|
61
|
+
super().__init__()
|
|
61
62
|
self.async_mode = async_mode
|
|
62
63
|
self.async_type = "~azure.core.credentials_async.AsyncTokenCredential"
|
|
63
64
|
self.sync_type = "~azure.core.credentials.TokenCredential"
|
|
@@ -68,24 +69,27 @@ class TokenCredentialSchema(CredentialSchema):
|
|
|
68
69
|
return self.async_type
|
|
69
70
|
return self.sync_type
|
|
70
71
|
|
|
71
|
-
def type_annotation(
|
|
72
|
+
def type_annotation(
|
|
73
|
+
self, *, is_operation_file: bool = False # pylint: disable=unused-argument
|
|
74
|
+
) -> str:
|
|
72
75
|
if self.async_mode:
|
|
73
76
|
return '"AsyncTokenCredential"'
|
|
74
77
|
return '"TokenCredential"'
|
|
75
78
|
|
|
76
|
-
|
|
77
79
|
def imports(self) -> FileImport:
|
|
78
80
|
file_import = FileImport()
|
|
79
81
|
if self.async_mode:
|
|
80
82
|
file_import.add_submodule_import(
|
|
81
|
-
"azure.core.credentials_async",
|
|
83
|
+
"azure.core.credentials_async",
|
|
84
|
+
"AsyncTokenCredential",
|
|
82
85
|
ImportType.AZURECORE,
|
|
83
|
-
typing_section=TypingSection.TYPING
|
|
86
|
+
typing_section=TypingSection.TYPING,
|
|
84
87
|
)
|
|
85
88
|
else:
|
|
86
89
|
file_import.add_submodule_import(
|
|
87
|
-
"azure.core.credentials",
|
|
90
|
+
"azure.core.credentials",
|
|
91
|
+
"TokenCredential",
|
|
88
92
|
ImportType.AZURECORE,
|
|
89
|
-
typing_section=TypingSection.TYPING
|
|
93
|
+
typing_section=TypingSection.TYPING,
|
|
90
94
|
)
|
|
91
95
|
return file_import
|
|
@@ -7,9 +7,9 @@ from abc import abstractmethod
|
|
|
7
7
|
from typing import List
|
|
8
8
|
from .credential_schema import CredentialSchema
|
|
9
9
|
|
|
10
|
-
class CredentialSchemaPolicy:
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
class CredentialSchemaPolicy:
|
|
12
|
+
def __init__(self, credential: CredentialSchema) -> None:
|
|
13
13
|
self.credential = credential
|
|
14
14
|
|
|
15
15
|
@abstractmethod
|
|
@@ -22,11 +22,8 @@ class CredentialSchemaPolicy:
|
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
class BearerTokenCredentialPolicy(CredentialSchemaPolicy):
|
|
25
|
-
|
|
26
25
|
def __init__(
|
|
27
|
-
self,
|
|
28
|
-
credential: CredentialSchema,
|
|
29
|
-
credential_scopes: List[str]
|
|
26
|
+
self, credential: CredentialSchema, credential_scopes: List[str]
|
|
30
27
|
) -> None:
|
|
31
28
|
super().__init__(credential)
|
|
32
29
|
self._credential_scopes = credential_scopes
|
|
@@ -41,18 +38,14 @@ class BearerTokenCredentialPolicy(CredentialSchemaPolicy):
|
|
|
41
38
|
|
|
42
39
|
|
|
43
40
|
class ARMChallengeAuthenticationPolicy(BearerTokenCredentialPolicy):
|
|
44
|
-
|
|
45
41
|
def call(self, async_mode: bool) -> str:
|
|
46
42
|
policy_name = f"Async{self.name()}" if async_mode else self.name()
|
|
47
43
|
return f"{policy_name}(self.credential, *self.credential_scopes, **kwargs)"
|
|
48
44
|
|
|
49
45
|
|
|
50
46
|
class AzureKeyCredentialPolicy(CredentialSchemaPolicy):
|
|
51
|
-
|
|
52
47
|
def __init__(
|
|
53
|
-
self,
|
|
54
|
-
credential: CredentialSchema,
|
|
55
|
-
credential_key_header_name: str
|
|
48
|
+
self, credential: CredentialSchema, credential_key_header_name: str
|
|
56
49
|
) -> None:
|
|
57
50
|
super().__init__(credential)
|
|
58
51
|
self._credential_key_header_name = credential_key_header_name
|
|
@@ -64,14 +57,17 @@ class AzureKeyCredentialPolicy(CredentialSchemaPolicy):
|
|
|
64
57
|
def call(self, async_mode: bool) -> str:
|
|
65
58
|
return f'policies.AzureKeyCredentialPolicy(self.credential, "{self.credential_key_header_name}", **kwargs)'
|
|
66
59
|
|
|
60
|
+
|
|
67
61
|
def get_credential_schema_policy_type(name):
|
|
68
|
-
policies = [
|
|
62
|
+
policies = [
|
|
63
|
+
ARMChallengeAuthenticationPolicy,
|
|
64
|
+
BearerTokenCredentialPolicy,
|
|
65
|
+
AzureKeyCredentialPolicy,
|
|
66
|
+
]
|
|
69
67
|
try:
|
|
70
68
|
return next(p for p in policies if p.name().lower() == name.lower())
|
|
71
69
|
except StopIteration:
|
|
72
70
|
raise ValueError(
|
|
73
71
|
"The credential policy you pass in with --credential-default-policy-type must be either "
|
|
74
|
-
"{}".format(
|
|
75
|
-
" or ".join([p.name() for p in policies])
|
|
76
|
-
)
|
|
72
|
+
"{}".format(" or ".join([p.name() for p in policies]))
|
|
77
73
|
)
|