如何在 Apache 和 mod_wsgi 中使用 Flask 路由?

Posted

技术标签:

【中文标题】如何在 Apache 和 mod_wsgi 中使用 Flask 路由?【英文标题】:How do I use Flask routes with Apache and mod_wsgi? 【发布时间】:2012-03-29 14:53:00 【问题描述】:

我已经设置好我的 Apache 服务器,它正在通过 mod_wsgi 处理 Flask 响应。我已经通过别名注册了 WSGI 脚本:

[httpd.conf]

WSGIScriptAlias /service "/mnt/www/wsgi-scripts/service.wsgi"

我已经在上面的路径添加了对应的WSGI文件:

[/mnt/www/wsgi-scripts/service.wsgi]

import sys
sys.path.insert(0, "/mnt/www/wsgi-scripts")

from service import application

我有一个提供服务模块的简单测试 Flask Python 脚本:

[/mnt/www/wsgi-scripts/service.py]

from flask import Flask

app = Flask(__name__)

@app.route('/')
def application(environ, start_response):
        status = '200 OK'
        output = "Hello World!"
        response_headers = [('Content-type', 'text/plain'),
                            ('Content-Length', str(len(output)))]
        start_response(status, response_headers)
        return [output]

@app.route('/upload')
def upload(environ, start_response):
        output = "Uploading"
        status = '200 OK'
        response_headers = [('Content-type', 'text/plain'),
                            ('Content-Length', str(len(output)))]
        start_response(status, response_headers)
        return [output]

if __name__ == '__main__':
        app.run()

当我转到我的网站 URL [主机名]/服务时,它按预期工作,我得到“Hello World!”背部。问题是我不知道如何让其他路线像上面示例中的“上传”一样工作。这在独立的 Flask 中运行良好,但在 mod_wsgi 下我很难过。我唯一能想到的是在 httpd.conf 中为我想要的每个端点注册一个单独的 WSGI 脚本别名,但这会带走 Flask 的花哨路由支持。有没有办法让这个工作?

【问题讨论】:

你试过浏览到/service/upload吗?您可能会感到惊喜。 当我点击 /service/upload 时,请求仍会发送到“应用程序”功能。事实上,我可以在应用程序函数之前删除路由语句,它仍然有效。这就像应用程序总是被 mod_wsgi 用作​​应用程序的入口点。感觉我需要在“应用程序”中做一些事情来启动 Flask 的路由逻辑。 【参考方案1】:

在您的 wsgi 文件中,您正在执行 from service import application,它只导入您的 application 方法。

将其更改为from service import app as application,一切都会按预期进行。

在您发表评论后,我想我会稍微扩展一下答案:

您的 wsgi 文件是 Python 代码 - 您可以在此文件中包含任何有效的 Python 代码。安装在 Apache 中的 wsgi“处理程序”正在此文件中查找 application 名称,它将把请求交给该名称。 Flask 类实例 - app = Flask(__name__) - 提供了这样的接口,但由于它被称为 app 而不是 application,因此您必须在导入时为其命名 - 这就是 from 行的作用。

您可以 - 这非常好 - 只需执行此操作 application = Flask(__name__),然后将 Apache 中的 wsgi 处理程序指向您的 service.py 文件。如果service.py 是可导入的(也就是说,在PYTHONPATH 中的某处),则不需要中间的wsgi 脚本。

虽然上述方法有效,但它是不好的做法。 wsgi 文件需要 Apache 进程的权限才能工作;并且您通常将其与实际源代码分开,该源代码应该位于文件系统的其他位置,并具有适当的权限。

【讨论】:

成功了。谢谢!除了更改 service.wsgi 以匹配您所指示的内容外,我还需要将我的 service.py 恢复为纯烧瓶。在最初的问题陈述中,我认为我已经脱离了将纯 mod_wsgi 代码与 Flask 混合的轨道。我认为这种混乱的起因是将我的根路由处理程序命名为“应用程序”。 我想我不清楚 mod_wsgi 与 Flask 代码的区别。我知道这都是Python。我遇到的问题是,在上面的示例中,我的@app.route('/') 正在装饰函数application。在我原来的设置中,我只导入了应用程序,所以只有那个函数被调用。当我将 service.wsgi 更改为使用正确引用 Flask 对象的from service import app as application 时,它似乎也与application 函数产生了命名冲突。我将此函数重命名为@def root():,现在它可以正常工作了。再次感谢! 甜蜜!这就是我的困境的答案。

以上是关于如何在 Apache 和 mod_wsgi 中使用 Flask 路由?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Windows 上为 apache 2.4 和 python 3.4 安装 mod_wsgi?

如何使用WSGI部署Django

如何在同一个域下部署多个 django cms 项目。我使用的是 apache 2.2 和 mod_wsgi

在 linux 中使用 apache 和 mod_wsgi 配置 Python flask 应用程序

使用 Python 3.6、Apache 2.4 和 Django 1.11 在 Ubuntu 上安装 mod_wsgi

apache/mod_wsgi - 如何使用不同的 python 虚拟环境配置多个 webapps