Add http server jsonrpc code
This commit is contained in:
parent
a7f859b952
commit
2e687114af
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
__pycache__
|
||||
*.pyc
|
||||
dist/
|
||||
*.egg-info
|
||||
gmon.out
|
3
config/httpd.ini
Normal file
3
config/httpd.ini
Normal file
@ -0,0 +1,3 @@
|
||||
[httpd]
|
||||
host =
|
||||
port =
|
2
config/store.ini
Normal file
2
config/store.ini
Normal file
@ -0,0 +1,2 @@
|
||||
[store]
|
||||
base_dir = /run
|
144
eth_stat_syncer/runnable/server.py
Normal file
144
eth_stat_syncer/runnable/server.py
Normal file
@ -0,0 +1,144 @@
|
||||
# standard import
|
||||
import json
|
||||
import os
|
||||
import logging
|
||||
import argparse
|
||||
import sys
|
||||
from http.server import (
|
||||
HTTPServer,
|
||||
BaseHTTPRequestHandler,
|
||||
)
|
||||
|
||||
# external imports
|
||||
import confini
|
||||
from jsonrpc_std.parse import jsonrpc_from_str
|
||||
from jsonrpc_std.interface import jsonrpc_response
|
||||
|
||||
# local imports
|
||||
from eth_stat_syncer.store import RunStore
|
||||
|
||||
logging.basicConfig(level=logging.WARNING)
|
||||
logg = logging.getLogger()
|
||||
|
||||
default_config_dir = os.environ.get('CONFINI_DIR', './config')
|
||||
|
||||
argparser = argparse.ArgumentParser()
|
||||
argparser.add_argument('-c', '--config', dest='c', default=default_config_dir, type=str, help='rpc provider')
|
||||
argparser.add_argument('--host', type=str, help='httpd host')
|
||||
argparser.add_argument('--port', type=str, help='httpd port')
|
||||
argparser.add_argument('--store-dir', dest='store_dir', type=str, help='syncerd data store base directory')
|
||||
argparser.add_argument('--env-prefix', default=os.environ.get('CONFINI_ENV_PREFIX'), dest='env_prefix', type=str, help='environment prefix for variables to overwrite configuration')
|
||||
argparser.add_argument('-v', action='store_true', help='be verbose')
|
||||
argparser.add_argument('-vv', action='store_true', help='be more verbose')
|
||||
args = argparser.parse_args()
|
||||
|
||||
if args.vv:
|
||||
logging.getLogger().setLevel(logging.DEBUG)
|
||||
elif args.v:
|
||||
logging.getLogger().setLevel(logging.INFO)
|
||||
|
||||
config = confini.Config(args.c, args.env_prefix)
|
||||
config.process()
|
||||
# override args
|
||||
args_override = {
|
||||
'HTTPD_HOST': getattr(args, 'host'),
|
||||
'HTTPD_PORT': getattr(args, 'port'),
|
||||
'STORE_BASE_DIR': getattr(args, 'store_dir'),
|
||||
}
|
||||
config.dict_override(args_override, 'cli flag')
|
||||
logg.debug('loaded config: {}\n'.format(config))
|
||||
|
||||
class StatRequestHandler(BaseHTTPRequestHandler):
|
||||
|
||||
runstore = None
|
||||
server_version = 'eth_stat_syncer/0.0.1'
|
||||
|
||||
|
||||
def do_POST(self):
|
||||
|
||||
if self.headers.get('Content-Type') != 'application/json':
|
||||
self.send_response(400, 'me read json only')
|
||||
self.end_headers()
|
||||
return
|
||||
|
||||
if 'application/json' not in self.headers.get('Accept').split(','):
|
||||
self.send_response(400, 'me json only speak')
|
||||
self.end_headers()
|
||||
return
|
||||
|
||||
l = self.headers.get('Content-Length')
|
||||
try:
|
||||
l = int(l)
|
||||
except ValueError:
|
||||
self.send_response(400, 'content length must be integer')
|
||||
self.end_headers()
|
||||
return
|
||||
if l > 4096:
|
||||
self.send_response(400, 'too much information')
|
||||
self.end_headers()
|
||||
return
|
||||
if l < 0:
|
||||
self.send_response(400, 'you are too negative')
|
||||
self.end_headers()
|
||||
return
|
||||
|
||||
b = b''
|
||||
c = 0
|
||||
while c < l:
|
||||
d = self.rfile.read(l-c)
|
||||
if d == None:
|
||||
break
|
||||
b += d
|
||||
c += len(d)
|
||||
if c > 4096:
|
||||
self.send_response(413, 'i should slap you around for lying about your size')
|
||||
self.end_headers()
|
||||
return
|
||||
|
||||
o = None
|
||||
err = None
|
||||
try:
|
||||
o = jsonrpc_from_str(b.decode('utf-8'))
|
||||
except JSONRPCException as e:
|
||||
err = e
|
||||
|
||||
if err != None:
|
||||
res = e
|
||||
self.send_response(200, 'alas with jsonrpc error')
|
||||
|
||||
else:
|
||||
r = self.runstore.get('high', 'minute')
|
||||
r = int(r)
|
||||
if r == 0:
|
||||
r = 1
|
||||
res = jsonrpc_response(o['id'], r)
|
||||
logg.debug('returning {} for req {} {}'.format(r, o, self.requestline))
|
||||
self.send_response(200, 'It\'s a gas')
|
||||
|
||||
b = json.dumps(res).encode('utf-8')
|
||||
l = len(b)
|
||||
self.send_header('Content-Length', str(l))
|
||||
self.send_header('Cache-Control', 'no-cache')
|
||||
self.send_header('Content-Type', 'application/json')
|
||||
self.end_headers()
|
||||
|
||||
c = 0
|
||||
while c < l:
|
||||
n = self.wfile.write(b[c:])
|
||||
c += n
|
||||
|
||||
|
||||
def run(store, host=None, port=None):
|
||||
if host == None:
|
||||
host = ''
|
||||
if port == None:
|
||||
port = 8000
|
||||
StatRequestHandler.runstore = store
|
||||
server_address = (host, port)
|
||||
httpd = HTTPServer(server_address, StatRequestHandler)
|
||||
httpd.serve_forever()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
store = RunStore(basedir=config.get('STORE_BASE_DIR'))
|
||||
run(store, host=config.get('HTTPD_HOST'), port=config.get('HTTPD_PORT'))
|
@ -91,7 +91,6 @@ def main():
|
||||
syncer.loop(0.0, conn)
|
||||
except NoBlockForYou:
|
||||
logg.info('history done at {}'.format(syncer.backend.get()))
|
||||
pass
|
||||
|
||||
syncer_backend = MemBackend(chain_spec, None)
|
||||
syncer_backend.set(start_block + 1, 0)
|
||||
|
Loading…
Reference in New Issue
Block a user