@autorest/python 5.15.0 → 5.16.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 +20 -0
- package/autorest/__init__.py +1 -2
- package/autorest/black/__init__.py +12 -5
- package/autorest/codegen/__init__.py +145 -73
- package/autorest/codegen/models/__init__.py +29 -18
- package/autorest/codegen/models/base_builder.py +48 -11
- package/autorest/codegen/models/base_model.py +6 -4
- package/autorest/codegen/models/base_schema.py +19 -18
- package/autorest/codegen/models/client.py +65 -21
- package/autorest/codegen/models/code_model.py +107 -61
- package/autorest/codegen/models/constant_schema.py +25 -13
- package/autorest/codegen/models/credential_model.py +23 -15
- package/autorest/codegen/models/credential_schema.py +18 -14
- package/autorest/codegen/models/credential_schema_policy.py +11 -15
- package/autorest/codegen/models/dictionary_schema.py +20 -17
- package/autorest/codegen/models/enum_schema.py +35 -25
- package/autorest/codegen/models/imports.py +70 -41
- package/autorest/codegen/models/list_schema.py +25 -13
- package/autorest/codegen/models/lro_operation.py +58 -22
- package/autorest/codegen/models/lro_paging_operation.py +2 -3
- package/autorest/codegen/models/object_schema.py +99 -49
- package/autorest/codegen/models/operation.py +236 -117
- package/autorest/codegen/models/operation_group.py +64 -34
- package/autorest/codegen/models/paging_operation.py +45 -18
- package/autorest/codegen/models/parameter.py +151 -83
- package/autorest/codegen/models/parameter_list.py +183 -162
- package/autorest/codegen/models/primitive_schemas.py +84 -55
- package/autorest/codegen/models/property.py +44 -26
- package/autorest/codegen/models/request_builder.py +65 -30
- package/autorest/codegen/models/request_builder_parameter.py +47 -23
- package/autorest/codegen/models/request_builder_parameter_list.py +77 -108
- package/autorest/codegen/models/schema_request.py +16 -6
- package/autorest/codegen/models/schema_response.py +18 -13
- package/autorest/codegen/models/utils.py +5 -2
- package/autorest/codegen/serializers/__init__.py +182 -91
- package/autorest/codegen/serializers/builder_serializer.py +667 -331
- package/autorest/codegen/serializers/client_serializer.py +98 -37
- package/autorest/codegen/serializers/general_serializer.py +61 -26
- package/autorest/codegen/serializers/import_serializer.py +93 -31
- package/autorest/codegen/serializers/metadata_serializer.py +73 -24
- package/autorest/codegen/serializers/model_base_serializer.py +35 -15
- package/autorest/codegen/serializers/model_generic_serializer.py +1 -4
- package/autorest/codegen/serializers/model_init_serializer.py +5 -1
- package/autorest/codegen/serializers/model_python3_serializer.py +7 -6
- package/autorest/codegen/serializers/operation_groups_serializer.py +20 -9
- package/autorest/codegen/serializers/operations_init_serializer.py +23 -11
- package/autorest/codegen/serializers/patch_serializer.py +4 -1
- package/autorest/codegen/serializers/{rest_serializer.py → request_builders_serializer.py} +29 -12
- package/autorest/codegen/serializers/utils.py +35 -21
- package/autorest/codegen/templates/init.py.jinja2 +2 -2
- package/autorest/codegen/templates/lro_operation.py.jinja2 +5 -7
- package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +5 -7
- package/autorest/codegen/templates/metadata.json.jinja2 +7 -6
- package/autorest/codegen/templates/operation.py.jinja2 +7 -9
- package/autorest/codegen/templates/operation_group.py.jinja2 +2 -8
- package/autorest/codegen/templates/operation_groups_container.py.jinja2 +1 -1
- package/autorest/codegen/templates/paging_operation.py.jinja2 +7 -8
- package/autorest/codegen/templates/request_builder.py.jinja2 +18 -11
- package/autorest/jsonrpc/__init__.py +7 -12
- package/autorest/jsonrpc/localapi.py +4 -3
- package/autorest/jsonrpc/server.py +13 -6
- package/autorest/jsonrpc/stdstream.py +13 -6
- package/autorest/m2r/__init__.py +5 -8
- 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 +18 -23
- package/autorest/multiapi/serializers/import_serializer.py +47 -17
- package/autorest/multiapi/serializers/multiapi_serializer.py +17 -17
- package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +1 -1
- package/autorest/multiapi/utils.py +3 -3
- package/autorest/namer/__init__.py +2 -4
- package/autorest/namer/name_converter.py +200 -103
- package/autorest/namer/python_mappings.py +10 -22
- package/package.json +2 -2
- package/run-python3.js +2 -3
- package/venvtools.py +1 -1
- package/autorest/codegen/models/rest.py +0 -42
|
@@ -3,20 +3,30 @@
|
|
|
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, List, Optional
|
|
7
|
-
from .parameter import
|
|
6
|
+
from typing import Any, Dict, List, Optional, TYPE_CHECKING
|
|
7
|
+
from .parameter import (
|
|
8
|
+
ParameterMethodLocation,
|
|
9
|
+
ParameterOnlyPathAndBodyPositional,
|
|
10
|
+
ParameterLocation,
|
|
11
|
+
ParameterStyle,
|
|
12
|
+
get_target_property_name,
|
|
13
|
+
)
|
|
8
14
|
from .utils import get_schema
|
|
9
15
|
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from .code_model import CodeModel
|
|
18
|
+
|
|
19
|
+
|
|
10
20
|
def _make_public(name):
|
|
11
21
|
if name[0] == "_":
|
|
12
22
|
return name[1:]
|
|
13
23
|
return name
|
|
14
24
|
|
|
15
|
-
class RequestBuilderParameter(ParameterOnlyPathAndBodyPositional):
|
|
16
25
|
|
|
26
|
+
class RequestBuilderParameter(ParameterOnlyPathAndBodyPositional):
|
|
17
27
|
@property
|
|
18
28
|
def in_method_signature(self) -> bool:
|
|
19
|
-
return not(
|
|
29
|
+
return not (
|
|
20
30
|
# if not inputtable, don't put in signature
|
|
21
31
|
not self.inputtable_by_user
|
|
22
32
|
# If i'm not in the method code, no point in being in signature
|
|
@@ -28,11 +38,6 @@ class RequestBuilderParameter(ParameterOnlyPathAndBodyPositional):
|
|
|
28
38
|
|
|
29
39
|
@property
|
|
30
40
|
def name_in_high_level_operation(self) -> str:
|
|
31
|
-
template = "{}" if self.code_model.options["version_tolerant"] else "_{}"
|
|
32
|
-
if self.is_multipart:
|
|
33
|
-
return template.format("files")
|
|
34
|
-
if self.is_data_input:
|
|
35
|
-
return template.format("data")
|
|
36
41
|
if self.is_body and not self.constant:
|
|
37
42
|
return f"_{self.serialized_name}"
|
|
38
43
|
name = self.yaml_data["language"]["python"]["name"]
|
|
@@ -60,13 +65,20 @@ class RequestBuilderParameter(ParameterOnlyPathAndBodyPositional):
|
|
|
60
65
|
return super().default_value_declaration
|
|
61
66
|
|
|
62
67
|
@property
|
|
63
|
-
def
|
|
64
|
-
|
|
68
|
+
def method_location(self) -> ParameterMethodLocation:
|
|
69
|
+
super_method_location = super().method_location
|
|
70
|
+
if super_method_location in (
|
|
71
|
+
ParameterMethodLocation.KWARG,
|
|
72
|
+
ParameterMethodLocation.HIDDEN_KWARG,
|
|
73
|
+
):
|
|
74
|
+
return super_method_location
|
|
75
|
+
if self.location != ParameterLocation.Path:
|
|
76
|
+
return ParameterMethodLocation.KEYWORD_ONLY
|
|
77
|
+
return super_method_location
|
|
65
78
|
|
|
66
|
-
@
|
|
67
|
-
def
|
|
68
|
-
self.
|
|
69
|
-
self.is_kwarg = False
|
|
79
|
+
@method_location.setter
|
|
80
|
+
def method_location(self, val: ParameterMethodLocation) -> None:
|
|
81
|
+
self._method_location = val
|
|
70
82
|
|
|
71
83
|
@property
|
|
72
84
|
def full_serialized_name(self) -> str:
|
|
@@ -74,17 +86,25 @@ class RequestBuilderParameter(ParameterOnlyPathAndBodyPositional):
|
|
|
74
86
|
|
|
75
87
|
@classmethod
|
|
76
88
|
def from_yaml(
|
|
77
|
-
cls,
|
|
89
|
+
cls,
|
|
90
|
+
yaml_data: Dict[str, Any],
|
|
91
|
+
code_model: "CodeModel",
|
|
92
|
+
*,
|
|
93
|
+
content_types: Optional[List[str]] = None,
|
|
78
94
|
) -> "RequestBuilderParameter":
|
|
79
|
-
http_protocol = yaml_data["protocol"].get(
|
|
95
|
+
http_protocol = yaml_data["protocol"].get(
|
|
96
|
+
"http", {"in": ParameterLocation.Other}
|
|
97
|
+
)
|
|
80
98
|
name = yaml_data["language"]["python"]["name"]
|
|
81
99
|
location = ParameterLocation(http_protocol["in"])
|
|
82
100
|
serialized_name = yaml_data["language"]["python"]["name"]
|
|
83
|
-
schema = get_schema(
|
|
84
|
-
code_model, yaml_data.get("schema"), serialized_name
|
|
85
|
-
)
|
|
101
|
+
schema = get_schema(code_model, yaml_data.get("schema"), serialized_name)
|
|
86
102
|
target_property = yaml_data.get("targetProperty")
|
|
87
|
-
target_property_name =
|
|
103
|
+
target_property_name = (
|
|
104
|
+
get_target_property_name(code_model, id(target_property))
|
|
105
|
+
if target_property
|
|
106
|
+
else None
|
|
107
|
+
)
|
|
88
108
|
return cls(
|
|
89
109
|
code_model=code_model,
|
|
90
110
|
yaml_data=yaml_data,
|
|
@@ -98,10 +118,14 @@ class RequestBuilderParameter(ParameterOnlyPathAndBodyPositional):
|
|
|
98
118
|
implementation=yaml_data["implementation"],
|
|
99
119
|
required=yaml_data.get("required", False),
|
|
100
120
|
location=location,
|
|
101
|
-
skip_url_encoding=yaml_data.get("extensions", {}).get(
|
|
121
|
+
skip_url_encoding=yaml_data.get("extensions", {}).get(
|
|
122
|
+
"x-ms-skip-url-encoding", False
|
|
123
|
+
),
|
|
102
124
|
constraints=[], # FIXME constraints
|
|
103
125
|
target_property_name=target_property_name,
|
|
104
|
-
style=ParameterStyle(http_protocol["style"])
|
|
126
|
+
style=ParameterStyle(http_protocol["style"])
|
|
127
|
+
if "style" in http_protocol
|
|
128
|
+
else None,
|
|
105
129
|
explode=http_protocol.get("explode", False),
|
|
106
130
|
grouped_by=yaml_data.get("groupedBy", None),
|
|
107
131
|
original_parameter=yaml_data.get("originalParameter", None),
|
|
@@ -4,38 +4,48 @@
|
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
6
|
from copy import copy
|
|
7
|
-
from typing import List, Optional, Tuple, TypeVar, Dict
|
|
7
|
+
from typing import List, Optional, Tuple, TypeVar, Dict, TYPE_CHECKING
|
|
8
8
|
from .request_builder_parameter import RequestBuilderParameter
|
|
9
9
|
from .parameter_list import ParameterList
|
|
10
|
-
from .parameter import
|
|
11
|
-
|
|
10
|
+
from .parameter import (
|
|
11
|
+
ParameterLocation,
|
|
12
|
+
Parameter,
|
|
13
|
+
ParameterMethodLocation,
|
|
14
|
+
ParameterStyle,
|
|
15
|
+
)
|
|
16
|
+
from .primitive_schemas import AnySchema
|
|
12
17
|
from .dictionary_schema import DictionarySchema
|
|
13
18
|
from .base_schema import BaseSchema
|
|
19
|
+
from .list_schema import ListSchema
|
|
20
|
+
from .object_schema import ObjectSchema
|
|
14
21
|
from .schema_request import SchemaRequest
|
|
15
22
|
from .utils import JSON_REGEXP
|
|
16
23
|
|
|
17
|
-
|
|
24
|
+
if TYPE_CHECKING:
|
|
25
|
+
from .code_model import CodeModel
|
|
26
|
+
|
|
27
|
+
T = TypeVar("T")
|
|
18
28
|
OrderedSet = Dict[T, None]
|
|
19
29
|
|
|
20
30
|
|
|
21
31
|
def _update_content_types(content_types_to_assign: List[str], param: Parameter):
|
|
22
|
-
return [
|
|
23
|
-
|
|
24
|
-
]
|
|
32
|
+
return [c for c in content_types_to_assign if c not in param.content_types]
|
|
33
|
+
|
|
25
34
|
|
|
26
35
|
def _kwarg_not_added(body_method_params, serialized_name: str) -> bool:
|
|
27
|
-
return not any(
|
|
36
|
+
return not any(
|
|
37
|
+
b for b in body_method_params if b.serialized_name == serialized_name
|
|
38
|
+
)
|
|
39
|
+
|
|
28
40
|
|
|
29
41
|
class RequestBuilderParameterList(ParameterList):
|
|
30
42
|
def __init__(
|
|
31
43
|
self,
|
|
32
|
-
code_model,
|
|
44
|
+
code_model: "CodeModel",
|
|
33
45
|
parameters: Optional[List[RequestBuilderParameter]] = None,
|
|
34
46
|
schema_requests: Optional[List[SchemaRequest]] = None,
|
|
35
47
|
) -> None:
|
|
36
|
-
super(
|
|
37
|
-
code_model, parameters, schema_requests # type: ignore
|
|
38
|
-
)
|
|
48
|
+
super().__init__(code_model, parameters, schema_requests) # type: ignore
|
|
39
49
|
self.body_kwarg_names: OrderedSet[str] = {}
|
|
40
50
|
self.parameters: List[RequestBuilderParameter] = parameters or [] # type: ignore
|
|
41
51
|
|
|
@@ -45,17 +55,20 @@ class RequestBuilderParameterList(ParameterList):
|
|
|
45
55
|
parameter.is_body_kwarg = True
|
|
46
56
|
|
|
47
57
|
def _is_json(self, body_method_param: Parameter) -> bool:
|
|
48
|
-
if
|
|
58
|
+
if "json" in body_method_param.serialization_formats:
|
|
49
59
|
return True
|
|
50
60
|
if not any(
|
|
51
|
-
flag
|
|
61
|
+
flag
|
|
62
|
+
for flag in ["version_tolerant", "low_level_client"]
|
|
52
63
|
if self.code_model.options.get(flag)
|
|
53
64
|
):
|
|
54
65
|
if body_method_param.style == ParameterStyle.binary:
|
|
55
66
|
return False
|
|
56
67
|
if any(
|
|
57
|
-
sr
|
|
58
|
-
|
|
68
|
+
sr
|
|
69
|
+
for sr in self.schema_requests
|
|
70
|
+
if sr.yaml_data.get("protocol", {}).get("http", {}).get("knownMediaType")
|
|
71
|
+
== "json"
|
|
59
72
|
):
|
|
60
73
|
return True
|
|
61
74
|
return any(c for c in self.content_types if JSON_REGEXP.match(c))
|
|
@@ -70,11 +83,9 @@ class RequestBuilderParameterList(ParameterList):
|
|
|
70
83
|
# we don't currently have a fully constant data or files input
|
|
71
84
|
# so we don't need to modify the body kwarg
|
|
72
85
|
constant_bodies = [
|
|
73
|
-
p
|
|
74
|
-
|
|
75
|
-
and p.constant
|
|
76
|
-
and not p.is_data_input
|
|
77
|
-
and not p.is_multipart
|
|
86
|
+
p
|
|
87
|
+
for p in self.parameters
|
|
88
|
+
if p.location == ParameterLocation.Body and p.constant
|
|
78
89
|
]
|
|
79
90
|
for constant_body in constant_bodies:
|
|
80
91
|
if self._is_json(constant_body):
|
|
@@ -82,48 +93,6 @@ class RequestBuilderParameterList(ParameterList):
|
|
|
82
93
|
else:
|
|
83
94
|
constant_body.serialized_name = "content"
|
|
84
95
|
|
|
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
96
|
def _add_json_kwarg(
|
|
128
97
|
self, content_types_to_assign, body_method_param
|
|
129
98
|
) -> Tuple[List[str], RequestBuilderParameter]:
|
|
@@ -131,15 +100,19 @@ class RequestBuilderParameterList(ParameterList):
|
|
|
131
100
|
self._change_body_param_name(json_kwarg, "json")
|
|
132
101
|
json_kwarg.description = (
|
|
133
102
|
"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
|
|
103
|
+
"See the template in our example to find the input shape. "
|
|
104
|
+
+ json_kwarg.description
|
|
136
105
|
)
|
|
137
|
-
|
|
106
|
+
if not isinstance(
|
|
107
|
+
body_method_param.schema, (ObjectSchema, DictionarySchema, ListSchema)
|
|
108
|
+
):
|
|
109
|
+
json_kwarg.schema = AnySchema(yaml_data={}, code_model=self.code_model)
|
|
138
110
|
json_kwarg.content_types = [
|
|
139
|
-
c for c in content_types_to_assign
|
|
140
|
-
if JSON_REGEXP.match(c)
|
|
111
|
+
c for c in content_types_to_assign if JSON_REGEXP.match(c)
|
|
141
112
|
]
|
|
142
|
-
content_types_to_assign = _update_content_types(
|
|
113
|
+
content_types_to_assign = _update_content_types(
|
|
114
|
+
content_types_to_assign, json_kwarg
|
|
115
|
+
)
|
|
143
116
|
return content_types_to_assign, json_kwarg
|
|
144
117
|
|
|
145
118
|
def _add_content_kwarg(
|
|
@@ -147,14 +120,11 @@ class RequestBuilderParameterList(ParameterList):
|
|
|
147
120
|
) -> RequestBuilderParameter:
|
|
148
121
|
content_kwarg = copy(body_method_param)
|
|
149
122
|
self._change_body_param_name(content_kwarg, "content")
|
|
150
|
-
content_kwarg.schema = AnySchema(
|
|
123
|
+
content_kwarg.schema = AnySchema(yaml_data={}, code_model=self.code_model)
|
|
151
124
|
content_kwarg.description = (
|
|
152
125
|
"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
|
|
126
|
+
"a byte iterator, or stream input). " + content_kwarg.description
|
|
155
127
|
)
|
|
156
|
-
content_kwarg.is_data_input = False
|
|
157
|
-
content_kwarg.is_multipart = False
|
|
158
128
|
content_kwarg.content_types = content_types_to_assign
|
|
159
129
|
return content_kwarg
|
|
160
130
|
|
|
@@ -162,25 +132,18 @@ class RequestBuilderParameterList(ParameterList):
|
|
|
162
132
|
self._update_constant_params()
|
|
163
133
|
body_kwargs_added: List[RequestBuilderParameter] = []
|
|
164
134
|
body_method_params = [
|
|
165
|
-
p
|
|
166
|
-
|
|
135
|
+
p
|
|
136
|
+
for p in self.parameters
|
|
137
|
+
if p.location == ParameterLocation.Body
|
|
138
|
+
and not (p.constant or p.is_multipart or p.is_data_input)
|
|
167
139
|
]
|
|
168
140
|
if not body_method_params:
|
|
169
141
|
return
|
|
170
142
|
content_types_to_assign = copy(self.content_types)
|
|
171
143
|
for body_method_param in body_method_params:
|
|
172
|
-
if body_method_param
|
|
173
|
-
|
|
174
|
-
|
|
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"):
|
|
144
|
+
if self._is_json(body_method_param) and _kwarg_not_added(
|
|
145
|
+
body_kwargs_added, "json"
|
|
146
|
+
):
|
|
184
147
|
content_types_to_assign, json_kwarg = self._add_json_kwarg(
|
|
185
148
|
content_types_to_assign, body_method_param
|
|
186
149
|
)
|
|
@@ -206,8 +169,7 @@ class RequestBuilderParameterList(ParameterList):
|
|
|
206
169
|
if not self._json_body:
|
|
207
170
|
try:
|
|
208
171
|
json_param = next(
|
|
209
|
-
b for b in self.body if not b.is_body_kwarg and
|
|
210
|
-
b.is_json_parameter
|
|
172
|
+
b for b in self.body if not b.is_body_kwarg and b.is_json_parameter
|
|
211
173
|
)
|
|
212
174
|
self._json_body = json_param.schema
|
|
213
175
|
return self._json_body
|
|
@@ -219,13 +181,14 @@ class RequestBuilderParameterList(ParameterList):
|
|
|
219
181
|
# we don't want to pop the body kwargs in py2.7. We send them straight to HttpRequest
|
|
220
182
|
kwargs_to_pop = self.kwargs
|
|
221
183
|
if not is_python3_file:
|
|
222
|
-
kwargs_to_pop += [
|
|
184
|
+
kwargs_to_pop += [
|
|
185
|
+
k for k in self.keyword_only if not (k.is_body and not k.constant)
|
|
186
|
+
]
|
|
223
187
|
return kwargs_to_pop
|
|
224
188
|
|
|
225
189
|
@property
|
|
226
190
|
def method(self) -> List[Parameter]:
|
|
227
|
-
"""The list of parameter used in method signature. Includes both positional and kwargs
|
|
228
|
-
"""
|
|
191
|
+
"""The list of parameter used in method signature. Includes both positional and kwargs"""
|
|
229
192
|
signature_parameters_no_default_value = []
|
|
230
193
|
signature_parameters_default_value = []
|
|
231
194
|
|
|
@@ -233,29 +196,28 @@ class RequestBuilderParameterList(ParameterList):
|
|
|
233
196
|
# Also allow client parameters if they're going to be used in the request body.
|
|
234
197
|
# i.e., path parameter, query parameter, header.
|
|
235
198
|
parameters = self.get_from_predicate(
|
|
236
|
-
lambda parameter: parameter.implementation == self.implementation
|
|
199
|
+
lambda parameter: parameter.implementation == self.implementation
|
|
200
|
+
or parameter.in_method_code
|
|
237
201
|
)
|
|
238
202
|
seen_content_type = False
|
|
239
203
|
|
|
240
204
|
for parameter in parameters:
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
parameter.location == ParameterLocation.Body and
|
|
244
|
-
(parameter.is_data_input or parameter.is_multipart) and
|
|
245
|
-
not parameter.is_body_kwarg
|
|
205
|
+
if parameter.location == ParameterLocation.Body and (
|
|
206
|
+
parameter.is_multipart or parameter.is_data_input
|
|
246
207
|
):
|
|
247
|
-
#
|
|
248
|
-
# data kwarg, ignore me
|
|
208
|
+
# don't want any multipart for formdata params in our signature
|
|
249
209
|
continue
|
|
250
210
|
if (
|
|
251
|
-
parameter.location == ParameterLocation.Body
|
|
252
|
-
not parameter.is_body_kwarg
|
|
253
|
-
not parameter.constant
|
|
211
|
+
parameter.location == ParameterLocation.Body
|
|
212
|
+
and not parameter.is_body_kwarg
|
|
213
|
+
and not parameter.constant
|
|
254
214
|
):
|
|
255
215
|
# we keep the original body param from the swagger for documentation purposes
|
|
256
216
|
# we don't want it in the method signature
|
|
257
217
|
continue
|
|
258
|
-
if any(
|
|
218
|
+
if any(
|
|
219
|
+
[g for g in self.groupers if id(g.yaml_data) == id(parameter.yaml_data)]
|
|
220
|
+
):
|
|
259
221
|
# we don't allow a grouped parameter for the body param
|
|
260
222
|
continue
|
|
261
223
|
if seen_content_type and parameter.serialized_name == "content_type":
|
|
@@ -270,9 +232,16 @@ class RequestBuilderParameterList(ParameterList):
|
|
|
270
232
|
else:
|
|
271
233
|
signature_parameters_default_value.append(parameter)
|
|
272
234
|
|
|
273
|
-
signature_parameters =
|
|
274
|
-
|
|
275
|
-
|
|
235
|
+
signature_parameters = (
|
|
236
|
+
signature_parameters_no_default_value + signature_parameters_default_value
|
|
237
|
+
)
|
|
238
|
+
signature_parameters.sort(
|
|
239
|
+
key=lambda item: item.method_location
|
|
240
|
+
== ParameterMethodLocation.KEYWORD_ONLY
|
|
241
|
+
)
|
|
242
|
+
signature_parameters = self._filter_out_multiple_content_type(
|
|
243
|
+
signature_parameters
|
|
244
|
+
)
|
|
276
245
|
return signature_parameters
|
|
277
246
|
|
|
278
247
|
@staticmethod
|
|
@@ -3,32 +3,41 @@
|
|
|
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 Dict, List, Any, Optional
|
|
6
|
+
from typing import Dict, List, Any, Optional, TYPE_CHECKING
|
|
7
7
|
|
|
8
8
|
from .base_model import BaseModel
|
|
9
9
|
from .parameter import Parameter
|
|
10
10
|
from .parameter_list import ParameterList
|
|
11
11
|
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from .code_model import CodeModel
|
|
14
|
+
|
|
15
|
+
|
|
12
16
|
class SchemaRequest(BaseModel):
|
|
13
17
|
def __init__(
|
|
14
18
|
self,
|
|
15
19
|
yaml_data: Dict[str, Any],
|
|
20
|
+
code_model: "CodeModel",
|
|
16
21
|
content_types: List[str],
|
|
17
22
|
parameters: ParameterList,
|
|
18
23
|
) -> None:
|
|
19
|
-
super().__init__(yaml_data)
|
|
24
|
+
super().__init__(yaml_data, code_model)
|
|
20
25
|
self.content_types = content_types
|
|
21
26
|
self.parameters = parameters
|
|
22
27
|
|
|
23
28
|
@property
|
|
24
29
|
def is_stream_request(self) -> bool:
|
|
25
30
|
"""Is the request expected to be streamable, like a download."""
|
|
26
|
-
if self.yaml_data[
|
|
27
|
-
return
|
|
31
|
+
if self.yaml_data["protocol"]["http"].get("knownMediaType"):
|
|
32
|
+
return (
|
|
33
|
+
self.yaml_data["protocol"]["http"]["knownMediaType"] == "binary"
|
|
34
|
+
) # FIXME: this might be an m4 issue
|
|
28
35
|
return self.yaml_data["protocol"]["http"].get("binary", False)
|
|
29
36
|
|
|
30
37
|
@classmethod
|
|
31
|
-
def from_yaml(
|
|
38
|
+
def from_yaml(
|
|
39
|
+
cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
|
|
40
|
+
) -> "SchemaRequest":
|
|
32
41
|
|
|
33
42
|
parameters: Optional[List[Parameter]] = [
|
|
34
43
|
Parameter.from_yaml(yaml, code_model=code_model)
|
|
@@ -37,8 +46,9 @@ class SchemaRequest(BaseModel):
|
|
|
37
46
|
|
|
38
47
|
return cls(
|
|
39
48
|
yaml_data=yaml_data,
|
|
49
|
+
code_model=code_model,
|
|
40
50
|
content_types=yaml_data["protocol"]["http"].get("mediaTypes", []),
|
|
41
|
-
parameters=ParameterList(code_model, parameters)
|
|
51
|
+
parameters=ParameterList(code_model, parameters),
|
|
42
52
|
)
|
|
43
53
|
|
|
44
54
|
def __repr__(self) -> str:
|
|
@@ -29,16 +29,15 @@ class HeaderResponse:
|
|
|
29
29
|
class SchemaResponse(BaseModel):
|
|
30
30
|
def __init__(
|
|
31
31
|
self,
|
|
32
|
-
code_model: "CodeModel",
|
|
33
32
|
yaml_data: Dict[str, Any],
|
|
33
|
+
code_model: "CodeModel",
|
|
34
34
|
schema: Optional[BaseSchema],
|
|
35
35
|
content_types: List[str],
|
|
36
36
|
status_codes: List[Union[str, int]],
|
|
37
37
|
headers: List[HeaderResponse],
|
|
38
38
|
binary: bool,
|
|
39
39
|
) -> None:
|
|
40
|
-
super().__init__(yaml_data)
|
|
41
|
-
self.code_model = code_model
|
|
40
|
+
super().__init__(yaml_data, code_model)
|
|
42
41
|
self.schema = schema
|
|
43
42
|
self.content_types = content_types
|
|
44
43
|
self.status_codes = status_codes
|
|
@@ -48,14 +47,12 @@ class SchemaResponse(BaseModel):
|
|
|
48
47
|
|
|
49
48
|
@property
|
|
50
49
|
def has_body(self) -> bool:
|
|
51
|
-
"""Tell if that response defines a body.
|
|
52
|
-
"""
|
|
50
|
+
"""Tell if that response defines a body."""
|
|
53
51
|
return bool(self.schema)
|
|
54
52
|
|
|
55
53
|
@property
|
|
56
54
|
def has_headers(self) -> bool:
|
|
57
|
-
"""Tell if that response defines headers.
|
|
58
|
-
"""
|
|
55
|
+
"""Tell if that response defines headers."""
|
|
59
56
|
return bool(self.headers)
|
|
60
57
|
|
|
61
58
|
@property
|
|
@@ -105,27 +102,35 @@ class SchemaResponse(BaseModel):
|
|
|
105
102
|
def imports(self, code_model) -> FileImport:
|
|
106
103
|
file_import = FileImport()
|
|
107
104
|
if not code_model.options["models_mode"] and self.is_xml:
|
|
108
|
-
file_import.add_submodule_import(
|
|
105
|
+
file_import.add_submodule_import(
|
|
106
|
+
"xml.etree", "ElementTree", ImportType.STDLIB, alias="ET"
|
|
107
|
+
)
|
|
109
108
|
return file_import
|
|
110
109
|
|
|
111
110
|
@classmethod
|
|
112
|
-
def from_yaml(
|
|
111
|
+
def from_yaml(
|
|
112
|
+
cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
|
|
113
|
+
) -> "SchemaResponse":
|
|
113
114
|
binary = yaml_data.get("binary", False)
|
|
114
115
|
if binary:
|
|
115
|
-
schema: BaseSchema = IOSchema(
|
|
116
|
+
schema: BaseSchema = IOSchema(yaml_data={}, code_model=code_model)
|
|
116
117
|
else:
|
|
117
118
|
schema = get_schema(code_model, yaml_data.get("schema"))
|
|
118
119
|
return cls(
|
|
119
|
-
code_model=code_model,
|
|
120
120
|
yaml_data=yaml_data,
|
|
121
|
+
code_model=code_model,
|
|
121
122
|
schema=schema,
|
|
122
123
|
content_types=yaml_data["protocol"]["http"].get("mediaTypes", []),
|
|
123
124
|
status_codes=[
|
|
124
|
-
int(code) if code != "default" else "default"
|
|
125
|
+
int(code) if code != "default" else "default"
|
|
126
|
+
for code in yaml_data["protocol"]["http"]["statusCodes"]
|
|
125
127
|
],
|
|
126
128
|
headers=[
|
|
127
129
|
HeaderResponse(
|
|
128
|
-
header_prop["header"],
|
|
130
|
+
header_prop["header"],
|
|
131
|
+
get_schema(
|
|
132
|
+
code_model, header_prop["schema"], header_prop["header"]
|
|
133
|
+
),
|
|
129
134
|
)
|
|
130
135
|
for header_prop in yaml_data["protocol"]["http"].get("headers", [])
|
|
131
136
|
],
|
|
@@ -14,9 +14,12 @@ if TYPE_CHECKING:
|
|
|
14
14
|
|
|
15
15
|
_LOGGER = logging.getLogger(__name__)
|
|
16
16
|
|
|
17
|
-
JSON_REGEXP = re.compile(r
|
|
17
|
+
JSON_REGEXP = re.compile(r"^(application|text)/(.+\+)?json$")
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
|
|
20
|
+
def get_schema(
|
|
21
|
+
code_model: "CodeModel", schema: Any, serialized_name: str = "unknown"
|
|
22
|
+
) -> BaseSchema:
|
|
20
23
|
if not isinstance(schema, dict):
|
|
21
24
|
return schema
|
|
22
25
|
schema_id = id(schema)
|