def __call__(self, *args, **kwargs): initial_ctx = MethodContext(self) initial_ctx.method_request_string = self.__key initial_ctx.in_header = self.__in_header initial_ctx.in_object = args initial_ctx.transport.type = NullServer.transport contexts = self.app.in_protocol.generate_method_contexts(initial_ctx) cnt = 0 retval = None logger.warning( "%s start request %s" % (_big_header, _big_footer) ) for ctx in contexts: if cnt == 0: p_ctx = ctx else: ctx.descriptor.aux.initialize_context(ctx, p_ctx, error=None) # do logging.getLogger('rpclib.server.null').setLevel(logging.CRITICAL) # to hide the following logger.warning( "%s start context %s" % (_small_header, _small_footer) ) self.app.process_request(ctx) logger.warning( "%s end context %s" % (_small_header, _small_footer) ) if ctx.out_error: raise ctx.out_error else: if len(ctx.descriptor.out_message._type_info) == 0: _retval = None elif len(ctx.descriptor.out_message._type_info) == 1: _retval = ctx.out_object[0] # workaround to have the context disposed of when the caller is # done with the return value. the context is sometimes needed to # fully construct the return object (e.g. when the object is a # sqlalchemy object bound to a session that's defined in the # context object). try: _retval.__ctx__ = ctx except AttributeError: # not all objects let this happen. (eg. built-in types # like str, but they don't need the context anyway). pass else: _retval = ctx.out_object # same as above try: _retval[0].__ctx__ = ctx except AttributeError: pass if cnt == 0: retval = _retval cnt += 1 logger.warning( "%s end request %s" % (_big_header, _big_footer) ) return retval