Skip to content

Commit

Permalink
Introduce explode into autorest (#705)
Browse files Browse the repository at this point in the history
* Introduce explode into autorest

* Model null element of a multi array as empty string

* Update parameter.py

* Pylint

* ChangeLog

Co-authored-by: iscai-msft <[email protected]>
  • Loading branch information
lmazuel and iscai-msft authored Aug 11, 2020
1 parent 9dbe2d1 commit 1fe8a1a
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 20 deletions.
4 changes: 4 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ Modelerfour version: 4.15.400
- Updated minimum `azure-core` version to 1.8.0 #747
- Updated minimum `msrest` version to 0.6.18 #747

**Bug fixes**

- Fix "multi" in Swagger (will generate correctly multiple query param now)

### 2020-08-07 - 5.1.0-preview.7
Autorest Core version: 3.0.6302
Modelerfour version: 4.15.400
Expand Down
32 changes: 24 additions & 8 deletions autorest/codegen/models/operation.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from .schema_request import SchemaRequest
from .object_schema import ObjectSchema
from .constant_schema import ConstantSchema
from .list_schema import ListSchema


_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -197,7 +198,7 @@ def build_serialize_data_call(parameter: Parameter, function_name: str) -> str:
if parameter.skip_url_encoding:
optional_parameters.append("skip_quote=True")

if parameter.style:
if parameter.style and not parameter.explode:
if parameter.style in [ParameterStyle.simple, ParameterStyle.form]:
div_char = ","
elif parameter.style in [ParameterStyle.spaceDelimited]:
Expand All @@ -210,17 +211,32 @@ def build_serialize_data_call(parameter: Parameter, function_name: str) -> str:
raise ValueError(f"Do not support {parameter.style} yet")
optional_parameters.append(f"div='{div_char}'")

serialization_constraints = parameter.schema.serialization_constraints
optional_parameters += serialization_constraints if serialization_constraints else ""
if parameter.explode:
if not isinstance(parameter.schema, ListSchema):
raise ValueError("Got a explode boolean on a non-array schema")
serialization_schema = parameter.schema.element_type
else:
serialization_schema = parameter.schema

optional_parameters_string = "" if not optional_parameters else ", " + ", ".join(optional_parameters)
serialization_constraints = serialization_schema.serialization_constraints
if serialization_constraints:
optional_parameters += serialization_constraints

origin_name = parameter.full_serialized_name

return (
f"""self._serialize.{function_name}("{origin_name.lstrip('_')}", {origin_name}, """
+ f"""'{parameter.schema.serialization_type}'{optional_parameters_string})"""
)
parameters = [
f'"{origin_name.lstrip("_")}"',
"q" if parameter.explode else origin_name,
f"'{serialization_schema.serialization_type}'",
*optional_parameters
]
parameters_line = ', '.join(parameters)

serialize_line = f'self._serialize.{function_name}({parameters_line})'

if parameter.explode:
return f"[{serialize_line} if q is not None else '' for q in {origin_name}]"
return serialize_line

@property
def serialization_context(self) -> str:
Expand Down
3 changes: 3 additions & 0 deletions autorest/codegen/models/parameter.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def __init__(
constraints: List[Any],
target_property_name: Optional[Union[int, str]] = None, # first uses id as placeholder
style: Optional[ParameterStyle] = None,
explode: Optional[bool] = False,
*,
flattened: bool = False,
grouped_by: Optional["Parameter"] = None,
Expand All @@ -72,6 +73,7 @@ def __init__(
self.constraints = constraints
self.target_property_name = target_property_name
self.style = style
self.explode = explode
self.flattened = flattened
self.grouped_by = grouped_by
self.original_parameter = original_parameter
Expand Down Expand Up @@ -194,6 +196,7 @@ def from_yaml(cls, yaml_data: Dict[str, Any]) -> "Parameter":
constraints=[], # FIXME constraints
target_property_name=id(yaml_data["targetProperty"]) if yaml_data.get("targetProperty") else None,
style=ParameterStyle(http_protocol["style"]) if "style" in http_protocol else None,
explode=http_protocol.get("explode", False),
grouped_by=yaml_data.get("groupedBy", None),
original_parameter=yaml_data.get("originalParameter", None),
flattened=yaml_data.get("flattened", False),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ async def array_string_multi_null(
# Construct parameters
query_parameters = {} # type: Dict[str, Any]
if array_query is not None:
query_parameters['arrayQuery'] = self._serialize.query("array_query", array_query, '[str]', div=',')
query_parameters['arrayQuery'] = [self._serialize.query("array_query", q, 'str') if q is not None else '' for q in array_query]

# Construct headers
header_parameters = {} # type: Dict[str, Any]
Expand All @@ -92,6 +92,8 @@ async def array_string_multi_empty(
) -> None:
"""Get an empty array [] of string using the multi-array format.
No query parameter should be sent, since the array is empty.
:param array_query: an empty array [] of string using the multi-array format.
:type array_query: list[str]
:keyword callable cls: A custom type or function that will be passed the direct response
Expand All @@ -109,7 +111,7 @@ async def array_string_multi_empty(
# Construct parameters
query_parameters = {} # type: Dict[str, Any]
if array_query is not None:
query_parameters['arrayQuery'] = self._serialize.query("array_query", array_query, '[str]', div=',')
query_parameters['arrayQuery'] = [self._serialize.query("array_query", q, 'str') if q is not None else '' for q in array_query]

# Construct headers
header_parameters = {} # type: Dict[str, Any]
Expand All @@ -134,11 +136,13 @@ async def array_string_multi_valid(
array_query: Optional[List[str]] = None,
**kwargs
) -> None:
"""Get an array of string ['ArrayQuery1', 'begin!*'();:@ &=+$,/?#[]end' , null, ''] using the
mult-array format.
"""Get an array of string using the multi-array format.
Parameter is ['ArrayQuery1', 'begin!*'();:@ &=+$,/?#[]end' , null, '']. null is sent as empty
string.
:param array_query: an array of string ['ArrayQuery1', 'begin!*'();:@ &=+$,/?#[]end' , null,
''] using the mult-array format.
''] using the multi-array format.
:type array_query: list[str]
:keyword callable cls: A custom type or function that will be passed the direct response
:return: None, or the result of cls(response)
Expand All @@ -155,7 +159,7 @@ async def array_string_multi_valid(
# Construct parameters
query_parameters = {} # type: Dict[str, Any]
if array_query is not None:
query_parameters['arrayQuery'] = self._serialize.query("array_query", array_query, '[str]', div=',')
query_parameters['arrayQuery'] = [self._serialize.query("array_query", q, 'str') if q is not None else '' for q in array_query]

# Construct headers
header_parameters = {} # type: Dict[str, Any]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def array_string_multi_null(
# Construct parameters
query_parameters = {} # type: Dict[str, Any]
if array_query is not None:
query_parameters['arrayQuery'] = self._serialize.query("array_query", array_query, '[str]', div=',')
query_parameters['arrayQuery'] = [self._serialize.query("array_query", q, 'str') if q is not None else '' for q in array_query]

# Construct headers
header_parameters = {} # type: Dict[str, Any]
Expand Down Expand Up @@ -98,6 +98,8 @@ def array_string_multi_empty(
# type: (...) -> None
"""Get an empty array [] of string using the multi-array format.
No query parameter should be sent, since the array is empty.
:param array_query: an empty array [] of string using the multi-array format.
:type array_query: list[str]
:keyword callable cls: A custom type or function that will be passed the direct response
Expand All @@ -115,7 +117,7 @@ def array_string_multi_empty(
# Construct parameters
query_parameters = {} # type: Dict[str, Any]
if array_query is not None:
query_parameters['arrayQuery'] = self._serialize.query("array_query", array_query, '[str]', div=',')
query_parameters['arrayQuery'] = [self._serialize.query("array_query", q, 'str') if q is not None else '' for q in array_query]

# Construct headers
header_parameters = {} # type: Dict[str, Any]
Expand All @@ -141,11 +143,13 @@ def array_string_multi_valid(
**kwargs # type: Any
):
# type: (...) -> None
"""Get an array of string ['ArrayQuery1', 'begin!*'();:@ &=+$,/?#[]end' , null, ''] using the
mult-array format.
"""Get an array of string using the multi-array format.
Parameter is ['ArrayQuery1', 'begin!*'();:@ &=+$,/?#[]end' , null, '']. null is sent as empty
string.
:param array_query: an array of string ['ArrayQuery1', 'begin!*'();:@ &=+$,/?#[]end' , null,
''] using the mult-array format.
''] using the multi-array format.
:type array_query: list[str]
:keyword callable cls: A custom type or function that will be passed the direct response
:return: None, or the result of cls(response)
Expand All @@ -162,7 +166,7 @@ def array_string_multi_valid(
# Construct parameters
query_parameters = {} # type: Dict[str, Any]
if array_query is not None:
query_parameters['arrayQuery'] = self._serialize.query("array_query", array_query, '[str]', div=',')
query_parameters['arrayQuery'] = [self._serialize.query("array_query", q, 'str') if q is not None else '' for q in array_query]

# Construct headers
header_parameters = {} # type: Dict[str, Any]
Expand Down

0 comments on commit 1fe8a1a

Please sign in to comment.