Array query parameters using square brackets cause error
Description
A query parameter representing an array of strings is parsed incorrectly by the deep object processing in the OpenAPIURIParser.
Expected behaviour
For example, if the path /users/{user_id} has the parameter:
expand:
in: query
name: expand
required: false
schema:
type: array
items:
type: string
description: List of fields which should be expanded in the response.
The request URI https://api.example.com/users/123?expand[]=user.profile&expand[]=user.address should pass the array of strings ['user.profile', 'user.address'] to the expand argument of the handler.
Actual behaviour
An TypeError: sequence item 0: expected str instance, dict found exception is thrown on line 237 of decorators/uri_parsing.py. This is due to the _preprocess_deep_objects method of the OpenAPIURIParser misinterpreting the square brackets and periods for nested notation and converting the query_data from {'expand[]': ['user.profile', 'user.address']} to {'expand': [{'': 'user.profile'}]}
Steps to reproduce
Make a path which accepts a query parameter as described above. Send a request to the path which uses repeated-key/square-bracket notation for the query parameter.
Additional info:
I would attempt a PR but I'm not familiar enough with the code base. I was not aware that Connexion had support for nested objects in query parameters so I'm not sure how it should be distinguished from the situation I've described above. I also didn't see a way to disable it in the code.
Output of the commands:
python --versionPython 3.8.5pip show connexion | grep "^Version\:"Version: 2.7.0
[Update] It looks like the notation for array-based query params isn't standardized. I was let axios serializing my query params which results in the square bracket notation described above. I was able to customize the param serialization to use the qs library and disabled square brackets. This is a workaround if this issue is not considered a bug.
Bump. This is a pretty egregious bug. Both ?ids[]=1&ids[]=2 and ?ids[0]=1&ids[1]=2 are pretty standard ways of passing around multiple values for a single param. This is the default behavior for a number of http libraries in various languages.
For axios case, if you switch to qs then json objects passed as string won't work.
The OpenAPI spec defines serialization formats for arrays in the query string. ?ids[0]=1&ids[1]=2 does not seem to be supported. ?ids[]=1&ids[]=2 seems to be the default with a parameter name of ids[].
This issue seems to come from uri_parsing.py :
def _make_deep_object(self, k, v):
""" consumes keys, value pairs like (a[foo][bar], "baz")
returns (a, {"foo": {"bar": "baz"}}}, is_deep_object)
"""
root_key = None
if k in self.param_schemas.keys():
return k, v, False
else:
for keys in self.param_schemas.keys():
if k.startswith(keys):
rest = keys.replace(k, '')
root_key = rest
In my case I was able to quickly avoid this issue by adding a similar parameters (or just replacing the old one). e.g.
expand:
in: query
name: expand
required: false
schema:
type: array
items:
type: string
description: List of fields which should be expanded in the response.
expand[]:
in: query
name: expand
required: false
schema:
type: array
items:
type: string
description: List of fields which should be expanded in the response.
Fixed in #1408