connexion
connexion copied to clipboard
Schema using `allOf`, `anyOf`, `oneOf` in parameter or form data raises `KeyError: type` during validation
Description
Currently, query parameters with a merged schema via allOf are not supported. A merged schema is sometimes useful for extending a base schema with additional constraints, and it's a legal schema declaration, so Connexion should support it.
Expected behaviour
It should be possible to use a merged schema via allOf for declaring the schema of a query parameter.
Actual behaviour
When a merged schema via allOf is used, a KeyError: type is raised:
https://github.com/spec-first/connexion/blob/64f42547dc76316c09d53ce57484beb03206a38a/connexion/decorators/uri_parsing.py#L114
This happens because with a merged schema via allOf there is no type key in the schema field directly, instead the child schemas of allOf must be parsed.
Steps to reproduce
I've created two test cases that both fail because of a raised KeyError: type:
-
# tests/fixtures/simple/openapi.yaml /test_query_param_allof: get: operationId: fakeapi.hello.test_query_param_allof parameters: - name: 'n' in: query required: true schema: allOf: - type: number - type: number minimum: 0 responses: '200': description: OK# tests/api/test_parameters.py def test_query_param_allof(simple_app): app_client = simple_app.app.test_client() url = "/v1.0/test_query_param_allof" response = app_client.get(url) assert response.status_code == 400 response = app_client.get(url, query_string={"n": "1.23"}) assert response.status_code == 200 -
# tests/fixtures/simple/openapi.yaml /test_array_multi_query_param_allof: get: operationId: fakeapi.hello.test_array_multi_query_param_allof parameters: - name: items in: query description: An comma separated array of items style: form explode: true schema: allOf: - type: array default: ["squash", "banana"] items: type: string - type: array maxItems: 10 responses: '200': description: OK# tests/api/test_parameters.py def test_array_query_param(simple_app): app_client = simple_app.app.test_client() # ... url = "/v1.0/test_array_multi_query_param_allof?items=A&items=B&items=C&items=D,E,F" response = app_client.get(url, headers=headers) array_response: List[str] = json.loads( response.data.decode("utf-8", "replace") ) # multi array with csv format assert array_response == ["A", "B", "C", "D", "E", "F"] # ...
Additional info:
Output of the commands:
python --version: Python 3.9.7pip show connexion | grep "^Version\:": Version: -2020.0.dev1-
Hi @sisp,
This is a known issue (see #1409, #1263, #1300, #1013, #1231) and is caused by some custom validation code. I'd like to tackle this as part of the validation refactoring for connexion 3.X (#1525).
Let me close those other issues and rephrase this one slightly to cover the general issue, as I appreciate the effort you put into this report.
Sounds good, @RobbeSneyders. Thanks!
Version
2.14.2
Description
Hey @RobbeSneyders. I discovered this open issue after running into the same issue.The offending line of code is this in "url_parsing.py":
if defn and defn["type"] == "array":
form_data[k] = self._split(form_data[k], encoding, "form")
Steps to reproduce
It's simple to reproduce - same as @sisp mentioned: when I use anyOf in the OpenAPI 3.0 schema, a "KeyError: 'type'" is raised at the line I quoted above.
I tried to debug this issue a bit myself by printing out defn to see what key it has.
Here's an example defn object when anyOf is used. Notice that the type dictionary key is wrapped inside each element of the anyOf JSON value array, and does not exist at root level of defn.
# json.dumps(defn, indent=2)
{
"anyOf": [
{
"properties": {
# ......
},
"title": "AWS S3",
"type": "object",
},
# ......
{
"properties": {
# ......
},
"title": "GCP Cloud Storage",
"type": "object",
}
],
"title": "data_source"
}
Question
Since this issue has been open for almost a year, I wonder is there plan to support anyof and the other aggregate functions in form data parsing any time soon? If not, do you see any immediate workaround or hotfix other than asking users to not use these aggregation keywords? Thanks!