我正在使用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运行它?
答案 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