You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm trying to support arbitrary query parameters in my API. The API is a published specification where the user may offer query parameters for an object that is permitted to have additionalProperties per the jsonschema. The idea is the backend will return all objects subject to a query filter presented.
DEBUG - Query Parameter 'tags' (sanitized: 'tags') in function arguments
DEBUG - tags is a {'in': 'query', 'name': 'tags', 'schema': {'type': 'object', 'additionalProperties': {'type': 'string', 'pattern': '^[A-Za-z][A-Za-z0-9]*$'}, 'example': {'tagName1': 'tagValue1', 'tagName2': 'tagValue2'}}}
DEBUG - Query Parameter 'tagName1' (sanitized: 'tagName1') in function arguments
ERROR - Function argument 'tagName1' (non-sanitized: tagName1) not defined in specification
DEBUG - Query Parameter 'tagName2' (sanitized: 'tagName2') in function arguments
ERROR - Function argument 'tagName2' (non-sanitized: tagName2) not defined in specification
In the UI, I can submit the default example and given the specification above, it fails seemingly due to the query parameter deserialization issue mentioned in #1291. I try the workaround of using style: deepObject and explode: true and this now works in the UI, but the URL looks like this (url-encoded):
DEBUG - Query Parameter 'tags' (sanitized: 'tags') in function arguments
DEBUG - tags is a {'in': 'query', 'name': 'tags', 'style': 'deepObject', 'explode': True, 'schema': {'type': 'object', 'additionalProperties': {'type': 'string', 'pattern': '^[A-Za-z][A-Za-z0-9]*$'}, 'example': {'tagName1': 'tagValue1', 'tagName2': 'tagValue2'}}}
DEBUG - Query Parameter 'tags' (sanitized: 'tags') in function arguments
DEBUG - tags is a {'in': 'query', 'name': 'tags', 'style': 'deepObject', 'explode': True, 'schema': {'type': 'object', 'additionalProperties': {'type': 'string', 'pattern': '^[A-Za-z][A-Za-z0-9]*$'}, 'example': {'tagName1': 'tagValue1', 'tagName2': 'tagValue2'}}}
INFO - Received query: {'tags': {'tagName2': 'tagValue2', 'tagName1': 'tagValue1'}}
INFO: 127.0.0.1:58654 - "GET /images?tags%5BtagName1%5D=tagValue1&tags%5BtagName2%5D=tagValue2 HTTP/1.1" 200 OK
All the other options I've tried so far have also come up short, including using the full jsonschema specification as a reference and setting additionalProperties: True.
Expected behaviour
I expected to be able to pass additionalProperties via arbitrary key-values in the query string and they would be passed into the function kwargs dictionary and validated according to the additionalProperties schema, if given.
The parameters are scrubbed after being mistakenly not in the specification.
Related logs:
DEBUG - /api/images validating parameters...
DEBUG - Query Parameter 'tags' (sanitized: 'tags') in function arguments
DEBUG - tags is a {'in': 'query', 'name': 'tags', 'style': 'deepObject', 'explode': True, 'schema': {'type': 'object', 'additionalProperties': {'type': 'string', 'pattern': '^[A-Za-z][A-Za-z0-9]*$'}, 'example': {'tagName1': 'tagValue1', 'tagName2': 'tagValue2'}}}
DEBUG - Query Parameter 'foo' (sanitized: 'foo') in function arguments
ERROR - Function argument 'foo' (non-sanitized: foo) not defined in specification
DEBUG - Query Parameter 'architecture' (sanitized: 'architecture') in function arguments
ERROR - Function argument 'architecture' (non-sanitized: architecture) not defined in specification
DEBUG - Query Parameter 'tags' (sanitized: 'tags') in function arguments
DEBUG - tags is a {'in': 'query', 'name': 'tags', 'style': 'deepObject', 'explode': True, 'schema': {'type': 'object', 'additionalProperties': {'type': 'string', 'pattern': '^[A-Za-z][A-Za-z0-9]*$'}, 'example': {'tagName1': 'tagValue1', 'tagName2': 'tagValue2'}}}
DEBUG - Query Parameter 'foo' (sanitized: 'foo') in function arguments
ERROR - Function argument 'foo' (non-sanitized: foo) not defined in specification
DEBUG - Query Parameter 'architecture' (sanitized: 'architecture') in function arguments
ERROR - Function argument 'architecture' (non-sanitized: architecture) not defined in specification
INFO - Received query: {'tags': {}}
INFO: 127.0.0.1:50460 - "GET /images?foo=bar&architecture=x86_64 HTTP/1.1" 200 OK
Steps to reproduce
Use the documented specification and queries noted above.
Additional info:
Per the comment on the OpenAPI specification here, it seems like this is officially supported in OAS 3.0, and with a bit more flexibility in OAS 3.1.
After reading through the code, I think the issue lies in this segment. When **kwargs is used, the function signature is ignored, however the query_definitions lookup ignores additionalProperties and blindly attempts to access the parameter by key (which doesn't exist). This is mistakenly interpreted as "not being defined in specification".
Workaround: As a workaround, it seems I can pull this information out of the Flask request object, but I'd rather not do that unless I'm desperate. I note it here in case someone else is hitting the same thing and needs it working right away.
RELATED WEIRDNESS: In the "Actual behavior" logs above, it seems like the query args are processed twice. This doesn't happen with deepObject style.
Output of the commands:
python --version : Python 3.11.3
pip show connexion | grep "^Version\:": Version: 3.0.0a6
I initially tried this with the current stable, "2.14.2", and had the same issue. I reworked it all hoping the new 3.x alpha might work.
The text was updated successfully, but these errors were encountered:
I think there's two options to work around this, which you seem to have figured out already:
Don't specify the arguments in your specification, make sure strict_validation is disabled, and access the arguments via the request object exposed by connexion:
This way you can specify the additionalProperties and Connexion should validate them. But this is only possible if you have control of the client and can change the query this way.
Description
I'm trying to support arbitrary query parameters in my API. The API is a published specification where the user may offer query parameters for an object that is permitted to have additionalProperties per the jsonschema. The idea is the backend will return all objects subject to a query filter presented.
For example:
In my specification, I have the following, pulled verbatim from the linked comment above.
The function
images.read_all
is:related logs:
In the UI, I can submit the default example and given the specification above, it fails seemingly due to the query parameter deserialization issue mentioned in #1291. I try the workaround of using
style: deepObject
andexplode: true
and this now works in the UI, but the URL looks like this (url-encoded):Specification
Logs:
All the other options I've tried so far have also come up short, including using the full jsonschema specification as a reference and setting
additionalProperties: True
.Expected behaviour
I expected to be able to pass
additionalProperties
via arbitrary key-values in the query string and they would be passed into the functionkwargs
dictionary and validated according to theadditionalProperties
schema, if given.Desired query:
Actual behaviour
The parameters are scrubbed after being mistakenly not in the specification.
Related logs:
Steps to reproduce
Use the documented specification and queries noted above.
Additional info:
Per the comment on the OpenAPI specification here, it seems like this is officially supported in OAS 3.0, and with a bit more flexibility in OAS 3.1.
After reading through the code, I think the issue lies in this segment. When
**kwargs
is used, the function signature is ignored, however thequery_definitions
lookup ignoresadditionalProperties
and blindly attempts to access the parameter by key (which doesn't exist). This is mistakenly interpreted as "not being defined in specification".connexion/connexion/decorators/parameter.py
Lines 349 to 364 in 0c0c517
Workaround: As a workaround, it seems I can pull this information out of the Flask request object, but I'd rather not do that unless I'm desperate. I note it here in case someone else is hitting the same thing and needs it working right away.
RELATED WEIRDNESS: In the "Actual behavior" logs above, it seems like the query args are processed twice. This doesn't happen with
deepObject
style.Output of the commands:
python --version
: Python 3.11.3pip show connexion | grep "^Version\:"
: Version: 3.0.0a6I initially tried this with the current stable, "2.14.2", and had the same issue. I reworked it all hoping the new 3.x alpha might work.
The text was updated successfully, but these errors were encountered: