X-Git-Url: http://xvm.mit.edu/gitweb/invirt/packages/python-jsonrpclib.git/blobdiff_plain/8ce7c31e5d151b8376e3d06a291a2cd25466dbc5..b2a4ba47c80af3bd11c3a1fd68c1ea579e23092e:/jsonrpclib.py diff --git a/jsonrpclib.py b/jsonrpclib.py index 7fc6177..19cb47d 100644 --- a/jsonrpclib.py +++ b/jsonrpclib.py @@ -106,6 +106,9 @@ class Transport(XMLTransport): if self.verbose: print 'body: %s' % response response_body += response + if response_body == '': + # Notification + return None return_obj = loads(response_body) return return_obj @@ -160,10 +163,6 @@ class ServerProxy(XMLServerProxy): global _last_request global _last_response _last_request = request - - if notify is True: - _last_response = None - return None response = self.__transport.request( self.__host, @@ -179,7 +178,10 @@ class ServerProxy(XMLServerProxy): # outputting the response appropriately? _last_response = response - return response + if not response: + # notification, no result + return None + return check_for_errors(response) def __getattr__(self, name): # Same as original, just with new _Method and wrapper @@ -201,7 +203,7 @@ class _Method(XML_Method): # Batch implementation -class Job(object): +class MultiCallMethod(object): def __init__(self, method, notify=False): self.method = method @@ -224,15 +226,15 @@ class Job(object): def __repr__(self): return '%s' % self.request() -class BatchServerProxy(ServerProxy): +class MultiCall(object): - def __init__(self, uri, *args, **kwargs): + def __init__(self, server): + self.__server = server self.__job_list = [] - ServerProxy.__init__(self, uri, *args, **kwargs) def __run_request(self, request_body): - run_request = getattr(ServerProxy, '_ServerProxy__run_request') - return run_request(self, request_body) + run_request = getattr(self.__server, '_ServerProxy__run_request') + return run_request(request_body) def __request(self): if len(self.__job_list) < 1: @@ -244,50 +246,42 @@ class BatchServerProxy(ServerProxy): del self.__job_list[:] return [ response['result'] for response in responses ] - def __notify(self, method, params): - new_job = Job(method, notify=True) + def __notify(self, method, params=[]): + new_job = MultiCallMethod(method, notify=True) + new_job.params = params self.__job_list.append(new_job) - + def __getattr__(self, name): if name in ('__run', '__notify'): wrapped_name = '_%s%s' % (self.__class__.__name__, name) return getattr(self, wrapped_name) - new_job = Job(name) + new_job = MultiCallMethod(name) self.__job_list.append(new_job) return new_job - __run = __request + __call__ = __request # These lines conform to xmlrpclib's "compatibility" line. # Not really sure if we should include these, but oh well. Server = ServerProxy -BatchServer = BatchServerProxy - -def run(batch): - """ - This method is just a caller for the __run() on the actual - BatchServer itself. Useful only for those who don't like - calling __ methods. :) - """ - batch.__run() - - -class Fault(dict): +class Fault(object): # JSON-RPC error class def __init__(self, code=-32000, message='Server error'): - self.code = code - self.message = message + self.faultCode = code + self.faultString = message def error(self): - return {'code':self.code, 'message':self.message} + return {'code':self.faultCode, 'message':self.faultString} def response(self, rpcid=None, version=None): global _version if not version: version = _version - return dumps(self, rpcid=None, methodresponse=True, - version=version) + return dumps(self, rpcid=rpcid, version=version) + + def __repr__(self): + return '' % (self.faultCode, self.faultString) def random_id(length=8): import string @@ -350,7 +344,7 @@ def dumps(params=[], methodname=None, methodresponse=None, """ global _version if not version: - verion = _version + version = _version valid_params = (types.TupleType, types.ListType, types.DictType) if methodname in types.StringTypes and \ type(params) not in valid_params and \ @@ -361,18 +355,16 @@ def dumps(params=[], methodname=None, methodresponse=None, """ raise TypeError('Params must be a dict, list, tuple or Fault ' + 'instance.') - if type(methodname) not in types.StringTypes and methodresponse != True: - raise ValueError('Method name must be a string, or methodresponse '+ - 'must be set to True.') - if isinstance(params, Fault) and not methodresponse: - raise TypeError('You can only use a Fault for responses.') # Begin parsing object payload = Payload(rpcid=rpcid, version=version) if not encoding: encoding = 'utf-8' if type(params) is Fault: - response = payload.error(params.code, params.message) + response = payload.error(params.faultCode, params.faultString) return jdumps(response, encoding=encoding) + if type(methodname) not in types.StringTypes and methodresponse != True: + raise ValueError('Method name must be a string, or methodresponse '+ + 'must be set to True.') if methodresponse is True: if rpcid is None: raise ValueError('A method response must have an rpcid.') @@ -391,11 +383,16 @@ def loads(data): the request structure in Dict format instead of the method, params. It will return a list in the case of a batch request / response. """ + if data == '': + # notification + return None result = jloads(data) # if the above raises an error, the implementing server code # should return something like the following: # { 'jsonrpc':'2.0', 'error': fault.error(), id: None } - + return result + +def check_for_errors(result): result_list = [] if not isbatch(result): result_list.append(result)