I have handlers that handle request with get and post method,i want to use authentication with my own custom decorator,not tornado itself @tornado.web.authenticated decorator. In my custom decorator,i need to query the db to identify the user,but db query in tornado are asynchronously with @gen.coroutine.
My codes are:
handlers.py;
@account.utils.authentication
@gen.coroutine
def get(self, page):
account/utils.py:
@tornado.gen.coroutine
def authentication(fun):
def test(self,*args, **kwargs ):
print(self)
db = self.application.settings['db']
result = yield db.user.find()
r = yield result.to_list(None)
print(r)
return test
but the erros occurred when accessed it :
Traceback (most recent call last): File "/Users/moonmoonbird/Documents/kuolie/lib/python2.7/site-packages/tornado/web.py", line 1443, in _execute result = method(*self.path_args, **self.path_kwargs) TypeError: 'Future' object is not callable
can anyone meet this before,what is the correctly way to write custom decorator to authenticate with async db operation ? thanks in advance~
The decorator needs to be synchronous; it's the function it returns that's a coroutine. You need to change:
@tornado.gen.coroutine
def authentication(fun):
def test(self, *args, **kwargs):
...
return test
To:
def authentication(fun):
@tornado.gen.coroutine # note
def test(self, *args, **kwargs):
...
return test