Last active
February 25, 2021 19:58
-
-
Save vdparikh/d0dca9828ca798aee8561877a09faa5f to your computer and use it in GitHub Desktop.
Python JSONRPC and HTTP with Flask
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
Author
vdparikh
commented
Jul 21, 2018
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment