questions for tornado.routing

144 views
Skip to first unread message

HENG

unread,
Apr 2, 2017, 11:52:11 PM4/2/17
to python-tornado
Hi:

I'm notice tornado has new module named tornado.routing and happy to have a test

app1 = Application([
    (r"/app1/handler", Handler1),
    # other handlers ...
])

app2 = Application([
    (r"/app2/handler", Handler2),
    # other handlers ...
])

router = RuleRouter([
    Rule(PathMatches("/app1.*"), app1),
    Rule(PathMatches("/app2.*"), app2)
])

server = HTTPServer(router)



BUT it can not run ....

It will thorow an error as follow:

[E 170403 03:26:12 http1connection:54] Uncaught exception 
Traceback (most recent call last): 
File "/home/vagrant/www/local/lib/python2.7/site-packages/tornado/http1connection.py", line 238, in _read_message
delegate.finish() 
File "/home/vagrant/www/local/lib/python2.7/site-packages/tornado/httpserver.py", line 314, in finish 
self.delegate.finish() 
File "/home/vagrant/www/local/lib/python2.7/site-packages/tornado/routing.py", line 251, in finish 
self.delegate.finish() 
File "/home/vagrant/www/local/lib/python2.7/site-packages/tornado/httpserver.py", line 229, in finish 
self.request_callback(self.request) 
TypeError: __init__() takes exactly 1 argument (2 given)


I use Tornado repo master code, just use:   pip install git+https://github.com/tornadoweb/tornado.git

How to use tornado.routing???? Do we have some document that more details???

Thx





--
--------------------------------------------------------------------
Heng
---------------------------------------------------------------------
--

Сумин Андрей

unread,
Apr 3, 2017, 4:53:09 AM4/3/17
to python-...@googlegroups.com
Hi,

Thank you for your feedback!

Could you please show the complete code that throws this exception?

I've created a gist with a simple demonstration here: https://gist.github.com/SuminAndrew/1d66c21a42478a7a9f53174d472a1a77
It uses an example from the docs, adding missing imports and handler definitions.

Could you also check it out?

Best regards,
Andrew.

--
You received this message because you are subscribed to the Google Groups "Tornado Web Server" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python-tornado+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

HENG

unread,
Apr 3, 2017, 10:49:02 AM4/3/17
to python-tornado
Thanks for sumin.andrew!

I do not have Linux at home so just use my wife windows to has a test.



That is an error, but I get a normal response in Chrome

That is a little strange~


HENG

unread,
Apr 3, 2017, 11:14:51 AM4/3/17
to python-tornado
I ask for help because I forgot to initialize the `tornado.web.Application` class

1.as normal, we rewrite the Application class as follow:


class MyApplication(tornado.web.Application):
    def __init__(self):
        pass # do something
        super(.....).__init__(handlers=[], **settings)


Then, we use `MyApplication` like this:


router = RuleRouter([
    Rule(PathMatches("/app1.*"), MyApplication),  # here Application class has not init as instance!!!!
])
server = HTTPServer(router)



This code will throw error because the Application has NOT init, just as follow:


[E 170403 03:26:12 http1connection:54] Uncaught exception 
Traceback (most recent call last): 
File "/home/vagrant/www/local/lib/python2.7/site-packages/tornado/http1connection.py", line 238, in _read_message
delegate.finish() 
File "/home/vagrant/www/local/lib/python2.7/site-packages/tornado/httpserver.py", line 314, in finish 
self.delegate.finish() 
File "/home/vagrant/www/local/lib/python2.7/site-packages/tornado/routing.py", line 251, in finish 
self.delegate.finish() 
File "/home/vagrant/www/local/lib/python2.7/site-packages/tornado/httpserver.py", line 229, in finish 
self.request_callback(self.request) 
TypeError: __init__() takes exactly 1 argument (2 given)



As the truth, `tornado.routing.Rule` target can access `tornado.web.Application` instance, 

But the 4.5b1 document just consider HTTPServerConnectionDelegate and forgot to remind that `tornado.web.Application` is a sub-class of HTTPServerConnectionDelegate

And

I follow tornado from it was release from friendfeed

It'code was simple and beatiful in v1.0

now Tornado was stronger and better than before, but I feel heavy to follow the code change, even I use day by day

Maybe this is the software rule: the more it have, the heavy code they are

Just as joke to have fun

Thanks



Сумин Андрей

unread,
Apr 3, 2017, 11:20:22 AM4/3/17
to python-...@googlegroups.com
Hi,

This happens because Chrome may generate other requests alongside with your request for "/app1/handler", for example, a request for favicon.
This path is not mapped in the RuleRouter, so the router returns None when it tries to find a suitable handler. This results in an error that you see in your logs (and the original request succeeds).

If you use low-level routing mechanisms like this, you're on your own with handling such situations.

To handle this this in real code, you can add one more rule:

Rule(PathMatches(".*"), _Some404Handler_)

with a handler of your choosing.

HENG

unread,
Apr 3, 2017, 11:38:23 AM4/3/17
to python-tornado
Thanks for reply! 

Сумин Андрей

unread,
Apr 3, 2017, 11:51:37 AM4/3/17
to python-...@googlegroups.com
Hi again!

Let's look at the code that you provided:

router = RuleRouter([
    Rule(PathMatches("/app1.*"), MyApplication),  # here Application class has not init as instance!!!!
])
server = HTTPServer(router)

This code is broken as you correctly pointed out, but neveretheless due to Python's dynamic nature it reveals its flow only at runtime.

Moreover, MyApplication may still be a valid routing target, because any class object is callable and RuleRouter accepts callables as routing targets: https://github.com/tornadoweb/tornado/blob/master/tornado/routing.py#L346

So the exception is raised only when we actually try to use this target as the contract dictates us (https://github.com/tornadoweb/tornado/blob/master/tornado/httpserver.py#L229), calling __init__(self, request).
But your MyApplication.__init__ signature looks like __init__(self) — and that is exactly what you see in the error message.

The docs actually contain the information about Application implementing Router/HTTPServerConnectionDelegate here: https://github.com/tornadoweb/tornado/blob/master/tornado/routing.py#L17

And I agree with you — unfortunately sometimes you must pay for flexibility, especially when breaking backwards compatibility is not an option.

HENG

unread,
Apr 4, 2017, 4:37:38 AM4/4/17
to python-tornado
Thanks for the details. Thanks!
Reply all
Reply to author
Forward
0 new messages