@autorest/python 6.4.1 → 6.4.3
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/autorest/codegen/models/__init__.py +1 -0
- package/autorest/codegen/models/base_builder.py +1 -2
- package/autorest/codegen/models/client.py +32 -13
- package/autorest/codegen/models/lro_operation.py +18 -24
- package/autorest/codegen/models/operation.py +15 -7
- package/autorest/codegen/models/operation_group.py +3 -2
- package/autorest/codegen/models/paging_operation.py +0 -4
- package/autorest/codegen/models/request_builder.py +18 -8
- package/autorest/codegen/serializers/builder_serializer.py +33 -11
- package/autorest/codegen/serializers/import_serializer.py +4 -4
- package/autorest/codegen/serializers/metadata_serializer.py +33 -2
- package/autorest/codegen/templates/lro_operation.py.jinja2 +1 -1
- package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +1 -1
- package/autorest/codegen/templates/metadata.json.jinja2 +2 -0
- package/autorest/codegen/templates/operation.py.jinja2 +2 -2
- package/autorest/codegen/templates/paging_operation.py.jinja2 +2 -2
- package/autorest/m4reformatter/__init__.py +44 -22
- package/autorest/multiapi/models/operation_mixin_group.py +14 -0
- package/autorest/multiapi/serializers/__init__.py +2 -1
- package/autorest/multiapi/serializers/import_serializer.py +3 -2
- package/autorest/preprocess/__init__.py +86 -59
- package/autorest/preprocess/helpers.py +0 -15
- package/autorest/preprocess/python_mappings.py +2 -0
- package/package.json +1 -1
- package/requirements.txt +1 -1
|
@@ -45,7 +45,6 @@ class BaseBuilder(
|
|
|
45
45
|
parameters: ParameterListType,
|
|
46
46
|
*,
|
|
47
47
|
overloads=None,
|
|
48
|
-
want_tracing: bool = True,
|
|
49
48
|
) -> None:
|
|
50
49
|
super().__init__(yaml_data=yaml_data, code_model=code_model)
|
|
51
50
|
self.client = client
|
|
@@ -56,7 +55,7 @@ class BaseBuilder(
|
|
|
56
55
|
overloads or []
|
|
57
56
|
)
|
|
58
57
|
self._summary: str = yaml_data.get("summary", "")
|
|
59
|
-
self.want_tracing =
|
|
58
|
+
self.want_tracing: bool = yaml_data.get("wantTracing", True)
|
|
60
59
|
self.group_name: str = yaml_data[
|
|
61
60
|
"groupName"
|
|
62
61
|
] # either operationGroup or client I am on
|
|
@@ -16,6 +16,8 @@ from .request_builder import (
|
|
|
16
16
|
get_request_builder,
|
|
17
17
|
)
|
|
18
18
|
from .parameter import Parameter, ParameterMethodLocation
|
|
19
|
+
from .lro_operation import LROOperation
|
|
20
|
+
from .lro_paging_operation import LROPagingOperation
|
|
19
21
|
|
|
20
22
|
ParameterListType = TypeVar(
|
|
21
23
|
"ParameterListType",
|
|
@@ -24,6 +26,7 @@ ParameterListType = TypeVar(
|
|
|
24
26
|
|
|
25
27
|
if TYPE_CHECKING:
|
|
26
28
|
from .code_model import CodeModel
|
|
29
|
+
from . import OperationType
|
|
27
30
|
|
|
28
31
|
|
|
29
32
|
class _ClientConfigBase(Generic[ParameterListType], BaseModel):
|
|
@@ -72,7 +75,7 @@ class Client(_ClientConfigBase[ClientGlobalParameterList]):
|
|
|
72
75
|
OperationGroup.from_yaml(op_group, code_model, self)
|
|
73
76
|
for op_group in self.yaml_data.get("operationGroups", [])
|
|
74
77
|
]
|
|
75
|
-
self.
|
|
78
|
+
self.link_lro_initial_operations()
|
|
76
79
|
|
|
77
80
|
def _build_request_builders(
|
|
78
81
|
self,
|
|
@@ -80,11 +83,21 @@ class Client(_ClientConfigBase[ClientGlobalParameterList]):
|
|
|
80
83
|
request_builders: List[Union[RequestBuilder, OverloadedRequestBuilder]] = []
|
|
81
84
|
for og_group in self.yaml_data["operationGroups"]:
|
|
82
85
|
for operation_yaml in og_group["operations"]:
|
|
86
|
+
if operation_yaml["discriminator"] in ("lro", "lropaging"):
|
|
87
|
+
continue
|
|
83
88
|
request_builder = get_request_builder(
|
|
84
89
|
operation_yaml,
|
|
85
90
|
code_model=self.code_model,
|
|
86
91
|
client=self,
|
|
87
92
|
)
|
|
93
|
+
if operation_yaml.get("isLroInitialOperation"):
|
|
94
|
+
# we want to change the name
|
|
95
|
+
request_builder.name = request_builder.get_name(
|
|
96
|
+
request_builder.yaml_data["name"][1 : -len("_initial")],
|
|
97
|
+
request_builder.yaml_data,
|
|
98
|
+
request_builder.code_model,
|
|
99
|
+
request_builder.client,
|
|
100
|
+
)
|
|
88
101
|
if request_builder.overloads:
|
|
89
102
|
request_builders.extend(request_builder.overloads)
|
|
90
103
|
request_builders.append(request_builder)
|
|
@@ -160,6 +173,17 @@ class Client(_ClientConfigBase[ClientGlobalParameterList]):
|
|
|
160
173
|
f"No request builder with id {request_builder_id} found."
|
|
161
174
|
) from exc
|
|
162
175
|
|
|
176
|
+
def lookup_operation(self, operation_id: int) -> "OperationType":
|
|
177
|
+
try:
|
|
178
|
+
return next(
|
|
179
|
+
o
|
|
180
|
+
for og in self.operation_groups
|
|
181
|
+
for o in og.operations
|
|
182
|
+
if id(o.yaml_data) == operation_id
|
|
183
|
+
)
|
|
184
|
+
except StopIteration as exc:
|
|
185
|
+
raise KeyError(f"No operation with id {operation_id} found.") from exc
|
|
186
|
+
|
|
163
187
|
def _imports_shared(self, async_mode: bool) -> FileImport:
|
|
164
188
|
file_import = FileImport()
|
|
165
189
|
|
|
@@ -221,19 +245,14 @@ class Client(_ClientConfigBase[ClientGlobalParameterList]):
|
|
|
221
245
|
for operation_group in self.operation_groups
|
|
222
246
|
)
|
|
223
247
|
|
|
224
|
-
def
|
|
225
|
-
"""
|
|
226
|
-
If there are LRO functions in here, will add initial LRO function. Will also set the return
|
|
227
|
-
type of the LRO operation
|
|
228
|
-
"""
|
|
248
|
+
def link_lro_initial_operations(self) -> None:
|
|
249
|
+
"""Link each LRO operation to its initial operation"""
|
|
229
250
|
for operation_group in self.operation_groups:
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
i += 1
|
|
236
|
-
i += 1
|
|
251
|
+
for operation in operation_group.operations:
|
|
252
|
+
if isinstance(operation, (LROOperation, LROPagingOperation)):
|
|
253
|
+
operation.initial_operation = self.lookup_operation(
|
|
254
|
+
id(operation.yaml_data["initialOperation"])
|
|
255
|
+
)
|
|
237
256
|
|
|
238
257
|
@property
|
|
239
258
|
def need_request_converter(self) -> bool:
|
|
@@ -14,6 +14,7 @@ from .parameter_list import ParameterList
|
|
|
14
14
|
if TYPE_CHECKING:
|
|
15
15
|
from .code_model import CodeModel
|
|
16
16
|
from .client import Client
|
|
17
|
+
from . import OperationType
|
|
17
18
|
|
|
18
19
|
LROResponseType = TypeVar(
|
|
19
20
|
"LROResponseType", bound=Union[LROResponse, LROPagingResponse]
|
|
@@ -33,8 +34,6 @@ class LROOperationBase(OperationBase[LROResponseType]):
|
|
|
33
34
|
exceptions: List[Response],
|
|
34
35
|
*,
|
|
35
36
|
overloads: Optional[List[Operation]] = None,
|
|
36
|
-
public: bool = True,
|
|
37
|
-
want_tracing: bool = True,
|
|
38
37
|
) -> None:
|
|
39
38
|
super().__init__(
|
|
40
39
|
code_model=code_model,
|
|
@@ -46,11 +45,22 @@ class LROOperationBase(OperationBase[LROResponseType]):
|
|
|
46
45
|
responses=responses,
|
|
47
46
|
exceptions=exceptions,
|
|
48
47
|
overloads=overloads,
|
|
49
|
-
public=public,
|
|
50
|
-
want_tracing=want_tracing,
|
|
51
48
|
)
|
|
52
49
|
self.name = "begin_" + self.name
|
|
53
50
|
self.lro_options: Dict[str, Any] = self.yaml_data.get("lroOptions", {})
|
|
51
|
+
self._initial_operation: Optional["OperationType"] = None
|
|
52
|
+
|
|
53
|
+
@property
|
|
54
|
+
def initial_operation(self) -> "OperationType":
|
|
55
|
+
if not self._initial_operation:
|
|
56
|
+
raise ValueError(
|
|
57
|
+
"You need to first call client.link_lro_initial_operations before accessing"
|
|
58
|
+
)
|
|
59
|
+
return self._initial_operation
|
|
60
|
+
|
|
61
|
+
@initial_operation.setter
|
|
62
|
+
def initial_operation(self, val: "OperationType") -> None:
|
|
63
|
+
self._initial_operation = val
|
|
54
64
|
|
|
55
65
|
@property
|
|
56
66
|
def operation_type(self) -> str:
|
|
@@ -93,26 +103,6 @@ class LROOperationBase(OperationBase[LROResponseType]):
|
|
|
93
103
|
"""We don't want the poller to show up in ClsType, so we call super() on resposne type annotation"""
|
|
94
104
|
return f"ClsType[{Response.type_annotation(self.responses[0], async_mode=async_mode)}]"
|
|
95
105
|
|
|
96
|
-
@property
|
|
97
|
-
def initial_operation(self) -> Operation:
|
|
98
|
-
"""Initial operation that creates the first call for LRO polling"""
|
|
99
|
-
return Operation(
|
|
100
|
-
yaml_data=self.yaml_data,
|
|
101
|
-
code_model=self.code_model,
|
|
102
|
-
client=self.client,
|
|
103
|
-
request_builder=self.client.lookup_request_builder(id(self.yaml_data)),
|
|
104
|
-
name=self.name[5:] + "_initial",
|
|
105
|
-
overloads=self.overloads,
|
|
106
|
-
parameters=self.parameters,
|
|
107
|
-
responses=[
|
|
108
|
-
Response(r.yaml_data, self.code_model, headers=r.headers, type=r.type)
|
|
109
|
-
for r in self.responses
|
|
110
|
-
],
|
|
111
|
-
exceptions=self.exceptions,
|
|
112
|
-
public=False,
|
|
113
|
-
want_tracing=False,
|
|
114
|
-
)
|
|
115
|
-
|
|
116
106
|
def get_poller(self, async_mode: bool) -> str:
|
|
117
107
|
return self.responses[0].get_poller(async_mode)
|
|
118
108
|
|
|
@@ -144,6 +134,10 @@ class LROOperationBase(OperationBase[LROResponseType]):
|
|
|
144
134
|
file_import.add_submodule_import("typing", "cast", ImportType.STDLIB)
|
|
145
135
|
return file_import
|
|
146
136
|
|
|
137
|
+
@classmethod
|
|
138
|
+
def get_request_builder(cls, yaml_data: Dict[str, Any], client: "Client"):
|
|
139
|
+
return client.lookup_request_builder(id(yaml_data["initialOperation"]))
|
|
140
|
+
|
|
147
141
|
|
|
148
142
|
class LROOperation(LROOperationBase[LROResponse]):
|
|
149
143
|
...
|
|
@@ -41,6 +41,7 @@ from .request_builder import OverloadedRequestBuilder, RequestBuilder
|
|
|
41
41
|
if TYPE_CHECKING:
|
|
42
42
|
from .code_model import CodeModel
|
|
43
43
|
from .client import Client
|
|
44
|
+
from . import OperationType
|
|
44
45
|
|
|
45
46
|
ResponseType = TypeVar(
|
|
46
47
|
"ResponseType",
|
|
@@ -63,8 +64,6 @@ class OperationBase( # pylint: disable=too-many-public-methods
|
|
|
63
64
|
exceptions: List[Response],
|
|
64
65
|
*,
|
|
65
66
|
overloads: Optional[List["Operation"]] = None,
|
|
66
|
-
public: bool = True,
|
|
67
|
-
want_tracing: bool = True,
|
|
68
67
|
) -> None:
|
|
69
68
|
super().__init__(
|
|
70
69
|
code_model=code_model,
|
|
@@ -73,14 +72,20 @@ class OperationBase( # pylint: disable=too-many-public-methods
|
|
|
73
72
|
name=name,
|
|
74
73
|
parameters=parameters,
|
|
75
74
|
overloads=overloads,
|
|
76
|
-
want_tracing=want_tracing,
|
|
77
75
|
)
|
|
78
76
|
self.overloads: List["Operation"] = overloads or []
|
|
79
77
|
self.responses = responses
|
|
80
|
-
self.public = public
|
|
81
78
|
self.request_builder = request_builder
|
|
82
79
|
self.deprecated = False
|
|
83
80
|
self.exceptions = exceptions
|
|
81
|
+
self.is_lro_initial_operation: bool = self.yaml_data.get(
|
|
82
|
+
"isLroInitialOperation", False
|
|
83
|
+
)
|
|
84
|
+
self.include_documentation: bool = not self.is_lro_initial_operation
|
|
85
|
+
|
|
86
|
+
@property
|
|
87
|
+
def expose_stream_keyword(self) -> bool:
|
|
88
|
+
return self.yaml_data.get("exposeStreamKeyword", False)
|
|
84
89
|
|
|
85
90
|
@property
|
|
86
91
|
def operation_type(self) -> str:
|
|
@@ -438,6 +443,10 @@ class OperationBase( # pylint: disable=too-many-public-methods
|
|
|
438
443
|
def has_stream_response(self) -> bool:
|
|
439
444
|
return any(r.is_stream_response for r in self.responses)
|
|
440
445
|
|
|
446
|
+
@classmethod
|
|
447
|
+
def get_request_builder(cls, yaml_data: Dict[str, Any], client: "Client"):
|
|
448
|
+
return client.lookup_request_builder(id(yaml_data))
|
|
449
|
+
|
|
441
450
|
@classmethod
|
|
442
451
|
def from_yaml(
|
|
443
452
|
cls,
|
|
@@ -446,7 +455,7 @@ class OperationBase( # pylint: disable=too-many-public-methods
|
|
|
446
455
|
client: "Client",
|
|
447
456
|
):
|
|
448
457
|
name = yaml_data["name"]
|
|
449
|
-
request_builder =
|
|
458
|
+
request_builder = cls.get_request_builder(yaml_data, client)
|
|
450
459
|
responses = [
|
|
451
460
|
cast(ResponseType, get_response(r, code_model))
|
|
452
461
|
for r in yaml_data["responses"]
|
|
@@ -470,7 +479,6 @@ class OperationBase( # pylint: disable=too-many-public-methods
|
|
|
470
479
|
overloads=overloads,
|
|
471
480
|
responses=responses,
|
|
472
481
|
exceptions=exceptions,
|
|
473
|
-
want_tracing=not yaml_data["isOverload"],
|
|
474
482
|
)
|
|
475
483
|
|
|
476
484
|
|
|
@@ -510,7 +518,7 @@ class Operation(OperationBase[Response]):
|
|
|
510
518
|
|
|
511
519
|
def get_operation(
|
|
512
520
|
yaml_data: Dict[str, Any], code_model: "CodeModel", client: "Client"
|
|
513
|
-
) ->
|
|
521
|
+
) -> "OperationType":
|
|
514
522
|
if yaml_data["discriminator"] == "lropaging":
|
|
515
523
|
from .lro_paging_operation import LROPagingOperation as OperationCls
|
|
516
524
|
elif yaml_data["discriminator"] == "lro":
|
|
@@ -8,13 +8,14 @@ from typing import Dict, List, Any, TYPE_CHECKING
|
|
|
8
8
|
from autorest.codegen.models.utils import OrderedSet
|
|
9
9
|
|
|
10
10
|
from .base import BaseModel
|
|
11
|
-
from .operation import
|
|
11
|
+
from .operation import get_operation
|
|
12
12
|
from .imports import FileImport, ImportType, TypingSection
|
|
13
13
|
from .utils import add_to_pylint_disable
|
|
14
14
|
|
|
15
15
|
if TYPE_CHECKING:
|
|
16
16
|
from .code_model import CodeModel
|
|
17
17
|
from .client import Client
|
|
18
|
+
from . import OperationType
|
|
18
19
|
|
|
19
20
|
|
|
20
21
|
class OperationGroup(BaseModel):
|
|
@@ -25,7 +26,7 @@ class OperationGroup(BaseModel):
|
|
|
25
26
|
yaml_data: Dict[str, Any],
|
|
26
27
|
code_model: "CodeModel",
|
|
27
28
|
client: "Client",
|
|
28
|
-
operations: List[
|
|
29
|
+
operations: List["OperationType"],
|
|
29
30
|
api_versions: List[str],
|
|
30
31
|
) -> None:
|
|
31
32
|
super().__init__(yaml_data, code_model)
|
|
@@ -38,8 +38,6 @@ class PagingOperationBase(OperationBase[PagingResponseType]):
|
|
|
38
38
|
exceptions: List[Response],
|
|
39
39
|
*,
|
|
40
40
|
overloads: Optional[List[Operation]] = None,
|
|
41
|
-
public: bool = True,
|
|
42
|
-
want_tracing: bool = True,
|
|
43
41
|
override_success_response_to_200: bool = False,
|
|
44
42
|
) -> None:
|
|
45
43
|
super().__init__(
|
|
@@ -52,8 +50,6 @@ class PagingOperationBase(OperationBase[PagingResponseType]):
|
|
|
52
50
|
responses=responses,
|
|
53
51
|
exceptions=exceptions,
|
|
54
52
|
overloads=overloads,
|
|
55
|
-
public=public,
|
|
56
|
-
want_tracing=want_tracing,
|
|
57
53
|
)
|
|
58
54
|
self.next_request_builder: Optional[
|
|
59
55
|
Union[RequestBuilder, OverloadedRequestBuilder]
|
|
@@ -50,11 +50,11 @@ class RequestBuilderBase(BaseBuilder[ParameterListType]):
|
|
|
50
50
|
name=name,
|
|
51
51
|
parameters=parameters,
|
|
52
52
|
overloads=overloads,
|
|
53
|
-
want_tracing=False,
|
|
54
53
|
)
|
|
55
54
|
self.overloads: List["RequestBuilder"] = overloads or []
|
|
56
55
|
self.url: str = yaml_data["url"]
|
|
57
56
|
self.method: str = yaml_data["method"]
|
|
57
|
+
self.want_tracing = False
|
|
58
58
|
|
|
59
59
|
def response_type_annotation(self, **kwargs) -> str:
|
|
60
60
|
return "HttpRequest"
|
|
@@ -127,14 +127,13 @@ class RequestBuilderBase(BaseBuilder[ParameterListType]):
|
|
|
127
127
|
...
|
|
128
128
|
|
|
129
129
|
@classmethod
|
|
130
|
-
def
|
|
130
|
+
def get_name(
|
|
131
131
|
cls,
|
|
132
|
+
name: str,
|
|
132
133
|
yaml_data: Dict[str, Any],
|
|
133
134
|
code_model: "CodeModel",
|
|
134
135
|
client: "Client",
|
|
135
|
-
):
|
|
136
|
-
# when combine embedded builders into one operation file, we need to avoid duplicated build function name.
|
|
137
|
-
# So add operation group name is effective method
|
|
136
|
+
) -> str:
|
|
138
137
|
additional_mark = ""
|
|
139
138
|
if (
|
|
140
139
|
code_model.options["combine_operation_files"]
|
|
@@ -146,10 +145,21 @@ class RequestBuilderBase(BaseBuilder[ParameterListType]):
|
|
|
146
145
|
names = [
|
|
147
146
|
"build",
|
|
148
147
|
additional_mark,
|
|
149
|
-
|
|
148
|
+
name,
|
|
150
149
|
"request",
|
|
151
150
|
]
|
|
152
|
-
|
|
151
|
+
return "_".join([n for n in names if n])
|
|
152
|
+
|
|
153
|
+
@classmethod
|
|
154
|
+
def from_yaml(
|
|
155
|
+
cls,
|
|
156
|
+
yaml_data: Dict[str, Any],
|
|
157
|
+
code_model: "CodeModel",
|
|
158
|
+
client: "Client",
|
|
159
|
+
):
|
|
160
|
+
# when combine embedded builders into one operation file, we need to avoid duplicated build function name.
|
|
161
|
+
# So add operation group name is effective method
|
|
162
|
+
|
|
153
163
|
overloads = [
|
|
154
164
|
RequestBuilder.from_yaml(rb_yaml_data, code_model, client)
|
|
155
165
|
for rb_yaml_data in yaml_data.get("overloads", [])
|
|
@@ -160,7 +170,7 @@ class RequestBuilderBase(BaseBuilder[ParameterListType]):
|
|
|
160
170
|
yaml_data=yaml_data,
|
|
161
171
|
code_model=code_model,
|
|
162
172
|
client=client,
|
|
163
|
-
name=name,
|
|
173
|
+
name=cls.get_name(yaml_data["name"], yaml_data, code_model, client),
|
|
164
174
|
parameters=parameter_list,
|
|
165
175
|
overloads=overloads,
|
|
166
176
|
)
|
|
@@ -639,11 +639,17 @@ class _OperationSerializer(
|
|
|
639
639
|
|
|
640
640
|
def make_pipeline_call(self, builder: OperationType) -> List[str]:
|
|
641
641
|
type_ignore = self.async_mode and builder.group_name == "" # is in a mixin
|
|
642
|
+
stream_value = (
|
|
643
|
+
'kwargs.pop("stream", False)'
|
|
644
|
+
if builder.expose_stream_keyword
|
|
645
|
+
else builder.has_stream_response
|
|
646
|
+
)
|
|
642
647
|
return [
|
|
648
|
+
f"_stream = {stream_value}",
|
|
643
649
|
f"pipeline_response: PipelineResponse = {self._call_method}self._client._pipeline.run( "
|
|
644
650
|
+ f"{'# type: ignore' if type_ignore else ''} # pylint: disable=protected-access",
|
|
645
651
|
" request,",
|
|
646
|
-
|
|
652
|
+
" stream=_stream,",
|
|
647
653
|
" **kwargs",
|
|
648
654
|
")",
|
|
649
655
|
]
|
|
@@ -669,6 +675,11 @@ class _OperationSerializer(
|
|
|
669
675
|
|
|
670
676
|
def param_description(self, builder: OperationType) -> List[str]:
|
|
671
677
|
description_list = super().param_description(builder)
|
|
678
|
+
if builder.expose_stream_keyword:
|
|
679
|
+
description_list.append(
|
|
680
|
+
":keyword bool stream: Whether to stream the response of this operation. "
|
|
681
|
+
"Defaults to False. You will have to context manage the returned stream."
|
|
682
|
+
)
|
|
672
683
|
if not self.code_model.options["version_tolerant"]:
|
|
673
684
|
description_list.append(
|
|
674
685
|
":keyword callable cls: A custom type or function that will be passed the direct response"
|
|
@@ -1014,6 +1025,7 @@ class _OperationSerializer(
|
|
|
1014
1025
|
|
|
1015
1026
|
def response_headers_and_deserialization(
|
|
1016
1027
|
self,
|
|
1028
|
+
builder: OperationType,
|
|
1017
1029
|
response: Response,
|
|
1018
1030
|
) -> List[str]:
|
|
1019
1031
|
retval: List[str] = [
|
|
@@ -1025,8 +1037,9 @@ class _OperationSerializer(
|
|
|
1025
1037
|
]
|
|
1026
1038
|
if response.headers:
|
|
1027
1039
|
retval.append("")
|
|
1040
|
+
deserialize_code: List[str] = []
|
|
1028
1041
|
if response.is_stream_response:
|
|
1029
|
-
|
|
1042
|
+
deserialize_code.append(
|
|
1030
1043
|
"deserialized = {}".format(
|
|
1031
1044
|
"response.iter_bytes()"
|
|
1032
1045
|
if self.code_model.options["version_tolerant"]
|
|
@@ -1035,11 +1048,11 @@ class _OperationSerializer(
|
|
|
1035
1048
|
)
|
|
1036
1049
|
elif response.type:
|
|
1037
1050
|
if self.code_model.options["models_mode"] == "msrest":
|
|
1038
|
-
|
|
1051
|
+
deserialize_code.append(
|
|
1039
1052
|
f"deserialized = self._deserialize('{response.serialization_type}', pipeline_response)"
|
|
1040
1053
|
)
|
|
1041
1054
|
elif self.code_model.options["models_mode"] == "dpg":
|
|
1042
|
-
|
|
1055
|
+
deserialize_code.append(
|
|
1043
1056
|
f"deserialized = _deserialize({response.type.type_annotation(is_operation_file=True)}"
|
|
1044
1057
|
", response.json())"
|
|
1045
1058
|
)
|
|
@@ -1049,10 +1062,17 @@ class _OperationSerializer(
|
|
|
1049
1062
|
if response.type.is_xml
|
|
1050
1063
|
else "response.json()"
|
|
1051
1064
|
)
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1065
|
+
deserialize_code.append("if response.content:")
|
|
1066
|
+
deserialize_code.append(f" deserialized = {deserialized_value}")
|
|
1067
|
+
deserialize_code.append("else:")
|
|
1068
|
+
deserialize_code.append(" deserialized = None")
|
|
1069
|
+
if builder.expose_stream_keyword:
|
|
1070
|
+
retval.append("if _stream:")
|
|
1071
|
+
retval.append(" deserialized = response.iter_bytes()")
|
|
1072
|
+
retval.append("else:")
|
|
1073
|
+
retval.extend([f" {dc}" for dc in deserialize_code])
|
|
1074
|
+
else:
|
|
1075
|
+
retval.extend(deserialize_code)
|
|
1056
1076
|
return retval
|
|
1057
1077
|
|
|
1058
1078
|
def handle_error_response(self, builder: OperationType) -> List[str]:
|
|
@@ -1106,14 +1126,16 @@ class _OperationSerializer(
|
|
|
1106
1126
|
[
|
|
1107
1127
|
f" {line}"
|
|
1108
1128
|
for line in self.response_headers_and_deserialization(
|
|
1109
|
-
response
|
|
1129
|
+
builder, response
|
|
1110
1130
|
)
|
|
1111
1131
|
]
|
|
1112
1132
|
)
|
|
1113
1133
|
retval.append("")
|
|
1114
1134
|
else:
|
|
1115
1135
|
retval.extend(
|
|
1116
|
-
self.response_headers_and_deserialization(
|
|
1136
|
+
self.response_headers_and_deserialization(
|
|
1137
|
+
builder, builder.responses[0]
|
|
1138
|
+
)
|
|
1117
1139
|
)
|
|
1118
1140
|
retval.append("")
|
|
1119
1141
|
type_ignore = (
|
|
@@ -1559,7 +1581,7 @@ class _LROOperationSerializer(_OperationSerializer[LROOperationType]):
|
|
|
1559
1581
|
[
|
|
1560
1582
|
f" {line}"
|
|
1561
1583
|
for line in self.response_headers_and_deserialization(
|
|
1562
|
-
builder.lro_response
|
|
1584
|
+
builder, builder.lro_response
|
|
1563
1585
|
)
|
|
1564
1586
|
]
|
|
1565
1587
|
)
|
|
@@ -108,8 +108,8 @@ class FileImportSerializer:
|
|
|
108
108
|
"typing", "TYPE_CHECKING", ImportType.STDLIB
|
|
109
109
|
)
|
|
110
110
|
|
|
111
|
-
def
|
|
112
|
-
def
|
|
111
|
+
def get_typing_definitions(self) -> str:
|
|
112
|
+
def declare_definition(
|
|
113
113
|
type_name: str, type_definition: TypeDefinition
|
|
114
114
|
) -> List[str]:
|
|
115
115
|
ret: List[str] = []
|
|
@@ -125,7 +125,7 @@ class FileImportSerializer:
|
|
|
125
125
|
return ""
|
|
126
126
|
declarations: List[str] = [""]
|
|
127
127
|
for type_name, value in self.file_import.type_definitions.items():
|
|
128
|
-
declarations.extend(
|
|
128
|
+
declarations.extend(declare_definition(type_name, value))
|
|
129
129
|
return "\n".join(declarations)
|
|
130
130
|
|
|
131
131
|
def __str__(self) -> str:
|
|
@@ -151,4 +151,4 @@ class FileImportSerializer:
|
|
|
151
151
|
typing_imports += "\n\n ".join(
|
|
152
152
|
_get_import_clauses(typing_imports_list, "\n ")
|
|
153
153
|
)
|
|
154
|
-
return regular_imports + typing_imports + self.
|
|
154
|
+
return regular_imports + typing_imports + self.get_typing_definitions()
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
6
|
import functools
|
|
7
7
|
import json
|
|
8
|
-
from typing import List, Optional, Set, Tuple, Dict, Union
|
|
8
|
+
from typing import List, Optional, Set, Tuple, Dict, Union, Any
|
|
9
9
|
from jinja2 import Environment
|
|
10
10
|
from ..models import (
|
|
11
11
|
OperationGroup,
|
|
@@ -16,6 +16,13 @@ from ..models import (
|
|
|
16
16
|
CodeModel,
|
|
17
17
|
)
|
|
18
18
|
from .builder_serializer import get_operation_serializer
|
|
19
|
+
from .import_serializer import FileImportSerializer
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _to_string(data: Union[Tuple[Any], List[Any], str]) -> str:
|
|
23
|
+
if isinstance(data, (list, tuple)):
|
|
24
|
+
return "".join([_to_string(item) for item in data])
|
|
25
|
+
return str(data)
|
|
19
26
|
|
|
20
27
|
|
|
21
28
|
def _json_serialize_imports(
|
|
@@ -59,7 +66,7 @@ def _json_serialize_imports(
|
|
|
59
66
|
if name_imports:
|
|
60
67
|
name_import_ordered_list = list(name_imports)
|
|
61
68
|
name_import_ordered_list.sort(
|
|
62
|
-
key=lambda e:
|
|
69
|
+
key=lambda e: _to_string(e) # type: ignore
|
|
63
70
|
if isinstance(e, (list, tuple))
|
|
64
71
|
else e
|
|
65
72
|
if isinstance(e, str)
|
|
@@ -85,6 +92,24 @@ def _mixin_imports(
|
|
|
85
92
|
), _json_serialize_imports(async_mixin_imports.to_dict())
|
|
86
93
|
|
|
87
94
|
|
|
95
|
+
def _mixin_typing_definitions(
|
|
96
|
+
mixin_operation_group: Optional[OperationGroup],
|
|
97
|
+
) -> Tuple[Optional[str], Optional[str]]:
|
|
98
|
+
if not mixin_operation_group:
|
|
99
|
+
return None, None
|
|
100
|
+
|
|
101
|
+
sync_mixin_imports = mixin_operation_group.imports_for_multiapi(async_mode=False)
|
|
102
|
+
async_mixin_imports = mixin_operation_group.imports_for_multiapi(async_mode=True)
|
|
103
|
+
sync_mixin_typing_definitions = FileImportSerializer(
|
|
104
|
+
sync_mixin_imports, False
|
|
105
|
+
).get_typing_definitions()
|
|
106
|
+
async_mixin_typing_definitions = FileImportSerializer(
|
|
107
|
+
async_mixin_imports, True
|
|
108
|
+
).get_typing_definitions()
|
|
109
|
+
|
|
110
|
+
return sync_mixin_typing_definitions, async_mixin_typing_definitions
|
|
111
|
+
|
|
112
|
+
|
|
88
113
|
class MetadataSerializer:
|
|
89
114
|
def __init__(self, code_model: CodeModel, env: Environment) -> None:
|
|
90
115
|
self.code_model = code_model
|
|
@@ -135,6 +160,10 @@ class MetadataSerializer:
|
|
|
135
160
|
mixin_operation_group.operations if mixin_operation_group else []
|
|
136
161
|
)
|
|
137
162
|
sync_mixin_imports, async_mixin_imports = _mixin_imports(mixin_operation_group)
|
|
163
|
+
(
|
|
164
|
+
sync_mixin_typing_definitions,
|
|
165
|
+
async_mixin_typing_definitions,
|
|
166
|
+
) = _mixin_typing_definitions(mixin_operation_group)
|
|
138
167
|
|
|
139
168
|
chosen_version, total_api_version_list = self._choose_api_version()
|
|
140
169
|
|
|
@@ -155,6 +184,8 @@ class MetadataSerializer:
|
|
|
155
184
|
str=str,
|
|
156
185
|
sync_mixin_imports=sync_mixin_imports,
|
|
157
186
|
async_mixin_imports=async_mixin_imports,
|
|
187
|
+
sync_mixin_typing_definitions=sync_mixin_typing_definitions,
|
|
188
|
+
async_mixin_typing_definitions=async_mixin_typing_definitions,
|
|
158
189
|
sync_client_imports=_json_serialize_imports(
|
|
159
190
|
self.client.imports_for_multiapi(async_mode=False).to_dict()
|
|
160
191
|
),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{% import 'operation_tools.jinja2' as op_tools with context %}
|
|
2
2
|
{# actual template starts here #}
|
|
3
|
-
{% if operation.overloads and operation.
|
|
3
|
+
{% if operation.overloads and operation.include_documentation %}
|
|
4
4
|
{{ op_tools.generate_overloads(operation_serializer, operation) }}
|
|
5
5
|
{% endif %}
|
|
6
6
|
{{ operation_serializer.method_signature_and_response_type_annotation(operation) }}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{% import 'operation_tools.jinja2' as op_tools with context %}
|
|
2
2
|
{% import 'keywords.jinja2' as keywords with context %}
|
|
3
3
|
{# actual template starts here #}
|
|
4
|
-
{% if operation.overloads and operation.
|
|
4
|
+
{% if operation.overloads and operation.include_documentation %}
|
|
5
5
|
{{ op_tools.generate_overloads(operation_serializer, operation) }}
|
|
6
6
|
{% endif %}
|
|
7
7
|
{{ operation_serializer.method_signature_and_response_type_annotation(operation) }}
|
|
@@ -115,6 +115,8 @@
|
|
|
115
115
|
"operation_mixins": {
|
|
116
116
|
"sync_imports": {{ str(sync_mixin_imports) | tojson }},
|
|
117
117
|
"async_imports": {{ str(async_mixin_imports) | tojson }},
|
|
118
|
+
"sync_mixin_typing_definitions": {{ str(sync_mixin_typing_definitions) | tojson }},
|
|
119
|
+
"async_mixin_typing_definitions": {{ str(async_mixin_typing_definitions) | tojson }},
|
|
118
120
|
"operations": {
|
|
119
121
|
{% for operation in mixin_operations %}
|
|
120
122
|
{{ operation.name | tojson }} : {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{% import 'keywords.jinja2' as keywords with context %}
|
|
2
2
|
{% import 'operation_tools.jinja2' as op_tools %}
|
|
3
3
|
{# actual template starts here #}
|
|
4
|
-
{% if operation.overloads and operation.
|
|
4
|
+
{% if operation.overloads and operation.include_documentation %}
|
|
5
5
|
{{ op_tools.generate_overloads(operation_serializer, operation) }}
|
|
6
6
|
{% endif %}
|
|
7
7
|
{{ operation_serializer.method_signature_and_response_type_annotation(operation) }}
|
|
8
|
-
{% if operation.
|
|
8
|
+
{% if operation.include_documentation %}
|
|
9
9
|
{{ op_tools.description(operation, operation_serializer) | indent }}{% endif %}
|
|
10
10
|
{% if not operation.abstract %}
|
|
11
11
|
{% if operation.deprecated %}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{% import 'operation_tools.jinja2' as op_tools with context %}
|
|
2
2
|
{# actual template starts here #}
|
|
3
|
-
{% if operation.overloads and operation.
|
|
3
|
+
{% if operation.overloads and operation.include_documentation %}
|
|
4
4
|
{{ op_tools.generate_overloads(operation_serializer, operation) }}
|
|
5
5
|
{% endif %}
|
|
6
6
|
{{ operation_serializer.method_signature_and_response_type_annotation(operation) }}
|
|
7
|
-
{% if operation.
|
|
7
|
+
{% if operation.include_documentation %}
|
|
8
8
|
{{ op_tools.description(operation, operation_serializer) | indent }}{% endif %}
|
|
9
9
|
{% if not operation.abstract %}
|
|
10
10
|
{% if operation.deprecated %}
|
|
@@ -299,10 +299,15 @@ def get_all_body_types(yaml_data: Dict[str, Any]) -> List[Dict[str, Any]]:
|
|
|
299
299
|
return list(seen_body_types.values())
|
|
300
300
|
|
|
301
301
|
|
|
302
|
-
def add_lro_information(
|
|
302
|
+
def add_lro_information(
|
|
303
|
+
operation: Dict[str, Any],
|
|
304
|
+
initial_operation: Dict[str, Any],
|
|
305
|
+
yaml_data: Dict[str, Any],
|
|
306
|
+
) -> None:
|
|
303
307
|
operation["discriminator"] = "lro"
|
|
304
308
|
extensions = yaml_data["extensions"]
|
|
305
309
|
operation["lroOptions"] = extensions.get("x-ms-long-running-operation-options")
|
|
310
|
+
operation["initialOperation"] = initial_operation
|
|
306
311
|
for response in operation["responses"]:
|
|
307
312
|
response["pollerSync"] = extensions.get("x-python-custom-poller-sync")
|
|
308
313
|
response["pollerAsync"] = extensions.get("x-python-custom-poller-async")
|
|
@@ -551,7 +556,7 @@ class M4Reformatter(
|
|
|
551
556
|
|
|
552
557
|
def get_operation_creator(
|
|
553
558
|
self, yaml_data: Dict[str, Any]
|
|
554
|
-
) -> Callable[[str, Dict[str, Any]], Dict[str, Any]]:
|
|
559
|
+
) -> Callable[[str, Dict[str, Any]], List[Dict[str, Any]]]:
|
|
555
560
|
lro_operation = yaml_data.get("extensions", {}).get(
|
|
556
561
|
"x-ms-long-running-operation"
|
|
557
562
|
)
|
|
@@ -566,7 +571,7 @@ class M4Reformatter(
|
|
|
566
571
|
|
|
567
572
|
def update_operation(
|
|
568
573
|
self, group_name: str, yaml_data: Dict[str, Any]
|
|
569
|
-
) -> Dict[str, Any]:
|
|
574
|
+
) -> List[Dict[str, Any]]:
|
|
570
575
|
body_parameter = (
|
|
571
576
|
self.update_body_parameter(yaml_data["requestMediaTypes"])
|
|
572
577
|
if yaml_data.get("requestMediaTypes")
|
|
@@ -578,7 +583,7 @@ class M4Reformatter(
|
|
|
578
583
|
group_name, yaml_data, body_parameter, content_types=content_types
|
|
579
584
|
)
|
|
580
585
|
operation["samples"] = yaml_data.get("extensions", {}).get("x-ms-examples", {})
|
|
581
|
-
return operation
|
|
586
|
+
return [operation]
|
|
582
587
|
|
|
583
588
|
def add_paging_information(
|
|
584
589
|
self, group_name: str, operation: Dict[str, Any], yaml_data: Dict[str, Any]
|
|
@@ -596,7 +601,7 @@ class M4Reformatter(
|
|
|
596
601
|
yaml_data=yaml_data["language"]["default"]["paging"][
|
|
597
602
|
"nextLinkOperation"
|
|
598
603
|
],
|
|
599
|
-
)
|
|
604
|
+
)[0]
|
|
600
605
|
extensions = yaml_data["extensions"]
|
|
601
606
|
for response in operation["responses"]:
|
|
602
607
|
response["pagerSync"] = extensions.get("x-python-custom-pager-sync")
|
|
@@ -604,27 +609,43 @@ class M4Reformatter(
|
|
|
604
609
|
|
|
605
610
|
def update_paging_operation(
|
|
606
611
|
self, group_name: str, yaml_data: Dict[str, Any]
|
|
607
|
-
) -> Dict[str, Any]:
|
|
608
|
-
|
|
609
|
-
self.
|
|
610
|
-
|
|
612
|
+
) -> List[Dict[str, Any]]:
|
|
613
|
+
retval: List[Dict[str, Any]] = []
|
|
614
|
+
for base_operation in self.update_operation(group_name, yaml_data):
|
|
615
|
+
self.add_paging_information(group_name, base_operation, yaml_data)
|
|
616
|
+
retval.append(base_operation)
|
|
617
|
+
return retval
|
|
611
618
|
|
|
612
619
|
def update_lro_paging_operation(
|
|
613
620
|
self, group_name: str, yaml_data: Dict[str, Any]
|
|
614
|
-
) -> Dict[str, Any]:
|
|
615
|
-
|
|
616
|
-
self.
|
|
617
|
-
|
|
618
|
-
|
|
621
|
+
) -> List[Dict[str, Any]]:
|
|
622
|
+
retval: List[Dict[str, Any]] = []
|
|
623
|
+
for operation in self.update_lro_operation(group_name, yaml_data):
|
|
624
|
+
if operation.get("discriminator") == "lro":
|
|
625
|
+
self.add_paging_information(group_name, operation, yaml_data)
|
|
626
|
+
operation["discriminator"] = "lropaging"
|
|
627
|
+
retval.append(operation)
|
|
628
|
+
return retval
|
|
629
|
+
|
|
630
|
+
def update_lro_initial_operation(self, initial_operation: Dict[str, Any]):
|
|
631
|
+
initial_operation["name"] = f"_{initial_operation['name']}_initial"
|
|
632
|
+
initial_operation["isLroInitialOperation"] = True
|
|
633
|
+
initial_operation["wantTracing"] = False
|
|
634
|
+
return initial_operation
|
|
619
635
|
|
|
620
636
|
def update_lro_operation(
|
|
621
637
|
self, group_name: str, yaml_data: Dict[str, Any]
|
|
622
|
-
) -> Dict[str, Any]:
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
638
|
+
) -> List[Dict[str, Any]]:
|
|
639
|
+
retval: List[Dict[str, Any]] = []
|
|
640
|
+
for base_operation in self.update_operation(group_name, yaml_data):
|
|
641
|
+
initial_operation = self.update_operation(group_name, yaml_data)[0]
|
|
642
|
+
self.update_lro_initial_operation(initial_operation)
|
|
643
|
+
add_lro_information(base_operation, initial_operation, yaml_data)
|
|
644
|
+
for overload in base_operation["overloads"]:
|
|
645
|
+
add_lro_information(overload, initial_operation, yaml_data)
|
|
646
|
+
retval.append(initial_operation)
|
|
647
|
+
retval.append(base_operation)
|
|
648
|
+
return retval
|
|
628
649
|
|
|
629
650
|
def update_overload(
|
|
630
651
|
self,
|
|
@@ -648,8 +669,9 @@ class M4Reformatter(
|
|
|
648
669
|
"className": property_name,
|
|
649
670
|
"operations": filter_out_paging_next_operation(
|
|
650
671
|
[
|
|
651
|
-
|
|
652
|
-
for
|
|
672
|
+
o
|
|
673
|
+
for ydo in yaml_data["operations"]
|
|
674
|
+
for o in self.get_operation_creator(ydo)(property_name, ydo)
|
|
653
675
|
]
|
|
654
676
|
),
|
|
655
677
|
}
|
|
@@ -31,6 +31,20 @@ class OperationMixinGroup:
|
|
|
31
31
|
imports.merge(current_version_imports)
|
|
32
32
|
return imports
|
|
33
33
|
|
|
34
|
+
def typing_definitions(self, async_mode: bool) -> str:
|
|
35
|
+
key = (
|
|
36
|
+
"sync_mixin_typing_definitions"
|
|
37
|
+
if async_mode
|
|
38
|
+
else "async_mixin_typing_definitions"
|
|
39
|
+
)
|
|
40
|
+
origin = "".join(
|
|
41
|
+
[
|
|
42
|
+
metadata_json.get("operation_mixins", {}).get(key, "")
|
|
43
|
+
for metadata_json in self.version_path_to_metadata.values()
|
|
44
|
+
]
|
|
45
|
+
)
|
|
46
|
+
return "\n".join(set(origin.split("\n")))
|
|
47
|
+
|
|
34
48
|
def _use_metadata_of_default_api_version(
|
|
35
49
|
self, mixin_operations: List[MixinOperation]
|
|
36
50
|
) -> List[MixinOperation]:
|
|
@@ -101,7 +101,8 @@ class MultiAPISerializer(ReaderAndWriter): # pylint: disable=abstract-method
|
|
|
101
101
|
# serialize mixins
|
|
102
102
|
if code_model.operation_mixin_group.mixin_operations:
|
|
103
103
|
imports = FileImportSerializer(
|
|
104
|
-
code_model.operation_mixin_group.imports(async_mode)
|
|
104
|
+
code_model.operation_mixin_group.imports(async_mode),
|
|
105
|
+
code_model.operation_mixin_group.typing_definitions(async_mode),
|
|
105
106
|
)
|
|
106
107
|
self.write_file(
|
|
107
108
|
_get_file_path("_operations_mixin", async_mode),
|
|
@@ -135,8 +135,9 @@ def _get_import_clauses(
|
|
|
135
135
|
|
|
136
136
|
|
|
137
137
|
class FileImportSerializer:
|
|
138
|
-
def __init__(self, file_import: FileImport) -> None:
|
|
138
|
+
def __init__(self, file_import: FileImport, typing_definitions: str = "") -> None:
|
|
139
139
|
self._file_import = file_import
|
|
140
|
+
self._typing_definitions = typing_definitions
|
|
140
141
|
|
|
141
142
|
def _switch_typing_section_key(self, new_key: TypingSection):
|
|
142
143
|
switched_dictionary = {}
|
|
@@ -193,4 +194,4 @@ class FileImportSerializer:
|
|
|
193
194
|
_get_import_clauses(typing_imports_dict, "\n ")
|
|
194
195
|
)
|
|
195
196
|
|
|
196
|
-
return regular_imports + typing_imports
|
|
197
|
+
return regular_imports + typing_imports + self._typing_definitions
|
|
@@ -10,11 +10,11 @@ from typing import Callable, Dict, Any, List, Optional
|
|
|
10
10
|
|
|
11
11
|
from .._utils import to_snake_case
|
|
12
12
|
from .helpers import (
|
|
13
|
-
pad_reserved_words,
|
|
14
13
|
add_redefined_builtin_info,
|
|
15
14
|
pad_builtin_namespaces,
|
|
15
|
+
pad_special_chars,
|
|
16
16
|
)
|
|
17
|
-
from .python_mappings import PadType
|
|
17
|
+
from .python_mappings import CADL_RESERVED_WORDS, RESERVED_WORDS, PadType
|
|
18
18
|
|
|
19
19
|
from .. import YamlUpdatePlugin, YamlUpdatePluginAutorest
|
|
20
20
|
from .._utils import parse_args, get_body_type_for_description, JSON_REGEXP, KNOWN_TYPES
|
|
@@ -68,6 +68,8 @@ def add_overload(
|
|
|
68
68
|
overload["bodyParameter"]["type"] = body_type
|
|
69
69
|
overload["bodyParameter"]["defaultToUnsetSentinel"] = False
|
|
70
70
|
overload["overloads"] = []
|
|
71
|
+
if yaml_data.get("initialOperation"):
|
|
72
|
+
overload["initialOperation"] = yaml_data["initialOperation"]
|
|
71
73
|
|
|
72
74
|
if for_flatten_params:
|
|
73
75
|
overload["bodyParameter"]["flattened"] = True
|
|
@@ -166,51 +168,6 @@ def update_operation_group_class_name(
|
|
|
166
168
|
return class_name + "Operations"
|
|
167
169
|
|
|
168
170
|
|
|
169
|
-
def update_parameter(yaml_data: Dict[str, Any]) -> None:
|
|
170
|
-
yaml_data["description"] = update_description(yaml_data["description"])
|
|
171
|
-
if not (
|
|
172
|
-
yaml_data["location"] == "header"
|
|
173
|
-
and yaml_data["clientName"] in ("content_type", "accept")
|
|
174
|
-
):
|
|
175
|
-
yaml_data["clientName"] = pad_reserved_words(
|
|
176
|
-
yaml_data["clientName"].lower(), PadType.PARAMETER
|
|
177
|
-
)
|
|
178
|
-
if yaml_data.get("propertyToParameterName"):
|
|
179
|
-
# need to create a new one with padded keys and values
|
|
180
|
-
yaml_data["propertyToParameterName"] = {
|
|
181
|
-
pad_reserved_words(prop, PadType.PROPERTY)
|
|
182
|
-
.lower(): pad_reserved_words(param_name, PadType.PARAMETER)
|
|
183
|
-
.lower()
|
|
184
|
-
for prop, param_name in yaml_data["propertyToParameterName"].items()
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
def update_types(yaml_data: List[Dict[str, Any]]) -> None:
|
|
189
|
-
for type in yaml_data:
|
|
190
|
-
for property in type.get("properties", []):
|
|
191
|
-
property["description"] = update_description(property["description"])
|
|
192
|
-
property["clientName"] = pad_reserved_words(
|
|
193
|
-
property["clientName"].lower(), PadType.PROPERTY
|
|
194
|
-
)
|
|
195
|
-
add_redefined_builtin_info(property["clientName"], property)
|
|
196
|
-
if type.get("name"):
|
|
197
|
-
type["description"] = update_description(type["description"], type["name"])
|
|
198
|
-
type["snakeCaseName"] = to_snake_case(type["name"])
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
def update_client(yaml_data: Dict[str, Any]) -> None:
|
|
202
|
-
yaml_data["description"] = update_description(
|
|
203
|
-
yaml_data["description"], default_description=yaml_data["name"]
|
|
204
|
-
)
|
|
205
|
-
yaml_data["legacyFilename"] = to_snake_case(yaml_data["name"].replace(" ", "_"))
|
|
206
|
-
for parameter in yaml_data["parameters"]:
|
|
207
|
-
update_parameter(parameter)
|
|
208
|
-
prop_name = yaml_data["name"]
|
|
209
|
-
if prop_name.endswith("Client"):
|
|
210
|
-
prop_name = prop_name[: len(prop_name) - len("Client")]
|
|
211
|
-
yaml_data["builderPadName"] = to_snake_case(prop_name)
|
|
212
|
-
|
|
213
|
-
|
|
214
171
|
def update_paging_response(yaml_data: Dict[str, Any]) -> None:
|
|
215
172
|
yaml_data["discriminator"] = "paging"
|
|
216
173
|
yaml_data["pagerSync"] = yaml_data.get("pagerSync") or "azure.core.paging.ItemPaged"
|
|
@@ -228,9 +185,55 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
|
|
|
228
185
|
|
|
229
186
|
@property
|
|
230
187
|
def models_mode(self) -> Optional[str]:
|
|
231
|
-
return self.options.get(
|
|
232
|
-
|
|
188
|
+
return self.options.get("models-mode", "dpg" if self.is_cadl else None)
|
|
189
|
+
|
|
190
|
+
@property
|
|
191
|
+
def is_cadl(self) -> bool:
|
|
192
|
+
return self.options.get("cadl_file", False)
|
|
193
|
+
|
|
194
|
+
def pad_reserved_words(self, name: str, pad_type: PadType):
|
|
195
|
+
# we want to pad hidden variables as well
|
|
196
|
+
if not name:
|
|
197
|
+
# we'll pass in empty operation groups sometime etc.
|
|
198
|
+
return name
|
|
199
|
+
|
|
200
|
+
if self.is_cadl:
|
|
201
|
+
reserved_words = copy.copy(CADL_RESERVED_WORDS)
|
|
202
|
+
reserved_words.update(RESERVED_WORDS)
|
|
203
|
+
else:
|
|
204
|
+
reserved_words = RESERVED_WORDS
|
|
205
|
+
name = pad_special_chars(name)
|
|
206
|
+
name_prefix = "_" if name[0] == "_" else ""
|
|
207
|
+
name = name[1:] if name[0] == "_" else name
|
|
208
|
+
if name.lower() in reserved_words[pad_type]:
|
|
209
|
+
return name_prefix + name + pad_type
|
|
210
|
+
return name_prefix + name
|
|
211
|
+
|
|
212
|
+
def update_types(self, yaml_data: List[Dict[str, Any]]) -> None:
|
|
213
|
+
for type in yaml_data:
|
|
214
|
+
for property in type.get("properties", []):
|
|
215
|
+
property["description"] = update_description(property["description"])
|
|
216
|
+
property["clientName"] = self.pad_reserved_words(
|
|
217
|
+
property["clientName"].lower(), PadType.PROPERTY
|
|
218
|
+
)
|
|
219
|
+
add_redefined_builtin_info(property["clientName"], property)
|
|
220
|
+
if type.get("name"):
|
|
221
|
+
type["description"] = update_description(
|
|
222
|
+
type["description"], type["name"]
|
|
223
|
+
)
|
|
224
|
+
type["snakeCaseName"] = to_snake_case(type["name"])
|
|
225
|
+
|
|
226
|
+
def update_client(self, yaml_data: Dict[str, Any]) -> None:
|
|
227
|
+
yaml_data["description"] = update_description(
|
|
228
|
+
yaml_data["description"], default_description=yaml_data["name"]
|
|
233
229
|
)
|
|
230
|
+
yaml_data["legacyFilename"] = to_snake_case(yaml_data["name"].replace(" ", "_"))
|
|
231
|
+
for parameter in yaml_data["parameters"]:
|
|
232
|
+
self.update_parameter(parameter)
|
|
233
|
+
prop_name = yaml_data["name"]
|
|
234
|
+
if prop_name.endswith("Client"):
|
|
235
|
+
prop_name = prop_name[: len(prop_name) - len("Client")]
|
|
236
|
+
yaml_data["builderPadName"] = to_snake_case(prop_name)
|
|
234
237
|
|
|
235
238
|
def get_operation_updater(
|
|
236
239
|
self, yaml_data: Dict[str, Any]
|
|
@@ -243,6 +246,24 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
|
|
|
243
246
|
return self.update_paging_operation
|
|
244
247
|
return self.update_operation
|
|
245
248
|
|
|
249
|
+
def update_parameter(self, yaml_data: Dict[str, Any]) -> None:
|
|
250
|
+
yaml_data["description"] = update_description(yaml_data["description"])
|
|
251
|
+
if not (
|
|
252
|
+
yaml_data["location"] == "header"
|
|
253
|
+
and yaml_data["clientName"] in ("content_type", "accept")
|
|
254
|
+
):
|
|
255
|
+
yaml_data["clientName"] = self.pad_reserved_words(
|
|
256
|
+
yaml_data["clientName"].lower(), PadType.PARAMETER
|
|
257
|
+
)
|
|
258
|
+
if yaml_data.get("propertyToParameterName"):
|
|
259
|
+
# need to create a new one with padded keys and values
|
|
260
|
+
yaml_data["propertyToParameterName"] = {
|
|
261
|
+
self.pad_reserved_words(prop, PadType.PROPERTY)
|
|
262
|
+
.lower(): self.pad_reserved_words(param_name, PadType.PARAMETER)
|
|
263
|
+
.lower()
|
|
264
|
+
for prop, param_name in yaml_data["propertyToParameterName"].items()
|
|
265
|
+
}
|
|
266
|
+
|
|
246
267
|
def update_operation(
|
|
247
268
|
self,
|
|
248
269
|
code_model: Dict[str, Any],
|
|
@@ -250,23 +271,23 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
|
|
|
250
271
|
*,
|
|
251
272
|
is_overload: bool = False,
|
|
252
273
|
) -> None:
|
|
253
|
-
yaml_data["groupName"] = pad_reserved_words(
|
|
274
|
+
yaml_data["groupName"] = self.pad_reserved_words(
|
|
254
275
|
yaml_data["groupName"], PadType.OPERATION_GROUP
|
|
255
276
|
)
|
|
256
277
|
yaml_data["groupName"] = to_snake_case(yaml_data["groupName"])
|
|
257
278
|
yaml_data["name"] = yaml_data["name"].lower()
|
|
258
|
-
yaml_data["name"] = pad_reserved_words(yaml_data["name"], PadType.METHOD)
|
|
279
|
+
yaml_data["name"] = self.pad_reserved_words(yaml_data["name"], PadType.METHOD)
|
|
259
280
|
yaml_data["description"] = update_description(
|
|
260
281
|
yaml_data["description"], yaml_data["name"]
|
|
261
282
|
)
|
|
262
283
|
yaml_data["summary"] = update_description(yaml_data.get("summary", ""))
|
|
263
284
|
body_parameter = yaml_data.get("bodyParameter")
|
|
264
285
|
for parameter in yaml_data["parameters"]:
|
|
265
|
-
update_parameter(parameter)
|
|
286
|
+
self.update_parameter(parameter)
|
|
266
287
|
if yaml_data.get("bodyParameter"):
|
|
267
|
-
update_parameter(yaml_data["bodyParameter"])
|
|
288
|
+
self.update_parameter(yaml_data["bodyParameter"])
|
|
268
289
|
for entry in yaml_data["bodyParameter"].get("entries", []):
|
|
269
|
-
update_parameter(entry)
|
|
290
|
+
self.update_parameter(entry)
|
|
270
291
|
for overload in yaml_data.get("overloads", []):
|
|
271
292
|
self.update_operation(code_model, overload, is_overload=True)
|
|
272
293
|
for response in yaml_data.get("responses", []):
|
|
@@ -320,9 +341,15 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
|
|
|
320
341
|
is_overload: bool = False,
|
|
321
342
|
) -> None:
|
|
322
343
|
self.update_operation(code_model, yaml_data, is_overload=is_overload)
|
|
344
|
+
self.update_operation(
|
|
345
|
+
code_model, yaml_data["initialOperation"], is_overload=is_overload
|
|
346
|
+
)
|
|
323
347
|
self._update_lro_operation_helper(yaml_data)
|
|
324
348
|
for overload in yaml_data.get("overloads", []):
|
|
325
349
|
self._update_lro_operation_helper(overload)
|
|
350
|
+
self.update_operation(
|
|
351
|
+
code_model, overload["initialOperation"], is_overload=True
|
|
352
|
+
)
|
|
326
353
|
|
|
327
354
|
def update_paging_operation(
|
|
328
355
|
self,
|
|
@@ -352,7 +379,7 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
|
|
|
352
379
|
if yaml_data.get("nextOperation"):
|
|
353
380
|
if self.version_tolerant:
|
|
354
381
|
_remove_paging_maxpagesize(yaml_data["nextOperation"])
|
|
355
|
-
yaml_data["nextOperation"]["groupName"] = pad_reserved_words(
|
|
382
|
+
yaml_data["nextOperation"]["groupName"] = self.pad_reserved_words(
|
|
356
383
|
yaml_data["nextOperation"]["groupName"], PadType.OPERATION_GROUP
|
|
357
384
|
)
|
|
358
385
|
yaml_data["nextOperation"]["groupName"] = to_snake_case(
|
|
@@ -373,7 +400,7 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
|
|
|
373
400
|
operation_groups_yaml_data = client["operationGroups"]
|
|
374
401
|
for operation_group in operation_groups_yaml_data:
|
|
375
402
|
operation_group["clientName"] = client["name"]
|
|
376
|
-
operation_group["propertyName"] = pad_reserved_words(
|
|
403
|
+
operation_group["propertyName"] = self.pad_reserved_words(
|
|
377
404
|
operation_group["propertyName"], PadType.OPERATION_GROUP
|
|
378
405
|
)
|
|
379
406
|
operation_group["propertyName"] = to_snake_case(
|
|
@@ -387,13 +414,13 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
|
|
|
387
414
|
|
|
388
415
|
def update_yaml(self, yaml_data: Dict[str, Any]) -> None:
|
|
389
416
|
"""Convert in place the YAML str."""
|
|
390
|
-
update_types(yaml_data["types"])
|
|
417
|
+
self.update_types(yaml_data["types"])
|
|
391
418
|
for client in yaml_data["clients"]:
|
|
392
|
-
update_client(client)
|
|
419
|
+
self.update_client(client)
|
|
393
420
|
self.update_operation_groups(yaml_data, client)
|
|
394
421
|
for clients in yaml_data["subnamespaceToClients"].values():
|
|
395
422
|
for client in clients:
|
|
396
|
-
update_client(client)
|
|
423
|
+
self.update_client(client)
|
|
397
424
|
self.update_operation_groups(yaml_data, client)
|
|
398
425
|
if yaml_data.get("namespace"):
|
|
399
426
|
yaml_data["namespace"] = pad_builtin_namespaces(yaml_data["namespace"])
|
|
@@ -6,26 +6,11 @@
|
|
|
6
6
|
import re
|
|
7
7
|
from typing import Any, Dict
|
|
8
8
|
from .python_mappings import (
|
|
9
|
-
PadType,
|
|
10
|
-
RESERVED_WORDS,
|
|
11
9
|
REDEFINED_BUILTINS,
|
|
12
10
|
BUILTIN_PACKAGES,
|
|
13
11
|
)
|
|
14
12
|
|
|
15
13
|
|
|
16
|
-
def pad_reserved_words(name: str, pad_type: PadType):
|
|
17
|
-
# we want to pad hidden variables as well
|
|
18
|
-
if not name:
|
|
19
|
-
# we'll pass in empty operation groups sometime etc.
|
|
20
|
-
return name
|
|
21
|
-
name = pad_special_chars(name)
|
|
22
|
-
name_prefix = "_" if name[0] == "_" else ""
|
|
23
|
-
name = name[1:] if name[0] == "_" else name
|
|
24
|
-
if name.lower() in RESERVED_WORDS[pad_type]:
|
|
25
|
-
return name_prefix + name + pad_type
|
|
26
|
-
return name_prefix + name
|
|
27
|
-
|
|
28
|
-
|
|
29
14
|
def add_redefined_builtin_info(name: str, yaml_data: Dict[str, Any]) -> None:
|
|
30
15
|
if name in REDEFINED_BUILTINS:
|
|
31
16
|
yaml_data["pylintDisable"] = "redefined-builtin"
|
package/package.json
CHANGED