Search code examples
tornado

How to do an "internal redirect" in Tornado?


I'm porting a multi-tenant web app to Python/Tornado. Let's say each tenant site has two pages: "/foo" and "/bar". So far, so easy with Handlers.

However, tenants may choose what content to show on their homepage ("/"). This may be the content from /foo or /bar, but end-users shouldn't be redirected. In fact, tenants can choose any page from their site and make it their homepage.

In the PHP framework I'm used to, this was accomplished via internal routing logic. But I can't for the life of me figure out how to accomplish the same thing with Tornado.

I'm currently reading in the configuration state of each tenant in my BaseHandler's prepare() method. But this is clearly too late to affect routing logic, which has already mapped the request to a Handler.

Is there any way I can attach a custom routing function to "/" that allows to me to select a Handler to fulfil the request?


Solution

  • I figured it out after the hint from @xyres. I don't believe this is documented anywhere.

    The rule in Application:

    url(r"/", HomeRouter(self), name="home"),

    The class:

    from tornado.routing import Router
    
    class HomeRouter(Router):
        def __init__(self, application):
            self.application = application
    
        def find_handler(self, request, **kwargs):
            ...logic here...
            home_handler = ChosenHandler
            return self.application.get_handler_delegate(request, home_handler)