Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# JSON-RPC Server/Client
2from ..server import ServerIf
3from ..client import ClientIf
4import json
5import requests
6from logging import getLogger
7import tornado.web
8from tornado.gen import coroutine as tasync
9# from tornado.web import asynchronous as tasync
10from tornado.ioloop import IOLoop
11from concurrent.futures import ThreadPoolExecutor
12from tornado.platform.asyncio import to_tornado_future
14log = getLogger(__name__)
17class Server(ServerIf):
18 class Handler(tornado.web.RequestHandler):
19 executor = ThreadPoolExecutor()
21 def initialize(self, d):
22 log.debug("initialize %s", d)
23 self.d = d
25 def set_default_headers(self):
26 self.set_header("content-type", "application/json")
28 async def bgtask(self, method, params):
29 ft = Server.Handler.executor.submit(self.d, method, params)
30 result = await to_tornado_future(ft)
31 return result
33 @tasync
34 def post(self):
35 payload = json.loads(self.request.body)
36 log.debug("got request %s", payload)
37 method = payload.get("method")
38 params = payload.get("params", {})
39 result = yield from self.bgtask(method, params)
40 resp = {
41 "result": result,
42 "id": payload.get("id"),
43 }
44 json.dump(resp, self, ensure_ascii=False)
46 def __init__(self, addr: str, params: dict = {}):
47 super().__init__(addr, params)
48 self.baseurl = self.addr_parsed.path
50 def serve(self, fn):
51 app = tornado.web.Application(
52 handlers=[(self.baseurl, self.Handler, {"d": fn}), ])
53 app.listen(self.addr_parsed.port)
54 try:
55 IOLoop.current().start()
56 except RuntimeError as e:
57 log.error("error %s", e)
58 # raise e
61class Client(ClientIf):
62 hdrs = {
63 "content-type": "application/json",
64 }
66 def call(self, method, params=None):
67 payload = {
68 "method": method,
69 "params": params,
70 "jsonrpc": "2.0",
71 "id": 0,
72 }
73 log.debug("send request %s", payload)
74 return requests.post(self.addr, data=json.dumps(payload), headers=self.hdrs).json().get("result")