1
2
3
4
5
6
7 """ JSONService is a module providing JSON RPC Client side proxying.
8 """
9
10 import sys
11 from HTTPRequest import HTTPRequest
12
13 try:
14 from jsonrpc.json import dumps, loads, JSONDecodeException
15 except ImportError:
16 from pyjamas.JSONParser import JSONParser
17 parser = JSONParser()
18 dumps = getattr(parser, 'encode')
19 loads = getattr(parser, 'decodeAsObject')
20 JSONDecodeException = None
21
22
25
26 __requestID = 0
27 __requestIDPrefix = 'ID'
28 __lastRequestID = None
45
46
48 - def __init__(self, url, handler=None, headers=None):
49 """
50 Create a JSON remote service object. The url is the URL that will
51 receive POST data with the JSON request. See the JSON-RPC spec for
52 more information.
53
54 The handler object should implement
55 onRemoteResponse(value, requestInfo)
56 to accept the return value of the remote method, and
57 onRemoteError(code, error_dict, requestInfo)
58 code = http-code or 0
59 error_dict is an jsonrpc 2.0 error dict:
60 {
61 'code': jsonrpc-error-code (integer) ,
62 'message': jsonrpc-error-message (string) ,
63 'data' : extra-error-data
64 }
65 to handle errors.
66 """
67 self.url = url
68 self.handler = handler
69 self.headers = headers if headers is not None else {}
70 if not self.headers.get("Accept"):
71 self.headers["Accept"] = "application/json"
72
73 - def callMethod(self, method, params, handler = None):
74 if handler is None:
75 handler = self.handler
76
77 if handler is None:
78 return self.sendNotify(method, params)
79 else:
80 return self.sendRequest(method, params, handler)
81
84
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106 msg = {"jsonrpc": "2.0",
107 "version": "1.1",
108 "method": method,
109 "params": params
110 }
111 msg_data = dumps(msg)
112 if not HTTPRequest().asyncPost(self.url, msg_data, self,
113 False, "text/json",
114 self.headers):
115 return -1
116 return 1
117
119 id = nextRequestID()
120 msg = {"jsonrpc": "2.0",
121 "id": id,
122 "method": method,
123 "params": params
124 }
125 msg_data = dumps(msg)
126
127 request_info = JSONRequestInfo(id, method, handler)
128 if not HTTPRequest().asyncPost(self.url, msg_data,
129 JSONResponseTextHandler(request_info),
130 False, "text/json",
131 self.headers):
132 return -1
133 return id
134
135
137 - def __init__(self, id, method, handler):
138 self.id = id
139 self.method = method
140 self.handler = handler
141
142
144 - def __init__(self, request):
145 self.request = request
146
147 - def onCompletion(self, json_str):
148 try:
149 response = loads(json_str)
150 except JSONDecodeException:
151
152 error = dict(
153 code=-32700,
154 message="Parse error while decoding response",
155 data=None,
156 )
157 self.request.handler.onRemoteError(0, error, self.request)
158 return
159
160 if not response:
161 error = dict(
162 code=-32603,
163 message="Empty Response",
164 data=None,
165 )
166 self.request.handler.onRemoteError(0, error, self.request)
167 elif response.get("error"):
168 error = response["error"]
169 jsonrpc = response.get("jsonrpc")
170 code = error.get("code", 0)
171 message = error.get("message", error)
172 data = error.get("data")
173 if not jsonrpc:
174 jsonrpc = response.get("version", "1.0")
175 if jsonrpc == "1.0":
176 message = error
177 else:
178 data = error.get("error")
179 error = dict(
180 code=code,
181 message=message,
182 data=data,
183 )
184 self.request.handler.onRemoteError(0, error, self.request)
185 elif "result" in response:
186 self.request.handler.onRemoteResponse(response["result"],
187 self.request)
188 else:
189 error = dict(
190 code=-32603,
191 message="No result or error in response",
192 data=response,
193 )
194 self.request.handler.onRemoteError(0, error, self.request)
195
196 - def onError(self, error_str, error_code):
197 error = dict(
198 code=error_code,
199 message=error_str,
200 data=None,
201 )
202 self.request.handler.onRemoteError(error_code, error, self.request)
203
205 - def __init__(self, serviceURL, serviceName=None, headers=None):
206 JSONService.__init__(self, serviceURL, headers=headers)
207 self.__serviceName = serviceName
208
210 if isinstance(params, tuple):
211 params = list(params)
212 if params and hasattr(params[-1], "onRemoteResponse"):
213 handler = params.pop()
214 else:
215 handler = None
216 if kwargs:
217 if params:
218 if not isinstance(params, dict):
219 raise JSONServiceError("Cannot mix positional and keyword arguments")
220 params.update(kwargs)
221 else:
222 params = kwargs
223 if handler is not None:
224 return JSONService.sendRequest(self, self.__serviceName,
225 params, handler)
226 else:
227 return JSONService.sendNotify(self, self.__serviceName, params)
228
229
231 - def __init__(self, url, methods=None, headers=None):
232 self._serviceURL = url
233 self.methods = methods
234 self.headers = {} if headers is None else headers
235
236 JSONService.__init__(self, url, headers=self.headers)
237 self.__registerMethods(methods)
238
240 if methods:
241 for method in methods:
242 setattr(self,
243 method,
244 getattr(ServiceProxy(self._serviceURL, method,
245 headers=self.headers),
246 '__call__')
247 )
248
249
250
251
252
253
254
255
256
257