-
Notifications
You must be signed in to change notification settings - Fork 89
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Object of type 'Promise' is not JSON serializable occurs when multiple levels of async resolvers used #12
Comments
+1 |
Our team also have the same problem when clients try to subscribe on multiple levels of graphql objects. We're using aiohttp and we made a simple workaround to solve the problem. import asyncio
import inspect
from typing import Union, Awaitable, Any, List, Tuple, Dict
from graphql_ws.aiohttp import AiohttpSubscriptionServer
class SubscriptionServer(AiohttpSubscriptionServer):
async def send_execution_result(self, connection_context, op_id, execution_result) -> None:
resolving_items: List[Awaitable[Any]] = []
queue: List[Tuple[Union[List[Any], Dict[Union[int, str], Any]], Union[int, str], Any]] = [
(
None,
None,
execution_result.data,
),
]
while queue:
container, key, item = queue.pop(0)
if isinstance(item, list):
self.__extend_list_item(queue, item)
elif isinstance(item, dict):
self.__extend_dict_item(queue, item)
elif inspect.isawaitable(item):
container = container if container is not None else queue
key = key if key is not None else 0
resolving_items.append(self.__resolve_container_item(container, key, item))
await asyncio.gather(*resolving_items)
await super().send_execution_result(connection_context, op_id, execution_result)
return None
async def __resolve_container_item(
self,
container: Union[List[Any], Dict[Union[int, str], Any]],
key: Union[int, str],
item: Awaitable[Any],
) -> None:
container[key] = await item
def __extend_list_item(
self,
queue: List[Tuple[Union[List[Any], Dict[Union[int, str], Any]], Union[int, str], Any]],
item: List[Any],
) -> None:
queue.extend(
(
item,
index,
value,
)
for index, value in enumerate(item)
)
def __extend_dict_item(
self,
queue: List[Tuple[Union[List[Any], Dict[Union[int, str], Any]], Union[int, str], Any]],
item: Dict[Union[int, str], Any],
) -> None:
queue.extend(
(
item,
key,
value,
)
for key, value in item.items()
) The main idea is to walk through the containers' objects and await for awaitable objects |
Hopefully fixed. Reopen if you can still reproduce using code on master |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Description
Accessing a field with an async resolver in an object type that resolves with an async resolver doesn't seem to work.
What I Did
Consider the following modification to
https://github.com/graphql-python/graphql-ws/blob/master/examples/aiohttp/schema.py
Results in
Changing
resolve_new_field
toworks as expected, but I should think having an async resolver here should be fine as well.
The text was updated successfully, but these errors were encountered: