spec-first / connexion

Connexion is a modern Python web framework that makes spec-first and api-first development easy.
https://connexion.readthedocs.io/en/latest/
Apache License 2.0
4.45k stars 756 forks source link

Custom "uri_parser" stops working when "connexion" is upgraded to "v3.0.6" from "v2.14.2" #1920

Open thearifismail opened 2 months ago

thearifismail commented 2 months ago

Description

We use a custom uri_parser to serve requests like this http://localhost:8080/api/inventory/v1/hosts?fields[system_profile]=arch,cpu_flags. The uri_parser converts "fields[system_profile]=arch,cpu_flag" to {'fields': {'system_profile': {'arch': True, 'cpu_flags': True}}}. This is has been working as expected and has been using connexion v2.14.2. The following code snippet shows how the custom uri_parser was provided as a `connexion_option.

def create_app(runtime_environment):
    connexion_options = {
        "swagger_ui": True,
        "uri_parser_class": customURIParser,
        "openapi_spec_path": "/dev/openapi.json",
    }
    connexion_app = connexion.FlaskApp("inventory", specification_dir="./swagger/", options=connexion_options)

Now I need to upgrade the connexion to v3.0.6, which requires the custom uri_parser be provided directly to the FlaskApp or as an argument to the `FlaskApp.add_api() call.

connexion_app = connexion.FlaskApp("inventory", specification_dir="./swagger/", uri_parser_class=customURIParser)

With this change when the request http://localhost:8080/api/inventory/v1/hosts?fields[system_profile]=arch,cpu_flags is hit, the customURIParser is not hit at all, if strict_validation=True is used. The customURIParser is hit as expected IF strict_validation=False is used.

Questions:

  1. Am I hitting some bug?
  2. How do I get it work?

I will appreciate any help I can get. Thanks.

Expected behaviour

When using connexion v3.0.6, the customURIParser should transform the input URI to an expected form but it does not. Debugger does not even hit this code. i.e. the customURIParser is ignored altogether.

If it helps, here is the validator_map:

def build_validator_map(system_profile_spec, unindexed_fields):
    return {
        "response": CustomResponseValidator,
        "parameter": functools.partial(
            CustomParameterValidator, system_profile_spec=system_profile_spec, unindexed_fields=unindexed_fields
        ),
    }
...
...
...
class CustomResponseValidator(ResponseValidator):

The import packages are:

# `connexion v2.14.2` 
from connexion.decorators.response import ResponseValidator
from connexion.decorators.validation import ParameterValidator
from connexion.decorators.uri_parsing import OpenAPIURIParser

# `connexion v3.0.6`
from connexion.validators.abstract import AbstractResponseBodyValidator
from connexion.validators.parameter import ParameterValidator
from connexion.uri_parsing import OpenAPIURIParser

Actual behaviour

Steps to reproduce

Use the code snippet provided above.

Additional info:

thearifismail commented 1 month ago

What's the criteria or potential of this issue getting a look?

RobbeSneyders commented 1 month ago

Hi @thearifismail,

The best way to get this issue looked at is to provide a minimal reproducible example, so we can easily investigate it.