@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,41 +3,92 @@
|
|
|
3
3
|
# Licensed under the MIT License. See License.txt in the project root for
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
|
-
from collections.abc import MutableSequence
|
|
7
|
-
from copy import copy
|
|
8
6
|
import logging
|
|
9
|
-
from typing import
|
|
7
|
+
from typing import (
|
|
8
|
+
Any,
|
|
9
|
+
Callable,
|
|
10
|
+
Dict,
|
|
11
|
+
List,
|
|
12
|
+
Optional,
|
|
13
|
+
TYPE_CHECKING,
|
|
14
|
+
Union,
|
|
15
|
+
Generic,
|
|
16
|
+
TypeVar,
|
|
17
|
+
cast,
|
|
18
|
+
)
|
|
19
|
+
from abc import abstractmethod
|
|
20
|
+
from collections.abc import MutableSequence
|
|
21
|
+
from enum import Enum
|
|
22
|
+
|
|
23
|
+
from .request_builder_parameter import (
|
|
24
|
+
RequestBuilderBodyParameter,
|
|
25
|
+
RequestBuilderMultipartBodyParameter,
|
|
26
|
+
RequestBuilderParameter,
|
|
27
|
+
get_request_body_parameter,
|
|
28
|
+
)
|
|
29
|
+
from .parameter import (
|
|
30
|
+
MultipartBodyParameter,
|
|
31
|
+
ParameterLocation,
|
|
32
|
+
BodyParameter,
|
|
33
|
+
Parameter,
|
|
34
|
+
ParameterMethodLocation,
|
|
35
|
+
ClientParameter,
|
|
36
|
+
ConfigParameter,
|
|
37
|
+
get_body_parameter,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
ParameterType = TypeVar(
|
|
41
|
+
"ParameterType", bound=Union[Parameter, RequestBuilderParameter]
|
|
42
|
+
)
|
|
43
|
+
BodyParameterType = TypeVar(
|
|
44
|
+
"BodyParameterType", bound=Union[BodyParameter, RequestBuilderBodyParameter]
|
|
45
|
+
)
|
|
46
|
+
RequestBuilderBodyParameterType = Union[
|
|
47
|
+
RequestBuilderBodyParameter, RequestBuilderMultipartBodyParameter
|
|
48
|
+
]
|
|
10
49
|
|
|
11
|
-
from .parameter import Parameter, ParameterLocation
|
|
12
|
-
from .base_schema import BaseSchema
|
|
13
|
-
from .dictionary_schema import DictionarySchema
|
|
14
|
-
from .primitive_schemas import AnySchema, StringSchema
|
|
15
|
-
from .utils import JSON_REGEXP
|
|
16
50
|
|
|
17
51
|
if TYPE_CHECKING:
|
|
18
|
-
from .
|
|
52
|
+
from .code_model import CodeModel
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class ParameterImplementation(Enum):
|
|
56
|
+
METHOD = "method"
|
|
57
|
+
CLIENT = "client"
|
|
19
58
|
|
|
20
|
-
T = TypeVar('T')
|
|
21
|
-
OrderedSet = Dict[T, None]
|
|
22
59
|
|
|
23
60
|
_LOGGER = logging.getLogger(__name__)
|
|
24
61
|
|
|
25
|
-
|
|
62
|
+
|
|
63
|
+
def method_signature_helper(
|
|
64
|
+
positional: List[str], keyword_only: Optional[List[str]], kwarg_params: List[str]
|
|
65
|
+
):
|
|
26
66
|
keyword_only = keyword_only or []
|
|
27
67
|
return positional + keyword_only + kwarg_params
|
|
28
68
|
|
|
29
69
|
|
|
30
|
-
|
|
70
|
+
def _sort(params):
|
|
71
|
+
return sorted(
|
|
72
|
+
params, key=lambda x: not (x.client_default_value or x.optional), reverse=True
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class _ParameterListBase(
|
|
77
|
+
MutableSequence, Generic[ParameterType, BodyParameterType]
|
|
78
|
+
): # pylint: disable=too-many-public-methods
|
|
79
|
+
"""Base class for all of our different ParameterList classes"""
|
|
80
|
+
|
|
31
81
|
def __init__(
|
|
32
82
|
self,
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
83
|
+
yaml_data: Dict[str, Any],
|
|
84
|
+
code_model: "CodeModel",
|
|
85
|
+
parameters: List[ParameterType],
|
|
86
|
+
body_parameter: Optional[BodyParameterType] = None,
|
|
36
87
|
) -> None:
|
|
88
|
+
self.yaml_data = yaml_data
|
|
37
89
|
self.code_model = code_model
|
|
38
|
-
self.schema_requests = schema_requests or []
|
|
39
90
|
self.parameters = parameters or []
|
|
40
|
-
self.
|
|
91
|
+
self._body_parameter = body_parameter
|
|
41
92
|
|
|
42
93
|
# MutableSequence
|
|
43
94
|
|
|
@@ -55,431 +106,389 @@ class ParameterList(MutableSequence): # pylint: disable=too-many-public-methods
|
|
|
55
106
|
def __delitem__(self, index):
|
|
56
107
|
del self.parameters[index]
|
|
57
108
|
|
|
58
|
-
def insert(self, index: int, value:
|
|
109
|
+
def insert(self, index: int, value: ParameterType) -> None:
|
|
59
110
|
self.parameters.insert(index, value)
|
|
60
111
|
|
|
61
112
|
# Parameter helpers
|
|
62
113
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
def get_from_location(self, location: ParameterLocation) -> List[Parameter]:
|
|
70
|
-
return self.get_from_predicate(lambda parameter: parameter.location == location)
|
|
71
|
-
|
|
72
|
-
@property
|
|
73
|
-
def content_types(self) -> List[str]:
|
|
74
|
-
ordered_set = {
|
|
75
|
-
m: None
|
|
76
|
-
for request in self.schema_requests
|
|
77
|
-
for m in request.content_types
|
|
78
|
-
}
|
|
79
|
-
return list(ordered_set.keys())
|
|
114
|
+
@staticmethod
|
|
115
|
+
@abstractmethod
|
|
116
|
+
def parameter_creator() -> Callable[[Dict[str, Any], "CodeModel"], ParameterType]:
|
|
117
|
+
"""Callable for creating parameters"""
|
|
118
|
+
...
|
|
80
119
|
|
|
81
|
-
@
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
xml_content_types = [c for c in self.content_types if "xml" in c]
|
|
90
|
-
if xml_content_types:
|
|
91
|
-
if "application/xml" in xml_content_types:
|
|
92
|
-
return "application/xml"
|
|
93
|
-
return xml_content_types[0]
|
|
94
|
-
return self.content_types[0]
|
|
120
|
+
@staticmethod
|
|
121
|
+
@abstractmethod
|
|
122
|
+
def body_parameter_creator() -> Callable[
|
|
123
|
+
[Dict[str, Any], "CodeModel"], BodyParameterType
|
|
124
|
+
]:
|
|
125
|
+
"""Callable for creating body parameters"""
|
|
126
|
+
...
|
|
95
127
|
|
|
96
128
|
@property
|
|
97
|
-
def
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
129
|
+
def grouped(self) -> List[Union[ParameterType, BodyParameterType]]:
|
|
130
|
+
"""All parameters that are inside a parameter group"""
|
|
131
|
+
params: List[Union[ParameterType, BodyParameterType]] = [
|
|
132
|
+
p for p in self.parameters if p.grouped_by
|
|
133
|
+
]
|
|
134
|
+
if self.has_body and self.body_parameter.grouped_by:
|
|
135
|
+
params.append(self.body_parameter)
|
|
136
|
+
return params
|
|
101
137
|
|
|
102
138
|
@property
|
|
103
139
|
def has_body(self) -> bool:
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
@property
|
|
107
|
-
def body(self) -> List[Parameter]:
|
|
108
|
-
if not self.has_body:
|
|
109
|
-
raise ValueError(f"Can't get body parameter")
|
|
110
|
-
# Should we check if there is two body? Modeler role right?
|
|
111
|
-
body_params = self.get_from_location(ParameterLocation.Body)
|
|
112
|
-
return body_params
|
|
113
|
-
|
|
114
|
-
@staticmethod
|
|
115
|
-
def _wanted_path_parameter(parameter: Parameter):
|
|
116
|
-
# TODO add 'and parameter.location == "Method"' as requirement to this check once
|
|
117
|
-
# I can use send_request on operations.
|
|
118
|
-
# Don't want to duplicate code from send_request.
|
|
119
|
-
return parameter.location == ParameterLocation.Uri and parameter.rest_api_name != "$host"
|
|
120
|
-
|
|
121
|
-
@property
|
|
122
|
-
def implementation(self) -> str:
|
|
123
|
-
return "Method"
|
|
140
|
+
"""Whether there is a body parameter in the parameter list"""
|
|
141
|
+
return bool(self._body_parameter)
|
|
124
142
|
|
|
125
143
|
@property
|
|
126
|
-
def path(self) -> List[
|
|
144
|
+
def path(self) -> List[ParameterType]:
|
|
145
|
+
"""All path parameters"""
|
|
127
146
|
return [
|
|
128
|
-
|
|
129
|
-
for
|
|
130
|
-
if
|
|
147
|
+
p
|
|
148
|
+
for p in self.parameters
|
|
149
|
+
if p.location in (ParameterLocation.PATH, ParameterLocation.ENDPOINT_PATH)
|
|
131
150
|
]
|
|
132
151
|
|
|
133
152
|
@property
|
|
134
|
-
def query(self) -> List[
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
@property
|
|
138
|
-
def headers(self) -> List[Parameter]:
|
|
139
|
-
headers = self.get_from_location(ParameterLocation.Header)
|
|
140
|
-
if not headers:
|
|
141
|
-
return headers
|
|
142
|
-
return list({
|
|
143
|
-
header.serialized_name: header
|
|
144
|
-
for header in headers
|
|
145
|
-
}.values())
|
|
153
|
+
def query(self) -> List[ParameterType]:
|
|
154
|
+
"""All query parameters"""
|
|
155
|
+
return [p for p in self.parameters if p.location == ParameterLocation.QUERY]
|
|
146
156
|
|
|
147
157
|
@property
|
|
148
|
-
def
|
|
149
|
-
|
|
158
|
+
def headers(self) -> List[ParameterType]:
|
|
159
|
+
"""All header parameters"""
|
|
160
|
+
return [p for p in self.parameters if p.location == ParameterLocation.HEADER]
|
|
150
161
|
|
|
151
162
|
@property
|
|
152
|
-
def
|
|
153
|
-
|
|
154
|
-
for
|
|
155
|
-
if any([
|
|
156
|
-
p for p in self.grouped
|
|
157
|
-
if p.grouped_by and id(p.grouped_by.yaml_data) == id(parameter.yaml_data)
|
|
158
|
-
]):
|
|
159
|
-
groupers.append(parameter)
|
|
160
|
-
return groupers
|
|
163
|
+
def constant(self) -> List[Union[ParameterType, BodyParameterType]]:
|
|
164
|
+
"""All constant parameters"""
|
|
165
|
+
return [p for p in self.parameters if p.constant]
|
|
161
166
|
|
|
162
167
|
@property
|
|
163
|
-
def
|
|
164
|
-
"""
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
lambda parameter: parameter.constant
|
|
168
|
+
def positional(self) -> List[Union[ParameterType, BodyParameterType]]:
|
|
169
|
+
"""All positional parameters"""
|
|
170
|
+
return _sort(
|
|
171
|
+
[
|
|
172
|
+
p
|
|
173
|
+
for p in self.unsorted_method_params
|
|
174
|
+
if p.method_location == ParameterMethodLocation.POSITIONAL
|
|
175
|
+
]
|
|
172
176
|
)
|
|
173
177
|
|
|
174
178
|
@property
|
|
175
|
-
def
|
|
176
|
-
|
|
177
|
-
|
|
179
|
+
def keyword_only(self) -> List[Union[ParameterType, BodyParameterType]]:
|
|
180
|
+
"""All keyword only parameters"""
|
|
181
|
+
return _sort(
|
|
182
|
+
[
|
|
183
|
+
p
|
|
184
|
+
for p in self.unsorted_method_params
|
|
185
|
+
if p.method_location == ParameterMethodLocation.KEYWORD_ONLY
|
|
186
|
+
]
|
|
178
187
|
)
|
|
179
188
|
|
|
180
189
|
@property
|
|
181
|
-
def
|
|
182
|
-
|
|
183
|
-
|
|
190
|
+
def kwarg(self) -> List[Union[ParameterType, BodyParameterType]]:
|
|
191
|
+
"""All kwargs"""
|
|
192
|
+
return _sort(
|
|
193
|
+
[
|
|
194
|
+
p
|
|
195
|
+
for p in self.unsorted_method_params
|
|
196
|
+
if p.method_location == ParameterMethodLocation.KWARG
|
|
197
|
+
]
|
|
184
198
|
)
|
|
185
199
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
if
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
kwarg_params = [
|
|
193
|
-
k for k in kwarg_params
|
|
194
|
-
if not (
|
|
195
|
-
k.rest_api_name == "Content-Type"
|
|
196
|
-
and k.default_value_declaration != f'"{self.default_content_type}"'
|
|
197
|
-
)
|
|
198
|
-
]
|
|
199
|
-
return kwarg_params
|
|
200
|
+
@property
|
|
201
|
+
def body_parameter(self) -> BodyParameterType:
|
|
202
|
+
"""The body parameter of the parameter list. Will only ever be at most one."""
|
|
203
|
+
if not self._body_parameter:
|
|
204
|
+
raise ValueError("There is no body parameter")
|
|
205
|
+
return self._body_parameter
|
|
200
206
|
|
|
201
207
|
@property
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
"""
|
|
205
|
-
|
|
206
|
-
parameters_of_this_implementation = self.get_from_predicate(
|
|
207
|
-
lambda parameter: parameter.implementation == self.implementation
|
|
208
|
-
)
|
|
209
|
-
positional = [p for p in parameters_of_this_implementation if p.is_positional]
|
|
210
|
-
keyword_only = self._filter_out_multiple_content_type(
|
|
211
|
-
[p for p in parameters_of_this_implementation if p.is_keyword_only]
|
|
212
|
-
)
|
|
213
|
-
kwargs = self._filter_out_multiple_content_type(
|
|
214
|
-
[p for p in parameters_of_this_implementation if p.is_kwarg]
|
|
215
|
-
)
|
|
216
|
-
def _sort(params):
|
|
217
|
-
return sorted(params, key=lambda x: not x.default_value and x.required, reverse=True)
|
|
218
|
-
signature_parameters = (
|
|
219
|
-
_sort(positional) + _sort(keyword_only) + _sort(kwargs)
|
|
220
|
-
)
|
|
221
|
-
return signature_parameters
|
|
208
|
+
@abstractmethod
|
|
209
|
+
def implementation(self) -> str:
|
|
210
|
+
"""Whether this is a client or a method parameter"""
|
|
211
|
+
...
|
|
222
212
|
|
|
213
|
+
@property
|
|
214
|
+
def unsorted_method_params(self) -> List[Union[ParameterType, BodyParameterType]]:
|
|
215
|
+
"""Method params before sorting"""
|
|
216
|
+
method_params: List[Union[ParameterType, BodyParameterType]] = [
|
|
217
|
+
p
|
|
218
|
+
for p in self.parameters
|
|
219
|
+
if p.in_method_signature and p.implementation == self.implementation
|
|
220
|
+
]
|
|
221
|
+
if self._body_parameter:
|
|
222
|
+
if self._body_parameter.in_method_signature:
|
|
223
|
+
method_params.append(self._body_parameter)
|
|
224
|
+
try:
|
|
225
|
+
# i am a multipart body parameter
|
|
226
|
+
# Only legacy generates operations with me, so I will follow the legacy rules
|
|
227
|
+
# I will splat out my entries as individual entries
|
|
228
|
+
method_params.extend(self._body_parameter.entries) # type: ignore
|
|
229
|
+
except AttributeError:
|
|
230
|
+
pass
|
|
231
|
+
return method_params
|
|
223
232
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
233
|
+
@property
|
|
234
|
+
def method(self) -> List[Union[ParameterType, BodyParameterType]]:
|
|
235
|
+
"""Sorted method params. First positional, then keyword only, then kwarg"""
|
|
236
|
+
return self.positional + self.keyword_only + self.kwarg
|
|
237
|
+
|
|
238
|
+
def method_signature(self, is_python3_file: bool, async_mode: bool) -> List[str]:
|
|
239
|
+
"""Method signature for this parameter list."""
|
|
240
|
+
return method_signature_helper(
|
|
241
|
+
positional=self.method_signature_positional(is_python3_file, async_mode),
|
|
242
|
+
keyword_only=self.method_signature_keyword_only(
|
|
243
|
+
is_python3_file, async_mode
|
|
244
|
+
),
|
|
245
|
+
kwarg_params=self.method_signature_kwargs(is_python3_file),
|
|
229
246
|
)
|
|
230
247
|
|
|
231
|
-
def method_signature_positional(
|
|
232
|
-
|
|
248
|
+
def method_signature_positional(
|
|
249
|
+
self, is_python3_file: bool, async_mode: bool
|
|
250
|
+
) -> List[str]:
|
|
251
|
+
"""Signature for positional parameters"""
|
|
252
|
+
return [
|
|
253
|
+
parameter.method_signature(is_python3_file, async_mode)
|
|
254
|
+
for parameter in self.positional
|
|
255
|
+
]
|
|
233
256
|
|
|
234
|
-
def method_signature_keyword_only(
|
|
257
|
+
def method_signature_keyword_only(
|
|
258
|
+
self, is_python3_file: bool, async_mode: bool
|
|
259
|
+
) -> List[str]:
|
|
260
|
+
"""Signature for keyword only parameters"""
|
|
235
261
|
if not (self.keyword_only and is_python3_file):
|
|
236
262
|
return []
|
|
237
|
-
return ["*,"] + [
|
|
263
|
+
return ["*,"] + [
|
|
264
|
+
parameter.method_signature(is_python3_file, async_mode)
|
|
265
|
+
for parameter in self.keyword_only
|
|
266
|
+
]
|
|
238
267
|
|
|
239
268
|
@staticmethod
|
|
240
269
|
def method_signature_kwargs(is_python3_file: bool) -> List[str]:
|
|
270
|
+
"""Signature for kwargs"""
|
|
241
271
|
return ["**kwargs: Any"] if is_python3_file else ["**kwargs # type: Any"]
|
|
242
272
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
return [p for p in self.method if p.is_keyword_only]
|
|
250
|
-
|
|
251
|
-
@property
|
|
252
|
-
def kwargs(self) -> List[Parameter]:
|
|
253
|
-
return [p for p in self.method if p.is_kwarg]
|
|
254
|
-
|
|
255
|
-
def kwargs_to_pop(self, is_python3_file: bool) -> List[Parameter]:
|
|
256
|
-
kwargs_to_pop = self.kwargs
|
|
273
|
+
def kwargs_to_pop(
|
|
274
|
+
self, is_python3_file: bool
|
|
275
|
+
) -> List[Union[ParameterType, BodyParameterType]]:
|
|
276
|
+
"""Method kwargs we want to pop"""
|
|
277
|
+
# don't want to pop bodies unless it's a constant
|
|
278
|
+
kwargs_to_pop = self.kwarg
|
|
257
279
|
if not is_python3_file:
|
|
258
280
|
kwargs_to_pop += self.keyword_only
|
|
259
|
-
return
|
|
281
|
+
return [
|
|
282
|
+
k
|
|
283
|
+
for k in kwargs_to_pop
|
|
284
|
+
if k.location != ParameterLocation.BODY or k.constant
|
|
285
|
+
]
|
|
260
286
|
|
|
261
287
|
@property
|
|
262
288
|
def call(self) -> List[str]:
|
|
289
|
+
"""How to pass in parameters to call the operation"""
|
|
263
290
|
retval = [
|
|
264
|
-
p.
|
|
291
|
+
p.client_name
|
|
292
|
+
for p in self.method
|
|
293
|
+
if p.method_location == ParameterMethodLocation.POSITIONAL
|
|
265
294
|
]
|
|
266
|
-
retval.extend(
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
295
|
+
retval.extend(
|
|
296
|
+
[
|
|
297
|
+
f"{p.client_name}={p.client_name}"
|
|
298
|
+
for p in self.method
|
|
299
|
+
if p.method_location == ParameterMethodLocation.KEYWORD_ONLY
|
|
300
|
+
]
|
|
301
|
+
)
|
|
270
302
|
retval.append("**kwargs")
|
|
271
303
|
return retval
|
|
272
304
|
|
|
273
|
-
@
|
|
274
|
-
def
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
305
|
+
@classmethod
|
|
306
|
+
def from_yaml(cls, yaml_data: Dict[str, Any], code_model: "CodeModel"):
|
|
307
|
+
parameters = [
|
|
308
|
+
cls.parameter_creator()(parameter, code_model)
|
|
309
|
+
for parameter in yaml_data["parameters"]
|
|
310
|
+
]
|
|
311
|
+
body_parameter = None
|
|
312
|
+
if yaml_data.get("bodyParameter"):
|
|
313
|
+
body_parameter = cls.body_parameter_creator()(
|
|
314
|
+
yaml_data["bodyParameter"], code_model
|
|
315
|
+
)
|
|
316
|
+
return cls(
|
|
317
|
+
yaml_data,
|
|
318
|
+
code_model,
|
|
319
|
+
parameters=parameters,
|
|
320
|
+
body_parameter=body_parameter,
|
|
321
|
+
)
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
class _ParameterList(
|
|
325
|
+
_ParameterListBase[ # pylint: disable=unsubscriptable-object
|
|
326
|
+
Parameter, Union[MultipartBodyParameter, BodyParameter]
|
|
327
|
+
]
|
|
328
|
+
):
|
|
329
|
+
"""Base Parameter class for the two operation ParameterLists"""
|
|
330
|
+
|
|
331
|
+
@staticmethod
|
|
332
|
+
def parameter_creator() -> Callable[[Dict[str, Any], "CodeModel"], Parameter]:
|
|
333
|
+
return Parameter.from_yaml
|
|
334
|
+
|
|
335
|
+
@staticmethod
|
|
336
|
+
def body_parameter_creator() -> Callable[
|
|
337
|
+
[Dict[str, Any], "CodeModel"], Union[MultipartBodyParameter, BodyParameter]
|
|
338
|
+
]:
|
|
339
|
+
return get_body_parameter
|
|
290
340
|
|
|
291
|
-
|
|
292
|
-
|
|
341
|
+
@property
|
|
342
|
+
def implementation(self) -> str:
|
|
343
|
+
return "Method"
|
|
293
344
|
|
|
294
345
|
@property
|
|
295
|
-
def
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
data_params,
|
|
314
|
-
serialized_name="data",
|
|
315
|
-
description="Form-encoded input for data. See the template in our example to find the input shape."
|
|
316
|
-
)
|
|
317
|
-
file_and_data_params.append(data_param)
|
|
318
|
-
method_params = [p for p in method_params if not p.is_multipart and not p.is_data_input]
|
|
319
|
-
positional = [p for p in method_params if p.is_positional]
|
|
320
|
-
keyword_only = self._filter_out_multiple_content_type(
|
|
321
|
-
[p for p in method_params if p.is_keyword_only]
|
|
322
|
-
)
|
|
323
|
-
kwargs = self._filter_out_multiple_content_type(
|
|
324
|
-
[p for p in method_params if p.is_kwarg]
|
|
325
|
-
)
|
|
326
|
-
return positional + file_and_data_params + keyword_only + kwargs
|
|
346
|
+
def path(self) -> List[Parameter]:
|
|
347
|
+
return [
|
|
348
|
+
k for k in super().path if k.location == ParameterLocation.ENDPOINT_PATH
|
|
349
|
+
]
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
class ParameterList(_ParameterList):
|
|
353
|
+
"""ParameterList is the parameter list for Operation classes"""
|
|
354
|
+
|
|
355
|
+
...
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
class _RequestBuilderParameterList(
|
|
359
|
+
_ParameterListBase[ # pylint: disable=unsubscriptable-object
|
|
360
|
+
RequestBuilderParameter, RequestBuilderBodyParameterType
|
|
361
|
+
]
|
|
362
|
+
):
|
|
363
|
+
"""_RequestBuilderParameterList is base parameter list for RequestBuilder classes"""
|
|
327
364
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
365
|
+
@staticmethod
|
|
366
|
+
def parameter_creator() -> Callable[
|
|
367
|
+
[Dict[str, Any], "CodeModel"], RequestBuilderParameter
|
|
368
|
+
]:
|
|
369
|
+
return RequestBuilderParameter.from_yaml
|
|
332
370
|
|
|
333
|
-
|
|
371
|
+
@staticmethod
|
|
372
|
+
def body_parameter_creator() -> Callable[
|
|
373
|
+
[Dict[str, Any], "CodeModel"], RequestBuilderBodyParameterType
|
|
374
|
+
]:
|
|
375
|
+
return get_request_body_parameter
|
|
334
376
|
|
|
335
377
|
@property
|
|
336
378
|
def implementation(self) -> str:
|
|
337
|
-
return "
|
|
379
|
+
return "Method"
|
|
338
380
|
|
|
339
381
|
@property
|
|
340
|
-
def
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
#
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
382
|
+
def unsorted_method_params(
|
|
383
|
+
self,
|
|
384
|
+
) -> List[Union[RequestBuilderParameter, RequestBuilderBodyParameterType]]:
|
|
385
|
+
# don't have access to client params in request builder
|
|
386
|
+
retval = [
|
|
387
|
+
p
|
|
388
|
+
for p in super().unsorted_method_params
|
|
389
|
+
if not (
|
|
390
|
+
p.location == ParameterLocation.BODY
|
|
391
|
+
and cast(RequestBuilderBodyParameterType, p).is_partial_body
|
|
392
|
+
)
|
|
393
|
+
]
|
|
394
|
+
retval.extend(
|
|
395
|
+
[
|
|
396
|
+
p
|
|
397
|
+
for p in self.parameters
|
|
398
|
+
if p.implementation == "Client" and p.in_method_signature
|
|
399
|
+
]
|
|
355
400
|
)
|
|
356
|
-
return
|
|
401
|
+
return retval
|
|
357
402
|
|
|
358
403
|
@property
|
|
359
|
-
def
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
raise ValueError("You need to first set the code model")
|
|
404
|
+
def path(self) -> List[RequestBuilderParameter]:
|
|
405
|
+
return [
|
|
406
|
+
p for p in super().path if p.location != ParameterLocation.ENDPOINT_PATH
|
|
407
|
+
]
|
|
364
408
|
|
|
365
|
-
@code_model.setter
|
|
366
|
-
def code_model(self, val):
|
|
367
|
-
self._code_model = val
|
|
368
409
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
410
|
+
class RequestBuilderParameterList(_RequestBuilderParameterList):
|
|
411
|
+
"""Parameter list for Request Builder"""
|
|
412
|
+
|
|
413
|
+
...
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
class OverloadedRequestBuilderParameterList(_RequestBuilderParameterList):
|
|
417
|
+
"""Parameter list for OverloadedRequestBuilder"""
|
|
418
|
+
|
|
419
|
+
def method_signature(self, is_python3_file: bool, async_mode: bool) -> List[str]:
|
|
420
|
+
return self.method_signature_positional(
|
|
421
|
+
is_python3_file, async_mode
|
|
422
|
+
) + self.method_signature_kwargs(is_python3_file)
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
class _ClientGlobalParameterList(
|
|
426
|
+
# pylint: disable=unsubscriptable-object
|
|
427
|
+
_ParameterListBase[ParameterType, BodyParameter]
|
|
428
|
+
):
|
|
429
|
+
"""Base parameter list for client and config classes"""
|
|
376
430
|
|
|
377
431
|
@staticmethod
|
|
378
|
-
def
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
parameter.rest_api_name != "$host"
|
|
383
|
-
)
|
|
432
|
+
def body_parameter_creator() -> Callable[
|
|
433
|
+
[Dict[str, Any], "CodeModel"], BodyParameter
|
|
434
|
+
]:
|
|
435
|
+
return BodyParameter.from_yaml
|
|
384
436
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
self.code_model,
|
|
389
|
-
yaml_data={},
|
|
390
|
-
schema=StringSchema(namespace="", yaml_data={"type": "str"}),
|
|
391
|
-
rest_api_name=self.host_variable_name,
|
|
392
|
-
serialized_name=self.host_variable_name,
|
|
393
|
-
description=f"Service URL.",
|
|
394
|
-
implementation="Client",
|
|
395
|
-
required=True,
|
|
396
|
-
location=ParameterLocation.Other,
|
|
397
|
-
skip_url_encoding=False,
|
|
398
|
-
constraints=[],
|
|
399
|
-
client_default_value=host_value,
|
|
400
|
-
keyword_only=self.code_model.options["version_tolerant"] or self.code_model.options["low_level_client"],
|
|
401
|
-
)
|
|
402
|
-
self.parameters.append(host_param)
|
|
403
|
-
|
|
404
|
-
def add_credential_global_parameter(self) -> None:
|
|
405
|
-
credential_parameter = Parameter(
|
|
406
|
-
self.code_model,
|
|
407
|
-
yaml_data={},
|
|
408
|
-
schema=self.code_model.credential_schema_policy.credential,
|
|
409
|
-
serialized_name="credential",
|
|
410
|
-
rest_api_name="credential",
|
|
411
|
-
implementation="Client",
|
|
412
|
-
description="Credential needed for the client to connect to Azure.",
|
|
413
|
-
required=True,
|
|
414
|
-
location=ParameterLocation.Other,
|
|
415
|
-
skip_url_encoding=True,
|
|
416
|
-
constraints=[],
|
|
417
|
-
)
|
|
418
|
-
if self.code_model.options["version_tolerant"] or self.code_model.options["low_level_client"]:
|
|
419
|
-
self.parameters.append(credential_parameter)
|
|
420
|
-
else:
|
|
421
|
-
self.parameters.insert(0, credential_parameter)
|
|
437
|
+
@property
|
|
438
|
+
def implementation(self) -> str:
|
|
439
|
+
return "Client"
|
|
422
440
|
|
|
423
441
|
@property
|
|
424
|
-
def
|
|
442
|
+
def credential(self) -> Optional[ParameterType]:
|
|
425
443
|
try:
|
|
426
|
-
return next(p for p in self.parameters if p.
|
|
444
|
+
return next(p for p in self.parameters if p.client_name == "credential")
|
|
427
445
|
except StopIteration:
|
|
428
446
|
return None
|
|
429
447
|
|
|
430
448
|
@property
|
|
431
|
-
def
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
449
|
+
def path(self) -> List[ParameterType]:
|
|
450
|
+
return [
|
|
451
|
+
p for p in super().path if p.location == ParameterLocation.ENDPOINT_PATH
|
|
452
|
+
]
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
class ClientGlobalParameterList(_ClientGlobalParameterList[ClientParameter]):
|
|
456
|
+
"""Parameter list for Client class"""
|
|
457
|
+
|
|
458
|
+
@staticmethod
|
|
459
|
+
def parameter_creator() -> Callable[[Dict[str, Any], "CodeModel"], ClientParameter]:
|
|
460
|
+
return ClientParameter.from_yaml
|
|
438
461
|
|
|
439
462
|
@property
|
|
440
|
-
def
|
|
441
|
-
return
|
|
463
|
+
def path(self) -> List[ClientParameter]:
|
|
464
|
+
return [p for p in super().path if not p.is_host]
|
|
442
465
|
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
466
|
+
@property
|
|
467
|
+
def host(self) -> Optional[ClientParameter]:
|
|
468
|
+
"""Get the host parameter"""
|
|
469
|
+
try:
|
|
470
|
+
return next(p for p in self.parameters if p.is_host)
|
|
471
|
+
except StopIteration:
|
|
472
|
+
return None
|
|
447
473
|
|
|
448
|
-
def kwargs_to_pop(
|
|
474
|
+
def kwargs_to_pop(
|
|
475
|
+
self, is_python3_file: bool
|
|
476
|
+
) -> List[Union[ClientParameter, BodyParameter]]:
|
|
477
|
+
"""We only want to pass base url path parameters in the client"""
|
|
449
478
|
return [
|
|
450
|
-
k
|
|
451
|
-
|
|
479
|
+
k
|
|
480
|
+
for k in super().kwargs_to_pop(is_python3_file=is_python3_file)
|
|
481
|
+
if k.location == ParameterLocation.ENDPOINT_PATH
|
|
452
482
|
]
|
|
453
483
|
|
|
454
|
-
def config_kwargs_to_pop(self, is_python3_file: bool) -> List[Parameter]:
|
|
455
|
-
current_kwargs_to_pop = super().kwargs_to_pop(is_python3_file)
|
|
456
|
-
return [k for k in current_kwargs_to_pop if self._param_is_in_config_method(k.serialized_name)]
|
|
457
484
|
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
return [p for p in self.method if self._param_is_in_config_method(p.serialized_name)]
|
|
461
|
-
|
|
462
|
-
def client_method_signature(self, is_python3_file: bool) -> List[str]:
|
|
463
|
-
return self.method_signature(is_python3_file)
|
|
485
|
+
class ConfigGlobalParameterList(_ClientGlobalParameterList[ConfigParameter]):
|
|
486
|
+
"""Parameter list for config"""
|
|
464
487
|
|
|
465
|
-
|
|
488
|
+
@staticmethod
|
|
489
|
+
def parameter_creator() -> Callable[[Dict[str, Any], "CodeModel"], ConfigParameter]:
|
|
490
|
+
return ConfigParameter.from_yaml
|
|
466
491
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
if self._param_is_in_config_method(p.serialized_name)
|
|
471
|
-
]
|
|
472
|
-
keyword_only_params = [p for p in self.keyword_only if self._param_is_in_config_method(p.serialized_name)]
|
|
473
|
-
keyword_only_method_signature = []
|
|
474
|
-
if is_python3_file:
|
|
475
|
-
keyword_only_method_signature = (
|
|
476
|
-
["*,"] +
|
|
477
|
-
[
|
|
478
|
-
p.method_signature(is_python3_file) for p in keyword_only_params
|
|
479
|
-
]
|
|
480
|
-
) if keyword_only_params else []
|
|
481
|
-
return _method_signature_helper(
|
|
482
|
-
positional=positional,
|
|
483
|
-
keyword_only=keyword_only_method_signature,
|
|
484
|
-
kwarg_params=self.method_signature_kwargs(is_python3_file)
|
|
485
|
-
)
|
|
492
|
+
@property
|
|
493
|
+
def implementation(self) -> str:
|
|
494
|
+
return "Client"
|