Skip to content

Instantly share code, notes, and snippets.

@vdparikh
Last active February 25, 2021 19:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vdparikh/d0dca9828ca798aee8561877a09faa5f to your computer and use it in GitHub Desktop.
Save vdparikh/d0dca9828ca798aee8561877a09faa5f to your computer and use it in GitHub Desktop.
Python JSONRPC and HTTP with Flask
from flask import Flask, request, Response
from jsonrpcserver import methods
import os
app = Flask(__name__)
# JSON RPC Methods
@methods.add
def ping():
return 'pong'
# HTTP Routing
@app.route('/health', methods=['GET'])
def health():
return 'OK'
@app.route('/exit', methods=['GET'])
def exit():
os._exit(1)
return 'OK'
@app.route('/debug', methods=['GET'])
def debug():
return ''
# JSONRPC Routing
@app.route('/jsonrpc', methods=['POST'])
def jsonrpc():
req = request.get_data().decode()
response = methods.dispatch(req)
return Response(str(response), response.http_status,
mimetype='application/json')
if __name__ == '__main__':
app.run()
from jsonrpcserver import methods
from jsonrpcserver.exceptions import InvalidParams,ServerError
import werkzeug.serving
from werkzeug.wrappers import Request, Response
from werkzeug.routing import Map, Rule
from werkzeug.exceptions import HTTPException, NotFound
from werkzeug.wsgi import SharedDataMiddleware
from werkzeug.utils import redirect
import os
import pyping
import sys
import logging
logging.getLogger("jsonrpcserver.dispatcher.request").setLevel(logging.WARNING)
logging.getLogger("jsonrpcserver.dispatcher.response").setLevel(logging.WARNING)
# JSON RPC Methods
@methods.add
def ping(data={},context={}):
# You can verify different attributes in incoming data as below
# Verify if connection is provided
if 'connection' not in data:
raise InvalidParams(data='Connection is required')
# Verify if input is provided
if 'input' not in data:
raise InvalidParams(data='Input is required')
# Functional Logic of what needs to be done
try:
# connection = data["connection"]
# input = data["input"]
return data
except Exception as e:
raise ServerError(data=e)
class Plugin(object):
def __init__(self, config):
self.url_map = Map([
Rule('/jsonrpc', endpoint='jsonrpc'),
Rule('/health', endpoint='health'),
Rule('/exit', endpoint='exit'),
Rule('/debug', endpoint='debug'),
])
def on_jsonrpc(self, request):
# Context is just added to show how to send additional parameters to the JSONRPC request
# for example some other environment attributes etc
r = methods.dispatch(request.data.decode(), context={'feature_enabled': True}, debug=False)
return Response(str(r), r.http_status, mimetype='application/json')
def on_health(self, request):
response = Response('OK', mimetype='text/html')
response.status_code = 200
return response
def on_debug(self, request):
response = Response({}, mimetype='application/json')
response.status_code = 200
return response
def on_exit(self, request):
os._exit(1)
def error_404(self):
response = Response('Not Found', mimetype='text/html')
response.status_code = 404
return response
def dispatch_request(self, request):
adapter = self.url_map.bind_to_environ(request.environ)
try:
endpoint, values = adapter.match()
return getattr(self, 'on_' + endpoint)(request, **values)
except NotFound, e:
return self.error_404()
except HTTPException, e:
return e
def wsgi_app(self, environ, start_response):
request = Request(environ)
response = self.dispatch_request(request)
return response(environ, start_response)
def __call__(self, environ, start_response):
return self.wsgi_app(environ, start_response)
def create_app():
application = Plugin({})
return application
if __name__ == '__main__':
application = create_app()
werkzeug.serving.run_simple('localhost', 5000, application)
@vdparikh
Copy link
Author

virtualenv -p /usr/bin/python venv
source venv/bin/activate
python server.py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment