将路由前缀添加到 Flask 应用程序 运行 behing Gunicorn

Add route prefix to Flask application running behing Gunicorn

tldr; 寻找一种方法来为应用程序中的所有路由添加前缀 运行 在 Gunicorn 后面而不在 @route(PREFIX + '/') 中使用反向 proxy/blueprint/duplicate 前缀等等


使用 Flask 在 Docker 个容器中 运行 创建一些 Python 服务。
目前,不使用 Nginx/Apache 进行反向代理。

当 运行 烧瓶本身
时,有类似下面的东西 - (例如 % python app.py 响应 localhost:5000/a/b/some-route

base_path = "/a/b"
app = DispatcherMiddleware(_root_app, {base_path: self})
run_simple(host, port, app, **options)

不知道如何在 运行 落后于 Gunicorn 时获得相同的结果。
(真的很想在不为主应用程序制作蓝图的情况下这样做。还要尽量避免在每个 @route(PREFIX + '') 中使用相同的前缀)

这样做的原因
使用添加几条路线的扩展以及蓝图。希望所有应用程序路由和 extension/blueprint 路由都带有前缀。

This question asked this specifically for Flask, which I'm able to get working using the DispatcherMiddleware approach.
My question is how to get this working when running behind Gunicorn (no Nginx or Apache in front, just Gunicorn)


潜在修复:

目前正在使用 Flask 的子类(需要做一些自定义的日志记录废话。)
覆盖 add_url_rule 有效。

prefixed_rule = self._prefix_rule(rule)
super().add_url_rule(prefixed_rule,
                     endpoint=endpoint,
                     view_func=view_func,
                     **options)

这也适用于我们的扩展

您可以为特定蓝图的所有路由添加前缀

from flask import Blueprint
my_blueprint = Blueprint('my_blueprint_name', __name__, url_prefix='/my_prefix')

那么对于蓝图的所有路线,只需输入

@my_blueprint.route('my_route')

在函数定义及其路由之前将是 url_prefix+my_route

您可能会发现此 link 有帮助 http://flask.pocoo.org/docs/0.10/patterns/urlprocessors/

如果您正在编写应用组合,那么您可以使用您引用的 DispatcherMiddleware trick。但是,听起来您正在尝试安装子路径的单个服务,但根本不提供 "higher" 路径之外的任何服务。

有几种不同的方法可以做到这一点。

  1. 替换Flask.url_map._rules with a werkzeug.routing.Submount规则工厂:

    from werkzeug.routing import SubPath
    
    app = Flask(__name__)
    
    # register blueprints and extensions
    # load config, etc.
    
    app.url_map._rules = SubPath(app.config['APPLICATION_ROOT'], app.url_map._rules)
    
  2. 替换Flask.url_rule_class:

    from werkzeug.routing import Rule
    
    app.url_rule_class = lambda path, **options: Rule(PREFIX + path, **options)
    
  3. 按照您在问题中的建议替换 add_url_rule

试试这个

app = dash.Dash(
    __name__,
    server=server,
    routes_pathname_prefix='/dash/'
)