@autorest/python 5.13.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.
Files changed (101) hide show
  1. package/ChangeLog.md +67 -0
  2. package/autorest/__init__.py +1 -2
  3. package/autorest/black/__init__.py +12 -5
  4. package/autorest/codegen/__init__.py +239 -105
  5. package/autorest/codegen/models/__init__.py +29 -18
  6. package/autorest/codegen/models/base_builder.py +48 -11
  7. package/autorest/codegen/models/base_model.py +6 -4
  8. package/autorest/codegen/models/base_schema.py +21 -24
  9. package/autorest/codegen/models/client.py +70 -20
  10. package/autorest/codegen/models/code_model.py +144 -129
  11. package/autorest/codegen/models/constant_schema.py +32 -16
  12. package/autorest/codegen/models/credential_model.py +55 -0
  13. package/autorest/codegen/models/credential_schema.py +21 -16
  14. package/autorest/codegen/models/credential_schema_policy.py +11 -15
  15. package/autorest/codegen/models/dictionary_schema.py +27 -24
  16. package/autorest/codegen/models/enum_schema.py +41 -62
  17. package/autorest/codegen/models/imports.py +72 -41
  18. package/autorest/codegen/models/list_schema.py +40 -18
  19. package/autorest/codegen/models/lro_operation.py +61 -25
  20. package/autorest/codegen/models/lro_paging_operation.py +5 -6
  21. package/autorest/codegen/models/object_schema.py +113 -59
  22. package/autorest/codegen/models/operation.py +251 -111
  23. package/autorest/codegen/models/operation_group.py +67 -32
  24. package/autorest/codegen/models/paging_operation.py +48 -21
  25. package/autorest/codegen/models/parameter.py +182 -90
  26. package/autorest/codegen/models/parameter_list.py +184 -163
  27. package/autorest/codegen/models/primitive_schemas.py +89 -70
  28. package/autorest/codegen/models/property.py +49 -31
  29. package/autorest/codegen/models/request_builder.py +67 -32
  30. package/autorest/codegen/models/request_builder_parameter.py +54 -23
  31. package/autorest/codegen/models/request_builder_parameter_list.py +77 -108
  32. package/autorest/codegen/models/schema_request.py +16 -6
  33. package/autorest/codegen/models/schema_response.py +35 -17
  34. package/autorest/codegen/models/utils.py +24 -1
  35. package/autorest/codegen/serializers/__init__.py +273 -89
  36. package/autorest/codegen/serializers/builder_serializer.py +711 -333
  37. package/autorest/codegen/serializers/client_serializer.py +114 -43
  38. package/autorest/codegen/serializers/general_serializer.py +84 -25
  39. package/autorest/codegen/serializers/import_serializer.py +93 -31
  40. package/autorest/codegen/serializers/metadata_serializer.py +73 -24
  41. package/autorest/codegen/serializers/model_base_serializer.py +42 -14
  42. package/autorest/codegen/serializers/model_generic_serializer.py +1 -4
  43. package/autorest/codegen/serializers/model_init_serializer.py +5 -1
  44. package/autorest/codegen/serializers/model_python3_serializer.py +9 -8
  45. package/autorest/codegen/serializers/operation_groups_serializer.py +20 -8
  46. package/autorest/codegen/serializers/operations_init_serializer.py +23 -11
  47. package/autorest/codegen/serializers/patch_serializer.py +14 -2
  48. package/autorest/codegen/serializers/{rest_serializer.py → request_builders_serializer.py} +29 -12
  49. package/autorest/codegen/serializers/utils.py +60 -21
  50. package/autorest/codegen/templates/CHANGELOG.md.jinja2 +6 -0
  51. package/autorest/codegen/templates/LICENSE.jinja2 +21 -0
  52. package/autorest/codegen/templates/MANIFEST.in.jinja2 +7 -0
  53. package/autorest/codegen/templates/README.md.jinja2 +105 -0
  54. package/autorest/codegen/templates/config.py.jinja2 +4 -4
  55. package/autorest/codegen/templates/dev_requirements.txt.jinja2 +10 -0
  56. package/autorest/codegen/templates/enum.py.jinja2 +1 -1
  57. package/autorest/codegen/templates/enum_container.py.jinja2 +0 -1
  58. package/autorest/codegen/templates/init.py.jinja2 +9 -6
  59. package/autorest/codegen/templates/keywords.jinja2 +14 -1
  60. package/autorest/codegen/templates/lro_operation.py.jinja2 +5 -7
  61. package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +5 -7
  62. package/autorest/codegen/templates/metadata.json.jinja2 +10 -9
  63. package/autorest/codegen/templates/model.py.jinja2 +1 -6
  64. package/autorest/codegen/templates/model_init.py.jinja2 +7 -4
  65. package/autorest/codegen/templates/operation.py.jinja2 +8 -11
  66. package/autorest/codegen/templates/operation_group.py.jinja2 +15 -18
  67. package/autorest/codegen/templates/operation_groups_container.py.jinja2 +1 -2
  68. package/autorest/codegen/templates/operations_folder_init.py.jinja2 +4 -0
  69. package/autorest/codegen/templates/paging_operation.py.jinja2 +7 -8
  70. package/autorest/codegen/templates/patch.py.jinja2 +18 -29
  71. package/autorest/codegen/templates/request_builder.py.jinja2 +19 -14
  72. package/autorest/codegen/templates/setup.py.jinja2 +79 -20
  73. package/autorest/codegen/templates/vendor.py.jinja2 +12 -2
  74. package/autorest/jsonrpc/__init__.py +7 -12
  75. package/autorest/jsonrpc/localapi.py +4 -3
  76. package/autorest/jsonrpc/server.py +13 -6
  77. package/autorest/jsonrpc/stdstream.py +13 -6
  78. package/autorest/m2r/__init__.py +5 -8
  79. package/autorest/multiapi/__init__.py +24 -14
  80. package/autorest/multiapi/models/client.py +21 -11
  81. package/autorest/multiapi/models/code_model.py +23 -10
  82. package/autorest/multiapi/models/config.py +4 -1
  83. package/autorest/multiapi/models/constant_global_parameter.py +1 -0
  84. package/autorest/multiapi/models/global_parameter.py +2 -1
  85. package/autorest/multiapi/models/global_parameters.py +14 -8
  86. package/autorest/multiapi/models/imports.py +35 -18
  87. package/autorest/multiapi/models/mixin_operation.py +5 -5
  88. package/autorest/multiapi/models/operation_group.py +2 -1
  89. package/autorest/multiapi/models/operation_mixin_group.py +21 -10
  90. package/autorest/multiapi/serializers/__init__.py +18 -23
  91. package/autorest/multiapi/serializers/import_serializer.py +47 -15
  92. package/autorest/multiapi/serializers/multiapi_serializer.py +17 -17
  93. package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +1 -1
  94. package/autorest/multiapi/utils.py +3 -3
  95. package/autorest/namer/__init__.py +2 -4
  96. package/autorest/namer/name_converter.py +200 -103
  97. package/autorest/namer/python_mappings.py +10 -22
  98. package/package.json +3 -3
  99. package/run-python3.js +2 -3
  100. package/venvtools.py +1 -1
  101. package/autorest/codegen/models/rest.py +0 -42
@@ -3,7 +3,8 @@
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, TypeVar, Optional
6
+ from typing import Any, Dict, List, TypeVar, Optional, TYPE_CHECKING
7
+ import logging
7
8
 
8
9
  from .base_builder import BaseBuilder, create_parameters
9
10
  from .request_builder_parameter import RequestBuilderParameter
@@ -13,15 +14,20 @@ from .schema_response import SchemaResponse
13
14
  from .imports import FileImport, ImportType, TypingSection
14
15
  from .parameter import Parameter
15
16
 
17
+ if TYPE_CHECKING:
18
+ from .code_model import CodeModel
16
19
 
17
- T = TypeVar('T')
20
+ _LOGGER = logging.getLogger(__name__)
21
+
22
+ T = TypeVar("T")
18
23
  OrderedSet = Dict[T, None]
19
24
 
25
+
20
26
  class RequestBuilder(BaseBuilder):
21
27
  def __init__(
22
28
  self,
23
- code_model,
24
29
  yaml_data: Dict[str, Any],
30
+ code_model: "CodeModel",
25
31
  name: str,
26
32
  url: str,
27
33
  method: str,
@@ -31,16 +37,20 @@ class RequestBuilder(BaseBuilder):
31
37
  description: str,
32
38
  summary: str,
33
39
  responses: Optional[List[SchemaResponse]] = None,
40
+ *,
41
+ abstract: bool = False,
34
42
  ):
35
43
  super().__init__(
36
- code_model=code_model,
37
44
  yaml_data=yaml_data,
45
+ code_model=code_model,
38
46
  name=name,
39
47
  description=description,
40
48
  parameters=parameters,
41
49
  responses=responses,
42
50
  schema_requests=schema_requests,
43
51
  summary=summary,
52
+ abstract=abstract,
53
+ want_tracing=False,
44
54
  )
45
55
  self.url = url
46
56
  self.method = method
@@ -65,64 +75,86 @@ class RequestBuilder(BaseBuilder):
65
75
 
66
76
  def imports(self) -> FileImport:
67
77
  file_import = FileImport()
68
- for parameter in self.parameters:
69
- if parameter.need_import:
70
- file_import.merge(parameter.imports())
78
+ for parameter in self.parameters.method:
79
+ if self.abstract and (parameter.is_multipart or parameter.is_data_input):
80
+ continue
81
+ file_import.merge(parameter.imports())
71
82
 
72
83
  file_import.add_submodule_import(
73
84
  "azure.core.rest",
74
85
  "HttpRequest",
75
86
  ImportType.AZURECORE,
76
87
  )
77
- if self.parameters.path:
78
- relative_path = ".."
79
- if not self.code_model.options["builders_visibility"] == "embedded" and self.operation_group_name:
80
- relative_path = "..." if self.operation_group_name else ".."
81
- file_import.add_submodule_import(
82
- f"{relative_path}_vendor", "_format_url_section", ImportType.LOCAL
83
- )
84
- if self.parameters.headers or self.parameters.query:
85
- file_import.add_submodule_import(
86
- "typing", "Dict", ImportType.STDLIB, typing_section=TypingSection.CONDITIONAL
87
- )
88
+ if not self.abstract:
89
+ if self.parameters.path:
90
+ relative_path = ".."
91
+ if (
92
+ not self.code_model.options["builders_visibility"] == "embedded"
93
+ and self.operation_group_name
94
+ ):
95
+ relative_path = "..." if self.operation_group_name else ".."
96
+ file_import.add_submodule_import(
97
+ f"{relative_path}_vendor", "_format_url_section", ImportType.LOCAL
98
+ )
99
+ if self.parameters.headers or self.parameters.query:
100
+ file_import.add_submodule_import(
101
+ "azure.core.utils", "case_insensitive_dict", ImportType.AZURECORE
102
+ )
88
103
  file_import.add_submodule_import(
89
104
  "typing", "Any", ImportType.STDLIB, typing_section=TypingSection.CONDITIONAL
90
105
  )
91
106
  file_import.add_submodule_import("msrest", "Serializer", ImportType.THIRDPARTY)
92
- if self.parameters.has_body and (
93
- self.code_model.options["builders_visibility"] != "embedded" or
94
- self.code_model.options["add_python3_operation_files"]
95
- ):
96
- file_import.define_mypy_type("JSONType", "Any")
97
107
  return file_import
98
108
 
99
109
  @classmethod
100
- def from_yaml(cls, yaml_data: Dict[str, Any], *, code_model) -> "RequestBuilder":
110
+ def from_yaml(
111
+ cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
112
+ ) -> "RequestBuilder":
101
113
 
102
114
  # when combine embeded builders into one operation file, we need to avoid duplicated build function name.
103
115
  # So add operation group name is effective method
104
116
  additional_mark = ""
105
- if code_model.options["combine_operation_files"] and code_model.options["builders_visibility"] == "embedded":
117
+ if (
118
+ code_model.options["combine_operation_files"]
119
+ and code_model.options["builders_visibility"] == "embedded"
120
+ ):
106
121
  additional_mark = yaml_data["language"]["python"]["builderGroupName"]
107
122
  names = [
108
123
  "build",
109
124
  additional_mark,
110
125
  yaml_data["language"]["python"]["name"],
111
- "request"
126
+ "request",
112
127
  ]
113
128
  name = "_".join([n for n in names if n])
114
129
 
115
130
  first_request = yaml_data["requests"][0]
116
- schema_requests = [SchemaRequest.from_yaml(yaml, code_model=code_model) for yaml in yaml_data["requests"]]
117
- parameters, multiple_content_type_parameters = (
118
- create_parameters(yaml_data, code_model, RequestBuilderParameter.from_yaml)
131
+ schema_requests = [
132
+ SchemaRequest.from_yaml(yaml, code_model=code_model)
133
+ for yaml in yaml_data["requests"]
134
+ ]
135
+ parameters, multiple_content_type_parameters = create_parameters(
136
+ yaml_data, code_model, RequestBuilderParameter.from_yaml
119
137
  )
120
138
  parameter_list = RequestBuilderParameterList(
121
139
  code_model, parameters + multiple_content_type_parameters, schema_requests
122
140
  )
141
+ abstract = False
142
+ if (
143
+ code_model.options["version_tolerant"]
144
+ or code_model.options["low_level_client"]
145
+ ) and any(p for p in parameter_list if p.is_multipart or p.is_data_input):
146
+ _LOGGER.warning(
147
+ 'Not going to generate request_builder "%s" because it has multipart / urlencoded '
148
+ "body parameters. Multipart / urlencoded body parameters are not supported for version "
149
+ "tolerant and low level generations right now. Please write your own custom operation "
150
+ "in the _patch.py file following https://aka.ms/azsdk/python/dpcodegen/python/customize.",
151
+ name,
152
+ )
153
+ abstract = True
154
+
123
155
  request_builder_class = cls(
124
- code_model=code_model,
125
156
  yaml_data=yaml_data,
157
+ code_model=code_model,
126
158
  name=name,
127
159
  url=first_request["protocol"]["http"]["path"],
128
160
  method=first_request["protocol"]["http"]["method"].upper(),
@@ -130,9 +162,12 @@ class RequestBuilder(BaseBuilder):
130
162
  schema_requests=schema_requests,
131
163
  parameters=parameter_list,
132
164
  description=yaml_data["language"]["python"]["description"],
133
- responses=[SchemaResponse.from_yaml(yaml) for yaml in yaml_data.get("responses", [])],
165
+ responses=[
166
+ SchemaResponse.from_yaml(yaml, code_model=code_model)
167
+ for yaml in yaml_data.get("responses", [])
168
+ ],
134
169
  summary=yaml_data["language"]["python"].get("summary"),
170
+ abstract=abstract,
135
171
  )
136
- code_model.request_builder_ids[id(yaml_data)] = request_builder_class
137
172
  parameter_list.add_body_kwargs()
138
173
  return request_builder_class
@@ -3,21 +3,32 @@
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 ParameterOnlyPathAndBodyPositional, ParameterLocation, ParameterStyle
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
+ )
14
+ from .utils import get_schema
15
+
16
+ if TYPE_CHECKING:
17
+ from .code_model import CodeModel
18
+
8
19
 
9
20
  def _make_public(name):
10
21
  if name[0] == "_":
11
22
  return name[1:]
12
23
  return name
13
24
 
14
- class RequestBuilderParameter(ParameterOnlyPathAndBodyPositional):
15
25
 
26
+ class RequestBuilderParameter(ParameterOnlyPathAndBodyPositional):
16
27
  @property
17
28
  def in_method_signature(self) -> bool:
18
- return not(
19
- # don't put accept in method signature
20
- self.rest_api_name == "Accept"
29
+ return not (
30
+ # if not inputtable, don't put in signature
31
+ not self.inputtable_by_user
21
32
  # If i'm not in the method code, no point in being in signature
22
33
  or not self.in_method_code
23
34
  # If I'm a flattened property of a body, don't want me, want the body param
@@ -27,11 +38,6 @@ class RequestBuilderParameter(ParameterOnlyPathAndBodyPositional):
27
38
 
28
39
  @property
29
40
  def name_in_high_level_operation(self) -> str:
30
- template = "{}" if self.code_model.options["version_tolerant"] else "_{}"
31
- if self.is_multipart:
32
- return template.format("files")
33
- if self.is_data_input:
34
- return template.format("data")
35
41
  if self.is_body and not self.constant:
36
42
  return f"_{self.serialized_name}"
37
43
  name = self.yaml_data["language"]["python"]["name"]
@@ -59,13 +65,20 @@ class RequestBuilderParameter(ParameterOnlyPathAndBodyPositional):
59
65
  return super().default_value_declaration
60
66
 
61
67
  @property
62
- def is_keyword_only(self) -> bool:
63
- return not self.location == ParameterLocation.Path and not self.is_kwarg
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
64
78
 
65
- @is_keyword_only.setter
66
- def is_keyword_only(self, val: bool) -> None:
67
- self._keyword_only = val
68
- self.is_kwarg = False
79
+ @method_location.setter
80
+ def method_location(self, val: ParameterMethodLocation) -> None:
81
+ self._method_location = val
69
82
 
70
83
  @property
71
84
  def full_serialized_name(self) -> str:
@@ -73,15 +86,29 @@ class RequestBuilderParameter(ParameterOnlyPathAndBodyPositional):
73
86
 
74
87
  @classmethod
75
88
  def from_yaml(
76
- cls, yaml_data: Dict[str, Any], *, code_model, content_types: Optional[List[str]] = None
89
+ cls,
90
+ yaml_data: Dict[str, Any],
91
+ code_model: "CodeModel",
92
+ *,
93
+ content_types: Optional[List[str]] = None,
77
94
  ) -> "RequestBuilderParameter":
78
- http_protocol = yaml_data["protocol"].get("http", {"in": ParameterLocation.Other})
95
+ http_protocol = yaml_data["protocol"].get(
96
+ "http", {"in": ParameterLocation.Other}
97
+ )
79
98
  name = yaml_data["language"]["python"]["name"]
80
99
  location = ParameterLocation(http_protocol["in"])
100
+ serialized_name = yaml_data["language"]["python"]["name"]
101
+ schema = get_schema(code_model, yaml_data.get("schema"), serialized_name)
102
+ target_property = yaml_data.get("targetProperty")
103
+ target_property_name = (
104
+ get_target_property_name(code_model, id(target_property))
105
+ if target_property
106
+ else None
107
+ )
81
108
  return cls(
82
109
  code_model=code_model,
83
110
  yaml_data=yaml_data,
84
- schema=yaml_data.get("schema", None), # FIXME replace by operation model
111
+ schema=schema,
85
112
  # See also https://github.com/Azure/autorest.modelerfour/issues/80
86
113
  rest_api_name=yaml_data["language"]["default"].get(
87
114
  "serializedName", yaml_data["language"]["default"]["name"]
@@ -91,10 +118,14 @@ class RequestBuilderParameter(ParameterOnlyPathAndBodyPositional):
91
118
  implementation=yaml_data["implementation"],
92
119
  required=yaml_data.get("required", False),
93
120
  location=location,
94
- skip_url_encoding=yaml_data.get("extensions", {}).get("x-ms-skip-url-encoding", False),
121
+ skip_url_encoding=yaml_data.get("extensions", {}).get(
122
+ "x-ms-skip-url-encoding", False
123
+ ),
95
124
  constraints=[], # FIXME constraints
96
- target_property_name=id(yaml_data["targetProperty"]) if yaml_data.get("targetProperty") else None,
97
- style=ParameterStyle(http_protocol["style"]) if "style" in http_protocol else None,
125
+ target_property_name=target_property_name,
126
+ style=ParameterStyle(http_protocol["style"])
127
+ if "style" in http_protocol
128
+ else None,
98
129
  explode=http_protocol.get("explode", False),
99
130
  grouped_by=yaml_data.get("groupedBy", None),
100
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 ParameterLocation, Parameter, ParameterStyle
11
- from .primitive_schemas import AnySchema, JSONSchema
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
- T = TypeVar('T')
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
- c for c in content_types_to_assign if c not in param.content_types
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(b for b in body_method_params if b.serialized_name == serialized_name)
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(RequestBuilderParameterList, self).__init__(
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 'json' in body_method_param.serialization_formats:
58
+ if "json" in body_method_param.serialization_formats:
49
59
  return True
50
60
  if not any(
51
- flag for flag in ["version_tolerant", "low_level_client"]
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 for sr in self.schema_requests
58
- if sr.yaml_data.get("protocol", {}).get('http', {}).get('knownMediaType') == "json"
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 for p in self.parameters
74
- if p.location == ParameterLocation.Body
75
- and p.constant
76
- and not p.is_data_input
77
- and not p.is_multipart
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
- json_kwarg.schema = JSONSchema(namespace="", yaml_data={})
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(content_types_to_assign, json_kwarg)
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(namespace="", yaml_data={})
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 for p in self.parameters
166
- if p.location == ParameterLocation.Body and not p.constant
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.is_multipart and _kwarg_not_added(body_kwargs_added, "files"):
173
- content_types_to_assign, file_kwarg = self._add_files_kwarg(
174
- content_types_to_assign, body_method_param
175
- )
176
- body_kwargs_added.append(file_kwarg)
177
-
178
- elif body_method_param.is_data_input and _kwarg_not_added(body_kwargs_added, "data"):
179
- content_types_to_assign, data_kwarg = self._add_data_kwarg(
180
- content_types_to_assign, body_method_param
181
- )
182
- body_kwargs_added.append(data_kwarg)
183
- elif self._is_json(body_method_param) and _kwarg_not_added(body_kwargs_added, "json"):
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 += [k for k in self.keyword_only if not (k.is_body and not k.constant)]
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 or parameter.in_method_code
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
- if (
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
- # if i am a part of files or data, and i'm not the files or
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 and
252
- not parameter.is_body_kwarg and
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([g for g in self.groupers if id(g.yaml_data) == id(parameter.yaml_data)]):
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 = signature_parameters_no_default_value + signature_parameters_default_value
274
- signature_parameters.sort(key=lambda item: item.is_keyword_only)
275
- signature_parameters = self._filter_out_multiple_content_type(signature_parameters)
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