From 38a41f43b191606d7a7922eb56a9bb2794b04f31 Mon Sep 17 00:00:00 2001 From: Felix Delattre <fd@gfz-potsdam.de> Date: Thu, 22 Jul 2021 06:17:40 +0000 Subject: [PATCH] Switched to asynchronous quart framework --- .gitlab-ci.yml | 4 ++-- README.rst | 2 +- obmdataapi/__init__.py | 47 ++++++++++++-------------------------- obmdataapi/jsonrpcquart.py | 35 ++++++++++++++++++++++++++++ setup.py | 6 ++--- tests/conftest.py | 8 ++----- 6 files changed, 57 insertions(+), 45 deletions(-) create mode 100644 obmdataapi/jsonrpcquart.py diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index dde2b5a..574acac 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -30,6 +30,6 @@ tests: stage: test interruptible: true script: - - export FLASK_APP=obmdataapi - - nohup flask run > log.txt 2>&1 & + - export QUART_APP=obmdataapi + - nohup quart run > log.txt 2>&1 & - pytest tests diff --git a/README.rst b/README.rst index b7a747c..2b2490c 100644 --- a/README.rst +++ b/README.rst @@ -16,7 +16,7 @@ Requirements ------------ * python >= 3.7 - * Flask >= 2.0.1 + * quart >= 0.15.1 Installation ------------ diff --git a/obmdataapi/__init__.py b/obmdataapi/__init__.py index 278933d..9a1de2e 100644 --- a/obmdataapi/__init__.py +++ b/obmdataapi/__init__.py @@ -19,45 +19,26 @@ import logging import sys -from flask import Flask, request, Response -from jsonrpcserver import method, dispatch - +from quart import Quart +from .jsonrpcquart import JSONRPCQuart logger = logging.getLogger() logger.setLevel(logging.DEBUG) logger.addHandler(logging.StreamHandler(sys.stdout)) +logger.info("obmapidata has started") -def create_app(test_config=None): - """Create and configure an instance of the Flask application.""" - - logger.info("obmapidata has started") - - app = Flask(__name__, instance_relative_config=True) - app.config.from_mapping( - # a default secret that should be overridden by instance config - SECRET_KEY="dev" - ) - - if test_config is None: - # load the instance config, if it exists, when not testing - app.config.from_pyfile("config.py", silent=True) - else: - # load the test config if passed in - app.config.update(test_config) - - @method - def ping(): - return "pong" - - @app.route("/", methods=["POST"]) - def index(): - req = request.get_data().decode() - response = dispatch(req) - return Response(str(response), response.http_status, mimetype="application/json") +app = Quart(__name__) +app.api = JSONRPCQuart() - return app +app.route( + "/", + methods=[ + "POST", + ], +)(app.api.handler) -if __name__ == "__main__": - create_app().run() +@app.api.add_function +async def ping(): + return "pong" diff --git a/obmdataapi/jsonrpcquart.py b/obmdataapi/jsonrpcquart.py new file mode 100644 index 0000000..dc7e6b4 --- /dev/null +++ b/obmdataapi/jsonrpcquart.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 + +# Copyright (C) 2021: +# Helmholtz-Zentrum Potsdam Deutsches GeoForschungsZentrum GFZ +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero +# General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. + +import json + +from quart import Response, request +from ajsonrpc.backend.common import CommonBackend + + +class JSONRPCQuart(CommonBackend): + @property + def handler(self): + """Get Quart Handler""" + + async def handle(): + request_body = await request.body + response = await self.manager.get_response_for_payload(request_body) + return Response(json.dumps(response.body), mimetype="application/json") + + return handle diff --git a/setup.py b/setup.py index baedc32..705a150 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2020-2021 +# Copyright (C) 2021 # # * Helmholtz-Zentrum Potsdam Deutsches GeoForschungsZentrum GFZ # @@ -20,9 +20,9 @@ from setuptools import setup, find_packages tests_require = [ - "Flask>=2.0.1", "jsonrpcclient[requests]", "pytest", + "quart", ] linters_require = ["pre-commit", "pylint"] @@ -36,7 +36,7 @@ setup( license="AGPLv3+", keywords="API", author="Helmholtz-Zentrum Potsdam Deutsches GeoForschungsZentrum GFZ", - install_requires=["Flask>=2.0.1", "jsonrpcserver"], + install_requires=["ajsonrpc", "quart"], tests_require=tests_require, extras_require={ "tests": tests_require, diff --git a/tests/conftest.py b/tests/conftest.py index e371511..5cc4e52 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -17,16 +17,12 @@ # along with this program. If not, see http://www.gnu.org/licenses/. import pytest - -from obmdataapi import create_app +import obmdataapi @pytest.fixture def app(): - # create the app with common test config - app = create_app({"TESTING": True}) - - yield app + yield obmdataapi.app @pytest.fixture -- GitLab