Flask应用程序,可路由到多个顶级和子域

2024-10-04 01:27:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个应用程序,需要多个域指向同一个应用程序显示不同的数据,但我也有相同的“管理”子域在所有域,也显示不同的数据根据域。在

例如:

pinetree.com - displays information about pine trees
oaktree.com - displays information about oak trees

admin.pinetree.com - displays admin for managing pine trees
admin.oaktree.com - displays admin for managing oak trees

到目前为止,我发现您需要在Flask配置中编写SERVER_NAME(域名),以便在Flask中使用子域,但是由于我有许多不同类型的树,具有唯一的域,并且总是添加新的树,我不知道如何使用该功能。在

另外,我看到了GAE flexible没有多租户,这是我第一次想到的在GAE上管理多个域的方法。在


Tags: 数据子域com应用程序forinformationadmintrees
2条回答

如果一个基域包含多个子域,则应使用Subdomain matching, explained in another answer。它更直接,因为Flask可以推断出更多关于它匹配的url的信息。在

但是,如果您有多个基域,则应该使用host matching。必须在app对象上设置host_matching=True,同时设置static_host,这样static路由就知道要从哪个主机服务。与子域不同,您不设置SERVER_NAME。然后将host选项传递给routes。这与完整域相匹配,因此每次都需要写出完整的域,而不仅仅是子域。在

不幸的是,匹配完整主机意味着也要匹配端口。在dev服务器下,默认情况下端口为5000,但在生产中,端口可能是80、443或其他类型。在开发模式下运行时,您可以编写一个小助手来将端口设置为5000(或者您的部署所需的任何配置逻辑)。在

from flask.helpers import get_env

def p(host):
    if get_env() == "development":
        return host + ":5000"

    return host

# p("example.com") -> "example.com:5000"

此示例显示了路由到格式为{tree}tree.com和{}的任何主机,其中pinetree.com作为静态主机。在

^{pr2}$

Blueprint还不接受host选项,因此您需要为每个路由指定主机。您可以使用partial稍微简化一下。在

from functools import partial
from flask import Blueprint

admin = Blueprint("admin", __name__)
admin_route = partial(admin.route, host=p("admin.<tree>tree.com"))

@admin_route("/")
def index(tree):
    return f"admin for {tree} tree"

app.register_blueprint(admin)

请注意,host可以像路由中的路径一样接受URL参数。它将像路径参数一样传递给视图。这允许动态主机和子域。您可以使用^{}^{}将其提取到g中,而不是将其作为每个视图的参数写入。在

from flask import g

@app.url_value_preprocessor
def extract_tree(endpoint, values):
    g.tree = values.pop("tree")

@app.url_defaults
def inject_tree(endpoint, values):
    values.setdefault("tree", g.tree)

@app.route("/")
def index()
    return f"{g.tree} tree"

在开发期间,在Unix上添加hosts-your-hosts文件(/etc/hosts),以便它们路由到localhost。在

127.0.0.1 localhost pinetree.com admin.pinetree.com oaktree.com admin.oaktree.com

和运行:

export FLASK_ENV=development
flask run

这是我几年前创建的一个小库,它可能很有用:https://github.com/wiota/landlord(这种模式通常称为“多租户”或“多租户应用程序”,因此得名)。在

当您想用本质上相同的应用程序响应时,这是很有用的,根据主机名不同的内容,这似乎是您要寻找的。在

简而言之,您可以将现有的应用程序包装在app.py中:

from flask import Flask
from landlord import Landlord
from your_app import create_app

if __name__ == '__main__' :
    app = Flask(__name__)
    app.wsgi_app = Landlord(create_app)
    app.run()

然后在子应用程序的__init__.pycreate_app函数获得一个hostname参数,它允许您执行每主机逻辑:

^{pr2}$

相关问题 更多 >