Domanda

I am new to Tornado and trying to get simple OAuth twitter authentication working. As per the documention, I need to set up an authentication handler as follows:

class TwitterAuthHandler(BaseHandler, tornado.auth.TwitterMixin):
    @tornado.web.asynchronous
    @tornado.gen.coroutine
    def get(self):
        if self.get_argument("oauth_token", None):
            user = yield self.get_authenticated_user()
            if not user:
                raise tornado.web.HTTPError(500, "Twitter auth failed")
            self.set_secure_cookie("twitter_user", user)
            self.redirect("/")
        else:
            self.authenticate_redirect()

However, when I run this code I get the error:

  File "/Library/Python/2.7/site-packages/tornado/web.py", line 485, in redirect
    raise Exception("Cannot redirect after headers have been written")
Exception: Cannot redirect after headers have been written

This seems to be since the asynchronous call is not operating correctly, with the exception raised on the self.authenticate_redirect() line. If I replace @tornado.gen.coroutine with @tornado.gen.engine everything works fine. However, I understand that gen.engine is the old way of doing things, and gen.coroutine should be preferred as it returns a future.

I've also tried wrapping the call to self.get_authenticated_user() in tornado.gen.Task(). Am not sure when wrapping with gen.Task() is even necessary, but this does not seem to make any difference in this case.

What is wrong with this code, and why does gen.coroutine fail but gen.engine work?

È stato utile?

Soluzione

After checking this I thought it's probably a bug. Posting example code into this thread of python-tornado Google Group: https://groups.google.com/forum/?fromgroups#!topic/python-tornado/YypdSaXsM_Y confirmed it:

The auth*_redirect methods don't return Futures so they can't be yielded, but they should. As a workaround for now you can continue to use @gen.engine and call these methods without yielding.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top