Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Variable in server url not being interpolated #1915

Open
RoamingNoMaD opened this issue Apr 25, 2024 · 1 comment
Open

Variable in server url not being interpolated #1915

RoamingNoMaD opened this issue Apr 25, 2024 · 1 comment

Comments

@RoamingNoMaD
Copy link

Description

When the api spec in use specifies variables in the server url and the values are being passed when instantiating the connexion.FlaskApp, interpolation is not executed. See simple example below.

Expected behaviour

====== test session starts =====
test_app.py .
====== 1 passed ======

Actual behaviour

pytest test_app.py
============================================================================ test session starts ============================================================================
platform linux -- Python 3.11.8, pytest-8.1.1, pluggy-1.5.0
rootdir: /home/jvasik/dev/connexion-dummy
configfile: pyproject.toml
plugins: anyio-4.3.0
collected 1 item                                                                                                                                                            

test_app.py F                                                                                                                                                         [100%]

================================================================================= FAILURES ==================================================================================
________________________________________________________________________________ test_route _________________________________________________________________________________

    def test_route():
        app_client = create_app((Path(os.getcwd()) / "api.yml").as_posix())
        response = app_client.get("test/v1/")
>       assert response.status_code == 200
E       assert 404 == 200
E        +  where 404 = <Response [404 Not Found]>.status_code

test_app.py:23: AssertionError
----------------------------------------------------------------------------- Captured log call -----------------------------------------------------------------------------
ERROR    connexion.middleware.exceptions:exceptions.py:84 HTTPException(status_code=404, detail='The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.')
========================================================================== short test summary info ==========================================================================
FAILED test_app.py::test_route - assert 404 == 200
======================================================================= 1 failed, 7 warnings in 0.79s =======================================================================
Full log
pytest test_app.py
============================================================================ test session starts ============================================================================
platform linux -- Python 3.11.8, pytest-8.1.1, pluggy-1.5.0
rootdir: /home/jvasik/dev/connexion-dummy
configfile: pyproject.toml
plugins: anyio-4.3.0
collected 1 item                                                                                                                                                            

test_app.py F                                                                                                                                                         [100%]

================================================================================= FAILURES ==================================================================================
________________________________________________________________________________ test_route _________________________________________________________________________________

    def test_route():
        app_client = create_app((Path(os.getcwd()) / "api.yml").as_posix())
        response = app_client.get("test/v1/")
>       assert response.status_code == 200
E       assert 404 == 200
E        +  where 404 = <Response [404 Not Found]>.status_code

test_app.py:23: AssertionError
----------------------------------------------------------------------------- Captured log call -----------------------------------------------------------------------------
ERROR    connexion.middleware.exceptions:exceptions.py:84 HTTPException(status_code=404, detail='The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.')
============================================================================= warnings summary ==============================================================================
../../.local/share/virtualenvs/connexion-dummy-LMhlc2UK/lib64/python3.11/site-packages/connexion/json_schema.py:16
../../.local/share/virtualenvs/connexion-dummy-LMhlc2UK/lib64/python3.11/site-packages/connexion/json_schema.py:16
  /home/jvasik/.local/share/virtualenvs/connexion-dummy-LMhlc2UK/lib64/python3.11/site-packages/connexion/json_schema.py:16: DeprecationWarning: jsonschema.RefResolver is deprecated as of v4.18.0, in favor of the https://github.com/python-jsonschema/referencing library, which provides more compliant referencing behavior as well as more flexible APIs for customization. A future release will remove RefResolver. Please file a feature request (on referencing) if you are missing an API for the kind of customization you need.
    from jsonschema import Draft4Validator, RefResolver

../../.local/share/virtualenvs/connexion-dummy-LMhlc2UK/lib64/python3.11/site-packages/connexion/json_schema.py:17
  /home/jvasik/.local/share/virtualenvs/connexion-dummy-LMhlc2UK/lib64/python3.11/site-packages/connexion/json_schema.py:17: DeprecationWarning: jsonschema.exceptions.RefResolutionError is deprecated as of version 4.18.0. If you wish to catch potential reference resolution errors, directly catch referencing.exceptions.Unresolvable.
    from jsonschema.exceptions import RefResolutionError, ValidationError  # noqa

../../.local/share/virtualenvs/connexion-dummy-LMhlc2UK/lib64/python3.11/site-packages/connexion/validators/form_data.py:4
../../.local/share/virtualenvs/connexion-dummy-LMhlc2UK/lib64/python3.11/site-packages/connexion/validators/form_data.py:4
  /home/jvasik/.local/share/virtualenvs/connexion-dummy-LMhlc2UK/lib64/python3.11/site-packages/connexion/validators/form_data.py:4: DeprecationWarning: Accessing jsonschema.draft4_format_checker is deprecated and will be removed in a future release. Instead, use the FORMAT_CHECKER attribute on the corresponding Validator.
    from jsonschema import ValidationError, draft4_format_checker

../../.local/share/virtualenvs/connexion-dummy-LMhlc2UK/lib64/python3.11/site-packages/connexion/validators/json.py:6
../../.local/share/virtualenvs/connexion-dummy-LMhlc2UK/lib64/python3.11/site-packages/connexion/validators/json.py:6
  /home/jvasik/.local/share/virtualenvs/connexion-dummy-LMhlc2UK/lib64/python3.11/site-packages/connexion/validators/json.py:6: DeprecationWarning: Accessing jsonschema.draft4_format_checker is deprecated and will be removed in a future release. Instead, use the FORMAT_CHECKER attribute on the corresponding Validator.
    from jsonschema import Draft4Validator, ValidationError, draft4_format_checker

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
========================================================================== short test summary info ==========================================================================
FAILED test_app.py::test_route - assert 404 == 200
======================================================================= 1 failed, 7 warnings in 0.79s =======================================================================

Steps to reproduce

Worked with: pip install connexion==2.14.2 flask==2.2.5

Does not work: pip install connexion==3.0.6 flask==3.0.3

Execute the test: pytest test_app.py

api.yml:

openapi: "3.0.0"
info:
  description: "..."
  version: "1.0.0"
  title: "..."

servers:
  - url: "/{{path_prefix}}/v1"

paths:
  /:
    get:
      operationId: route.index
      responses:
        "200":
          description: "..."

route.py:

def index():
    return "Hello World!"

test_app.py:

import os
import json
from pathlib import Path

import yaml

from connexion import FlaskApp


def create_app(spec_path: str):
    with open(spec_path, "r") as f:
        specs = yaml.safe_load(f)

    openapi_args = {"path_prefix": 'test'}
    connexion_app = FlaskApp(__name__, specification_dir="", arguments=openapi_args)
    connexion_app.add_api(specs)
    return connexion_app.test_client()


def test_route():
    app_client = create_app((Path(os.getcwd()) / "api.yml").as_posix())
    response = app_client.get("test/v1/")
    assert response.status_code == 200
    assert json.loads(response.content) == "Hello World!"

To prove the failure of interpolation, change:
response = app_client.get("test/v1/")
to:
response = app_client.get("{path_prefix}/v1/")

The test will now pass.

Additional info:

Output of the commands:

  • python --version:
    Python 3.11.8
  • pip show connexion | grep "^Version\:":
    Version: 3.0.6
@RoamingNoMaD
Copy link
Author

RoamingNoMaD commented Apr 26, 2024

Fix: if the arguments for substitution by Jinja are passed to the add_api method instead, it works.

Error:

connexion_app = FlaskApp(__name__, specification_dir="", arguments=openapi_args)
connexion_app.add_api(spec_path)

Success:

connexion_app = FlaskApp(__name__, specification_dir="")
connexion_app.add_api(spec_path, arguments=openapi_args)

Don't know if this is intentional, there's not a word on this in the 3.0 docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant