Flask和SubdomainDispatcher,首先运行应用程序的方式?

时间:2013-08-23 08:53:55

标签: flask subdomain

我正在使用Flask建立一个网站,我想使用指示的SubdomainDispatcher,但我不知道如何使它工作(它缺少初始run开始服务器)。

以下是代码:

给定here的create_app函数:

def create_app(database_uri, debug=False):
    app = Flask(__name__)
    app.debug = debug

    # set up your database
    app.engine = create_engine(database_uri)

    # add your modules
    app.register_module(frontend)

    # other setup tasks

    return app

SubdomainDispatcher:

class SubdomainDispatcher(object):

    def __init__(self, domain, create_app):
        self.domain = domain
        self.create_app = create_app
        self.lock = Lock()
        self.instances = {}

    def get_application(self, host):
        host = host.split(':')[0]
        assert host.endswith(self.domain), 'Configuration error'
        subdomain = host[:-len(self.domain)].rstrip('.')
        with self.lock:
            app = self.instances.get(subdomain)
            if app is None:
                app = self.create_app(subdomain)
                self.instances[subdomain] = app
            return app

    def __call__(self, environ, start_response):
        app = self.get_application(environ['HTTP_HOST'])
        return app(environ, start_response)

主要应用

def make_app(subdomain):
    user = get_user_for_subdomain(subdomain)
    if user is None:
        # if there is no user for that subdomain we still have
        # to return a WSGI application that handles that request.
        # We can then just return the NotFound() exception as
        # application which will render a default 404 page.
        # You might also redirect the user to the main page then
        return NotFound()

    # otherwise create the application for the specific user
    return create_app(user)

application = SubdomainDispatcher('example.com', make_app)

到目前为止,我的代码工作没有错误,但随后,它停止了。这是正常的,因为没有,有:

if __name__ == "__main__":
    application = create_app(config.DATABASE_URI, debug=True)
    application.run()

使初始服务器运行的代码。

我试过了:

if __name__ == "__main__":
    application = SubdomainDispatcher('example.com', make_app)
    application.run()

但它失败了:

  

AttributeError:'SubdomainDispatcher'对象没有属性'run'

如何使用SubdomainDispatcher运行它?

2 个答案:

答案 0 :(得分:2)

让我们分析你的代码。

您创建了一个SubdomainDispatcher课程,用于创建Flask application并根据host中传递的get_application

返回

这也是callable

问题是.run方法属于Flask对象(应用程序本身)。 它在开发过程中仅用于test应用程序,它适用于单个应用程序。

因此您无法使用开发服务器作为整个系统进行测试。您一次只能测试其中一个域(app)。

if __name__ == "__main__":
    application = SubdomainDispatcher('example.com', make_app)
    app = application.get_application('example.com')
    app.run()

测试服务器不是全功能服务器。

更好的解决方案

BTW我认为,如果你解释一下你想要实现的目标(而不是你打算如何在烧瓶中做到:) :)我们可以找到更好的解决方案。即使用Flask子域关键字,或使用基于某些内容本地化应用参数的@before_request。 如果问题只是基于子域加载用户类,则不需要使用不同的Flask应用程序(特别是因为您使用相同的代码库),但只需要一个@before_request处理程序。

答案 1 :(得分:0)

要将SubdomainDispatcher与Flask本地开发服务器一起使用,我将flask.Flask.run中的大部分代码复制到一个单独的函数中,并将其挂在SubdomainDispatcher中间件中。繁重的工作由werkzeug.serving.run_simple完成:

def rundevserver(host=None, port=None, domain='', debug=True, **options):
    from werkzeug.serving import run_simple

    if host is None:
        host = '127.0.0.1'
    if port is None:
        port = 5000
    options.setdefault('use_reloader', debug)
    options.setdefault('use_debugger', debug)

    app = SubdomainDispatcher(create_app, domain, debug=debug)

    run_simple(host, port, app, **options)

有关详细信息,请参阅我的博文:Subdomain-based configuration for a Flask local development server