1 from __future__ import division
7 from twisted.internet import defer
8 from twisted.web import client
12 class Error(Exception):
13 def __init__(self, code, message, data=None):
14 if not isinstance(code, int):
15 raise TypeError('code must be an int')
16 if not isinstance(message, unicode):
17 raise TypeError('message must be a unicode')
18 self._code, self._message, self._data = code, message, data
20 return '%i %s %r' % (self._code, self._message, self._data)
24 'message': self._message,
29 def __init__(self, url, auth=None):
33 @defer.inlineCallbacks
34 def callRemote(self, method, *params):
38 'Content-Type': 'text/json',
40 if self._auth is not None:
41 headers['Authorization'] = 'Basic ' + base64.b64encode(':'.join(self._auth))
42 resp = json.loads((yield client.getPage(
55 raise ValueError('invalid id')
56 if 'error' in resp and resp['error'] is not None:
57 raise Error(resp['error'])
58 defer.returnValue(resp['result'])
60 def __getattr__(self, attr):
61 if attr.startswith('rpc_'):
62 return lambda *params: self.callRemote(attr[len('rpc_'):], *params)
63 raise AttributeError('%r object has no attribute %r' % (self.__class__.__name__, attr))
65 class Server(util.DeferredResource):
68 @defer.inlineCallbacks
69 def render_POST(self, request):
70 # missing batching, 1.0 notifications
71 data = request.content.read()
73 if self.extra_headers is not None:
74 for name, value in self.extra_headers.iteritems():
75 request.setHeader(name, value)
79 req = json.loads(data)
81 raise RemoteError(-32700, u'Parse error')
84 request.write(json.dumps({
91 id_ = req.get('id', None)
95 method = req['method']
96 if not isinstance(method, unicode):
98 params = req.get('params', [])
99 if not isinstance(params, list):
102 raise Error(-32600, u'Invalid Request')
104 method_name = 'rpc_' + method
105 if not hasattr(self, method_name):
106 raise Error(-32601, u'Method not found')
107 method_meth = getattr(self, method_name)
109 df = defer.maybeDeferred(method_meth, *params)
119 print 'Squelched JSON method error:'
120 traceback.print_exc()
121 raise Error(-32099, u'Unknown error')
123 request.write(json.dumps({
130 request.write(json.dumps({
134 'error': e._to_obj(),