From 780012da477309e452b2c1b97d782b11627c6d71 Mon Sep 17 00:00:00 2001 From: Victor Date: Tue, 27 Dec 2022 23:56:31 +0300 Subject: [PATCH] feat: Add `subscribe` to Field --- graphene/types/field.py | 12 ++++++++---- graphene/types/tests/test_subscribe_async.py | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/graphene/types/field.py b/graphene/types/field.py index dafb04b5..b1cb529b 100644 --- a/graphene/types/field.py +++ b/graphene/types/field.py @@ -51,6 +51,8 @@ class Field(MountedType): value object. If not set, the default resolver method for the schema is used. source (optional, str): attribute name to resolve for this field from the parent value object. Alternative to resolver (cannot set both source and resolver). + subscribe (optional, AsyncIterable): Asynchronous iterator to get the value for a Field from the parent + value object. If not set, the default resolver method for the schema is used. deprecation_reason (optional, str): Setting this value indicates that the field is depreciated and may provide instruction or reason on how for clients to proceed. required (optional, bool): indicates this field as not null in the graphql schema. Same behavior as @@ -69,6 +71,7 @@ class Field(MountedType): args=None, resolver=None, source=None, + subscribe=None, deprecation_reason=None, name=None, description=None, @@ -107,6 +110,7 @@ class Field(MountedType): if source: resolver = partial(source_resolver, source) self.resolver = resolver + self.subscribe = subscribe self.deprecation_reason = deprecation_reason self.description = description self.default_value = default_value @@ -131,8 +135,8 @@ class Field(MountedType): return self.resolver or parent_resolver def wrap_subscribe(self, parent_subscribe): + """Wraps a function subscribe. + - using the ObjectType subscribe_{FIELD_NAME} (parent_subscribe) if the Field definition has no subscribe. + - using the Field.subscribe """ - Wraps a function subscribe, using the ObjectType subscribe_{FIELD_NAME} - (parent_subscribe) if the Field definition has no subscribe. - """ - return parent_subscribe + return parent_subscribe or self.subscribe diff --git a/graphene/types/tests/test_subscribe_async.py b/graphene/types/tests/test_subscribe_async.py index 50e5ba68..f5d8ffb7 100644 --- a/graphene/types/tests/test_subscribe_async.py +++ b/graphene/types/tests/test_subscribe_async.py @@ -10,13 +10,21 @@ class Query(ObjectType): return "Hello, world!" +async def subscribe_count_to_five(root, info): + for count in range(1, 6): + yield count + + class Subscription(ObjectType): + count_to_ten = Field(Int) async def subscribe_count_to_ten(root, info): for count in range(1, 11): yield count + count_to_five = Field(Int, subscribe=subscribe_count_to_five) + schema = Schema(query=Query, subscription=Subscription) @@ -30,6 +38,13 @@ async def test_subscription(): count = item.data["countToTen"] assert count == 10 + subscription = "subscription { countToFive }" + result = await schema.subscribe(subscription) + count = 0 + async for item in result: + count = item.data["countToFive"] + assert count == 5 + @mark.asyncio async def test_subscription_fails_with_invalid_query():