Files
revng-revng/python/revng/daemon/api.py
Giacomo Vercesi d51e19dbac Introduce the revng.daemon GraphQL API
This commit introduces the `revng.daemon` Python module, a Flask-powered
web application that exposes the functionality from `revng.api` across a
GraphQL API
2022-04-26 15:05:30 +02:00

75 lines
1.9 KiB
Python

#
# This file is distributed under the MIT License. See LICENSE.md for details.
#
import json
from typing import TYPE_CHECKING, cast
from flask import Blueprint, current_app, jsonify, request
from ariadne import graphql
from ariadne.constants import PLAYGROUND_HTML
from ariadne.contrib.tracing.apollotracing import ApolloTracingExtension
from ariadne.file_uploads import FilesDict, combine_multipart_data
from .schema import SchemafulManager
if TYPE_CHECKING:
from flask.ctx import _AppCtxGlobals
class FlaskGlobals(_AppCtxGlobals):
manager: SchemafulManager
g = FlaskGlobals()
else:
from flask import g
api_blueprint = Blueprint("api", __name__)
def json_response(data=None):
if data is None:
data = {}
return jsonify(data)
def json_error(message, http_code=404):
data = {
"error": message,
}
return jsonify(data), http_code
# When navigating to http://<server>/graphql show a graphql sandbox
@api_blueprint.route("/graphql", methods=["GET"])
def graphql_playground():
return PLAYGROUND_HTML, 200
@api_blueprint.route("/graphql", methods=["POST"])
async def graphql_server():
if request.content_type.startswith("multipart/form-data;"):
operations = request.form.get("operations")
req_map = request.form.get("map")
if operations is not None and req_map is not None:
request_files = cast(FilesDict, request.files)
data = combine_multipart_data(
json.loads(operations), json.loads(req_map), request_files
)
else:
return json_error("Invalid form data")
else:
data = request.get_json()
success, result = await graphql(
g.manager.schema,
data,
context_value={"g": g, "request": request},
extensions=[ApolloTracingExtension],
debug=current_app.config["DEBUG"],
)
status_code = 200 if success else 400
return jsonify(result), status_code