Source code for benchmarkstt.cli.entrypoints.api

"""
Make benchmarkstt available through a rudimentary JSON-RPC_ interface

.. attention::

    Only supported for Python versions 3.6 and above

.. _JSON-RPC: https://www.jsonrpc.org

"""

import jsonrpcserver
import os
from flask import Flask, request, Response, render_template
from benchmarkstt.docblock import format_docs, parse, process_rst
from benchmarkstt.api.jsonrpc import get_methods


[docs]def argparser(parser): """ Adds the help and arguments specific to this module """ parser.add_argument('--debug', action='store_true', help='Run in debug mode') parser.add_argument('--host', help='Hostname or ip to serve api') parser.add_argument('--port', type=int, default=8080, help='Port used by the server') parser.add_argument('--entrypoint', default='/api', help='The jsonrpc api address') parser.add_argument('--list-methods', action='store_true', help='List the available jsonrpc methods') parser.add_argument('--with-explorer', action='store_true', help='Also create the explorer to test api calls with, ' 'this is a rudimentary feature currently ' 'only meant for testing and debugging.\n' 'Warning: the API explorer is provided as-is, without any tests ' 'or code reviews. This is marked as a low-priority feature.') return parser
[docs]def create_app(entrypoint: str = None, with_explorer: bool = None): """ Create the Flask app :param entrypoint: The HTTP path on which the api will be served :param bool with_explorer: Whether to also serve the JSON-RPC API explorer :return: """ template_folder = os.path.abspath(os.path.join( __file__, os.pardir, os.pardir, os.pardir, 'api', 'templates' )) app = Flask(__name__, template_folder=template_folder) if entrypoint is None: entrypoint = '/api' methods = get_methods() @app.route(entrypoint, methods=["POST"]) def jsonrpc(): req = request.get_data().decode() response = jsonrpcserver.dispatch(req, methods=methods, debug=True, convert_camel_case=False) response_str = str(response) return Response(response_str, response.http_status, mimetype="application/json") if with_explorer: # pragma: nocover app.template_filter('parse_rst')(process_rst) @app.route(entrypoint, methods=['GET']) def explorer(): split_methods = {} individual_methods = [] for name, func in methods.items.items(): id_ = name.replace('.', '-') cat = 'METHODS' splitted = name.split('.', 1) if len(splitted) == 2: cat = splitted[0] item = dict(id=id_, name=name, details=parse(func)) individual_methods.append(item) if cat not in split_methods: split_methods[cat] = [] split_methods[cat].append(item) return render_template('api-explorer.html', grouped_methods=split_methods, methods=individual_methods) return app
[docs]def run(_parser, args): # pragma: nocover if args.list_methods: methods = get_methods() for name, func in methods.items.items(): print('%s\n%s' % (name, '-' * len(name))) print('') print(format_docs(func.__doc__)) print('') else: app = create_app(args.entrypoint, args.with_explorer) app.run(host=args.host, port=args.port, debug=args.debug)