Browse code
refactoring: removing code duplicated between server and client
Ed L authored on 03/06/2011 02:14:42
Showing 6 changed files
Showing 6 changed files
- doc/source/getting_started.rst
- doc/source/index.rst
- jsonrpc/common.py
- jsonrpc/example_server.py
- jsonrpc/proxy.py
- jsonrpc/server.py
... | ... |
@@ -40,15 +40,13 @@ add and subtract: |
40 | 40 |
:tab-width: 2 |
41 | 41 |
:lines: 2,3,34- |
42 | 42 |
|
43 |
-To use the server, start the client this way: |
|
43 |
+To use this server (which is included as jsonrpc.example_server), start it and the client in this way: |
|
44 | 44 |
|
45 |
-.. code-block:: bash |
|
45 |
+.. code-block:: console |
|
46 | 46 |
|
47 |
- # Python 2.6 |
|
48 |
- % python2.6 -i -m jsonrpc.__main__ http://localhost:8007 |
|
47 |
+ % python -m jsonrpc.example_server & |
|
49 | 48 |
|
50 |
- # Python 2.7 |
|
51 |
- % python2.7 -i -m jsonrpc http://localhost:8007 |
|
49 |
+ % python -i -m jsonrpc.__main__ http://localhost:8007 |
|
52 | 50 |
|
53 | 51 |
.. code-block:: python |
54 | 52 |
|
54 | 54 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,187 @@ |
1 |
+# |
|
2 |
+# Copyright (c) 2011 Edward Langley |
|
3 |
+# All rights reserved. |
|
4 |
+# |
|
5 |
+# Redistribution and use in source and binary forms, with or without |
|
6 |
+# modification, are permitted provided that the following conditions |
|
7 |
+# are met: |
|
8 |
+# |
|
9 |
+# Redistributions of source code must retain the above copyright notice, |
|
10 |
+# this list of conditions and the following disclaimer. |
|
11 |
+# |
|
12 |
+# Redistributions in binary form must reproduce the above copyright |
|
13 |
+# notice, this list of conditions and the following disclaimer in the |
|
14 |
+# documentation and/or other materials provided with the distribution. |
|
15 |
+# |
|
16 |
+# Neither the name of the project's author nor the names of its |
|
17 |
+# contributors may be used to endorse or promote products derived from |
|
18 |
+# this software without specific prior written permission. |
|
19 |
+# |
|
20 |
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
21 |
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
22 |
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
23 |
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|
24 |
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
25 |
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED |
|
26 |
+# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
|
27 |
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
|
28 |
+# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
|
29 |
+# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
|
30 |
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
31 |
+# |
|
32 |
+# |
|
33 |
+from jsonrpc.utilities import public |
|
34 |
+import jsonrpc.jsonutil |
|
35 |
+ |
|
36 |
+@public |
|
37 |
+class RPCError(Exception): |
|
38 |
+ '''Base Exception for JSON-RPC Errors, if this or a subclass of this is raised by a JSON-RPC method, |
|
39 |
+ The server will convert it into an appropriate error object |
|
40 |
+ ''' |
|
41 |
+ |
|
42 |
+ #: Error code |
|
43 |
+ code = 0 |
|
44 |
+ #: Error message |
|
45 |
+ msg = "" |
|
46 |
+ |
|
47 |
+ @classmethod |
|
48 |
+ def from_dict(cls, err): |
|
49 |
+ self = cls() |
|
50 |
+ self.code = err['code'] |
|
51 |
+ self.msg = err['message'] |
|
52 |
+ return self |
|
53 |
+ |
|
54 |
+ def json_equivalent(self): |
|
55 |
+ '''return a dictionary which matches an JSON-RPC Response''' |
|
56 |
+ return dict(code=self.code, message=self.msg) |
|
57 |
+ |
|
58 |
+ def __str__(self): |
|
59 |
+ return jsonrpc.jsonutil.encode(self) |
|
60 |
+ |
|
61 |
+@public |
|
62 |
+class InvalidRequest(RPCError): |
|
63 |
+ '''Raise this when the Request object does not match the schema''' |
|
64 |
+ code = -32600 |
|
65 |
+ msg = "Invalid Request." |
|
66 |
+ |
|
67 |
+@public |
|
68 |
+class MethodNotFound(RPCError): |
|
69 |
+ '''Raise this when the desired method is not found''' |
|
70 |
+ code = -32601 |
|
71 |
+ msg = "Procedure not found." |
|
72 |
+ |
|
73 |
+@public |
|
74 |
+class ParseError(RPCError): |
|
75 |
+ '''Raise this when the request contains invalid JSON''' |
|
76 |
+ code = -32700 |
|
77 |
+ msg = "Parse error." |
|
78 |
+ |
|
79 |
+codemap = {0: RPCError} |
|
80 |
+codemap.update( (e.code, e) for e in RPCError.__subclasses__() ) |
|
81 |
+ |
|
82 |
+class JsonInstantiate: |
|
83 |
+ @classmethod |
|
84 |
+ def from_json(cls, json): |
|
85 |
+ data = jsonrpc.jsonutil.decode(json) |
|
86 |
+ if isinstance(data, list): |
|
87 |
+ result = cls.from_list(data) |
|
88 |
+ else: |
|
89 |
+ result = cls.from_dict(data) |
|
90 |
+ return result |
|
91 |
+ |
|
92 |
+ @classmethod |
|
93 |
+ def from_list(cls, responses): |
|
94 |
+ return [cls.from_dict(r) for r in responses] |
|
95 |
+ |
|
96 |
+ |
|
97 |
+class Request(object, JsonInstantiate): |
|
98 |
+ def __init__(self, id, method, args=None, kwargs=None, extra=None, version='2.0'): |
|
99 |
+ self.version = version |
|
100 |
+ self.id = id |
|
101 |
+ self.method = method |
|
102 |
+ self.args = args |
|
103 |
+ self.kwargs = kwargs |
|
104 |
+ self.extra = extra or {} |
|
105 |
+ |
|
106 |
+ @classmethod |
|
107 |
+ def from_dict(cls, content): |
|
108 |
+ version = content.pop('jsonrpc', None) |
|
109 |
+ id = content.pop('id', None) |
|
110 |
+ |
|
111 |
+ method = content.pop('method', None) |
|
112 |
+ |
|
113 |
+ kwargs = content.pop('params', {}) |
|
114 |
+ args = () |
|
115 |
+ if not isinstance(kwargs, dict): |
|
116 |
+ args = tuple(kwargs) |
|
117 |
+ kwargs = {} |
|
118 |
+ else: |
|
119 |
+ args = kwargs.pop('__args', args) |
|
120 |
+ |
|
121 |
+ args = args |
|
122 |
+ kwargs = dict( (str(k), v) for k,v in kwargs.items() ) |
|
123 |
+ extra = content |
|
124 |
+ return cls(id, method, args, kwargs, extra, version) |
|
125 |
+ |
|
126 |
+ |
|
127 |
+ def check(self): |
|
128 |
+ if self.version != '2.0': raise InvalidRequest |
|
129 |
+ if not isinstance(self.method, (str, unicode)): raise InvalidRequest |
|
130 |
+ |
|
131 |
+ |
|
132 |
+ def json_equivalent(self): |
|
133 |
+ if self.kwargs.has_key('__args'): |
|
134 |
+ raise ValueError, 'invalid argument name: __args' |
|
135 |
+ |
|
136 |
+ params = self.args |
|
137 |
+ if self.args and self.kwargs: |
|
138 |
+ self.kwargs['__args'] = self.args |
|
139 |
+ if self.kwargs: |
|
140 |
+ result['params'] = self.kwargs |
|
141 |
+ |
|
142 |
+ return dict( |
|
143 |
+ jsonrpc = self.version, |
|
144 |
+ id = self.id, |
|
145 |
+ method = self.method, |
|
146 |
+ params = params |
|
147 |
+ ) |
|
148 |
+ |
|
149 |
+ |
|
150 |
+ |
|
151 |
+class Response(object, JsonInstantiate): |
|
152 |
+ def __init__(self, id=None, result=None, error=None, version='2.0'): |
|
153 |
+ self.version = version |
|
154 |
+ self.id = id |
|
155 |
+ self.result = result |
|
156 |
+ self.error = error |
|
157 |
+ |
|
158 |
+ |
|
159 |
+ @classmethod |
|
160 |
+ def from_dict(cls, response): |
|
161 |
+ version = response.get('jsonrpc', None) |
|
162 |
+ id = response['id'] |
|
163 |
+ result = response.get('result', None) |
|
164 |
+ error = response.get('error', None) |
|
165 |
+ |
|
166 |
+ return cls(id, result, error, version) |
|
167 |
+ |
|
168 |
+ def json_equivalent(self): |
|
169 |
+ res = dict(jsonrpc=self.version, id=self.id) |
|
170 |
+ if self.error is None: |
|
171 |
+ res['result'] = self.result |
|
172 |
+ else: |
|
173 |
+ res['error'] = self.error |
|
174 |
+ return res |
|
175 |
+ |
|
176 |
+ def get_result(self): |
|
177 |
+ '''get result and raise any errors''' |
|
178 |
+ if self.error: |
|
179 |
+ code = self.error['code'] |
|
180 |
+ raise codemap.get(code, RPCError).from_dict(self.error) |
|
181 |
+ return self.result |
|
182 |
+ |
|
183 |
+ def get_output(self): |
|
184 |
+ '''get tuple (result, error)''' |
|
185 |
+ return self.result, self.error |
|
186 |
+ |
|
187 |
+ |
... | ... |
@@ -42,10 +42,10 @@ class ExampleServer(ServerEvents): |
42 | 42 |
def log(self, responses, txrequest): |
43 | 43 |
if isinstance(responses, list): |
44 | 44 |
for response in responses: |
45 |
- msg = self.get_msg(response) |
|
45 |
+ msg = self._get_msg(response) |
|
46 | 46 |
print txrequest, msg |
47 | 47 |
else: |
48 |
- msg = self.get_msg(response) |
|
48 |
+ msg = self._get_msg(responses) |
|
49 | 49 |
print txrequest, msg |
50 | 50 |
|
51 | 51 |
def findmethod(self, method): |
... | ... |
@@ -57,7 +57,7 @@ class ExampleServer(ServerEvents): |
57 | 57 |
# helper methods |
58 | 58 |
methods = set(['add', 'subtract']) |
59 | 59 |
def _get_msg(self, response): |
60 |
- return ' '.join([response.id, response.result or response.error]) |
|
60 |
+ return ' '.join(str(x) for x in [response.id, response.result or response.error]) |
|
61 | 61 |
|
62 | 62 |
def subtract(self, a, b): |
63 | 63 |
return a-b |
... | ... |
@@ -65,7 +65,7 @@ class ExampleServer(ServerEvents): |
65 | 65 |
def add(self, a, b): |
66 | 66 |
return a+b |
67 | 67 |
|
68 |
-root = JSON_RPC().customize(JSONRPCTest) |
|
68 |
+root = JSON_RPC().customize(ExampleServer) |
|
69 | 69 |
site = server.Site(root) |
70 | 70 |
|
71 | 71 |
|
... | ... |
@@ -1,24 +1,24 @@ |
1 | 1 |
# $Id: proxy.py,v 1.20 2011/05/26 20:19:17 edwlan Exp $ |
2 | 2 |
|
3 |
-# |
|
3 |
+# |
|
4 | 4 |
# Copyright (c) 2011 Edward Langley |
5 | 5 |
# All rights reserved. |
6 |
-# |
|
6 |
+# |
|
7 | 7 |
# Redistribution and use in source and binary forms, with or without |
8 | 8 |
# modification, are permitted provided that the following conditions |
9 | 9 |
# are met: |
10 |
-# |
|
10 |
+# |
|
11 | 11 |
# Redistributions of source code must retain the above copyright notice, |
12 | 12 |
# this list of conditions and the following disclaimer. |
13 |
-# |
|
13 |
+# |
|
14 | 14 |
# Redistributions in binary form must reproduce the above copyright |
15 | 15 |
# notice, this list of conditions and the following disclaimer in the |
16 | 16 |
# documentation and/or other materials provided with the distribution. |
17 |
-# |
|
17 |
+# |
|
18 | 18 |
# Neither the name of the project's author nor the names of its |
19 | 19 |
# contributors may be used to endorse or promote products derived from |
20 | 20 |
# this software without specific prior written permission. |
21 |
-# |
|
21 |
+# |
|
22 | 22 |
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
23 | 23 |
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
24 | 24 |
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
... | ... |
@@ -30,7 +30,7 @@ |
30 | 30 |
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
31 | 31 |
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
32 | 32 |
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
33 |
-# |
|
33 |
+# |
|
34 | 34 |
# |
35 | 35 |
import copy |
36 | 36 |
import urllib |
... | ... |
@@ -44,6 +44,7 @@ collections.Mapping.register(UserDict.DictMixin) |
44 | 44 |
|
45 | 45 |
from hashlib import sha1 |
46 | 46 |
import jsonrpc.jsonutil |
47 |
+from jsonrpc.common import Response, Request |
|
47 | 48 |
|
48 | 49 |
__all__ = ['JSONRPCProxy', 'ProxyEvents'] |
49 | 50 |
|
... | ... |
@@ -56,13 +57,6 @@ class NewStyleBaseException(Exception): |
56 | 57 |
message = property(_get_message, _set_message) |
57 | 58 |
|
58 | 59 |
|
59 |
-class JSONRPCException(NewStyleBaseException): |
|
60 |
- def __init__(self, rpcError): |
|
61 |
- Exception.__init__(self, rpcError.get('message')) |
|
62 |
- self.data = rpcError.get('data') |
|
63 |
- self.message = rpcError.get('message') |
|
64 |
- self.code = rpcError.get('code') |
|
65 |
- |
|
66 | 60 |
class IDGen(object): |
67 | 61 |
def __init__(self): |
68 | 62 |
self._hasher = sha1() |
... | ... |
@@ -98,33 +92,6 @@ class ProxyEvents(object): |
98 | 92 |
'''allow a subclass to access the response data before it is returned to the user''' |
99 | 93 |
return data |
100 | 94 |
|
101 |
- |
|
102 |
-class Request(object): |
|
103 |
- |
|
104 |
- def __init__(self, id, method, args=None, kwargs=None): |
|
105 |
- self.version = '2.0' |
|
106 |
- self.id = id |
|
107 |
- self.method = method |
|
108 |
- self.args = args |
|
109 |
- self.kwargs = kwargs |
|
110 |
- |
|
111 |
- def json_equivalent(self): |
|
112 |
- if kwargs.has_key('__args'): |
|
113 |
- raise ValueError, 'invalid argument name: __args' |
|
114 |
- |
|
115 |
- result = dict( |
|
116 |
- jsonrpc = self.version, |
|
117 |
- id = self.id, |
|
118 |
- method = self.method |
|
119 |
- ) |
|
120 |
- |
|
121 |
- if self.args and self.kwargs: |
|
122 |
- self.kwargs['__args'] = self.args |
|
123 |
- |
|
124 |
- |
|
125 |
- |
|
126 |
- |
|
127 |
- |
|
128 | 95 |
class JSONRPCProxy(object): |
129 | 96 |
'''A class implementing a JSON-RPC Proxy. |
130 | 97 |
|
... | ... |
@@ -182,9 +149,8 @@ class JSONRPCProxy(object): |
182 | 149 |
def _get_postdata(self, args=None, kwargs=None): |
183 | 150 |
args,kwargs = self._eventhandler.get_postdata(args, kwargs) |
184 | 151 |
id = self._eventhandler.IDGen |
185 |
- return Request(id, self._serviceNams, args, kwargs) |
|
186 |
- postdata = jsonrpc.jsonutil.encode({ }) |
|
187 |
- return postdata |
|
152 |
+ result = Request(id, self._serviceName, args, kwargs) |
|
153 |
+ return jsonrpc.jsonutil.encode(result) |
|
188 | 154 |
|
189 | 155 |
|
190 | 156 |
def __call__(self, *args, **kwargs): |
... | ... |
@@ -192,14 +158,10 @@ class JSONRPCProxy(object): |
192 | 158 |
url = '%(host)s%(path)s' % dict(host = self.serviceURL, path = self._path) |
193 | 159 |
postdata = self._get_postdata(args, kwargs) |
194 | 160 |
respdata = urllib.urlopen(url, postdata).read() |
195 |
- resp = jsonrpc.jsonutil.decode(respdata) |
|
161 |
+ resp = Response.from_dict(jsonrpc.jsonutil.decode(respdata)) |
|
162 |
+ resp = self._eventhandler.proc_response(resp) |
|
196 | 163 |
|
197 |
- if resp.get('error') != None: |
|
198 |
- raise JSONRPCException(resp['error']) |
|
199 |
- else: |
|
200 |
- resp = self._eventhandler.proc_response(resp) |
|
201 |
- result = resp['result'] |
|
202 |
- return result |
|
164 |
+ return resp.get_result() |
|
203 | 165 |
|
204 | 166 |
|
205 | 167 |
def call(self, method, *args, **kwargs): |
... | ... |
@@ -218,9 +180,15 @@ class JSONRPCProxy(object): |
218 | 180 |
:param names: a dictionary { method: (args, kwargs) } |
219 | 181 |
:returns: a list of pairs (result, error) where only one is not None |
220 | 182 |
''' |
183 |
+ result = None |
|
221 | 184 |
if hasattr(methods, 'items'): methods = methods.items() |
222 | 185 |
data = [ getattr(self, k)._get_postdata(*v) for k, v in methods ] |
223 | 186 |
postdata = '[%s]' % ','.join(data) |
224 | 187 |
respdata = urllib.urlopen(self.serviceURL, postdata).read() |
225 |
- resp = jsonrpc.jsonutil.decode(respdata) |
|
226 |
- return [(res.get('result'), res.get('error')) for res in resp] |
|
188 |
+ resp = Response.from_json(respdata) |
|
189 |
+ try: |
|
190 |
+ result = resp.get_result() |
|
191 |
+ except AttributeError: |
|
192 |
+ result = [res.get_output() for res in resp] |
|
193 |
+ |
|
194 |
+ return result |
... | ... |
@@ -1,5 +1,3 @@ |
1 |
-# $Id: server.py,v 1.8 2011/05/26 19:34:19 edwlan Exp $ |
|
2 |
- |
|
3 | 1 |
# |
4 | 2 |
# Copyright (c) 2011 Edward Langley |
5 | 3 |
# All rights reserved. |
... | ... |
@@ -34,6 +32,7 @@ |
34 | 32 |
# |
35 | 33 |
import jsonrpc.jsonutil |
36 | 34 |
from jsonrpc.utilities import public |
35 |
+import jsonrpc.common |
|
37 | 36 |
|
38 | 37 |
# Twisted imports |
39 | 38 |
from twisted.web import server |
... | ... |
@@ -56,7 +55,7 @@ class ServerEvents(object): |
56 | 55 |
def callmethod(self, txrequest, rpcrequest, **extra): |
57 | 56 |
'''Finds the method and calls it with the specified args''' |
58 | 57 |
method = self.findmethod(rpcrequest.method) |
59 |
- if method is None: raise MethodNotFound |
|
58 |
+ if method is None: raise jsonrpc.common.MethodNotFound |
|
60 | 59 |
extra.update(rpcrequest.kwargs) |
61 | 60 |
|
62 | 61 |
return method(*rpcrequest.args, **extra) |
... | ... |
@@ -78,88 +77,6 @@ class ServerEvents(object): |
78 | 77 |
return content |
79 | 78 |
|
80 | 79 |
|
81 |
-@public |
|
82 |
-class ServerError(Exception): |
|
83 |
- '''Base Exception for JSON-RPC Errors, if this or a subclass of this is raised by a JSON-RPC method, |
|
84 |
- The server will convert it into an appropriate error object |
|
85 |
- ''' |
|
86 |
- |
|
87 |
- #: Error code |
|
88 |
- code = 0 |
|
89 |
- #: Error message |
|
90 |
- msg = "" |
|
91 |
- |
|
92 |
- def json_equivalent(self): |
|
93 |
- '''return a dictionary which matches an JSON-RPC Response''' |
|
94 |
- return dict(code=self.code, message=self.msg) |
|
95 |
- |
|
96 |
- def __str__(self): |
|
97 |
- return jsonrpc.jsonutil.encode(self) |
|
98 |
- |
|
99 |
-@public |
|
100 |
-class InvalidRequest(ServerError): |
|
101 |
- '''Raise this when the Request object does not match the schema''' |
|
102 |
- code = -32600 |
|
103 |
- msg = "Invalid Request." |
|
104 |
- |
|
105 |
-@public |
|
106 |
-class MethodNotFound(ServerError): |
|
107 |
- '''Raise this when the desired method is not found''' |
|
108 |
- code = -32601 |
|
109 |
- msg = "Procedure not found." |
|
110 |
- |
|
111 |
-@public |
|
112 |
-class ParseError(ServerError): |
|
113 |
- '''Raise this when the request contains invalid JSON''' |
|
114 |
- code = -32700 |
|
115 |
- msg = "Parse error." |
|
116 |
- |
|
117 |
-class Request(object): |
|
118 |
- def __init__(self, content): |
|
119 |
- self.version = content.pop('jsonrpc', None) |
|
120 |
- self.id = content.pop('id', None) |
|
121 |
- |
|
122 |
- self.method = content.pop('method', None) |
|
123 |
- |
|
124 |
- kwargs = content.pop('params', {}) |
|
125 |
- args = () |
|
126 |
- if not isinstance(kwargs, dict): |
|
127 |
- args = tuple(kwargs) |
|
128 |
- kwargs = {} |
|
129 |
- else: |
|
130 |
- args = kwargs.pop('__args', args) |
|
131 |
- |
|
132 |
- self.args = args |
|
133 |
- self.kwargs = dict( (str(k), v) for k,v in kwargs.items() ) |
|
134 |
- self.extra = content |
|
135 |
- |
|
136 |
- def check(self): |
|
137 |
- if self.version != '2.0': raise InvalidRequest |
|
138 |
- if not isinstance(self.method, (str, unicode)): raise InvalidRequest |
|
139 |
- |
|
140 |
- @classmethod |
|
141 |
- def from_list(cls, content): |
|
142 |
- result = [] |
|
143 |
- for req in content: |
|
144 |
- result.append(cls(req)) |
|
145 |
- return result |
|
146 |
- |
|
147 |
- |
|
148 |
-class Response(object): |
|
149 |
- def __init__(self, id=None, result=None, error=None): |
|
150 |
- self.version = '2.0' |
|
151 |
- self.id = id |
|
152 |
- self.result = result |
|
153 |
- self.error = error |
|
154 |
- |
|
155 |
- def json_equivalent(self): |
|
156 |
- res = dict(jsonrpc=self.version, id=self.id) |
|
157 |
- if self.error is None: |
|
158 |
- res['result'] = self.result |
|
159 |
- else: |
|
160 |
- res['error'] = self.error |
|
161 |
- return res |
|
162 |
- |
|
163 | 80 |
|
164 | 81 |
## Base class providing a JSON-RPC 2.0 implementation with 2 customizable hooks |
165 | 82 |
@public |
... | ... |
@@ -186,14 +103,14 @@ class JSON_RPC(Resource): |
186 | 103 |
try: |
187 | 104 |
try: |
188 | 105 |
content = jsonrpc.jsonutil.decode(request.content.read()) |
189 |
- except ValueError: raise ParseError |
|
106 |
+ except ValueError: raise jsonrpc.common.ParseError |
|
190 | 107 |
|
191 | 108 |
content = self.eventhandler.processcontent(content, request) |
192 | 109 |
|
193 | 110 |
if isinstance(content, list): |
194 |
- content = Request.from_list(content) |
|
111 |
+ content = jsonrpc.common.Request.from_list(content) |
|
195 | 112 |
else: |
196 |
- content = Request(content) |
|
113 |
+ content = jsonrpc.common.Request.from_dict(content) |
|
197 | 114 |
|
198 | 115 |
try: |
199 | 116 |
if hasattr(content, 'check'): |
... | ... |
@@ -201,7 +118,7 @@ class JSON_RPC(Resource): |
201 | 118 |
else: |
202 | 119 |
for item in content: item.check() |
203 | 120 |
|
204 |
- except ServerError, e: |
|
121 |
+ except jsonrpc.common.RPCError, e: |
|
205 | 122 |
self._ebRender(e, request, content.id if hasattr(content, 'id') else None) |
206 | 123 |
|
207 | 124 |
d = threads.deferToThread(self._action, request, content) |
... | ... |
@@ -218,7 +135,7 @@ class JSON_RPC(Resource): |
218 | 135 |
islist = (True if isinstance(contents, list) else False) |
219 | 136 |
if not islist: contents = [contents] |
220 | 137 |
|
221 |
- if contents == []: raise InvalidRequest |
|
138 |
+ if contents == []: raise jsonrpc.common.InvalidRequest |
|
222 | 139 |
|
223 | 140 |
for rpcrequest in contents: |
224 | 141 |
res = None |
... | ... |
@@ -226,7 +143,7 @@ class JSON_RPC(Resource): |
226 | 143 |
try: |
227 | 144 |
add = copy.deepcopy(rpcrequest.extra) |
228 | 145 |
add.update(kw) |
229 |
- res = Response(id=rpcrequest.id, result=self.eventhandler.callmethod(request, rpcrequest, **add)) |
|
146 |
+ res = jsonrpc.common.Response(id=rpcrequest.id, result=self.eventhandler.callmethod(request, rpcrequest, **add)) |
|
230 | 147 |
res = self.eventhandler.processrequest(res, request.args, **kw) |
231 | 148 |
except Exception, e: |
232 | 149 |
res = self.render_error(e, rpcrequest.id) |
... | ... |
@@ -274,10 +191,10 @@ class JSON_RPC(Resource): |
274 | 191 |
|
275 | 192 |
|
276 | 193 |
def render_error(self, e, id): |
277 |
- if isinstance(e, ServerError): |
|
278 |
- err = Response(id=id, error=e) |
|
194 |
+ if isinstance(e, jsonrpc.common.RPCError): |
|
195 |
+ err = jsonrpc.common.Response(id=id, error=e) |
|
279 | 196 |
else: |
280 |
- err = Response(id=id, error=dict(code=0, message=str(e), data=e.args)) |
|
197 |
+ err = jsonrpc.common.Response(id=id, error=dict(code=0, message=str(e), data=e.args)) |
|
281 | 198 |
|
282 | 199 |
return err |
283 | 200 |
|