【问题标题】:Add route prefix to Flask application running behing Gunicorn向运行 Gunicorn 的 Flask 应用程序添加路由前缀
【发布时间】:2015-12-21 06:54:30
【问题描述】:

tldr; 寻找一种方法来为运行在 Gunicorn 后面的应用程序中的所有路由添加前缀,而无需在 @route(PREFIX + '/') 等中使用反向代理/蓝图/重复前缀。


使用 Flask 创建一些 Python 服务,在 Docker 容器中运行。
目前,不使用 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 后面运行时获得相同的结果。
(真的很想在不为主应用程序制作蓝图的情况下执行此操作。同时尽量避免在每个 @987654326 中使用相同的前缀@)

这样做的原因
使用添加了一些路线的扩展以及蓝图。想要为所有应用程序路由和扩展/蓝图路由添加前缀。

This question 专门为 Flask 提出了这个问题,我可以使用 DispatcherMiddleware 方法来解决这个问题。
我的问题是如何在 Gunicorn 后面运行时让它工作(前面没有 Nginx 或 Apache,只有 Gunicorn)


潜在修复:

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

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

这也适用于我们的扩展程序

【问题讨论】:

  • 出于好奇,您在做什么需要将多个不可组合的服务视为一个站点?这是为了应用程序依赖隔离吗?为什么不在他们面前有一个反向代理呢?
  • 只是针对一些微服务,所以会有一个端点。只是有一些需要作为前缀的扩展以及应用程序。我们目前有一个反向代理,但这可能会在未来发生变化,因此我们希望在路由级别执行此操作,如果/当它确实对我们发生变化时。

标签: python flask gunicorn


【解决方案1】:

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

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

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

@my_blueprint.route('my_route')

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

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

【讨论】:

  • 我想避免在蓝图中这样做,因为这不会为应用中使用的其他扩展添加前缀。
【解决方案2】:

如果您正在做应用程序组合,那么您可以使用您引用的DispatcherMiddleware trick。但是,听起来您正在尝试安装一个已安装子路径的服务,但根本不提供“更高”路径之外的任何服务。

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

  1. Flask.url_map._rules 替换为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

【讨论】:

  • 我最初实现了#3,快速/简单,但我更喜欢#2,所以我使用了类似的东西(使用闭包,代替 lambda。那该死PEP8 =)
【解决方案3】:

试试这个

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-08
    • 2022-01-15
    • 1970-01-01
    • 1970-01-01
    • 2018-04-30
    • 2021-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多