Skip to content

Flask restx is not compatible with StrictUndefined mode of jinja #565

Open
@sloschert

Description

@sloschert

Repro Steps (if applicable)

  1. Change Flask app's Jinja environment from undefined to StrictUndefined:
app = Flask(__name__)
app.jinja_env.undefined = StrictUndefined
  1. Visit the swagger documentation of the app on /api/v1/doc/
  2. The documentation page crashes with a jinja2.exceptions.UndefinedError.

Expected Behavior

The docs page should load even with Flask's jinja enviroment being "StrictUndefined".

Actual Behavior

The app crashes.

Error Messages/Stack Trace

127.0.0.1 - - [23/Sep/2023 20:12:51] "GET /api/v1/doc/ HTTP/1.1" 500 -
Traceback (most recent call last):
  File "/nix/store/vnd7krkpq1cyla05s4wxqpkaghiykgcw-python3.10-flask-2.2.5/lib/python3.10/site-packages/flask/app.py", line 2552, in __call__
    return self.wsgi_app(environ, start_response)
  File "/nix/store/vnd7krkpq1cyla05s4wxqpkaghiykgcw-python3.10-flask-2.2.5/lib/python3.10/site-packages/flask/app.py", line 2532, in wsgi_app
    response = self.handle_exception(e)
  File "/nix/store/d9jb0b4d3yhba2yalqq3anv2841lmxf0-python3.10-flask-restx-1.1.0/lib/python3.10/site-packages/flask_restx/api.py", line 674, in error_router
    return original_handler(e)
  File "/nix/store/vnd7krkpq1cyla05s4wxqpkaghiykgcw-python3.10-flask-2.2.5/lib/python3.10/site-packages/flask/app.py", line 2529, in wsgi_app
    response = self.full_dispatch_request()
  File "/nix/store/vnd7krkpq1cyla05s4wxqpkaghiykgcw-python3.10-flask-2.2.5/lib/python3.10/site-packages/flask/app.py", line 1825, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/nix/store/d9jb0b4d3yhba2yalqq3anv2841lmxf0-python3.10-flask-restx-1.1.0/lib/python3.10/site-packages/flask_restx/api.py", line 674, in error_router
    return original_handler(e)
  File "/nix/store/vnd7krkpq1cyla05s4wxqpkaghiykgcw-python3.10-flask-2.2.5/lib/python3.10/site-packages/flask/app.py", line 1823, in full_dispatch_request
    rv = self.dispatch_request()
  File "/nix/store/vnd7krkpq1cyla05s4wxqpkaghiykgcw-python3.10-flask-2.2.5/lib/python3.10/site-packages/flask/app.py", line 1799, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
  File "/nix/store/4082f2rc70mwq5g93nmrv545645gs7d8-python3.10-flask_profiler-master/lib/python3.10/site-packages/flask_profiler/measured_route.py", line 40, in __call__
    response = self.use_case.record_measurement(
  File "/nix/store/4082f2rc70mwq5g93nmrv545645gs7d8-python3.10-flask_profiler-master/lib/python3.10/site-packages/flask_profiler/use_cases/observe_request_handling_use_case.py", line 35, in record_measurement
    response = self.request_handler.handle_request(
  File "/nix/store/4082f2rc70mwq5g93nmrv545645gs7d8-python3.10-flask_profiler-master/lib/python3.10/site-packages/flask_profiler/measured_route.py", line 27, in handle_request
    return self.original_route(*args, **kwargs)
  File "/nix/store/d9jb0b4d3yhba2yalqq3anv2841lmxf0-python3.10-flask-restx-1.1.0/lib/python3.10/site-packages/flask_restx/api.py", line 456, in render_doc
    return apidoc.ui_for(self)
  File "/nix/store/d9jb0b4d3yhba2yalqq3anv2841lmxf0-python3.10-flask-restx-1.1.0/lib/python3.10/site-packages/flask_restx/apidoc.py", line 35, in ui_for
    return render_template("swagger-ui.html", title=api.title, specs_url=api.specs_url)
  File "/nix/store/vnd7krkpq1cyla05s4wxqpkaghiykgcw-python3.10-flask-2.2.5/lib/python3.10/site-packages/flask/templating.py", line 147, in render_template
    return _render(app, template, context)
  File "/nix/store/vnd7krkpq1cyla05s4wxqpkaghiykgcw-python3.10-flask-2.2.5/lib/python3.10/site-packages/flask/templating.py", line 130, in _render
    rv = template.render(context)
  File "/nix/store/5qmbk3vzjhz9ng0d4k57nmp675v0vfb9-python3.10-Jinja2-3.1.2/lib/python3.10/site-packages/jinja2/environment.py", line 1301, in render
    self.environment.handle_exception()
  File "/nix/store/5qmbk3vzjhz9ng0d4k57nmp675v0vfb9-python3.10-Jinja2-3.1.2/lib/python3.10/site-packages/jinja2/environment.py", line 936, in handle_exception
    raise rewrite_traceback_stack(source=source)
  File "/nix/store/d9jb0b4d3yhba2yalqq3anv2841lmxf0-python3.10-flask-restx-1.1.0/lib/python3.10/site-packages/flask_restx/templates/swagger-ui.html", line 54, in top-level template code
    {% if config.SWAGGER_UI_OAUTH_CLIENT_ID -%}
jinja2.exceptions.UndefinedError: 'flask.config.Config object' has no attribute 'SWAGGER_UI_OAUTH_CLIENT_ID'

Environment

  • Python 3.10.12
  • Flask==2.2.5
  • flask-restx==1.1.0
  • Flask==2.2.5
  • flask-babel==3.1.0
  • Flask-HTTPAuth==4.8.0
  • Flask-Login==0.6.2
  • Flask-Mail==0.9.1
  • Flask-Migrate==4.0.4
  • Flask-SQLAlchemy==3.0.3
  • flask-talisman==1.1.0
  • Flask-WTF==1.1.1

Additional Context

The template swagger-ui.html contains in two places the following problematic jinja expression:

  • {% if config.SWAGGER_UI_OAUTH_CLIENT_ID -%}

It is problematic because it makes the docs page crash if the config variable SWAGGER_UI_OAUTH_CLIENT_ID is undefined and flask jinja environment is running in StrictUndefined mode (app.jinja_env.undefined = StrictUndefined).

There is no place in the flask restx documentation that specifies that the config variable has to be set or that StrictUndefined mode cannot be used.

The expression should be replaced with:

  • {% if config.SWAGGER_UI_OAUTH_CLIENT_ID is defined and config.SWAGGER_UI_OAUTH_CLIENT_ID -%}

This should fix the bug.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions