@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,102 +3,145 @@
|
|
|
3
3
|
# Licensed under the MIT License. See License.txt in the project root for
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
|
-
from typing import Any, Dict,
|
|
7
|
-
from .parameter import
|
|
6
|
+
from typing import TYPE_CHECKING, Any, Dict, Union
|
|
7
|
+
from .parameter import (
|
|
8
|
+
ParameterLocation,
|
|
9
|
+
ParameterMethodLocation,
|
|
10
|
+
Parameter,
|
|
11
|
+
BodyParameter,
|
|
12
|
+
_MultipartBodyParameter,
|
|
13
|
+
)
|
|
14
|
+
from .base_type import BaseType
|
|
15
|
+
from .primitive_types import BinaryType, StringType
|
|
16
|
+
from .combined_type import CombinedType
|
|
8
17
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
return name[1:]
|
|
12
|
-
return name
|
|
18
|
+
if TYPE_CHECKING:
|
|
19
|
+
from .code_model import CodeModel
|
|
13
20
|
|
|
14
|
-
|
|
21
|
+
|
|
22
|
+
class RequestBuilderBodyParameter(BodyParameter):
|
|
23
|
+
"""BOdy parmaeter for RequestBuilders"""
|
|
24
|
+
|
|
25
|
+
def __init__(self, *args, **kwargs) -> None:
|
|
26
|
+
super().__init__(*args, **kwargs)
|
|
27
|
+
if isinstance(self.type, (BinaryType, StringType)) or any(
|
|
28
|
+
"xml" in ct for ct in self.content_types
|
|
29
|
+
):
|
|
30
|
+
self.client_name = "content"
|
|
31
|
+
else:
|
|
32
|
+
self.client_name = "json"
|
|
33
|
+
|
|
34
|
+
def type_annotation(self, **kwargs: Any) -> str:
|
|
35
|
+
if self.type.is_xml:
|
|
36
|
+
return "Any" # xml type technically not in type signature for HttpRequest content param
|
|
37
|
+
return super().type_annotation(**kwargs)
|
|
15
38
|
|
|
16
39
|
@property
|
|
17
40
|
def in_method_signature(self) -> bool:
|
|
18
|
-
return not
|
|
19
|
-
# don't put accept in method signature
|
|
20
|
-
self.rest_api_name == "Accept"
|
|
21
|
-
# If i'm not in the method code, no point in being in signature
|
|
22
|
-
or not self.in_method_code
|
|
23
|
-
# If I'm a flattened property of a body, don't want me, want the body param
|
|
24
|
-
or self.target_property_name
|
|
25
|
-
or not self.in_method_code
|
|
26
|
-
)
|
|
41
|
+
return super().in_method_signature and not self.is_partial_body
|
|
27
42
|
|
|
28
43
|
@property
|
|
29
|
-
def
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if self.is_body and not self.constant:
|
|
36
|
-
return f"_{self.serialized_name}"
|
|
37
|
-
name = self.yaml_data["language"]["python"]["name"]
|
|
38
|
-
if self.implementation == "Client" and self.in_method_code:
|
|
39
|
-
# for these, we're passing the client params to the request builder.
|
|
40
|
-
# Need the self._config prefix
|
|
41
|
-
name = f"self._config.{name}"
|
|
42
|
-
return name
|
|
44
|
+
def method_location(self) -> ParameterMethodLocation:
|
|
45
|
+
return (
|
|
46
|
+
ParameterMethodLocation.KWARG
|
|
47
|
+
if (self.constant or isinstance(self.type, CombinedType))
|
|
48
|
+
else ParameterMethodLocation.KEYWORD_ONLY
|
|
49
|
+
)
|
|
43
50
|
|
|
44
|
-
@
|
|
45
|
-
def
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return super(RequestBuilderParameter, self).in_method_code
|
|
51
|
+
@classmethod
|
|
52
|
+
def from_yaml(
|
|
53
|
+
cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
|
|
54
|
+
) -> "RequestBuilderBodyParameter":
|
|
55
|
+
return super().from_yaml(yaml_data, code_model) # type: ignore
|
|
50
56
|
|
|
51
57
|
@property
|
|
52
|
-
def
|
|
53
|
-
if self.
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
# but we want to serialize content_type with no default.
|
|
57
|
-
# So, we just return None in default_value_declaration for now
|
|
58
|
-
return "None"
|
|
59
|
-
return super().default_value_declaration
|
|
58
|
+
def name_in_high_level_operation(self) -> str:
|
|
59
|
+
if self.client_name == "json":
|
|
60
|
+
return "_json"
|
|
61
|
+
return "_content"
|
|
60
62
|
|
|
61
|
-
@property
|
|
62
|
-
def is_keyword_only(self) -> bool:
|
|
63
|
-
return not self.location == ParameterLocation.Path and not self.is_kwarg
|
|
64
63
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
64
|
+
class RequestBuilderMultipartBodyParameter(
|
|
65
|
+
_MultipartBodyParameter[ # pylint: disable=unsubscriptable-object
|
|
66
|
+
RequestBuilderBodyParameter
|
|
67
|
+
]
|
|
68
|
+
):
|
|
69
|
+
"""Multipart body parameter for Request BUilders"""
|
|
69
70
|
|
|
70
71
|
@property
|
|
71
|
-
def
|
|
72
|
-
return self.
|
|
72
|
+
def name_in_high_level_operation(self) -> str:
|
|
73
|
+
return f"_{self.client_name}"
|
|
73
74
|
|
|
74
75
|
@classmethod
|
|
75
76
|
def from_yaml(
|
|
76
|
-
cls, yaml_data: Dict[str, Any],
|
|
77
|
-
) -> "
|
|
78
|
-
http_protocol = yaml_data["protocol"].get("http", {"in": ParameterLocation.Other})
|
|
79
|
-
name = yaml_data["language"]["python"]["name"]
|
|
80
|
-
location = ParameterLocation(http_protocol["in"])
|
|
77
|
+
cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
|
|
78
|
+
) -> "RequestBuilderMultipartBodyParameter":
|
|
81
79
|
return cls(
|
|
82
|
-
code_model=code_model,
|
|
83
80
|
yaml_data=yaml_data,
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
client_default_value=
|
|
103
|
-
|
|
81
|
+
code_model=code_model,
|
|
82
|
+
type=code_model.lookup_type(id(yaml_data["type"])),
|
|
83
|
+
entries=[
|
|
84
|
+
RequestBuilderBodyParameter.from_yaml(entry, code_model)
|
|
85
|
+
for entry in yaml_data["entries"]
|
|
86
|
+
],
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class RequestBuilderParameter(Parameter):
|
|
91
|
+
"""Basic RequestBuilder Parameter."""
|
|
92
|
+
|
|
93
|
+
def __init__(
|
|
94
|
+
self, yaml_data: Dict[str, Any], code_model: "CodeModel", type: BaseType
|
|
95
|
+
) -> None:
|
|
96
|
+
super().__init__(yaml_data, code_model, type)
|
|
97
|
+
# we don't want any default content type behavior in request builder
|
|
98
|
+
if self.rest_api_name == "Content-Type":
|
|
99
|
+
self.client_default_value = None
|
|
100
|
+
if self.grouped_by and self.client_name[0] == "_":
|
|
101
|
+
# we don't want hidden parameters for grouped by in request builders
|
|
102
|
+
self.client_name = self.client_name[1:]
|
|
103
|
+
|
|
104
|
+
@property
|
|
105
|
+
def in_method_signature(self) -> bool:
|
|
106
|
+
if self.grouped_by and not self.in_flattened_body:
|
|
107
|
+
return True
|
|
108
|
+
return super().in_method_signature and not (
|
|
109
|
+
self.location == ParameterLocation.ENDPOINT_PATH
|
|
110
|
+
or self.in_flattened_body
|
|
111
|
+
or self.grouper
|
|
104
112
|
)
|
|
113
|
+
|
|
114
|
+
@property
|
|
115
|
+
def full_client_name(self) -> str:
|
|
116
|
+
return self.client_name
|
|
117
|
+
|
|
118
|
+
@property
|
|
119
|
+
def method_location(self) -> ParameterMethodLocation:
|
|
120
|
+
super_method_location = super().method_location
|
|
121
|
+
if super_method_location == ParameterMethodLocation.KWARG:
|
|
122
|
+
return super_method_location
|
|
123
|
+
if (
|
|
124
|
+
self.in_overriden
|
|
125
|
+
and super_method_location == ParameterMethodLocation.KEYWORD_ONLY
|
|
126
|
+
):
|
|
127
|
+
return ParameterMethodLocation.KWARG
|
|
128
|
+
if self.location != ParameterLocation.PATH:
|
|
129
|
+
return ParameterMethodLocation.KEYWORD_ONLY
|
|
130
|
+
return super_method_location
|
|
131
|
+
|
|
132
|
+
@property
|
|
133
|
+
def name_in_high_level_operation(self) -> str:
|
|
134
|
+
if self.grouped_by:
|
|
135
|
+
return f"_{self.client_name}"
|
|
136
|
+
if self.implementation == "Client":
|
|
137
|
+
return f"self._config.{self.client_name}"
|
|
138
|
+
return self.client_name
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def get_request_body_parameter(
|
|
142
|
+
yaml_data: Dict[str, Any], code_model: "CodeModel"
|
|
143
|
+
) -> Union[RequestBuilderBodyParameter, RequestBuilderMultipartBodyParameter]:
|
|
144
|
+
"""Get body parameter for a request builder"""
|
|
145
|
+
if yaml_data.get("entries"):
|
|
146
|
+
return RequestBuilderMultipartBodyParameter.from_yaml(yaml_data, code_model)
|
|
147
|
+
return RequestBuilderBodyParameter.from_yaml(yaml_data, code_model)
|
|
@@ -0,0 +1,325 @@
|
|
|
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, Any, TYPE_CHECKING, Union
|
|
7
|
+
|
|
8
|
+
from .base_model import BaseModel
|
|
9
|
+
from .base_type import BaseType
|
|
10
|
+
from .imports import FileImport, ImportType
|
|
11
|
+
from .primitive_types import BinaryType, BinaryIteratorType
|
|
12
|
+
from .dictionary_type import DictionaryType
|
|
13
|
+
from .list_type import ListType
|
|
14
|
+
from .model_type import ModelType
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from .code_model import CodeModel
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class ResponseHeader(BaseModel):
|
|
21
|
+
def __init__(
|
|
22
|
+
self, yaml_data: Dict[str, Any], code_model: "CodeModel", type: BaseType
|
|
23
|
+
) -> None:
|
|
24
|
+
super().__init__(yaml_data, code_model)
|
|
25
|
+
self.rest_api_name: str = yaml_data["restApiName"]
|
|
26
|
+
self.type = type
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def serialization_type(self) -> str:
|
|
30
|
+
return self.type.serialization_type
|
|
31
|
+
|
|
32
|
+
@classmethod
|
|
33
|
+
def from_yaml(
|
|
34
|
+
cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
|
|
35
|
+
) -> "ResponseHeader":
|
|
36
|
+
return cls(
|
|
37
|
+
yaml_data=yaml_data,
|
|
38
|
+
code_model=code_model,
|
|
39
|
+
type=code_model.lookup_type(id(yaml_data["type"])),
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class Response(BaseModel):
|
|
44
|
+
def __init__(
|
|
45
|
+
self,
|
|
46
|
+
yaml_data: Dict[str, Any],
|
|
47
|
+
code_model: "CodeModel",
|
|
48
|
+
*,
|
|
49
|
+
headers: List[ResponseHeader] = [],
|
|
50
|
+
type: Optional[BaseType] = None,
|
|
51
|
+
) -> None:
|
|
52
|
+
super().__init__(yaml_data=yaml_data, code_model=code_model)
|
|
53
|
+
self.status_codes: List[Union[int, str]] = yaml_data["statusCodes"]
|
|
54
|
+
self.headers = headers
|
|
55
|
+
self.type = type
|
|
56
|
+
self.nullable = yaml_data.get("nullable")
|
|
57
|
+
|
|
58
|
+
def get_json_template_representation(self) -> Any:
|
|
59
|
+
if not self.type:
|
|
60
|
+
return None
|
|
61
|
+
if not isinstance(self.type, (DictionaryType, ListType, ModelType)):
|
|
62
|
+
return None
|
|
63
|
+
return self.type.get_json_template_representation()
|
|
64
|
+
|
|
65
|
+
@property
|
|
66
|
+
def is_stream_response(self) -> bool:
|
|
67
|
+
"""Is the response expected to be streamable, like a download."""
|
|
68
|
+
return isinstance(self.type, BinaryIteratorType)
|
|
69
|
+
|
|
70
|
+
@property
|
|
71
|
+
def serialization_type(self) -> str:
|
|
72
|
+
if self.type:
|
|
73
|
+
return self.type.serialization_type
|
|
74
|
+
return "None"
|
|
75
|
+
|
|
76
|
+
def type_annotation(self, **kwargs: Any) -> str:
|
|
77
|
+
if self.type:
|
|
78
|
+
kwargs["is_operation_file"] = True
|
|
79
|
+
type_annot = self.type.type_annotation(**kwargs)
|
|
80
|
+
if self.nullable:
|
|
81
|
+
return f"Optional[{type_annot}]"
|
|
82
|
+
return type_annot
|
|
83
|
+
return "None"
|
|
84
|
+
|
|
85
|
+
def docstring_text(self, **kwargs: Any) -> str:
|
|
86
|
+
if self.nullable and self.type:
|
|
87
|
+
return f"{self.type.docstring_text(**kwargs)} or None"
|
|
88
|
+
return self.type.docstring_text(**kwargs) if self.type else "None"
|
|
89
|
+
|
|
90
|
+
def docstring_type(self, **kwargs: Any) -> str:
|
|
91
|
+
if self.nullable and self.type:
|
|
92
|
+
return f"{self.type.docstring_type(**kwargs)} or None"
|
|
93
|
+
return self.type.docstring_type(**kwargs) if self.type else "None"
|
|
94
|
+
|
|
95
|
+
def _imports_shared(self, **kwargs: Any) -> FileImport:
|
|
96
|
+
file_import = FileImport()
|
|
97
|
+
if self.type:
|
|
98
|
+
file_import.merge(self.type.imports(is_operation_file=True, **kwargs))
|
|
99
|
+
if self.nullable:
|
|
100
|
+
file_import.add_submodule_import("typing", "Optional", ImportType.STDLIB)
|
|
101
|
+
return file_import
|
|
102
|
+
|
|
103
|
+
def imports(self, **kwargs: Any) -> FileImport:
|
|
104
|
+
return self._imports_shared(**kwargs)
|
|
105
|
+
|
|
106
|
+
def imports_for_multiapi(self, **kwargs: Any) -> FileImport:
|
|
107
|
+
return self._imports_shared(**kwargs)
|
|
108
|
+
|
|
109
|
+
@classmethod
|
|
110
|
+
def from_yaml(
|
|
111
|
+
cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
|
|
112
|
+
) -> "Response":
|
|
113
|
+
type = (
|
|
114
|
+
code_model.lookup_type(id(yaml_data["type"]))
|
|
115
|
+
if yaml_data.get("type")
|
|
116
|
+
else None
|
|
117
|
+
)
|
|
118
|
+
# use ByteIteratorType if we are returning a binary type
|
|
119
|
+
if isinstance(type, BinaryType):
|
|
120
|
+
type = BinaryIteratorType(type.yaml_data, type.code_model)
|
|
121
|
+
return cls(
|
|
122
|
+
yaml_data=yaml_data,
|
|
123
|
+
code_model=code_model,
|
|
124
|
+
headers=[
|
|
125
|
+
ResponseHeader.from_yaml(header, code_model)
|
|
126
|
+
for header in yaml_data["headers"]
|
|
127
|
+
],
|
|
128
|
+
type=type,
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
def __repr__(self) -> str:
|
|
132
|
+
return f"<{self.__class__.__name__} {self.status_codes}>"
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
class PagingResponse(Response):
|
|
136
|
+
def __init__(self, *args, **kwargs) -> None:
|
|
137
|
+
super().__init__(*args, **kwargs)
|
|
138
|
+
self.item_type = self.code_model.lookup_type(id(self.yaml_data["itemType"]))
|
|
139
|
+
|
|
140
|
+
def get_json_template_representation(self) -> Any:
|
|
141
|
+
return self.item_type.get_json_template_representation()
|
|
142
|
+
|
|
143
|
+
def get_pager_path(self, async_mode: bool) -> str:
|
|
144
|
+
return (
|
|
145
|
+
self.yaml_data["pagerAsync"] if async_mode else self.yaml_data["pagerSync"]
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
def get_pager(self, async_mode: bool) -> str:
|
|
149
|
+
return self.get_pager_path(async_mode).split(".")[-1]
|
|
150
|
+
|
|
151
|
+
def type_annotation(self, **kwargs: Any) -> str:
|
|
152
|
+
iterable = "AsyncIterable" if kwargs["async_mode"] else "Iterable"
|
|
153
|
+
return f"{iterable}[{self.item_type.type_annotation(**kwargs)}]"
|
|
154
|
+
|
|
155
|
+
def docstring_text(self, **kwargs: Any) -> str:
|
|
156
|
+
base_description = "An iterator like instance of "
|
|
157
|
+
if not self.code_model.options["version_tolerant"]:
|
|
158
|
+
base_description += "either "
|
|
159
|
+
return base_description + self.item_type.docstring_text(**kwargs)
|
|
160
|
+
|
|
161
|
+
def docstring_type(self, **kwargs: Any) -> str:
|
|
162
|
+
return f"~{self.get_pager_path(kwargs['async_mode'])}[{self.item_type.docstring_type(**kwargs)}]"
|
|
163
|
+
|
|
164
|
+
def _imports_shared(self, **kwargs: Any) -> FileImport:
|
|
165
|
+
file_import = super()._imports_shared(**kwargs)
|
|
166
|
+
async_mode = kwargs.pop("async_mode")
|
|
167
|
+
pager_import_path = ".".join(self.get_pager_path(async_mode).split(".")[:-1])
|
|
168
|
+
pager = self.get_pager(async_mode)
|
|
169
|
+
|
|
170
|
+
file_import.add_submodule_import(pager_import_path, pager, ImportType.AZURECORE)
|
|
171
|
+
return file_import
|
|
172
|
+
|
|
173
|
+
def imports(self, **kwargs: Any) -> FileImport:
|
|
174
|
+
file_import = self._imports_shared(**kwargs)
|
|
175
|
+
async_mode = kwargs.pop("async_mode")
|
|
176
|
+
if async_mode:
|
|
177
|
+
file_import.add_submodule_import(
|
|
178
|
+
"azure.core.async_paging", "AsyncList", ImportType.AZURECORE
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
return file_import
|
|
182
|
+
|
|
183
|
+
def imports_for_multiapi(self, **kwargs: Any) -> FileImport:
|
|
184
|
+
return self._imports_shared(**kwargs)
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
class LROResponse(Response):
|
|
188
|
+
def get_poller_path(self, async_mode: bool) -> str:
|
|
189
|
+
return (
|
|
190
|
+
self.yaml_data["pollerAsync"]
|
|
191
|
+
if async_mode
|
|
192
|
+
else self.yaml_data["pollerSync"]
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
def get_poller(self, async_mode: bool) -> str:
|
|
196
|
+
"""Get the name of the poller. Default is LROPoller / AsyncLROPoller"""
|
|
197
|
+
return self.get_poller_path(async_mode).split(".")[-1]
|
|
198
|
+
|
|
199
|
+
def get_polling_method_path(self, async_mode: bool) -> str:
|
|
200
|
+
"""Get the full name of the poller path. Default are the azure core pollers"""
|
|
201
|
+
return (
|
|
202
|
+
self.yaml_data["pollingMethodAsync"]
|
|
203
|
+
if async_mode
|
|
204
|
+
else self.yaml_data["pollingMethodSync"]
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
def get_polling_method(self, async_mode: bool) -> str:
|
|
208
|
+
"""Get the default pollint method"""
|
|
209
|
+
return self.get_polling_method_path(async_mode).split(".")[-1]
|
|
210
|
+
|
|
211
|
+
@staticmethod
|
|
212
|
+
def get_no_polling_method_path(async_mode: bool) -> str:
|
|
213
|
+
"""Get the path of the default of no polling method"""
|
|
214
|
+
return f"azure.core.polling.{'Async' if async_mode else ''}NoPolling"
|
|
215
|
+
|
|
216
|
+
def get_no_polling_method(self, async_mode: bool) -> str:
|
|
217
|
+
"""Get the default no polling method"""
|
|
218
|
+
return self.get_no_polling_method_path(async_mode).split(".")[-1]
|
|
219
|
+
|
|
220
|
+
@staticmethod
|
|
221
|
+
def get_base_polling_method_path(async_mode: bool) -> str:
|
|
222
|
+
"""Get the base polling method path. Used in docstrings and type annotations."""
|
|
223
|
+
return f"azure.core.polling.{'Async' if async_mode else ''}PollingMethod"
|
|
224
|
+
|
|
225
|
+
def get_base_polling_method(self, async_mode: bool) -> str:
|
|
226
|
+
"""Get the base polling method."""
|
|
227
|
+
return self.get_base_polling_method_path(async_mode).split(".")[-1]
|
|
228
|
+
|
|
229
|
+
def type_annotation(self, **kwargs: Any) -> str:
|
|
230
|
+
return f"{self.get_poller(kwargs.pop('async_mode'))}[{super().type_annotation(**kwargs)}]"
|
|
231
|
+
|
|
232
|
+
def docstring_type(self, **kwargs: Any) -> str:
|
|
233
|
+
return f"~{self.get_poller_path(kwargs.pop('async_mode'))}[{super().docstring_type(**kwargs)}]"
|
|
234
|
+
|
|
235
|
+
def docstring_text(self, **kwargs) -> str:
|
|
236
|
+
super_text = super().docstring_text(**kwargs)
|
|
237
|
+
base_description = (
|
|
238
|
+
f"An instance of {self.get_poller(kwargs.pop('async_mode'))} that returns "
|
|
239
|
+
)
|
|
240
|
+
if not self.code_model.options["version_tolerant"]:
|
|
241
|
+
base_description += "either "
|
|
242
|
+
return base_description + super_text
|
|
243
|
+
|
|
244
|
+
def _imports_shared(self, **kwargs: Any) -> FileImport:
|
|
245
|
+
file_import = super()._imports_shared(**kwargs)
|
|
246
|
+
async_mode = kwargs["async_mode"]
|
|
247
|
+
poller_import_path = ".".join(self.get_poller_path(async_mode).split(".")[:-1])
|
|
248
|
+
poller = self.get_poller(async_mode)
|
|
249
|
+
file_import.add_submodule_import(
|
|
250
|
+
poller_import_path, poller, ImportType.AZURECORE
|
|
251
|
+
)
|
|
252
|
+
return file_import
|
|
253
|
+
|
|
254
|
+
def imports(self, **kwargs: Any) -> FileImport:
|
|
255
|
+
file_import = self._imports_shared(**kwargs)
|
|
256
|
+
async_mode = kwargs["async_mode"]
|
|
257
|
+
|
|
258
|
+
default_polling_method_import_path = ".".join(
|
|
259
|
+
self.get_polling_method_path(async_mode).split(".")[:-1]
|
|
260
|
+
)
|
|
261
|
+
default_polling_method = self.get_polling_method(async_mode)
|
|
262
|
+
file_import.add_submodule_import(
|
|
263
|
+
default_polling_method_import_path,
|
|
264
|
+
default_polling_method,
|
|
265
|
+
ImportType.AZURECORE,
|
|
266
|
+
)
|
|
267
|
+
default_no_polling_method_import_path = ".".join(
|
|
268
|
+
self.get_no_polling_method_path(async_mode).split(".")[:-1]
|
|
269
|
+
)
|
|
270
|
+
default_no_polling_method = self.get_no_polling_method(async_mode)
|
|
271
|
+
file_import.add_submodule_import(
|
|
272
|
+
default_no_polling_method_import_path,
|
|
273
|
+
default_no_polling_method,
|
|
274
|
+
ImportType.AZURECORE,
|
|
275
|
+
)
|
|
276
|
+
|
|
277
|
+
base_polling_method_import_path = ".".join(
|
|
278
|
+
self.get_base_polling_method_path(async_mode).split(".")[:-1]
|
|
279
|
+
)
|
|
280
|
+
base_polling_method = self.get_base_polling_method(async_mode)
|
|
281
|
+
file_import.add_submodule_import(
|
|
282
|
+
base_polling_method_import_path, base_polling_method, ImportType.AZURECORE
|
|
283
|
+
)
|
|
284
|
+
return file_import
|
|
285
|
+
|
|
286
|
+
def imports_for_multiapi(self, **kwargs: Any) -> FileImport:
|
|
287
|
+
return self._imports_shared(**kwargs)
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
class LROPagingResponse(LROResponse, PagingResponse):
|
|
291
|
+
def type_annotation(self, **kwargs: Any) -> str:
|
|
292
|
+
paging_type_annotation = PagingResponse.type_annotation(self, **kwargs)
|
|
293
|
+
return f"{self.get_poller(kwargs.pop('async_mode'))}[{paging_type_annotation}]"
|
|
294
|
+
|
|
295
|
+
def docstring_type(self, **kwargs: Any) -> str:
|
|
296
|
+
paging_docstring_type = PagingResponse.docstring_type(self, **kwargs)
|
|
297
|
+
return f"~{self.get_poller_path(kwargs.pop('async_mode'))}[{paging_docstring_type}]"
|
|
298
|
+
|
|
299
|
+
def docstring_text(self, **kwargs) -> str:
|
|
300
|
+
base_description = (
|
|
301
|
+
"An instance of LROPoller that returns an iterator like instance of "
|
|
302
|
+
)
|
|
303
|
+
if not self.code_model.options["version_tolerant"]:
|
|
304
|
+
base_description += "either "
|
|
305
|
+
return base_description + Response.docstring_text(self)
|
|
306
|
+
|
|
307
|
+
def imports_for_multiapi(self, **kwargs: Any) -> FileImport:
|
|
308
|
+
file_import = LROResponse.imports_for_multiapi(self, **kwargs)
|
|
309
|
+
file_import.merge(PagingResponse.imports_for_multiapi(self, **kwargs))
|
|
310
|
+
return file_import
|
|
311
|
+
|
|
312
|
+
def imports(self, **kwargs: Any) -> FileImport:
|
|
313
|
+
file_import = LROResponse.imports(self, **kwargs)
|
|
314
|
+
file_import.merge(PagingResponse.imports(self, **kwargs))
|
|
315
|
+
return file_import
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
def get_response(yaml_data: Dict[str, Any], code_model: "CodeModel") -> Response:
|
|
319
|
+
if yaml_data["discriminator"] == "lropaging":
|
|
320
|
+
return LROPagingResponse.from_yaml(yaml_data, code_model)
|
|
321
|
+
if yaml_data["discriminator"] == "lro":
|
|
322
|
+
return LROResponse.from_yaml(yaml_data, code_model)
|
|
323
|
+
if yaml_data["discriminator"] == "paging":
|
|
324
|
+
return PagingResponse.from_yaml(yaml_data, code_model)
|
|
325
|
+
return Response.from_yaml(yaml_data, code_model)
|
|
@@ -4,5 +4,21 @@
|
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
6
|
import re
|
|
7
|
+
from typing import TypeVar, Dict
|
|
7
8
|
|
|
8
|
-
JSON_REGEXP = re.compile(r
|
|
9
|
+
JSON_REGEXP = re.compile(r"^(application|text)/(.+\+)?json$")
|
|
10
|
+
|
|
11
|
+
T = TypeVar("T")
|
|
12
|
+
OrderedSet = Dict[T, None]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def add_to_description(description: str, entry: str) -> str:
|
|
16
|
+
if description:
|
|
17
|
+
return f"{description} {entry}"
|
|
18
|
+
return entry
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def add_to_pylint_disable(curr_str: str, entry: str) -> str:
|
|
22
|
+
if curr_str:
|
|
23
|
+
return f"{curr_str},{entry}"
|
|
24
|
+
return f" # pylint: disable={entry}"
|