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.49k stars 765 forks source link

Lack of support for server URL basepath templated variables in Connexion library #1622

Open moshego189 opened 1 year ago

moshego189 commented 1 year ago

Description

The Connexion library, which helps create APIs using OpenAPI, has a problem when using variables in the server URL. The problem is when we use variables in the openapi.yaml file, the library automatically chooses a default value for the variable instead of letting us choose the value in the Swagger UI. This means we can't change the value of the variable easily, and also it doesn't allow us to receive the variable value in the request callback.

Here's an example of how variables are defined in the openapi.yaml file:

openapi: 3.0.0
info:
  title: "Example API"
  description: ''
  version: 1.0.0
servers:
  - description: ""
    url: https://example.com/
  - description: ""
    url: /{version}/example
    variables:
      version:
        description: The version number
        enum:
          - v1
          - v2
        default: v1

As you can see in the above example, we have defined a variable version with possible values v1 and v2 and a default value of v1. But the problem is, we can not change the value of the variable in the Swagger UI, and also we can not receive the variable value in the request callback.

Expected behaviour

We should be able to choose the value of the variable in the Swagger UI and also receive the variable value in the request callback.

Actual behaviour

The library automatically chooses a default value for the variable, we can not change the value of the variable easily, and also we can not receive the variable value in the request callback.

Steps to reproduce

  1. Create a new project using the Connexion library
  2. Add a variable in the server URL in the openapi.yaml file similar to the above example
  3. Try to change the value of the variable in the Swagger UI
  4. Observe that the default value is chosen and cannot be changed
  5. Try to access the variable value in the request callback and observe that it's not accessible

Additional info:

Output of the commands:

python --version : Python 3.10.9 pip show connexion | grep "^Version\:" : Version: 2.14.1

Ruwann commented 1 year ago

Hi @moshego189 , I am not sure I can fully reproduce the issue:

using the provided yaml as is in the hello world example raises an InvalidSpecification exception

connexion.exceptions.InvalidSpecification: 1 is not of type 'string'

Failed validating 'type' in schema['properties']['servers']['items']['properties']['variables']['additionalProperties']['properties']['enum']['items']:
    {'type': 'string'}

On instance['servers'][1]['variables']['version']['enum'][0]:
    1

When I change it to the string variants by adding quotes, I indeed see that it's not possible to select a value: image

However, when removing the first element of the servers list, I can access the UI on the following URL: http://127.0.0.1:9090/1/example/ui/ image but not on http://127.0.0.1:9090/2/example/ui/

Unfortunately I'll have to dig a bit deeper on this, I believe I'm simply overlooking something here :)

moshego189 commented 1 year ago

You are right , i will update the example. Anyway, swaggerUI component has a builtin support for servers.variables feature. It seems that connexion does not handle it correctly.