python-restx / flask-restx

Fork of Flask-RESTPlus: Fully featured framework for fast, easy and documented API development with Flask
https://flask-restx.readthedocs.io/en/latest/
Other
2.14k stars 333 forks source link

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

Open sloschert opened 11 months ago

sloschert commented 11 months ago

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

Additional Context

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

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:

This should fix the bug.