I'm building a website using Flask, and I'd like to use the indicated SubdomainDispatcher, but I don't know how to make it work (it's missing the initial run
to start the server).
Here's the code :
The create_app function given here :
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
The 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)
The main app :
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)
So far, my code works without errors, but then, it stops. This is normal because no where, there is the :
if __name__ == "__main__":
application = create_app(config.DATABASE_URI, debug=True)
application.run()
code that make the initial server to be run.
I tried this :
if __name__ == "__main__":
application = SubdomainDispatcher('example.com', make_app)
application.run()
But it fails with :
AttributeError: 'SubdomainDispatcher' object has no attribute 'run'
How can I run it using the SubdomainDispatcher ?
Let's analyze your code.
You create a SubdomainDispatcher
class that creates a Flask
application
and return it based on the host
passed in get_application
This is also a callable
.
The problem is that the .run
method is of the Flask
object (the application itself).
It is used to only test
the application during development and it works for the single application.
So you can't test it with the development server as a whole system. You can test only one of the domains (app) at a time.
if __name__ == "__main__":
application = SubdomainDispatcher('example.com', make_app)
app = application.get_application('example.com')
app.run()
The test server is not a full featured server.
BTW I think that if you explain what you're trying to achieve (and not how you plan to do it in flask :) ) we could find a better solution. i.e. using the Flask subdomain keyword, or using a @before_request
that localize the app parameters based on something.
If the problem is only loading a user class based on the subdomain, there's no need of different Flask Apps (in particural cause you're using the same codebase) but you only need one @before_request
handler.