Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pass-thru:
- subset-reducer
version: ~3.0.6306
use-extension:
"@autorest/modelerfour": 4.15.407
"@autorest/modelerfour": 4.15.410

modelerfour:
group-parameters: true
Expand Down
78 changes: 17 additions & 61 deletions autorest/codegen/models/operation.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
T = TypeVar('T')
OrderedSet = Dict[T, None]

_m4_header_parameters = ["content_type", "accept"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By convention module level variable should be upper case


def _non_binary_schema_media_types(media_types: List[str]) -> OrderedSet[str]:
response_media_types: OrderedSet[str] = {}
Expand All @@ -44,50 +45,23 @@ def _non_binary_schema_media_types(media_types: List[str]) -> OrderedSet[str]:
response_media_types[xml_media_types[0]] = None
return response_media_types

def _remove_multiple_content_type_parameters(parameters: List[Parameter]) -> List[Parameter]:
content_type_params = [p for p in parameters if p.serialized_name == "content_type"]
remaining_params = [p for p in parameters if p.serialized_name != "content_type"]
json_content_type_param = [p for p in content_type_params if p.yaml_data["schema"]["type"] == "constant"]
if json_content_type_param:
remaining_params.append(json_content_type_param[0])
else:
remaining_params.append(content_type_params[0])
return remaining_params

def _accept_content_type_helper(responses: List[SchemaResponse]) -> OrderedSet[str]:
media_types = {
media_type: None for response in responses for media_type in response.media_types
}

if not media_types:
return media_types

if len(media_types.keys()) == 1:
# if there's just one media type, we return it
return media_types
# if not, we want to return them as binary_media_types + non_binary_media types
binary_media_types = {
media_type: None for media_type in list(media_types.keys())
if not "json" in media_type and not "xml" in media_type
def _remove_multiple_m4_header_parameters(parameters: List[Parameter]) -> List[Parameter]:
m4_header_params_in_schema = {
k: [p for p in parameters if p.serialized_name == k]
for k in _m4_header_parameters
}
non_binary_schema_media_types = {
media_type: None for media_type in list(media_types.keys())
if "json" in media_type or "xml" in media_type
remaining_params = [p for p in parameters if p.serialized_name not in _m4_header_parameters]
json_m4_header_params = {
k: [p for p in m4_header_params_in_schema[k] if p.yaml_data["schema"]["type"] == "constant"]
for k in m4_header_params_in_schema
}
if all([response.binary for response in responses]):
response_media_types = binary_media_types
elif all([response.schema for response in responses]):
response_media_types = _non_binary_schema_media_types(
list(non_binary_schema_media_types.keys())
)
else:
non_binary_schema_media_types = _non_binary_schema_media_types(
list(non_binary_schema_media_types.keys())
)
response_media_types = binary_media_types
response_media_types.update(non_binary_schema_media_types)
for k, v in json_m4_header_params.items():
if v:
remaining_params.append(v[0])
else:
remaining_params.append(m4_header_params_in_schema[k][0])

return response_media_types
return remaining_params

class Operation(BaseModel): # pylint: disable=too-many-public-methods, too-many-instance-attributes
"""Represent an operation.
Expand Down Expand Up @@ -140,24 +114,6 @@ def request_content_type(self) -> str:
]
))

@property
def accept_content_type(self) -> str:
if not self.has_response_body:
raise TypeError(
"There is an error in the code model we're being supplied. We're getting response media types " +
f"even though no response of {self.name} has a body"
)
response_content_types = _accept_content_type_helper(self.responses)
response_content_types.update(_accept_content_type_helper(self.exceptions))

if not response_content_types.keys():
raise TypeError(
f"Operation {self.name} has tried to get its accept_content_type even though it has no media types"
)

return ", ".join(list(response_content_types.keys()))


@property
def is_stream_request(self) -> bool:
"""Is the request is a stream, like an upload."""
Expand Down Expand Up @@ -339,7 +295,7 @@ def from_yaml(cls, yaml_data: Dict[str, Any]) -> "Operation":
for request in yaml_data["requests"]:
for yaml in request.get("parameters", []):
parameter = Parameter.from_yaml(yaml)
if yaml["language"]["python"]["name"] == "content_type":
if yaml["language"]["python"]["name"] in _m4_header_parameters:
parameter.is_kwarg = True
parameters.append(parameter)
elif multiple_requests:
Expand All @@ -348,7 +304,7 @@ def from_yaml(cls, yaml_data: Dict[str, Any]) -> "Operation":
parameters.append(parameter)

if multiple_requests:
parameters = _remove_multiple_content_type_parameters(parameters)
parameters = _remove_multiple_m4_header_parameters(parameters)
chosen_parameter = multiple_media_type_parameters[0]

# binary body parameters are required, while object
Expand Down
3 changes: 0 additions & 3 deletions autorest/codegen/templates/operation_tools.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,6 @@ if {{ header_parameter.full_serialized_name }} is not None:
header_parameters['{{ header_parameter.rest_api_name }}'] = {{ operation.build_serialize_data_call(header_parameter, "header") }}
{% endif %}
{% endfor %}
{% endif %}
{% if operation.has_response_body %}
header_parameters['Accept'] = '{{ operation.accept_content_type }}'
{% endif %}{% endmacro %}
{# helper for stream body params #}
{% macro stream_body_params(operation) %}body_content_kwargs['stream_content'] = {{ operation.parameters.body[0].serialized_name }}{% endmacro %}
Expand Down
15 changes: 10 additions & 5 deletions autorest/namer/name_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,14 @@ def _convert_object_schema(schema: Dict[str, Any]) -> None:
for prop in schema.get("properties", []):
NameConverter._convert_language_default_python_case(schema=prop, pad_string=PadType.Property)

@staticmethod
def _is_schema_an_m4_header_parameter(schema_name: str, schema: Dict[str, Any]) -> bool:
m4_header_parameters = ["content_type", "accept"]
return (
schema_name in m4_header_parameters and
schema.get('protocol', {}).get('http', {}).get('in', {}) == 'header'
)

@staticmethod
def _convert_language_default_python_case(
schema: Dict[str, Any],
Expand All @@ -111,11 +119,8 @@ def _convert_language_default_python_case(
schema_name = schema['language']['default']['name']
schema_python_name = schema['language']['python']['name']

if not(
schema_name == 'content_type' and
schema.get('protocol') and
schema['protocol'].get('http') and
schema['protocol']['http']['in'] == "header"
if not NameConverter._is_schema_an_m4_header_parameter(
schema_name, schema
):
# only escaping name if it's not a content_type header parameter
schema_python_name = NameConverter._to_valid_python_name(
Expand Down
1 change: 1 addition & 0 deletions autorest/namer/python_mappings.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ class PadType(Enum):
"self",
# these are kwargs we've reserved for our autorest generated operations
"content_type",
"accept",
"cls",
"polling",
"continuation_token", # for LRO calls
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ async def get_null(
cls = kwargs.pop('cls', None) # type: ClsType[datetime.timedelta]
error_map = {404: ResourceNotFoundError, 409: ResourceExistsError}
error_map.update(kwargs.pop('error_map', {}))
accept = "application/json"

# Construct URL
url = self.get_null.metadata['url'] # type: ignore
Expand All @@ -65,7 +66,7 @@ async def get_null(

# Construct headers
header_parameters = {} # type: Dict[str, Any]
header_parameters['Accept'] = 'application/json'
header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')

request = self._client.get(url, query_parameters, header_parameters)
pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
Expand Down Expand Up @@ -103,6 +104,7 @@ async def put_positive_duration(
error_map = {404: ResourceNotFoundError, 409: ResourceExistsError}
error_map.update(kwargs.pop('error_map', {}))
content_type = kwargs.pop("content_type", "application/json")
accept = "application/json"

# Construct URL
url = self.put_positive_duration.metadata['url'] # type: ignore
Expand All @@ -113,6 +115,7 @@ async def put_positive_duration(
# Construct headers
header_parameters = {} # type: Dict[str, Any]
header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')

body_content_kwargs = {} # type: Dict[str, Any]
body_content = self._serialize.body(duration_body, 'duration')
Expand Down Expand Up @@ -146,6 +149,7 @@ async def get_positive_duration(
cls = kwargs.pop('cls', None) # type: ClsType[datetime.timedelta]
error_map = {404: ResourceNotFoundError, 409: ResourceExistsError}
error_map.update(kwargs.pop('error_map', {}))
accept = "application/json"

# Construct URL
url = self.get_positive_duration.metadata['url'] # type: ignore
Expand All @@ -155,7 +159,7 @@ async def get_positive_duration(

# Construct headers
header_parameters = {} # type: Dict[str, Any]
header_parameters['Accept'] = 'application/json'
header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')

request = self._client.get(url, query_parameters, header_parameters)
pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
Expand Down Expand Up @@ -189,6 +193,7 @@ async def get_invalid(
cls = kwargs.pop('cls', None) # type: ClsType[datetime.timedelta]
error_map = {404: ResourceNotFoundError, 409: ResourceExistsError}
error_map.update(kwargs.pop('error_map', {}))
accept = "application/json"

# Construct URL
url = self.get_invalid.metadata['url'] # type: ignore
Expand All @@ -198,7 +203,7 @@ async def get_invalid(

# Construct headers
header_parameters = {} # type: Dict[str, Any]
header_parameters['Accept'] = 'application/json'
header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')

request = self._client.get(url, query_parameters, header_parameters)
pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ def get_null(
cls = kwargs.pop('cls', None) # type: ClsType[datetime.timedelta]
error_map = {404: ResourceNotFoundError, 409: ResourceExistsError}
error_map.update(kwargs.pop('error_map', {}))
accept = "application/json"

# Construct URL
url = self.get_null.metadata['url'] # type: ignore
Expand All @@ -70,7 +71,7 @@ def get_null(

# Construct headers
header_parameters = {} # type: Dict[str, Any]
header_parameters['Accept'] = 'application/json'
header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')

request = self._client.get(url, query_parameters, header_parameters)
pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
Expand Down Expand Up @@ -109,6 +110,7 @@ def put_positive_duration(
error_map = {404: ResourceNotFoundError, 409: ResourceExistsError}
error_map.update(kwargs.pop('error_map', {}))
content_type = kwargs.pop("content_type", "application/json")
accept = "application/json"

# Construct URL
url = self.put_positive_duration.metadata['url'] # type: ignore
Expand All @@ -119,6 +121,7 @@ def put_positive_duration(
# Construct headers
header_parameters = {} # type: Dict[str, Any]
header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')

body_content_kwargs = {} # type: Dict[str, Any]
body_content = self._serialize.body(duration_body, 'duration')
Expand Down Expand Up @@ -153,6 +156,7 @@ def get_positive_duration(
cls = kwargs.pop('cls', None) # type: ClsType[datetime.timedelta]
error_map = {404: ResourceNotFoundError, 409: ResourceExistsError}
error_map.update(kwargs.pop('error_map', {}))
accept = "application/json"

# Construct URL
url = self.get_positive_duration.metadata['url'] # type: ignore
Expand All @@ -162,7 +166,7 @@ def get_positive_duration(

# Construct headers
header_parameters = {} # type: Dict[str, Any]
header_parameters['Accept'] = 'application/json'
header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')

request = self._client.get(url, query_parameters, header_parameters)
pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
Expand Down Expand Up @@ -197,6 +201,7 @@ def get_invalid(
cls = kwargs.pop('cls', None) # type: ClsType[datetime.timedelta]
error_map = {404: ResourceNotFoundError, 409: ResourceExistsError}
error_map.update(kwargs.pop('error_map', {}))
accept = "application/json"

# Construct URL
url = self.get_invalid.metadata['url'] # type: ignore
Expand All @@ -206,7 +211,7 @@ def get_invalid(

# Construct headers
header_parameters = {} # type: Dict[str, Any]
header_parameters['Accept'] = 'application/json'
header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')

request = self._client.get(url, query_parameters, header_parameters)
pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ async def post_required(
_path = parameter_grouping_post_required_parameters.path
_body = parameter_grouping_post_required_parameters.body
content_type = kwargs.pop("content_type", "application/json")
accept = "application/json"

# Construct URL
url = self.post_required.metadata['url'] # type: ignore
Expand All @@ -87,6 +88,7 @@ async def post_required(
if _custom_header is not None:
header_parameters['customHeader'] = self._serialize.header("custom_header", _custom_header, 'str')
header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')

body_content_kwargs = {} # type: Dict[str, Any]
body_content = self._serialize.body(_body, 'int')
Expand Down Expand Up @@ -129,6 +131,7 @@ async def post_optional(
if parameter_grouping_post_optional_parameters is not None:
_custom_header = parameter_grouping_post_optional_parameters.custom_header
_query = parameter_grouping_post_optional_parameters.query
accept = "application/json"

# Construct URL
url = self.post_optional.metadata['url'] # type: ignore
Expand All @@ -142,6 +145,7 @@ async def post_optional(
header_parameters = {} # type: Dict[str, Any]
if _custom_header is not None:
header_parameters['customHeader'] = self._serialize.header("custom_header", _custom_header, 'str')
header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')

request = self._client.post(url, query_parameters, header_parameters)
pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
Expand Down Expand Up @@ -189,6 +193,7 @@ async def post_multi_param_groups(
if parameter_grouping_post_multi_param_groups_second_param_group is not None:
_header_two = parameter_grouping_post_multi_param_groups_second_param_group.header_two
_query_two = parameter_grouping_post_multi_param_groups_second_param_group.query_two
accept = "application/json"

# Construct URL
url = self.post_multi_param_groups.metadata['url'] # type: ignore
Expand All @@ -206,6 +211,7 @@ async def post_multi_param_groups(
header_parameters['header-one'] = self._serialize.header("header_one", _header_one, 'str')
if _header_two is not None:
header_parameters['header-two'] = self._serialize.header("header_two", _header_two, 'str')
header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')

request = self._client.post(url, query_parameters, header_parameters)
pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
Expand Down Expand Up @@ -245,6 +251,7 @@ async def post_shared_parameter_group_object(
if first_parameter_group is not None:
_header_one = first_parameter_group.header_one
_query_one = first_parameter_group.query_one
accept = "application/json"

# Construct URL
url = self.post_shared_parameter_group_object.metadata['url'] # type: ignore
Expand All @@ -258,6 +265,7 @@ async def post_shared_parameter_group_object(
header_parameters = {} # type: Dict[str, Any]
if _header_one is not None:
header_parameters['header-one'] = self._serialize.header("header_one", _header_one, 'str')
header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')

request = self._client.post(url, query_parameters, header_parameters)
pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
Expand Down
Loading