asynchronous - Tornado async decorators where one depends on another -


i'm trying head around tornado. i'm writing chat application backed mongodb , i'm using motor non-blocking access it.

what i'm trying achieve is:

  1. create decorator uses motor asynchronously pull user's record mongo
  2. validate credentials (username & token)
  3. create decorator checks user_id retrieved in 1. above permitted access chat room. requires asynchronous call mongo motor retrieve 'chatroom' record.
  4. subscribe chat room if ok

i have decorator 1. working (basically taken http://tornadogists.org/5251927/):

def authenticated_async(f):     @functools.wraps(f)     @gen.engine     def wrapper(self, *args, **kwargs):         self.current_user = yield gen.task(self.get_current_user_async)         if self.current_user:             logging.info("user '%s' (%s) authenticated" %                          (self.current_user['username'],                           self.current_user['_id']))             f(self, *args, **kwargs)         else:             raise tornado.web.httperror(401, "user not authenticated, "                                              "aborting")     return wrapper 

the trouble second decorator, need access self.current_user. because set in asynchronous callback, it's not available when validation decorator (i.e validation decorator called before auth decorator completes).

is not possible me use decorators in way asynchronous functions? need call validation method inside above method after making sure self.current_user true it's more callback?

i'd ideally have methods in handler wrapped both of these decorators can reuse them elsewhere, i.e.:

class chatsockethandler(tornado.websocket.websockethandler):     @gen.coroutine     @validate_invitation_access_async     @authenticated_async     def open(self, invitation_id):         # stuff here... 

update in fact, there no dependency. user_id provided parameter, , used run both decorators in parallel - 1 confirm authentication, other see whether user id allowed access room. open() method proceed if self.auth_check == true , self.room_check == true.

could open() ever called before async decorators complete though?

you need switch order of decorators validate_invitation_access_async wrapper has access current_user:

@authenticated_async @validate_invitation_access_async def open(self, invitation_id):         # stuff here... 

then wrapper inside validate_invitation_access_async "f" in authenticated_async: it's called after self.current_user set. note don't need additional gen.engine decorator, wrappers engines. wrapper like:

def validate_invitation_access_async(f):     @gen.engine     def wrapper(self, *args, **kwargs):         # ... use motor see if user authorized ...         # if not, log , redirect. otherwise:         f(self, *args, **kwargs) 

you should update code use tornado 3's gen.coroutine instead of gen.engine: it's cleaner. leave exercise.


Comments

Popular posts from this blog

Android layout hidden on keyboard show -

google app engine - 403 Forbidden POST - Flask WTForms -

c - Why would PK11_GenerateRandom() return an error -8023? -