sargas
sargas

Reputation: 1144

How to replace or modify a Tornado Handler at runtime?

I am writing a Jupyter server extension, allowing me to write a tornado.web.RequestHandler class. I would like to modify one of the handlers that the application has been initialized with, specifically the one creating a default redirect:

(r'/?', web.RedirectHandler, {
    'url' : settings['default_url'],
    'permanent': False, # want 302, not 301
})

From the RequestHandler object I have access to the tornado.web.Application subclass used. Is there a public API to get the list of handlers that I could modify?

Specifically, I'm looking to change the 'url' parameter the tornado.web.RedirectHandler is created with. It doesn't look like there is a documented api for this, so I'm guessing I'd have to replace the handler entirely.

Upvotes: 4

Views: 966

Answers (2)

Nikolay Gatilov
Nikolay Gatilov

Reputation: 66

Any instance of tornado.web.Application has default_router:

>>> import tornado.web
>>> import tornado.routing
>>> r1 = tornado.routing.Rule(r'/', MainHandler, name="/")
>>> r2 = tornado.routing.Rule(r'/sub/[\w-]+/', SubHandler, name="/sub/{name of}")
>>> app_tornado = tornado.web.Application([r1, r2])
>>> app_tornado.default_router.rules
[Rule(<tornado.routing.AnyMatches object at 0x7f603cadd0b8>, <tornado.web._ApplicationRouter object at 0x7f603cadd080>, kwargs={}, name=None)]
>>> app_tornado.default_router.rules[0].target.rules
[Rule('/', <class '__main__.MainHandler'>, kwargs={}, name='/'), Rule('/sub/[\\w-]+/', <class '__main__.SubHandler'>, kwargs={}, name='/sub/{name of}')]

So, you can add rule:

>>> app_tornado.default_router.rules[0].target.add_rules([('/new_rule/', MainHandler)])
>>> app_tornado.default_router.rules[0].target.rules
[Rule('/', <class '__main__.MainHandler'>, kwargs={}, name='/'), Rule('/sub/[\\w-]+/', <class '__main__.SubHandler'>, kwargs={}, name='/sub/{name of}'), Rule(<tornado.routing.PathMatches object at 0x7f603cadd1d0>, <class '__main__.MainHandler'>, kwargs={}, name=None)]

May be it what you want.

Upvotes: 0

Ben Darnell
Ben Darnell

Reputation: 22134

Tornado does not support changing handlers at runtime. Instead, make your own handler which does the desired redirect based on whatever criteria you want:

class MyRedirectHandler(RequestHandler):
    def get(self):
        self.redirect(self.settings['default_url'], permanent=False)

Upvotes: 1

Related Questions