@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
|
@@ -1,280 +0,0 @@
|
|
|
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 copy import copy
|
|
7
|
-
from typing import List, Optional, Tuple, TypeVar, Dict
|
|
8
|
-
from .request_builder_parameter import RequestBuilderParameter
|
|
9
|
-
from .parameter_list import ParameterList
|
|
10
|
-
from .parameter import ParameterLocation, Parameter, ParameterStyle
|
|
11
|
-
from .primitive_schemas import AnySchema, JSONSchema
|
|
12
|
-
from .dictionary_schema import DictionarySchema
|
|
13
|
-
from .base_schema import BaseSchema
|
|
14
|
-
from .schema_request import SchemaRequest
|
|
15
|
-
from .utils import JSON_REGEXP
|
|
16
|
-
|
|
17
|
-
T = TypeVar('T')
|
|
18
|
-
OrderedSet = Dict[T, None]
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def _update_content_types(content_types_to_assign: List[str], param: Parameter):
|
|
22
|
-
return [
|
|
23
|
-
c for c in content_types_to_assign if c not in param.content_types
|
|
24
|
-
]
|
|
25
|
-
|
|
26
|
-
def _kwarg_not_added(body_method_params, serialized_name: str) -> bool:
|
|
27
|
-
return not any(b for b in body_method_params if b.serialized_name == serialized_name)
|
|
28
|
-
|
|
29
|
-
class RequestBuilderParameterList(ParameterList):
|
|
30
|
-
def __init__(
|
|
31
|
-
self,
|
|
32
|
-
code_model,
|
|
33
|
-
parameters: Optional[List[RequestBuilderParameter]] = None,
|
|
34
|
-
schema_requests: Optional[List[SchemaRequest]] = None,
|
|
35
|
-
) -> None:
|
|
36
|
-
super(RequestBuilderParameterList, self).__init__(
|
|
37
|
-
code_model, parameters, schema_requests # type: ignore
|
|
38
|
-
)
|
|
39
|
-
self.body_kwarg_names: OrderedSet[str] = {}
|
|
40
|
-
self.parameters: List[RequestBuilderParameter] = parameters or [] # type: ignore
|
|
41
|
-
|
|
42
|
-
def _change_body_param_name(self, parameter: Parameter, name: str) -> None:
|
|
43
|
-
self.body_kwarg_names[name] = None
|
|
44
|
-
parameter.serialized_name = name
|
|
45
|
-
parameter.is_body_kwarg = True
|
|
46
|
-
|
|
47
|
-
def _is_json(self, body_method_param: Parameter) -> bool:
|
|
48
|
-
if 'json' in body_method_param.serialization_formats:
|
|
49
|
-
return True
|
|
50
|
-
if not any(
|
|
51
|
-
flag for flag in ["version_tolerant", "low_level_client"]
|
|
52
|
-
if self.code_model.options.get(flag)
|
|
53
|
-
):
|
|
54
|
-
if body_method_param.style == ParameterStyle.binary:
|
|
55
|
-
return False
|
|
56
|
-
if any(
|
|
57
|
-
sr for sr in self.schema_requests
|
|
58
|
-
if sr.yaml_data.get("protocol", {}).get('http', {}).get('knownMediaType') == "json"
|
|
59
|
-
):
|
|
60
|
-
return True
|
|
61
|
-
return any(c for c in self.content_types if JSON_REGEXP.match(c))
|
|
62
|
-
|
|
63
|
-
@property
|
|
64
|
-
def body_kwargs_to_get(self) -> List[Parameter]:
|
|
65
|
-
if not self.body_kwarg_names:
|
|
66
|
-
return []
|
|
67
|
-
return [b for b in self.body if b.content_types]
|
|
68
|
-
|
|
69
|
-
def _update_constant_params(self):
|
|
70
|
-
# we don't currently have a fully constant data or files input
|
|
71
|
-
# so we don't need to modify the body kwarg
|
|
72
|
-
constant_bodies = [
|
|
73
|
-
p for p in self.parameters
|
|
74
|
-
if p.location == ParameterLocation.Body
|
|
75
|
-
and p.constant
|
|
76
|
-
and not p.is_data_input
|
|
77
|
-
and not p.is_multipart
|
|
78
|
-
]
|
|
79
|
-
for constant_body in constant_bodies:
|
|
80
|
-
if self._is_json(constant_body):
|
|
81
|
-
constant_body.serialized_name = "json"
|
|
82
|
-
else:
|
|
83
|
-
constant_body.serialized_name = "content"
|
|
84
|
-
|
|
85
|
-
def _add_files_kwarg(
|
|
86
|
-
self, content_types_to_assign, body_method_param
|
|
87
|
-
) -> Tuple[List[str], RequestBuilderParameter]:
|
|
88
|
-
file_kwarg = copy(body_method_param)
|
|
89
|
-
self._change_body_param_name(file_kwarg, "files")
|
|
90
|
-
file_kwarg.schema = DictionarySchema(
|
|
91
|
-
namespace="",
|
|
92
|
-
yaml_data={},
|
|
93
|
-
element_type=AnySchema(namespace="", yaml_data={}),
|
|
94
|
-
)
|
|
95
|
-
file_kwarg.description = (
|
|
96
|
-
"Multipart input for files. See the template in our example to find the input shape. " +
|
|
97
|
-
file_kwarg.description
|
|
98
|
-
)
|
|
99
|
-
file_kwarg.content_types = [
|
|
100
|
-
c for c in content_types_to_assign
|
|
101
|
-
if c == "multipart/form-data"
|
|
102
|
-
]
|
|
103
|
-
content_types_to_assign = _update_content_types(content_types_to_assign, file_kwarg)
|
|
104
|
-
return content_types_to_assign, file_kwarg
|
|
105
|
-
|
|
106
|
-
def _add_data_kwarg(
|
|
107
|
-
self, content_types_to_assign, body_method_param
|
|
108
|
-
) -> Tuple[List[str], RequestBuilderParameter]:
|
|
109
|
-
data_kwarg = copy(body_method_param)
|
|
110
|
-
self._change_body_param_name(data_kwarg, "data")
|
|
111
|
-
data_kwarg.schema = DictionarySchema(
|
|
112
|
-
namespace="",
|
|
113
|
-
yaml_data={},
|
|
114
|
-
element_type=AnySchema(namespace="", yaml_data={}),
|
|
115
|
-
)
|
|
116
|
-
data_kwarg.description = (
|
|
117
|
-
"Pass in dictionary that contains form data to include in the body of the request. " +
|
|
118
|
-
data_kwarg.description
|
|
119
|
-
)
|
|
120
|
-
data_kwarg.content_types = [
|
|
121
|
-
c for c in content_types_to_assign
|
|
122
|
-
if c == "application/x-www-form-urlencoded"
|
|
123
|
-
]
|
|
124
|
-
content_types_to_assign = _update_content_types(content_types_to_assign, data_kwarg)
|
|
125
|
-
return content_types_to_assign, data_kwarg
|
|
126
|
-
|
|
127
|
-
def _add_json_kwarg(
|
|
128
|
-
self, content_types_to_assign, body_method_param
|
|
129
|
-
) -> Tuple[List[str], RequestBuilderParameter]:
|
|
130
|
-
json_kwarg = copy(body_method_param)
|
|
131
|
-
self._change_body_param_name(json_kwarg, "json")
|
|
132
|
-
json_kwarg.description = (
|
|
133
|
-
"Pass in a JSON-serializable object (usually a dictionary). "
|
|
134
|
-
"See the template in our example to find the input shape. " +
|
|
135
|
-
json_kwarg.description
|
|
136
|
-
)
|
|
137
|
-
json_kwarg.schema = JSONSchema(namespace="", yaml_data={})
|
|
138
|
-
json_kwarg.content_types = [
|
|
139
|
-
c for c in content_types_to_assign
|
|
140
|
-
if JSON_REGEXP.match(c)
|
|
141
|
-
]
|
|
142
|
-
content_types_to_assign = _update_content_types(content_types_to_assign, json_kwarg)
|
|
143
|
-
return content_types_to_assign, json_kwarg
|
|
144
|
-
|
|
145
|
-
def _add_content_kwarg(
|
|
146
|
-
self, content_types_to_assign, body_method_param
|
|
147
|
-
) -> RequestBuilderParameter:
|
|
148
|
-
content_kwarg = copy(body_method_param)
|
|
149
|
-
self._change_body_param_name(content_kwarg, "content")
|
|
150
|
-
content_kwarg.schema = AnySchema(namespace="", yaml_data={})
|
|
151
|
-
content_kwarg.description = (
|
|
152
|
-
"Pass in binary content you want in the body of the request (typically bytes, "
|
|
153
|
-
"a byte iterator, or stream input). " +
|
|
154
|
-
content_kwarg.description
|
|
155
|
-
)
|
|
156
|
-
content_kwarg.is_data_input = False
|
|
157
|
-
content_kwarg.is_multipart = False
|
|
158
|
-
content_kwarg.content_types = content_types_to_assign
|
|
159
|
-
return content_kwarg
|
|
160
|
-
|
|
161
|
-
def add_body_kwargs(self) -> None:
|
|
162
|
-
self._update_constant_params()
|
|
163
|
-
body_kwargs_added: List[RequestBuilderParameter] = []
|
|
164
|
-
body_method_params = [
|
|
165
|
-
p for p in self.parameters
|
|
166
|
-
if p.location == ParameterLocation.Body and not p.constant
|
|
167
|
-
]
|
|
168
|
-
if not body_method_params:
|
|
169
|
-
return
|
|
170
|
-
content_types_to_assign = copy(self.content_types)
|
|
171
|
-
for body_method_param in body_method_params:
|
|
172
|
-
if body_method_param.is_multipart and _kwarg_not_added(body_kwargs_added, "files"):
|
|
173
|
-
content_types_to_assign, file_kwarg = self._add_files_kwarg(
|
|
174
|
-
content_types_to_assign, body_method_param
|
|
175
|
-
)
|
|
176
|
-
body_kwargs_added.append(file_kwarg)
|
|
177
|
-
|
|
178
|
-
elif body_method_param.is_data_input and _kwarg_not_added(body_kwargs_added, "data"):
|
|
179
|
-
content_types_to_assign, data_kwarg = self._add_data_kwarg(
|
|
180
|
-
content_types_to_assign, body_method_param
|
|
181
|
-
)
|
|
182
|
-
body_kwargs_added.append(data_kwarg)
|
|
183
|
-
elif self._is_json(body_method_param) and _kwarg_not_added(body_kwargs_added, "json"):
|
|
184
|
-
content_types_to_assign, json_kwarg = self._add_json_kwarg(
|
|
185
|
-
content_types_to_assign, body_method_param
|
|
186
|
-
)
|
|
187
|
-
body_kwargs_added.append(json_kwarg)
|
|
188
|
-
|
|
189
|
-
first_body_param = body_method_params[0]
|
|
190
|
-
if _kwarg_not_added(body_kwargs_added, "content"):
|
|
191
|
-
# we always add a content kwarg so users can pass in input by stream
|
|
192
|
-
content_kwarg = self._add_content_kwarg(
|
|
193
|
-
content_types_to_assign, first_body_param
|
|
194
|
-
)
|
|
195
|
-
body_kwargs_added.append(content_kwarg)
|
|
196
|
-
if len(body_kwargs_added) == 1:
|
|
197
|
-
body_kwargs_added[0].required = first_body_param.required
|
|
198
|
-
else:
|
|
199
|
-
for kwarg in body_kwargs_added:
|
|
200
|
-
kwarg.required = False
|
|
201
|
-
first_body_param.need_import = False
|
|
202
|
-
self.parameters = body_kwargs_added + self.parameters
|
|
203
|
-
|
|
204
|
-
@property
|
|
205
|
-
def json_body(self) -> BaseSchema:
|
|
206
|
-
if not self._json_body:
|
|
207
|
-
try:
|
|
208
|
-
json_param = next(
|
|
209
|
-
b for b in self.body if not b.is_body_kwarg and
|
|
210
|
-
b.is_json_parameter
|
|
211
|
-
)
|
|
212
|
-
self._json_body = json_param.schema
|
|
213
|
-
return self._json_body
|
|
214
|
-
except StopIteration:
|
|
215
|
-
raise ValueError("There is no JSON body in these parameters")
|
|
216
|
-
return self._json_body
|
|
217
|
-
|
|
218
|
-
def kwargs_to_pop(self, is_python3_file: bool) -> List[Parameter]:
|
|
219
|
-
# we don't want to pop the body kwargs in py2.7. We send them straight to HttpRequest
|
|
220
|
-
kwargs_to_pop = self.kwargs
|
|
221
|
-
if not is_python3_file:
|
|
222
|
-
kwargs_to_pop += [k for k in self.keyword_only if not (k.is_body and not k.constant)]
|
|
223
|
-
return kwargs_to_pop
|
|
224
|
-
|
|
225
|
-
@property
|
|
226
|
-
def method(self) -> List[Parameter]:
|
|
227
|
-
"""The list of parameter used in method signature. Includes both positional and kwargs
|
|
228
|
-
"""
|
|
229
|
-
signature_parameters_no_default_value = []
|
|
230
|
-
signature_parameters_default_value = []
|
|
231
|
-
|
|
232
|
-
# Want all method parameters.
|
|
233
|
-
# Also allow client parameters if they're going to be used in the request body.
|
|
234
|
-
# i.e., path parameter, query parameter, header.
|
|
235
|
-
parameters = self.get_from_predicate(
|
|
236
|
-
lambda parameter: parameter.implementation == self.implementation or parameter.in_method_code
|
|
237
|
-
)
|
|
238
|
-
seen_content_type = False
|
|
239
|
-
|
|
240
|
-
for parameter in parameters:
|
|
241
|
-
|
|
242
|
-
if (
|
|
243
|
-
parameter.location == ParameterLocation.Body and
|
|
244
|
-
(parameter.is_data_input or parameter.is_multipart) and
|
|
245
|
-
not parameter.is_body_kwarg
|
|
246
|
-
):
|
|
247
|
-
# if i am a part of files or data, and i'm not the files or
|
|
248
|
-
# data kwarg, ignore me
|
|
249
|
-
continue
|
|
250
|
-
if (
|
|
251
|
-
parameter.location == ParameterLocation.Body and
|
|
252
|
-
not parameter.is_body_kwarg and
|
|
253
|
-
not parameter.constant
|
|
254
|
-
):
|
|
255
|
-
# we keep the original body param from the swagger for documentation purposes
|
|
256
|
-
# we don't want it in the method signature
|
|
257
|
-
continue
|
|
258
|
-
if any([g for g in self.groupers if id(g.yaml_data) == id(parameter.yaml_data)]):
|
|
259
|
-
# we don't allow a grouped parameter for the body param
|
|
260
|
-
continue
|
|
261
|
-
if seen_content_type and parameter.serialized_name == "content_type":
|
|
262
|
-
# we ony want one content type
|
|
263
|
-
# there can be multiple content types in the case of multiple media types
|
|
264
|
-
continue
|
|
265
|
-
if parameter.serialized_name == "content_type":
|
|
266
|
-
seen_content_type = True
|
|
267
|
-
if parameter.in_method_signature:
|
|
268
|
-
if not parameter.default_value and parameter.required:
|
|
269
|
-
signature_parameters_no_default_value.append(parameter)
|
|
270
|
-
else:
|
|
271
|
-
signature_parameters_default_value.append(parameter)
|
|
272
|
-
|
|
273
|
-
signature_parameters = signature_parameters_no_default_value + signature_parameters_default_value
|
|
274
|
-
signature_parameters.sort(key=lambda item: item.is_keyword_only)
|
|
275
|
-
signature_parameters = self._filter_out_multiple_content_type(signature_parameters)
|
|
276
|
-
return signature_parameters
|
|
277
|
-
|
|
278
|
-
@staticmethod
|
|
279
|
-
def _wanted_path_parameter(parameter):
|
|
280
|
-
return parameter.location == ParameterLocation.Path
|
|
@@ -1,42 +0,0 @@
|
|
|
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
|
|
7
|
-
from .base_model import BaseModel
|
|
8
|
-
from .request_builder import RequestBuilder
|
|
9
|
-
from .imports import FileImport
|
|
10
|
-
|
|
11
|
-
class Rest(BaseModel):
|
|
12
|
-
"""Everything that goes into the request_builders
|
|
13
|
-
"""
|
|
14
|
-
def __init__(
|
|
15
|
-
self,
|
|
16
|
-
yaml_data: Dict[str, Any],
|
|
17
|
-
request_builders: List[RequestBuilder]
|
|
18
|
-
):
|
|
19
|
-
super(Rest, self). __init__(yaml_data=yaml_data)
|
|
20
|
-
self.request_builders = request_builders
|
|
21
|
-
|
|
22
|
-
def imports(self, builder_group_name: str) -> FileImport:
|
|
23
|
-
file_import = FileImport()
|
|
24
|
-
for request_builder in self.request_builders:
|
|
25
|
-
if request_builder.builder_group_name == builder_group_name:
|
|
26
|
-
file_import.merge(request_builder.imports())
|
|
27
|
-
return file_import
|
|
28
|
-
|
|
29
|
-
@classmethod
|
|
30
|
-
def from_yaml(cls, yaml_data: Dict[str, Any], *, code_model) -> "Rest":
|
|
31
|
-
request_builders = []
|
|
32
|
-
if yaml_data.get("operationGroups"):
|
|
33
|
-
request_builders = [
|
|
34
|
-
RequestBuilder.from_yaml(operation_yaml, code_model=code_model)
|
|
35
|
-
for og_group in yaml_data["operationGroups"]
|
|
36
|
-
for operation_yaml in og_group["operations"]
|
|
37
|
-
]
|
|
38
|
-
|
|
39
|
-
return cls(
|
|
40
|
-
yaml_data=yaml_data,
|
|
41
|
-
request_builders=request_builders
|
|
42
|
-
)
|
|
@@ -1,45 +0,0 @@
|
|
|
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 Dict, List, Any, Optional
|
|
7
|
-
|
|
8
|
-
from .base_model import BaseModel
|
|
9
|
-
from .parameter import Parameter
|
|
10
|
-
from .parameter_list import ParameterList
|
|
11
|
-
|
|
12
|
-
class SchemaRequest(BaseModel):
|
|
13
|
-
def __init__(
|
|
14
|
-
self,
|
|
15
|
-
yaml_data: Dict[str, Any],
|
|
16
|
-
content_types: List[str],
|
|
17
|
-
parameters: ParameterList,
|
|
18
|
-
) -> None:
|
|
19
|
-
super().__init__(yaml_data)
|
|
20
|
-
self.content_types = content_types
|
|
21
|
-
self.parameters = parameters
|
|
22
|
-
|
|
23
|
-
@property
|
|
24
|
-
def is_stream_request(self) -> bool:
|
|
25
|
-
"""Is the request expected to be streamable, like a download."""
|
|
26
|
-
if self.yaml_data['protocol']['http'].get('knownMediaType'):
|
|
27
|
-
return self.yaml_data['protocol']['http']['knownMediaType'] == 'binary' # FIXME: this might be an m4 issue
|
|
28
|
-
return self.yaml_data["protocol"]["http"].get("binary", False)
|
|
29
|
-
|
|
30
|
-
@classmethod
|
|
31
|
-
def from_yaml(cls, yaml_data: Dict[str, Any], *, code_model) -> "SchemaRequest":
|
|
32
|
-
|
|
33
|
-
parameters: Optional[List[Parameter]] = [
|
|
34
|
-
Parameter.from_yaml(yaml, code_model=code_model)
|
|
35
|
-
for yaml in yaml_data.get("parameters", [])
|
|
36
|
-
]
|
|
37
|
-
|
|
38
|
-
return cls(
|
|
39
|
-
yaml_data=yaml_data,
|
|
40
|
-
content_types=yaml_data["protocol"]["http"].get("mediaTypes", []),
|
|
41
|
-
parameters=ParameterList(code_model, parameters)
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
def __repr__(self) -> str:
|
|
45
|
-
return f"<{self.__class__.__name__} {self.content_types}>"
|
|
@@ -1,136 +0,0 @@
|
|
|
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 Dict, Optional, List, Union, Any, cast, TYPE_CHECKING
|
|
7
|
-
|
|
8
|
-
from .base_model import BaseModel
|
|
9
|
-
from .base_schema import BaseSchema
|
|
10
|
-
from .object_schema import ObjectSchema
|
|
11
|
-
from .imports import FileImport, ImportType
|
|
12
|
-
from .utils import get_schema
|
|
13
|
-
from .primitive_schemas import IOSchema
|
|
14
|
-
|
|
15
|
-
if TYPE_CHECKING:
|
|
16
|
-
from .code_model import CodeModel
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class HeaderResponse:
|
|
20
|
-
def __init__(self, name: str, schema) -> None:
|
|
21
|
-
self.name = name
|
|
22
|
-
self.schema = schema
|
|
23
|
-
|
|
24
|
-
@property
|
|
25
|
-
def serialization_type(self) -> str:
|
|
26
|
-
return self.schema.serialization_type
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
class SchemaResponse(BaseModel):
|
|
30
|
-
def __init__(
|
|
31
|
-
self,
|
|
32
|
-
code_model: "CodeModel",
|
|
33
|
-
yaml_data: Dict[str, Any],
|
|
34
|
-
schema: Optional[BaseSchema],
|
|
35
|
-
content_types: List[str],
|
|
36
|
-
status_codes: List[Union[str, int]],
|
|
37
|
-
headers: List[HeaderResponse],
|
|
38
|
-
binary: bool,
|
|
39
|
-
) -> None:
|
|
40
|
-
super().__init__(yaml_data)
|
|
41
|
-
self.code_model = code_model
|
|
42
|
-
self.schema = schema
|
|
43
|
-
self.content_types = content_types
|
|
44
|
-
self.status_codes = status_codes
|
|
45
|
-
self.headers = headers
|
|
46
|
-
self.binary = binary
|
|
47
|
-
self.nullable = self.yaml_data.get("nullable", False)
|
|
48
|
-
|
|
49
|
-
@property
|
|
50
|
-
def has_body(self) -> bool:
|
|
51
|
-
"""Tell if that response defines a body.
|
|
52
|
-
"""
|
|
53
|
-
return bool(self.schema)
|
|
54
|
-
|
|
55
|
-
@property
|
|
56
|
-
def has_headers(self) -> bool:
|
|
57
|
-
"""Tell if that response defines headers.
|
|
58
|
-
"""
|
|
59
|
-
return bool(self.headers)
|
|
60
|
-
|
|
61
|
-
@property
|
|
62
|
-
def serialization_type(self) -> str:
|
|
63
|
-
if self.schema:
|
|
64
|
-
return self.schema.serialization_type
|
|
65
|
-
return "None"
|
|
66
|
-
|
|
67
|
-
def type_annotation(self, *, is_operation_file: bool = False) -> str:
|
|
68
|
-
if not self.schema:
|
|
69
|
-
return "None"
|
|
70
|
-
if self.nullable:
|
|
71
|
-
return f"Optional[{self.schema.type_annotation(is_operation_file=is_operation_file)}]"
|
|
72
|
-
return self.schema.type_annotation(is_operation_file=is_operation_file)
|
|
73
|
-
|
|
74
|
-
@property
|
|
75
|
-
def docstring_text(self) -> str:
|
|
76
|
-
if not self.schema:
|
|
77
|
-
return "None"
|
|
78
|
-
if self.nullable:
|
|
79
|
-
return f"{self.schema.docstring_text} or None"
|
|
80
|
-
return self.schema.docstring_text
|
|
81
|
-
|
|
82
|
-
@property
|
|
83
|
-
def docstring_type(self) -> str:
|
|
84
|
-
if not self.schema:
|
|
85
|
-
return "None"
|
|
86
|
-
if self.nullable:
|
|
87
|
-
return f"{self.schema.docstring_type} or None"
|
|
88
|
-
return self.schema.docstring_type
|
|
89
|
-
|
|
90
|
-
@property
|
|
91
|
-
def is_stream_response(self) -> bool:
|
|
92
|
-
"""Is the response expected to be streamable, like a download."""
|
|
93
|
-
return self.binary
|
|
94
|
-
|
|
95
|
-
@property
|
|
96
|
-
def is_exception(self) -> bool:
|
|
97
|
-
if self.schema:
|
|
98
|
-
return cast(ObjectSchema, self.schema).is_exception
|
|
99
|
-
return False
|
|
100
|
-
|
|
101
|
-
@property
|
|
102
|
-
def is_xml(self) -> bool:
|
|
103
|
-
return any(["xml" in ct for ct in self.content_types])
|
|
104
|
-
|
|
105
|
-
def imports(self, code_model) -> FileImport:
|
|
106
|
-
file_import = FileImport()
|
|
107
|
-
if not code_model.options["models_mode"] and self.is_xml:
|
|
108
|
-
file_import.add_submodule_import("xml.etree", "ElementTree", ImportType.STDLIB, alias="ET")
|
|
109
|
-
return file_import
|
|
110
|
-
|
|
111
|
-
@classmethod
|
|
112
|
-
def from_yaml(cls, yaml_data: Dict[str, Any], *, code_model: "CodeModel") -> "SchemaResponse":
|
|
113
|
-
binary = yaml_data.get("binary", False)
|
|
114
|
-
if binary:
|
|
115
|
-
schema: BaseSchema = IOSchema(namespace=None, yaml_data={})
|
|
116
|
-
else:
|
|
117
|
-
schema = get_schema(code_model, yaml_data.get("schema"))
|
|
118
|
-
return cls(
|
|
119
|
-
code_model=code_model,
|
|
120
|
-
yaml_data=yaml_data,
|
|
121
|
-
schema=schema,
|
|
122
|
-
content_types=yaml_data["protocol"]["http"].get("mediaTypes", []),
|
|
123
|
-
status_codes=[
|
|
124
|
-
int(code) if code != "default" else "default" for code in yaml_data["protocol"]["http"]["statusCodes"]
|
|
125
|
-
],
|
|
126
|
-
headers=[
|
|
127
|
-
HeaderResponse(
|
|
128
|
-
header_prop["header"], get_schema(code_model, header_prop["schema"], header_prop["header"])
|
|
129
|
-
)
|
|
130
|
-
for header_prop in yaml_data["protocol"]["http"].get("headers", [])
|
|
131
|
-
],
|
|
132
|
-
binary=binary,
|
|
133
|
-
)
|
|
134
|
-
|
|
135
|
-
def __repr__(self) -> str:
|
|
136
|
-
return f"<{self.__class__.__name__} {self.status_codes}>"
|
|
@@ -1,57 +0,0 @@
|
|
|
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 List
|
|
7
|
-
from jinja2 import Environment
|
|
8
|
-
|
|
9
|
-
from ..models import RequestBuilder
|
|
10
|
-
from .import_serializer import FileImportSerializer
|
|
11
|
-
from ..models import CodeModel
|
|
12
|
-
from .builder_serializer import (
|
|
13
|
-
RequestBuilderGenericSerializer,
|
|
14
|
-
RequestBuilderPython3Serializer,
|
|
15
|
-
)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class RestSerializer:
|
|
19
|
-
def __init__(self, code_model: CodeModel, env: Environment, request_builders: List[RequestBuilder]) -> None:
|
|
20
|
-
self.code_model = code_model
|
|
21
|
-
self.env = env
|
|
22
|
-
self.request_builders = request_builders
|
|
23
|
-
self.builder_group_name = request_builders[0].builder_group_name
|
|
24
|
-
|
|
25
|
-
def serialize_init(self) -> str:
|
|
26
|
-
template = self.env.get_template("rest_init.py.jinja2")
|
|
27
|
-
return template.render(code_model=self.code_model, request_builders=self.request_builders)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
class RestPython3Serializer(RestSerializer):
|
|
31
|
-
def serialize_request_builders(self) -> str:
|
|
32
|
-
template = self.env.get_template("request_builders.py.jinja2")
|
|
33
|
-
|
|
34
|
-
return template.render(
|
|
35
|
-
code_model=self.code_model,
|
|
36
|
-
request_builders=self.request_builders,
|
|
37
|
-
imports=FileImportSerializer(self.code_model.rest.imports(
|
|
38
|
-
self.builder_group_name
|
|
39
|
-
), is_python3_file=True),
|
|
40
|
-
is_python3_file=True,
|
|
41
|
-
request_builder_serializer=RequestBuilderPython3Serializer(self.code_model),
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
class RestGenericSerializer(RestSerializer):
|
|
46
|
-
def serialize_request_builders(self) -> str:
|
|
47
|
-
template = self.env.get_template("request_builders.py.jinja2")
|
|
48
|
-
|
|
49
|
-
return template.render(
|
|
50
|
-
code_model=self.code_model,
|
|
51
|
-
request_builders=self.request_builders,
|
|
52
|
-
imports=FileImportSerializer(self.code_model.rest.imports(
|
|
53
|
-
self.builder_group_name
|
|
54
|
-
), is_python3_file=False),
|
|
55
|
-
is_python3_file=False,
|
|
56
|
-
request_builder_serializer=RequestBuilderGenericSerializer(self.code_model),
|
|
57
|
-
)
|
|
@@ -1,25 +0,0 @@
|
|
|
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
|
-
"""The namer autorest plugin.
|
|
7
|
-
"""
|
|
8
|
-
import logging
|
|
9
|
-
from typing import Dict, Any
|
|
10
|
-
|
|
11
|
-
from .. import YamlUpdatePlugin
|
|
12
|
-
from .name_converter import NameConverter
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
_LOGGER = logging.getLogger(__name__)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class Namer(YamlUpdatePlugin):
|
|
19
|
-
"""Add Python naming information.
|
|
20
|
-
"""
|
|
21
|
-
|
|
22
|
-
def update_yaml(self, yaml_data: Dict[str, Any]) -> None:
|
|
23
|
-
"""Convert in place the YAML str.
|
|
24
|
-
"""
|
|
25
|
-
NameConverter.convert_yaml_names(yaml_data)
|