DjangoChannelsGraphqlWs
DjangoChannelsGraphqlWs copied to clipboard
Initial payload
This pull request adds two features:
- ~~Per-operation context - allows sharing any data between different calls to
Subscription.publish
for the same subscription (and the same connection).~~ - Initial payload - allows sending an arbitrary "initial" response to a client as soon as it is subscribed (before any call to
Subscription.broadcast
).
I use them like so (in schema.py
):
from __future__ import annotations
from typing import Optional
import channels_graphql_ws
import graphene
from channels_graphql_ws.dict_as_object import DictAsObject
from graphene import ResolveInfo
from .task import Task
class TaskLogChanged(channels_graphql_ws.Subscription):
class Arguments:
id = graphene.Argument(graphene.NonNull(graphene.ID))
content = graphene.Field(graphene.NonNull(graphene.List(graphene.NonNull(graphene.String))))
begin = graphene.Field(graphene.NonNull(graphene.Int))
end = graphene.Field(graphene.NonNull(graphene.Int))
Payload = type(None)
initial_payload: Payload = None
@staticmethod
def subscribe(root: None, info: ResolveInfo, id: str) -> Optional[list[str]]:
task = Task(id)
return [task.uuid]
@classmethod
def trigger(cls, task: Task) -> None:
cls.broadcast_sync(group=task.uuid, payload=None)
@classmethod
async def trigger_async(cls, task: Task) -> None:
await cls.broadcast_async(group=task.uuid, payload=None)
@staticmethod
def publish(payload: None, info: ResolveInfo, id: str) -> Optional[TaskLogChanged]:
assert isinstance(info.context, DictAsObject)
try:
saved_cursor = info.context['cursor']
except KeyError:
saved_cursor = 0
task = Task(id)
content, new_cursor = task.get_log(saved_cursor)
if new_cursor == saved_cursor:
assert len(list(content)) == 0
return None # Skip this publication.
else:
info.context['cursor'] = new_cursor
return TaskLogChanged(content=content, begin=saved_cursor, end=new_cursor)
@stmarkevich @sergey-komissarov @prokher is there something preventing this pull request from being merged? I'm eagerly waiting for the initial payload feature to become available. :pray: