From 1abee567d567ef9b872bcb7c2f6f68f627c8455c Mon Sep 17 00:00:00 2001
From: Lukasz Piatkowski <lukaspiatkowski@gmail.com>
Date: Thu, 14 Sep 2023 10:51:12 +0200
Subject: [PATCH] wave: run graphql asynchronously on flask server

In GraphQLView.dispatch_request pass run_sync=False to run_http_query and,
if necessary, run the result on async loop.

There is an open PR upstream to handle async natively:
https://github.com/graphql-python/graphql-server/issues/110
---
 graphql_server/flask/graphqlview.py | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/graphql_server/flask/graphqlview.py b/graphql_server/flask/graphqlview.py
index 7440f82..8665a6a 100644
--- a/graphql_server/flask/graphqlview.py
+++ b/graphql_server/flask/graphqlview.py
@@ -1,3 +1,4 @@
+import asyncio
 import copy
 from collections.abc import MutableMapping
 from functools import partial
@@ -5,7 +6,7 @@
 
 from flask import Response, render_template_string, request
 from flask.views import View
-from graphql import specified_rules
+from graphql import pyutils, specified_rules
 from graphql.error import GraphQLError
 from graphql.type.schema import GraphQLSchema
 
@@ -115,9 +116,23 @@ def dispatch_request(self):
                 middleware=self.get_middleware(),
                 validation_rules=self.get_validation_rules(),
                 execution_context_class=self.get_execution_context_class(),
+                run_sync=False,
             )
+
+            # This is (almost) copied from graphql_server.aiohttp.GraphQLView
+            # It is a bit weird as it originally calls await in a loop which
+            # a bit breaks the gains from doing operations asynchronously...
+            # But maybe it is required for correctness to execute those
+            # operations like that, so leaving it.
+            exec_res = [
+                ex
+                if ex is None or not pyutils.is_awaitable(ex)
+                else asyncio.run(ex)
+                for ex in execution_results
+            ]
+
             result, status_code = encode_execution_results(
-                execution_results,
+                exec_res,
                 is_batch=isinstance(data, list),
                 format_error=self.format_error,
                 encode=partial(self.encode, pretty=pretty),  # noqa