def asynchronous(function):
 arg_names = inspect.getargspec(function).args
 MessageData = collections.namedtuple(function.__name__, arg_names[1:])
 @functools.wraps(function)
 def call_or_send(processor, *args, **kwargs):
  if ((len(args) == 1) and (not kwargs) and isinstance(args[0], MessageData)):
   try:
    return function(processor, **args[0]._asdict())
   except Exception as exc:
    LOG.exception('[%s] Exception in "%s": %s', processor.name, function.__name__, exc)
    raise
  else:
   data = inspect.getcallargs(function, processor, *args, **kwargs)
   data.pop(arg_names[0])
   return processor.queue.send(function.__name__, MessageData(**data))
 call_or_send.MessageData = MessageData
 return call_or_send

def asynchronous ( function ) : arg_names = inspect . getargspec ( function ) . args MessageData = collections . namedtuple ( function . __name__ , arg_names [ 1 : ] ) @ functools . wraps ( function ) def call_or_send ( processor , * args , ** kwargs ) : if ( ( len ( args ) == 1 ) and ( not kwargs ) and isinstance ( args [ 0 ] , MessageData ) ) : try : return function ( processor , ** args [ 0 ] . _asdict ( ) ) except Exception as exc : LOG . exception ( '[%s] Exception in "%s": %s' , processor . name , function . __name__ , exc ) raise else : data = inspect . getcallargs ( function , processor , * args , ** kwargs ) data . pop ( arg_names [ 0 ] ) return processor . queue . send ( function . __name__ , MessageData ( ** data ) ) call_or_send . MessageData = MessageData return call_or_send
wrap request handler methods with this if they are asynchronous .