@autorest/python 5.15.0 → 5.18.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 +98 -4
- package/README.md +30 -4
- package/autorest/__init__.py +2 -3
- package/autorest/black/__init__.py +12 -5
- package/autorest/codegen/__init__.py +122 -211
- package/autorest/codegen/models/__init__.py +122 -78
- package/autorest/codegen/models/base_builder.py +70 -72
- package/autorest/codegen/models/base_model.py +7 -5
- package/autorest/codegen/models/{base_schema.py → base_type.py} +68 -45
- package/autorest/codegen/models/client.py +193 -40
- package/autorest/codegen/models/code_model.py +145 -245
- package/autorest/codegen/models/combined_type.py +107 -0
- package/autorest/codegen/models/constant_type.py +122 -0
- package/autorest/codegen/models/credential_types.py +224 -0
- package/autorest/codegen/models/dictionary_type.py +131 -0
- package/autorest/codegen/models/enum_type.py +195 -0
- package/autorest/codegen/models/imports.py +93 -41
- package/autorest/codegen/models/list_type.py +149 -0
- package/autorest/codegen/models/lro_operation.py +90 -133
- package/autorest/codegen/models/lro_paging_operation.py +28 -12
- package/autorest/codegen/models/model_type.py +262 -0
- package/autorest/codegen/models/operation.py +412 -259
- package/autorest/codegen/models/operation_group.py +80 -91
- package/autorest/codegen/models/paging_operation.py +101 -117
- package/autorest/codegen/models/parameter.py +302 -341
- package/autorest/codegen/models/parameter_list.py +373 -357
- package/autorest/codegen/models/primitive_types.py +544 -0
- package/autorest/codegen/models/property.py +136 -134
- package/autorest/codegen/models/request_builder.py +138 -86
- package/autorest/codegen/models/request_builder_parameter.py +122 -86
- package/autorest/codegen/models/response.py +325 -0
- package/autorest/codegen/models/utils.py +13 -17
- package/autorest/codegen/serializers/__init__.py +212 -112
- package/autorest/codegen/serializers/builder_serializer.py +931 -1040
- package/autorest/codegen/serializers/client_serializer.py +140 -84
- package/autorest/codegen/serializers/general_serializer.py +26 -50
- package/autorest/codegen/serializers/import_serializer.py +96 -31
- package/autorest/codegen/serializers/metadata_serializer.py +39 -79
- package/autorest/codegen/serializers/model_base_serializer.py +62 -34
- package/autorest/codegen/serializers/model_generic_serializer.py +9 -10
- package/autorest/codegen/serializers/model_init_serializer.py +4 -2
- package/autorest/codegen/serializers/model_python3_serializer.py +29 -22
- package/autorest/codegen/serializers/operation_groups_serializer.py +21 -19
- package/autorest/codegen/serializers/operations_init_serializer.py +23 -11
- package/autorest/codegen/serializers/parameter_serializer.py +174 -0
- package/autorest/codegen/serializers/patch_serializer.py +4 -1
- package/autorest/codegen/serializers/request_builders_serializer.py +57 -0
- package/autorest/codegen/serializers/utils.py +0 -126
- package/autorest/codegen/templates/MANIFEST.in.jinja2 +1 -0
- package/autorest/codegen/templates/{service_client.py.jinja2 → client.py.jinja2} +7 -7
- package/autorest/codegen/templates/config.py.jinja2 +13 -13
- package/autorest/codegen/templates/enum.py.jinja2 +4 -4
- package/autorest/codegen/templates/enum_container.py.jinja2 +1 -1
- package/autorest/codegen/templates/init.py.jinja2 +3 -3
- package/autorest/codegen/templates/lro_operation.py.jinja2 +6 -5
- package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +6 -5
- package/autorest/codegen/templates/metadata.json.jinja2 +36 -35
- package/autorest/codegen/templates/model.py.jinja2 +23 -24
- package/autorest/codegen/templates/model_container.py.jinja2 +2 -1
- package/autorest/codegen/templates/model_init.py.jinja2 +3 -5
- package/autorest/codegen/templates/operation.py.jinja2 +10 -14
- package/autorest/codegen/templates/operation_group.py.jinja2 +9 -15
- package/autorest/codegen/templates/operation_groups_container.py.jinja2 +1 -1
- package/autorest/codegen/templates/operation_tools.jinja2 +8 -2
- package/autorest/codegen/templates/paging_operation.py.jinja2 +7 -8
- package/autorest/codegen/templates/request_builder.py.jinja2 +19 -10
- package/autorest/codegen/templates/setup.py.jinja2 +9 -3
- package/autorest/codegen/templates/vendor.py.jinja2 +1 -1
- package/autorest/jsonrpc/__init__.py +7 -12
- package/autorest/jsonrpc/localapi.py +4 -3
- package/autorest/jsonrpc/server.py +28 -9
- package/autorest/jsonrpc/stdstream.py +13 -6
- package/autorest/m2r/__init__.py +5 -8
- package/autorest/m4reformatter/__init__.py +1126 -0
- 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 +20 -25
- package/autorest/multiapi/serializers/import_serializer.py +47 -17
- package/autorest/multiapi/serializers/multiapi_serializer.py +17 -17
- package/autorest/multiapi/templates/multiapi_config.py.jinja2 +3 -3
- package/autorest/multiapi/templates/multiapi_init.py.jinja2 +2 -2
- package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +4 -4
- package/autorest/multiapi/templates/multiapi_service_client.py.jinja2 +9 -9
- package/autorest/multiapi/utils.py +3 -3
- package/autorest/postprocess/__init__.py +202 -0
- package/autorest/postprocess/get_all.py +19 -0
- package/autorest/postprocess/venvtools.py +73 -0
- package/autorest/preprocess/__init__.py +210 -0
- package/autorest/preprocess/helpers.py +54 -0
- package/autorest/{namer → preprocess}/python_mappings.py +25 -32
- package/package.json +3 -3
- package/run-python3.js +2 -3
- package/venvtools.py +1 -1
- package/autorest/codegen/models/constant_schema.py +0 -101
- package/autorest/codegen/models/credential_model.py +0 -47
- package/autorest/codegen/models/credential_schema.py +0 -91
- package/autorest/codegen/models/credential_schema_policy.py +0 -77
- package/autorest/codegen/models/dictionary_schema.py +0 -103
- package/autorest/codegen/models/enum_schema.py +0 -215
- package/autorest/codegen/models/list_schema.py +0 -123
- package/autorest/codegen/models/object_schema.py +0 -253
- package/autorest/codegen/models/primitive_schemas.py +0 -466
- package/autorest/codegen/models/request_builder_parameter_list.py +0 -280
- package/autorest/codegen/models/rest.py +0 -42
- package/autorest/codegen/models/schema_request.py +0 -45
- package/autorest/codegen/models/schema_response.py +0 -136
- package/autorest/codegen/serializers/rest_serializer.py +0 -57
- package/autorest/namer/__init__.py +0 -25
- package/autorest/namer/name_converter.py +0 -412
|
@@ -3,25 +3,16 @@
|
|
|
3
3
|
# Licensed under the MIT License. See License.txt in the project root for
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
|
-
import
|
|
7
|
-
from typing import cast, List, Dict, Optional, Any, Set
|
|
6
|
+
from typing import List, Dict, Optional, Any, Set, Union
|
|
8
7
|
|
|
9
|
-
from .
|
|
10
|
-
from .
|
|
11
|
-
from .
|
|
8
|
+
from .base_type import BaseType
|
|
9
|
+
from .enum_type import EnumType
|
|
10
|
+
from .model_type import ModelType
|
|
12
11
|
from .operation_group import OperationGroup
|
|
13
|
-
from .
|
|
14
|
-
from .
|
|
15
|
-
from .paging_operation import PagingOperation
|
|
12
|
+
from .client import Client, Config
|
|
13
|
+
from .request_builder import OverloadedRequestBuilder, RequestBuilder
|
|
16
14
|
from .parameter import Parameter
|
|
17
|
-
from .client import Client
|
|
18
|
-
from .parameter_list import GlobalParameterList
|
|
19
|
-
from .property import Property
|
|
20
|
-
from .request_builder import RequestBuilder
|
|
21
|
-
from .rest import Rest
|
|
22
|
-
from .credential_model import CredentialModel
|
|
23
15
|
|
|
24
|
-
_LOGGER = logging.getLogger(__name__)
|
|
25
16
|
|
|
26
17
|
class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-public-methods
|
|
27
18
|
"""Holds all of the information we have parsed out of the yaml file. The CodeModel is what gets
|
|
@@ -34,82 +25,117 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
34
25
|
:param str description: The description of the client
|
|
35
26
|
:param str namespace: The namespace of our module
|
|
36
27
|
:param schemas: The list of schemas we are going to serialize in the models files. Maps their yaml
|
|
37
|
-
id to our created
|
|
38
|
-
:type schemas: dict[int, ~autorest.models.
|
|
28
|
+
id to our created ModelType.
|
|
29
|
+
:type schemas: dict[int, ~autorest.models.ModelType]
|
|
39
30
|
:param sorted_schemas: Our schemas in order by inheritance and alphabet
|
|
40
|
-
:type sorted_schemas: list[~autorest.models.
|
|
41
|
-
:param enums: The enums, if any, we are going to serialize. Maps their yaml id to our created
|
|
42
|
-
:type enums: Dict[int, ~autorest.models.
|
|
31
|
+
:type sorted_schemas: list[~autorest.models.ModelType]
|
|
32
|
+
:param enums: The enums, if any, we are going to serialize. Maps their yaml id to our created EnumType.
|
|
33
|
+
:type enums: Dict[int, ~autorest.models.EnumType]
|
|
43
34
|
:param primitives: List of schemas we've created that are not EnumSchemas or ObjectSchemas. Maps their
|
|
44
35
|
yaml id to our created schemas.
|
|
45
|
-
:type primitives: Dict[int, ~autorest.models.
|
|
36
|
+
:type primitives: Dict[int, ~autorest.models.BaseType]
|
|
46
37
|
:param operation_groups: The operation groups we are going to serialize
|
|
47
38
|
:type operation_groups: list[~autorest.models.OperationGroup]
|
|
48
39
|
:param package_dependency: All the dependencies needed in setup.py
|
|
49
40
|
:type package_dependency: Dict[str, str]
|
|
50
|
-
:param credential_model: The class contains all the credential info
|
|
51
|
-
:type credential_model: CredentialMode
|
|
52
41
|
"""
|
|
53
42
|
|
|
54
43
|
def __init__(
|
|
55
44
|
self,
|
|
45
|
+
yaml_data: Dict[str, Any],
|
|
56
46
|
options: Dict[str, Any],
|
|
57
47
|
) -> None:
|
|
58
|
-
self.
|
|
59
|
-
self.rest_layer_name = "rest" if options["builders_visibility"] == "public" else "_rest"
|
|
48
|
+
self.yaml_data = yaml_data
|
|
60
49
|
self.options = options
|
|
61
|
-
self.
|
|
62
|
-
self.class_name: str = ""
|
|
63
|
-
self.description: str = ""
|
|
64
|
-
self.namespace: str = ""
|
|
65
|
-
self.namespace_path: str = ""
|
|
66
|
-
self.schemas: Dict[int, ObjectSchema] = {}
|
|
67
|
-
self.sorted_schemas: List[ObjectSchema] = []
|
|
68
|
-
self.enums: Dict[int, EnumSchema] = {}
|
|
69
|
-
self.primitives: Dict[int, BaseSchema] = {}
|
|
50
|
+
self.types_map: Dict[int, BaseType] = {} # map yaml id to schema
|
|
70
51
|
self.operation_groups: List[OperationGroup] = []
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
self.
|
|
74
|
-
self.
|
|
75
|
-
|
|
52
|
+
self._model_types: List[ModelType] = []
|
|
53
|
+
self._client: Optional[Client] = None
|
|
54
|
+
self._config: Optional[Config] = None
|
|
55
|
+
self.request_builders: List[
|
|
56
|
+
Union[RequestBuilder, OverloadedRequestBuilder]
|
|
57
|
+
] = []
|
|
76
58
|
self.package_dependency: Dict[str, str] = {}
|
|
77
|
-
self.
|
|
59
|
+
self.namespace: str = yaml_data["client"]["namespace"].lower()
|
|
60
|
+
self.module_name: str = self.yaml_data["client"]["moduleName"]
|
|
61
|
+
|
|
62
|
+
def lookup_type(self, schema_id: int) -> BaseType:
|
|
63
|
+
"""Looks to see if the schema has already been created.
|
|
64
|
+
|
|
65
|
+
:param int schema_id: The yaml id of the schema
|
|
66
|
+
:return: If created, we return the created schema, otherwise, we throw.
|
|
67
|
+
:rtype: ~autorest.models.BaseType
|
|
68
|
+
:raises: KeyError if schema is not found
|
|
69
|
+
"""
|
|
70
|
+
try:
|
|
71
|
+
return next(type for id, type in self.types_map.items() if id == schema_id)
|
|
72
|
+
except StopIteration:
|
|
73
|
+
raise KeyError(f"Couldn't find schema with id {schema_id}")
|
|
78
74
|
|
|
79
75
|
@property
|
|
80
|
-
def
|
|
81
|
-
|
|
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
|
|
82
89
|
|
|
83
|
-
@
|
|
84
|
-
def
|
|
85
|
-
self.
|
|
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
|
+
def lookup_request_builder(
|
|
101
|
+
self, request_builder_id: int
|
|
102
|
+
) -> Union[RequestBuilder, OverloadedRequestBuilder]:
|
|
103
|
+
"""Find the request builder based off of id"""
|
|
104
|
+
try:
|
|
105
|
+
return next(
|
|
106
|
+
rb
|
|
107
|
+
for rb in self.request_builders
|
|
108
|
+
if id(rb.yaml_data) == request_builder_id
|
|
109
|
+
)
|
|
110
|
+
except StopIteration:
|
|
111
|
+
raise KeyError(f"No request builder with id {request_builder_id} found.")
|
|
86
112
|
|
|
87
113
|
@property
|
|
88
|
-
def
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
114
|
+
def model_types(self) -> List[ModelType]:
|
|
115
|
+
"""All of the model types in this class"""
|
|
116
|
+
if not self._model_types:
|
|
117
|
+
self._model_types = [
|
|
118
|
+
t for t in self.types_map.values() if isinstance(t, ModelType)
|
|
119
|
+
]
|
|
120
|
+
return self._model_types
|
|
92
121
|
|
|
93
|
-
@
|
|
94
|
-
def
|
|
95
|
-
self.
|
|
122
|
+
@model_types.setter
|
|
123
|
+
def model_types(self, val: List[ModelType]) -> None:
|
|
124
|
+
self._model_types = val
|
|
96
125
|
|
|
97
|
-
|
|
98
|
-
|
|
126
|
+
@property
|
|
127
|
+
def public_model_types(self) -> List[ModelType]:
|
|
128
|
+
return [m for m in self.model_types if m.is_public]
|
|
99
129
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
"""
|
|
105
|
-
for attr in [self.schemas, self.enums, self.primitives]:
|
|
106
|
-
for elt_key, elt_value in attr.items(): # type: ignore
|
|
107
|
-
if schema_id == elt_key:
|
|
108
|
-
return elt_value
|
|
109
|
-
raise KeyError("Didn't find it!!!!!")
|
|
130
|
+
@property
|
|
131
|
+
def enums(self) -> List[EnumType]:
|
|
132
|
+
"""All of the enums"""
|
|
133
|
+
return [t for t in self.types_map.values() if isinstance(t, EnumType)]
|
|
110
134
|
|
|
111
135
|
@staticmethod
|
|
112
|
-
def
|
|
136
|
+
def _sort_model_types_helper(
|
|
137
|
+
current: ModelType, seen_schema_names: Set[str], seen_schema_yaml_ids: Set[int]
|
|
138
|
+
):
|
|
113
139
|
if current.id in seen_schema_yaml_ids:
|
|
114
140
|
return []
|
|
115
141
|
if current.name in seen_schema_names:
|
|
@@ -117,20 +143,23 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
117
143
|
f"We have already generated a schema with name {current.name}"
|
|
118
144
|
)
|
|
119
145
|
ancestors = [current]
|
|
120
|
-
if current.
|
|
121
|
-
for
|
|
122
|
-
parent = cast(ObjectSchema, base_model)
|
|
146
|
+
if current.parents:
|
|
147
|
+
for parent in current.parents:
|
|
123
148
|
if parent.id in seen_schema_yaml_ids:
|
|
124
149
|
continue
|
|
125
150
|
seen_schema_names.add(current.name)
|
|
126
151
|
seen_schema_yaml_ids.add(current.id)
|
|
127
|
-
ancestors =
|
|
152
|
+
ancestors = (
|
|
153
|
+
CodeModel._sort_model_types_helper(
|
|
154
|
+
parent, seen_schema_names, seen_schema_yaml_ids
|
|
155
|
+
)
|
|
156
|
+
+ ancestors
|
|
157
|
+
)
|
|
128
158
|
seen_schema_names.add(current.name)
|
|
129
159
|
seen_schema_yaml_ids.add(current.id)
|
|
130
160
|
return ancestors
|
|
131
161
|
|
|
132
|
-
|
|
133
|
-
def sort_schemas(self) -> None:
|
|
162
|
+
def sort_model_types(self) -> None:
|
|
134
163
|
"""Sorts the final object schemas by inheritance and by alphabetical order.
|
|
135
164
|
|
|
136
165
|
:return: None
|
|
@@ -138,29 +167,14 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
138
167
|
"""
|
|
139
168
|
seen_schema_names: Set[str] = set()
|
|
140
169
|
seen_schema_yaml_ids: Set[int] = set()
|
|
141
|
-
|
|
142
|
-
for schema in sorted(self.
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
def setup_client_input_parameters(self, yaml_data: Dict[str, Any]):
|
|
147
|
-
dollar_host = [
|
|
148
|
-
parameter for parameter in self.global_parameters
|
|
149
|
-
if parameter.rest_api_name == "$host"
|
|
150
|
-
]
|
|
151
|
-
if not dollar_host:
|
|
152
|
-
# We don't want to support multi-api customurl YET (will see if that goes well....)
|
|
153
|
-
# So far now, let's get the first one in the first operation
|
|
154
|
-
# UGLY as hell.....
|
|
155
|
-
if yaml_data.get("operationGroups"):
|
|
156
|
-
first_req_of_first_op_of_first_grp = yaml_data["operationGroups"][0]["operations"][0]["requests"][0]
|
|
157
|
-
self.service_client.parameterized_host_template = (
|
|
158
|
-
first_req_of_first_op_of_first_grp["protocol"]["http"]["uri"]
|
|
170
|
+
sorted_object_schemas: List[ModelType] = []
|
|
171
|
+
for schema in sorted(self.model_types, key=lambda x: x.name.lower()):
|
|
172
|
+
sorted_object_schemas.extend(
|
|
173
|
+
CodeModel._sort_model_types_helper(
|
|
174
|
+
schema, seen_schema_names, seen_schema_yaml_ids
|
|
159
175
|
)
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
self.global_parameters.remove(host)
|
|
163
|
-
self.service_client.parameters.add_host(dollar_host[0].yaml_data["clientDefaultValue"])
|
|
176
|
+
)
|
|
177
|
+
self.model_types = sorted_object_schemas
|
|
164
178
|
|
|
165
179
|
def format_lro_operations(self) -> None:
|
|
166
180
|
"""Adds operations and attributes needed for LROs.
|
|
@@ -171,188 +185,68 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
171
185
|
i = 0
|
|
172
186
|
while i < len(operation_group.operations):
|
|
173
187
|
operation = operation_group.operations[i]
|
|
174
|
-
if
|
|
175
|
-
operation_group.operations.insert(i, operation.initial_operation)
|
|
188
|
+
if operation.operation_type in ("lro", "lropaging"):
|
|
189
|
+
operation_group.operations.insert(i, operation.initial_operation) # type: ignore
|
|
176
190
|
i += 1
|
|
177
191
|
i += 1
|
|
178
192
|
|
|
179
|
-
def remove_next_operation(self) -> None:
|
|
180
|
-
"""Linking paging operations together.
|
|
181
|
-
"""
|
|
182
|
-
def _lookup_operation(yaml_id: int) -> Operation:
|
|
183
|
-
for operation_group in self.operation_groups:
|
|
184
|
-
for operation in operation_group.operations:
|
|
185
|
-
if operation.id == yaml_id:
|
|
186
|
-
return operation
|
|
187
|
-
raise KeyError("Didn't find it!!!!!")
|
|
188
|
-
|
|
189
|
-
for operation_group in self.operation_groups:
|
|
190
|
-
next_operations = []
|
|
191
|
-
for operation in operation_group.operations:
|
|
192
|
-
# when we add in "LRO" functions we don't include yaml_data, so yaml_data can be empty in these cases
|
|
193
|
-
next_link_yaml = None
|
|
194
|
-
if operation.yaml_data and operation.yaml_data['language']['python'].get('paging'):
|
|
195
|
-
next_link_yaml = operation.yaml_data['language']['python']['paging'].get('nextLinkOperation')
|
|
196
|
-
if isinstance(operation, PagingOperation) and next_link_yaml:
|
|
197
|
-
next_operation = _lookup_operation(id(next_link_yaml))
|
|
198
|
-
operation.next_operation = next_operation
|
|
199
|
-
next_operations.append(next_operation)
|
|
200
|
-
|
|
201
|
-
operation_group.operations = [
|
|
202
|
-
operation for operation in operation_group.operations if operation not in next_operations
|
|
203
|
-
]
|
|
204
|
-
|
|
205
|
-
@property
|
|
206
|
-
def has_schemas(self):
|
|
207
|
-
return self.schemas or self.enums
|
|
208
|
-
|
|
209
|
-
@property
|
|
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
|
|
214
|
-
|
|
215
|
-
@credential_model.setter
|
|
216
|
-
def credential_model(self, val: CredentialModel) -> None:
|
|
217
|
-
self._credential_model = val
|
|
218
|
-
|
|
219
|
-
@staticmethod
|
|
220
|
-
def _add_properties_from_inheritance_helper(schema, properties) -> List[Property]:
|
|
221
|
-
if not schema.base_models:
|
|
222
|
-
return properties
|
|
223
|
-
if schema.base_models:
|
|
224
|
-
for base_model in schema.base_models:
|
|
225
|
-
parent = cast(ObjectSchema, base_model)
|
|
226
|
-
# need to make sure that the properties we choose from our parent also don't contain
|
|
227
|
-
# any of our own properties
|
|
228
|
-
schema_property_names = set([p.name for p in properties] + [p.name for p in schema.properties])
|
|
229
|
-
chosen_parent_properties = [
|
|
230
|
-
p for p in parent.properties
|
|
231
|
-
if p.name not in schema_property_names
|
|
232
|
-
]
|
|
233
|
-
properties = (
|
|
234
|
-
CodeModel._add_properties_from_inheritance_helper(parent, chosen_parent_properties) +
|
|
235
|
-
properties
|
|
236
|
-
)
|
|
237
|
-
|
|
238
|
-
return properties
|
|
239
|
-
|
|
240
193
|
@property
|
|
241
194
|
def operations_folder_name(self) -> str:
|
|
195
|
+
"""Get the name of the operations folder that holds operations."""
|
|
242
196
|
name = "operations"
|
|
243
197
|
if self.options["version_tolerant"] and not any(
|
|
244
|
-
og for og in self.operation_groups if not og.
|
|
198
|
+
og for og in self.operation_groups if not og.is_mixin
|
|
245
199
|
):
|
|
246
200
|
name = f"_{name}"
|
|
247
201
|
return name
|
|
248
202
|
|
|
249
|
-
def _add_properties_from_inheritance(self) -> None:
|
|
250
|
-
"""Adds properties from base classes to schemas with parents.
|
|
251
|
-
|
|
252
|
-
:return: None
|
|
253
|
-
:rtype: None
|
|
254
|
-
"""
|
|
255
|
-
for schema in self.schemas.values():
|
|
256
|
-
schema.properties = CodeModel._add_properties_from_inheritance_helper(schema, schema.properties)
|
|
257
|
-
|
|
258
|
-
@staticmethod
|
|
259
|
-
def _add_exceptions_from_inheritance_helper(schema) -> bool:
|
|
260
|
-
if schema.is_exception:
|
|
261
|
-
return True
|
|
262
|
-
parent_is_exception: List[bool] = []
|
|
263
|
-
for base_model in schema.base_models:
|
|
264
|
-
parent = cast(ObjectSchema, base_model)
|
|
265
|
-
parent_is_exception.append(CodeModel._add_exceptions_from_inheritance_helper(parent))
|
|
266
|
-
return any(parent_is_exception)
|
|
267
|
-
|
|
268
|
-
def _add_exceptions_from_inheritance(self) -> None:
|
|
269
|
-
"""Sets a class as an exception if it's parent is an exception.
|
|
270
|
-
|
|
271
|
-
:return: None
|
|
272
|
-
:rtype: None
|
|
273
|
-
"""
|
|
274
|
-
for schema in self.schemas.values():
|
|
275
|
-
schema.is_exception = CodeModel._add_exceptions_from_inheritance_helper(schema)
|
|
276
|
-
|
|
277
|
-
def add_inheritance_to_models(self) -> None:
|
|
278
|
-
"""Adds base classes and properties from base classes to schemas with parents.
|
|
279
|
-
|
|
280
|
-
:return: None
|
|
281
|
-
:rtype: None
|
|
282
|
-
"""
|
|
283
|
-
for schema in self.schemas.values():
|
|
284
|
-
if schema.base_models:
|
|
285
|
-
# right now, the base model property just holds the name of the parent class
|
|
286
|
-
schema.base_models = [b for b in self.schemas.values() if b.id in schema.base_models]
|
|
287
|
-
self._add_properties_from_inheritance()
|
|
288
|
-
self._add_exceptions_from_inheritance()
|
|
289
|
-
|
|
290
|
-
def _populate_target_property(self, parameter: Parameter) -> None:
|
|
291
|
-
for obj in self.schemas.values():
|
|
292
|
-
for prop in obj.properties:
|
|
293
|
-
if prop.id == parameter.target_property_name:
|
|
294
|
-
parameter.target_property_name = prop.name
|
|
295
|
-
return
|
|
296
|
-
raise KeyError("Didn't find the target property")
|
|
297
|
-
|
|
298
|
-
def generate_single_parameter_from_multiple_content_types_operation(self) -> None:
|
|
299
|
-
for operation_group in self.operation_groups:
|
|
300
|
-
for operation in operation_group.operations:
|
|
301
|
-
if operation.multiple_content_type_parameters:
|
|
302
|
-
operation.convert_multiple_content_type_parameters()
|
|
303
|
-
|
|
304
203
|
def need_vendored_code(self, async_mode: bool) -> bool:
|
|
204
|
+
"""Whether we need to vendor code in the _vendor.py file for this SDK"""
|
|
305
205
|
if async_mode:
|
|
306
206
|
return self.need_mixin_abc
|
|
307
|
-
return
|
|
207
|
+
return (
|
|
208
|
+
self.need_request_converter or self.need_format_url or self.need_mixin_abc
|
|
209
|
+
)
|
|
308
210
|
|
|
309
211
|
@property
|
|
310
212
|
def need_request_converter(self) -> bool:
|
|
213
|
+
"""
|
|
214
|
+
Whether we need to convert our created azure.core.rest.HttpRequests to
|
|
215
|
+
azure.core.pipeline.transport.HttpRequests
|
|
216
|
+
"""
|
|
311
217
|
return (
|
|
312
|
-
self.options["show_operations"]
|
|
313
|
-
bool(self.
|
|
314
|
-
not self.options["version_tolerant"]
|
|
218
|
+
self.options["show_operations"]
|
|
219
|
+
and bool(self.request_builders)
|
|
220
|
+
and not self.options["version_tolerant"]
|
|
315
221
|
)
|
|
316
222
|
|
|
317
223
|
@property
|
|
318
224
|
def need_format_url(self) -> bool:
|
|
319
|
-
|
|
225
|
+
"""Whether we need to format urls. If so, we need to vendor core."""
|
|
226
|
+
return any(rq for rq in self.request_builders if rq.parameters.path)
|
|
320
227
|
|
|
321
228
|
@property
|
|
322
229
|
def need_mixin_abc(self) -> bool:
|
|
323
|
-
|
|
230
|
+
"""Do we want a mixin ABC class for typing purposes?"""
|
|
231
|
+
return any(
|
|
232
|
+
o
|
|
233
|
+
for o in self.operation_groups
|
|
234
|
+
if o.is_mixin and self.options["python3_only"]
|
|
235
|
+
)
|
|
324
236
|
|
|
325
237
|
@property
|
|
326
238
|
def has_lro_operations(self) -> bool:
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
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!!!!!")
|
|
345
|
-
|
|
346
|
-
def link_operation_to_request_builder(self) -> None:
|
|
347
|
-
for operation_group in self.operation_groups:
|
|
348
|
-
for operation in operation_group.operations:
|
|
349
|
-
request_builder = self._lookup_request_builder(id(operation.yaml_data))
|
|
350
|
-
if isinstance(operation, LROOperation):
|
|
351
|
-
request_builder.name = request_builder.name + "_initial"
|
|
352
|
-
operation.request_builder = request_builder
|
|
353
|
-
operation.link_body_kwargs_to_body_params()
|
|
239
|
+
"""Are there any LRO operations in this SDK?"""
|
|
240
|
+
return any(
|
|
241
|
+
[
|
|
242
|
+
operation.operation_type in ("lro", "lropaging")
|
|
243
|
+
for operation_group in self.operation_groups
|
|
244
|
+
for operation in operation_group.operations
|
|
245
|
+
]
|
|
246
|
+
)
|
|
354
247
|
|
|
355
248
|
def get_models_filename(self, is_python3_file: bool) -> str:
|
|
249
|
+
"""Get the names of the model file(s)"""
|
|
356
250
|
if (
|
|
357
251
|
self.options["version_tolerant"] or self.options["low_level_client"]
|
|
358
252
|
) and self.options["python3_only"]:
|
|
@@ -363,6 +257,12 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
363
257
|
|
|
364
258
|
@property
|
|
365
259
|
def enums_filename(self) -> str:
|
|
260
|
+
"""The name of the enums file"""
|
|
366
261
|
if self.options["version_tolerant"] or self.options["low_level_client"]:
|
|
367
262
|
return "_enums"
|
|
368
263
|
return f"_{self.module_name}_enums"
|
|
264
|
+
|
|
265
|
+
@property
|
|
266
|
+
def rest_layer_name(self) -> str:
|
|
267
|
+
"""If we have a separate rest layer, what is its name?"""
|
|
268
|
+
return "rest" if self.options["builders_visibility"] == "public" else "_rest"
|
|
@@ -0,0 +1,107 @@
|
|
|
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 Any, Dict, List, Optional, TYPE_CHECKING
|
|
7
|
+
|
|
8
|
+
from autorest.codegen.models.imports import FileImport, ImportType
|
|
9
|
+
from .base_type import BaseType
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from .code_model import CodeModel
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class CombinedType(BaseType):
|
|
16
|
+
"""A type that consists of multiple different types.
|
|
17
|
+
|
|
18
|
+
Used by body parameters that have multiple types, i.e. one that can be
|
|
19
|
+
a stream body or a JSON body.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(
|
|
23
|
+
self, yaml_data: Dict[str, Any], code_model: "CodeModel", types: List[BaseType]
|
|
24
|
+
) -> None:
|
|
25
|
+
super().__init__(yaml_data, code_model)
|
|
26
|
+
self.types = types # the types that this type is combining
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def serialization_type(self) -> str:
|
|
30
|
+
"""The tag recognized by 'msrest' as a serialization/deserialization.
|
|
31
|
+
|
|
32
|
+
'str', 'int', 'float', 'bool' or
|
|
33
|
+
https://github.com/Azure/msrest-for-python/blob/b505e3627b547bd8fdc38327e86c70bdb16df061/msrest/serialization.py#L407-L416
|
|
34
|
+
|
|
35
|
+
or the object schema name (e.g. DotSalmon).
|
|
36
|
+
|
|
37
|
+
If list: '[str]'
|
|
38
|
+
If dict: '{str}'
|
|
39
|
+
"""
|
|
40
|
+
...
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
def client_default_value(self) -> Any:
|
|
44
|
+
return self.yaml_data.get("clientDefaultValue")
|
|
45
|
+
|
|
46
|
+
def description(
|
|
47
|
+
self, *, is_operation_file: bool # pylint: disable=unused-argument
|
|
48
|
+
) -> str:
|
|
49
|
+
if len(self.types) == 2:
|
|
50
|
+
return (
|
|
51
|
+
f"Is either a {self.types[0].type} type or a {self.types[1].type} type."
|
|
52
|
+
)
|
|
53
|
+
return (
|
|
54
|
+
f"Is one of the following types: {', '.join([t.type for t in self.types])}"
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
def docstring_text(self, **kwargs: Any) -> str:
|
|
58
|
+
return " or ".join(t.docstring_text(**kwargs) for t in self.types)
|
|
59
|
+
|
|
60
|
+
def docstring_type(self, **kwargs: Any) -> str:
|
|
61
|
+
return " or ".join(t.docstring_type(**kwargs) for t in self.types)
|
|
62
|
+
|
|
63
|
+
def type_annotation(self, **kwargs: Any) -> str:
|
|
64
|
+
"""The python type used for type annotation
|
|
65
|
+
|
|
66
|
+
Special case for enum, for instance: Union[str, "EnumName"]
|
|
67
|
+
"""
|
|
68
|
+
kwargs["is_operation_file"] = True
|
|
69
|
+
return (
|
|
70
|
+
f'Union[{", ".join(type.type_annotation(**kwargs) for type in self.types)}]'
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
def get_json_template_representation(
|
|
74
|
+
self,
|
|
75
|
+
*,
|
|
76
|
+
optional: bool = True,
|
|
77
|
+
client_default_value_declaration: Optional[str] = None,
|
|
78
|
+
description: Optional[str] = None,
|
|
79
|
+
) -> Any:
|
|
80
|
+
"""Template of what this schema would look like as JSON input"""
|
|
81
|
+
raise ValueError(
|
|
82
|
+
"You shouldn't get a JSON template representation of multiple types"
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
@property
|
|
86
|
+
def instance_check_template(self) -> str:
|
|
87
|
+
"""Template of what an instance check of a variable for this type would look like"""
|
|
88
|
+
raise ValueError("You shouldn't do instance checks on a multiple type")
|
|
89
|
+
|
|
90
|
+
def imports(self, **kwargs: Any) -> FileImport:
|
|
91
|
+
file_import = FileImport()
|
|
92
|
+
for type in self.types:
|
|
93
|
+
file_import.merge(type.imports(**kwargs))
|
|
94
|
+
file_import.add_submodule_import("typing", "Union", ImportType.STDLIB)
|
|
95
|
+
return file_import
|
|
96
|
+
|
|
97
|
+
@classmethod
|
|
98
|
+
def from_yaml(
|
|
99
|
+
cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
|
|
100
|
+
) -> "BaseType":
|
|
101
|
+
from . import build_type
|
|
102
|
+
|
|
103
|
+
return cls(
|
|
104
|
+
yaml_data,
|
|
105
|
+
code_model,
|
|
106
|
+
[build_type(t, code_model) for t in yaml_data["types"]],
|
|
107
|
+
)
|