@autorest/python 5.14.0 → 5.17.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 +91 -2
- package/README.md +30 -4
- package/autorest/__init__.py +2 -3
- package/autorest/black/__init__.py +12 -5
- package/autorest/codegen/__init__.py +130 -179
- 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} +62 -49
- package/autorest/codegen/models/client.py +195 -36
- package/autorest/codegen/models/code_model.py +165 -299
- 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 +116 -0
- package/autorest/codegen/models/enum_type.py +195 -0
- package/autorest/codegen/models/imports.py +95 -41
- package/autorest/codegen/models/list_type.py +134 -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 +239 -0
- package/autorest/codegen/models/operation.py +415 -241
- package/autorest/codegen/models/operation_group.py +82 -88
- package/autorest/codegen/models/paging_operation.py +101 -117
- package/autorest/codegen/models/parameter.py +307 -322
- package/autorest/codegen/models/parameter_list.py +366 -357
- package/autorest/codegen/models/primitive_types.py +544 -0
- package/autorest/codegen/models/property.py +122 -134
- package/autorest/codegen/models/request_builder.py +138 -86
- package/autorest/codegen/models/request_builder_parameter.py +122 -79
- package/autorest/codegen/models/response.py +325 -0
- package/autorest/codegen/models/utils.py +17 -1
- package/autorest/codegen/serializers/__init__.py +242 -118
- package/autorest/codegen/serializers/builder_serializer.py +863 -1027
- package/autorest/codegen/serializers/client_serializer.py +148 -82
- package/autorest/codegen/serializers/general_serializer.py +44 -47
- 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 +65 -29
- 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 -18
- 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 +14 -2
- package/autorest/codegen/serializers/request_builders_serializer.py +57 -0
- package/autorest/codegen/serializers/utils.py +0 -103
- 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 -2
- 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 +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 -29
- package/autorest/codegen/templates/model_container.py.jinja2 +2 -1
- package/autorest/codegen/templates/model_init.py.jinja2 +9 -8
- package/autorest/codegen/templates/operation.py.jinja2 +10 -15
- package/autorest/codegen/templates/operation_group.py.jinja2 +14 -13
- package/autorest/codegen/templates/operation_groups_container.py.jinja2 +1 -2
- package/autorest/codegen/templates/operation_tools.jinja2 +8 -2
- package/autorest/codegen/templates/operations_folder_init.py.jinja2 +4 -0
- package/autorest/codegen/templates/paging_operation.py.jinja2 +7 -8
- package/autorest/codegen/templates/patch.py.jinja2 +18 -29
- package/autorest/codegen/templates/request_builder.py.jinja2 +20 -13
- package/autorest/codegen/templates/setup.py.jinja2 +9 -3
- package/autorest/codegen/templates/vendor.py.jinja2 +12 -2
- 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 +1108 -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 +35 -18
- 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 -15
- 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 +209 -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 -97
- package/autorest/codegen/models/credential_schema.py +0 -90
- 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 -246
- package/autorest/codegen/models/list_schema.py +0 -113
- package/autorest/codegen/models/object_schema.py +0 -249
- package/autorest/codegen/models/primitive_schemas.py +0 -476
- 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 -123
- 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,32 +3,17 @@
|
|
|
3
3
|
# Licensed under the MIT License. See License.txt in the project root for
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
|
-
from
|
|
7
|
-
import logging
|
|
8
|
-
from typing import cast, List, Dict, Optional, Any, Set, Type
|
|
6
|
+
from typing import List, Dict, Optional, Any, Set, Union
|
|
9
7
|
|
|
10
|
-
from .
|
|
11
|
-
from .
|
|
12
|
-
|
|
13
|
-
)
|
|
14
|
-
from .enum_schema import EnumSchema
|
|
15
|
-
from .object_schema import ObjectSchema
|
|
8
|
+
from .base_type import BaseType
|
|
9
|
+
from .enum_type import EnumType
|
|
10
|
+
from .model_type import ModelType
|
|
16
11
|
from .operation_group import OperationGroup
|
|
17
|
-
from .
|
|
18
|
-
from .
|
|
19
|
-
from .paging_operation import PagingOperation
|
|
12
|
+
from .client import Client, Config
|
|
13
|
+
from .request_builder import OverloadedRequestBuilder, RequestBuilder
|
|
20
14
|
from .parameter import Parameter
|
|
21
|
-
from .client import Client
|
|
22
|
-
from .parameter_list import GlobalParameterList
|
|
23
|
-
from .schema_response import SchemaResponse
|
|
24
|
-
from .property import Property
|
|
25
|
-
from .primitive_schemas import IOSchema
|
|
26
|
-
from .request_builder import RequestBuilder
|
|
27
|
-
from .rest import Rest
|
|
28
15
|
|
|
29
16
|
|
|
30
|
-
_LOGGER = logging.getLogger(__name__)
|
|
31
|
-
|
|
32
17
|
class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-public-methods
|
|
33
18
|
"""Holds all of the information we have parsed out of the yaml file. The CodeModel is what gets
|
|
34
19
|
serialized by the serializers.
|
|
@@ -40,15 +25,15 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
40
25
|
:param str description: The description of the client
|
|
41
26
|
:param str namespace: The namespace of our module
|
|
42
27
|
:param schemas: The list of schemas we are going to serialize in the models files. Maps their yaml
|
|
43
|
-
id to our created
|
|
44
|
-
:type schemas: dict[int, ~autorest.models.
|
|
28
|
+
id to our created ModelType.
|
|
29
|
+
:type schemas: dict[int, ~autorest.models.ModelType]
|
|
45
30
|
:param sorted_schemas: Our schemas in order by inheritance and alphabet
|
|
46
|
-
:type sorted_schemas: list[~autorest.models.
|
|
47
|
-
:param enums: The enums, if any, we are going to serialize. Maps their yaml id to our created
|
|
48
|
-
: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]
|
|
49
34
|
:param primitives: List of schemas we've created that are not EnumSchemas or ObjectSchemas. Maps their
|
|
50
35
|
yaml id to our created schemas.
|
|
51
|
-
:type primitives: Dict[int, ~autorest.models.
|
|
36
|
+
:type primitives: Dict[int, ~autorest.models.BaseType]
|
|
52
37
|
:param operation_groups: The operation groups we are going to serialize
|
|
53
38
|
:type operation_groups: list[~autorest.models.OperationGroup]
|
|
54
39
|
:param package_dependency: All the dependencies needed in setup.py
|
|
@@ -57,63 +42,100 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
57
42
|
|
|
58
43
|
def __init__(
|
|
59
44
|
self,
|
|
45
|
+
yaml_data: Dict[str, Any],
|
|
60
46
|
options: Dict[str, Any],
|
|
61
47
|
) -> None:
|
|
62
|
-
self.
|
|
63
|
-
self.rest_layer_name = "rest" if options["builders_visibility"] == "public" else "_rest"
|
|
48
|
+
self.yaml_data = yaml_data
|
|
64
49
|
self.options = options
|
|
65
|
-
self.
|
|
66
|
-
self.class_name: str = ""
|
|
67
|
-
self.description: str = ""
|
|
68
|
-
self.namespace: str = ""
|
|
69
|
-
self.namespace_path: str = ""
|
|
70
|
-
self.schemas: Dict[int, ObjectSchema] = {}
|
|
71
|
-
self.sorted_schemas: List[ObjectSchema] = []
|
|
72
|
-
self.enums: Dict[int, EnumSchema] = {}
|
|
73
|
-
self.primitives: Dict[int, BaseSchema] = {}
|
|
50
|
+
self.types_map: Dict[int, BaseType] = {} # map yaml id to schema
|
|
74
51
|
self.operation_groups: List[OperationGroup] = []
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
self.
|
|
78
|
-
self.
|
|
79
|
-
|
|
80
|
-
|
|
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
|
+
] = []
|
|
81
58
|
self.package_dependency: Dict[str, str] = {}
|
|
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}")
|
|
82
74
|
|
|
83
75
|
@property
|
|
84
|
-
def
|
|
85
|
-
|
|
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
|
|
86
89
|
|
|
87
|
-
@
|
|
88
|
-
def
|
|
89
|
-
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.")
|
|
90
112
|
|
|
91
113
|
@property
|
|
92
|
-
def
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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
|
|
96
121
|
|
|
97
|
-
@
|
|
98
|
-
def
|
|
99
|
-
self.
|
|
122
|
+
@model_types.setter
|
|
123
|
+
def model_types(self, val: List[ModelType]) -> None:
|
|
124
|
+
self._model_types = val
|
|
100
125
|
|
|
101
|
-
|
|
102
|
-
|
|
126
|
+
@property
|
|
127
|
+
def public_model_types(self) -> List[ModelType]:
|
|
128
|
+
return [m for m in self.model_types if m.is_public]
|
|
103
129
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
"""
|
|
109
|
-
for attr in [self.schemas, self.enums, self.primitives]:
|
|
110
|
-
for elt_key, elt_value in attr.items(): # type: ignore
|
|
111
|
-
if schema_id == elt_key:
|
|
112
|
-
return elt_value
|
|
113
|
-
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)]
|
|
114
134
|
|
|
115
135
|
@staticmethod
|
|
116
|
-
def
|
|
136
|
+
def _sort_model_types_helper(
|
|
137
|
+
current: ModelType, seen_schema_names: Set[str], seen_schema_yaml_ids: Set[int]
|
|
138
|
+
):
|
|
117
139
|
if current.id in seen_schema_yaml_ids:
|
|
118
140
|
return []
|
|
119
141
|
if current.name in seen_schema_names:
|
|
@@ -121,20 +143,23 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
121
143
|
f"We have already generated a schema with name {current.name}"
|
|
122
144
|
)
|
|
123
145
|
ancestors = [current]
|
|
124
|
-
if current.
|
|
125
|
-
for
|
|
126
|
-
parent = cast(ObjectSchema, base_model)
|
|
146
|
+
if current.parents:
|
|
147
|
+
for parent in current.parents:
|
|
127
148
|
if parent.id in seen_schema_yaml_ids:
|
|
128
149
|
continue
|
|
129
150
|
seen_schema_names.add(current.name)
|
|
130
151
|
seen_schema_yaml_ids.add(current.id)
|
|
131
|
-
ancestors =
|
|
152
|
+
ancestors = (
|
|
153
|
+
CodeModel._sort_model_types_helper(
|
|
154
|
+
parent, seen_schema_names, seen_schema_yaml_ids
|
|
155
|
+
)
|
|
156
|
+
+ ancestors
|
|
157
|
+
)
|
|
132
158
|
seen_schema_names.add(current.name)
|
|
133
159
|
seen_schema_yaml_ids.add(current.id)
|
|
134
160
|
return ancestors
|
|
135
161
|
|
|
136
|
-
|
|
137
|
-
def sort_schemas(self) -> None:
|
|
162
|
+
def sort_model_types(self) -> None:
|
|
138
163
|
"""Sorts the final object schemas by inheritance and by alphabetical order.
|
|
139
164
|
|
|
140
165
|
:return: None
|
|
@@ -142,29 +167,14 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
142
167
|
"""
|
|
143
168
|
seen_schema_names: Set[str] = set()
|
|
144
169
|
seen_schema_yaml_ids: Set[int] = set()
|
|
145
|
-
|
|
146
|
-
for schema in sorted(self.
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
def setup_client_input_parameters(self, yaml_data: Dict[str, Any]):
|
|
151
|
-
dollar_host = [
|
|
152
|
-
parameter for parameter in self.global_parameters
|
|
153
|
-
if parameter.rest_api_name == "$host"
|
|
154
|
-
]
|
|
155
|
-
if not dollar_host:
|
|
156
|
-
# We don't want to support multi-api customurl YET (will see if that goes well....)
|
|
157
|
-
# So far now, let's get the first one in the first operation
|
|
158
|
-
# UGLY as hell.....
|
|
159
|
-
if yaml_data.get("operationGroups"):
|
|
160
|
-
first_req_of_first_op_of_first_grp = yaml_data["operationGroups"][0]["operations"][0]["requests"][0]
|
|
161
|
-
self.service_client.parameterized_host_template = (
|
|
162
|
-
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
|
|
163
175
|
)
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
self.global_parameters.remove(host)
|
|
167
|
-
self.service_client.parameters.add_host(dollar_host[0].yaml_data["clientDefaultValue"])
|
|
176
|
+
)
|
|
177
|
+
self.model_types = sorted_object_schemas
|
|
168
178
|
|
|
169
179
|
def format_lro_operations(self) -> None:
|
|
170
180
|
"""Adds operations and attributes needed for LROs.
|
|
@@ -175,228 +185,84 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
175
185
|
i = 0
|
|
176
186
|
while i < len(operation_group.operations):
|
|
177
187
|
operation = operation_group.operations[i]
|
|
178
|
-
if
|
|
179
|
-
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
|
|
180
190
|
i += 1
|
|
181
191
|
i += 1
|
|
182
192
|
|
|
183
|
-
def remove_next_operation(self) -> None:
|
|
184
|
-
"""Linking paging operations together.
|
|
185
|
-
"""
|
|
186
|
-
def _lookup_operation(yaml_id: int) -> Operation:
|
|
187
|
-
for operation_group in self.operation_groups:
|
|
188
|
-
for operation in operation_group.operations:
|
|
189
|
-
if operation.id == yaml_id:
|
|
190
|
-
return operation
|
|
191
|
-
raise KeyError("Didn't find it!!!!!")
|
|
192
|
-
|
|
193
|
-
for operation_group in self.operation_groups:
|
|
194
|
-
next_operations = []
|
|
195
|
-
for operation in operation_group.operations:
|
|
196
|
-
# when we add in "LRO" functions we don't include yaml_data, so yaml_data can be empty in these cases
|
|
197
|
-
next_link_yaml = None
|
|
198
|
-
if operation.yaml_data and operation.yaml_data['language']['python'].get('paging'):
|
|
199
|
-
next_link_yaml = operation.yaml_data['language']['python']['paging'].get('nextLinkOperation')
|
|
200
|
-
if isinstance(operation, PagingOperation) and next_link_yaml:
|
|
201
|
-
next_operation = _lookup_operation(id(next_link_yaml))
|
|
202
|
-
operation.next_operation = next_operation
|
|
203
|
-
next_operations.append(next_operation)
|
|
204
|
-
|
|
205
|
-
operation_group.operations = [
|
|
206
|
-
operation for operation in operation_group.operations if operation not in next_operations
|
|
207
|
-
]
|
|
208
|
-
|
|
209
|
-
@property
|
|
210
|
-
def has_schemas(self):
|
|
211
|
-
return self.schemas or self.enums
|
|
212
|
-
|
|
213
|
-
@property
|
|
214
|
-
def default_authentication_policy(self) -> Type[CredentialSchemaPolicy]:
|
|
215
|
-
return ARMChallengeAuthenticationPolicy if self.options['azure_arm'] else BearerTokenCredentialPolicy
|
|
216
|
-
|
|
217
|
-
@property
|
|
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
|
|
222
|
-
|
|
223
|
-
@credential_schema_policy.setter
|
|
224
|
-
def credential_schema_policy(self, val: CredentialSchemaPolicy) -> None:
|
|
225
|
-
self._credential_schema_policy = val
|
|
226
|
-
|
|
227
|
-
@staticmethod
|
|
228
|
-
def _add_properties_from_inheritance_helper(schema, properties) -> List[Property]:
|
|
229
|
-
if not schema.base_models:
|
|
230
|
-
return properties
|
|
231
|
-
if schema.base_models:
|
|
232
|
-
for base_model in schema.base_models:
|
|
233
|
-
parent = cast(ObjectSchema, base_model)
|
|
234
|
-
# need to make sure that the properties we choose from our parent also don't contain
|
|
235
|
-
# any of our own properties
|
|
236
|
-
schema_property_names = set([p.name for p in properties] + [p.name for p in schema.properties])
|
|
237
|
-
chosen_parent_properties = [
|
|
238
|
-
p for p in parent.properties
|
|
239
|
-
if p.name not in schema_property_names
|
|
240
|
-
]
|
|
241
|
-
properties = (
|
|
242
|
-
CodeModel._add_properties_from_inheritance_helper(parent, chosen_parent_properties) +
|
|
243
|
-
properties
|
|
244
|
-
)
|
|
245
|
-
|
|
246
|
-
return properties
|
|
247
|
-
|
|
248
193
|
@property
|
|
249
194
|
def operations_folder_name(self) -> str:
|
|
195
|
+
"""Get the name of the operations folder that holds operations."""
|
|
250
196
|
name = "operations"
|
|
251
197
|
if self.options["version_tolerant"] and not any(
|
|
252
|
-
og for og in self.operation_groups if not og.
|
|
198
|
+
og for og in self.operation_groups if not og.is_mixin
|
|
253
199
|
):
|
|
254
200
|
name = f"_{name}"
|
|
255
201
|
return name
|
|
256
202
|
|
|
257
|
-
def
|
|
258
|
-
"""
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
schema.properties = CodeModel._add_properties_from_inheritance_helper(schema, schema.properties)
|
|
265
|
-
|
|
266
|
-
@staticmethod
|
|
267
|
-
def _add_exceptions_from_inheritance_helper(schema) -> bool:
|
|
268
|
-
if schema.is_exception:
|
|
269
|
-
return True
|
|
270
|
-
parent_is_exception: List[bool] = []
|
|
271
|
-
for base_model in schema.base_models:
|
|
272
|
-
parent = cast(ObjectSchema, base_model)
|
|
273
|
-
parent_is_exception.append(CodeModel._add_exceptions_from_inheritance_helper(parent))
|
|
274
|
-
return any(parent_is_exception)
|
|
275
|
-
|
|
276
|
-
def _add_exceptions_from_inheritance(self) -> None:
|
|
277
|
-
"""Sets a class as an exception if it's parent is an exception.
|
|
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"""
|
|
205
|
+
if async_mode:
|
|
206
|
+
return self.need_mixin_abc
|
|
207
|
+
return (
|
|
208
|
+
self.need_request_converter or self.need_format_url or self.need_mixin_abc
|
|
209
|
+
)
|
|
278
210
|
|
|
279
|
-
|
|
280
|
-
|
|
211
|
+
@property
|
|
212
|
+
def need_request_converter(self) -> bool:
|
|
281
213
|
"""
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
def add_inheritance_to_models(self) -> None:
|
|
286
|
-
"""Adds base classes and properties from base classes to schemas with parents.
|
|
287
|
-
|
|
288
|
-
:return: None
|
|
289
|
-
:rtype: None
|
|
214
|
+
Whether we need to convert our created azure.core.rest.HttpRequests to
|
|
215
|
+
azure.core.pipeline.transport.HttpRequests
|
|
290
216
|
"""
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
self._add_exceptions_from_inheritance()
|
|
297
|
-
|
|
298
|
-
def _populate_target_property(self, parameter: Parameter) -> None:
|
|
299
|
-
for obj in self.schemas.values():
|
|
300
|
-
for prop in obj.properties:
|
|
301
|
-
if prop.id == parameter.target_property_name:
|
|
302
|
-
parameter.target_property_name = prop.name
|
|
303
|
-
return
|
|
304
|
-
raise KeyError("Didn't find the target property")
|
|
305
|
-
|
|
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
|
-
def generate_single_parameter_from_multiple_content_types_operation(self) -> None:
|
|
357
|
-
for operation_group in self.operation_groups:
|
|
358
|
-
for operation in operation_group.operations:
|
|
359
|
-
if operation.multiple_content_type_parameters:
|
|
360
|
-
operation.convert_multiple_content_type_parameters()
|
|
217
|
+
return (
|
|
218
|
+
self.options["show_operations"]
|
|
219
|
+
and bool(self.request_builders)
|
|
220
|
+
and not self.options["version_tolerant"]
|
|
221
|
+
)
|
|
361
222
|
|
|
362
223
|
@property
|
|
363
|
-
def
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
@property
|
|
367
|
-
def need_request_converter(self) -> bool:
|
|
368
|
-
return self.options["show_operations"] and not self.options["version_tolerant"]
|
|
224
|
+
def need_format_url(self) -> bool:
|
|
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)
|
|
369
227
|
|
|
370
228
|
@property
|
|
371
|
-
def
|
|
372
|
-
|
|
229
|
+
def need_mixin_abc(self) -> bool:
|
|
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
|
+
)
|
|
373
236
|
|
|
374
237
|
@property
|
|
375
238
|
def has_lro_operations(self) -> bool:
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
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
|
+
)
|
|
247
|
+
|
|
248
|
+
def get_models_filename(self, is_python3_file: bool) -> str:
|
|
249
|
+
"""Get the names of the model file(s)"""
|
|
250
|
+
if (
|
|
251
|
+
self.options["version_tolerant"] or self.options["low_level_client"]
|
|
252
|
+
) and self.options["python3_only"]:
|
|
253
|
+
return "_models"
|
|
254
|
+
if is_python3_file:
|
|
255
|
+
return "_models_py3"
|
|
256
|
+
return "_models"
|
|
384
257
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
if schema_id == elt_key:
|
|
392
|
-
return elt_value
|
|
393
|
-
raise KeyError("Didn't find it!!!!!")
|
|
258
|
+
@property
|
|
259
|
+
def enums_filename(self) -> str:
|
|
260
|
+
"""The name of the enums file"""
|
|
261
|
+
if self.options["version_tolerant"] or self.options["low_level_client"]:
|
|
262
|
+
return "_enums"
|
|
263
|
+
return f"_{self.module_name}_enums"
|
|
394
264
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
if isinstance(operation, LROOperation):
|
|
400
|
-
request_builder.name = request_builder.name + "_initial"
|
|
401
|
-
operation.request_builder = request_builder
|
|
402
|
-
operation.link_body_kwargs_to_body_params()
|
|
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
|
+
)
|