strawberry-graphql / strawberry

A GraphQL library for Python that leverages type annotations 🍓
https://strawberry.rocks
MIT License
3.92k stars 516 forks source link

Subscription is not working with permission_classes #3317

Closed dvorakj31 closed 8 months ago

dvorakj31 commented 8 months ago

Subscription is failing with error after upgrading to version 0.217.0 from 0.216.1. Bug seems to be in permission_classes, because if I'm trying to use subscription without permission_classes, it works without any problem.

Describe the Bug

Error when subscription is used with permission_classes:

Traceback (most recent call last):
  File "/.../lib/python3.11/site-packages/graphql/execution/subscribe.py", line 206, in execute_subscription
    event_stream = await event_stream
                   ^^^^^^^^^^^^^^^^^^
  File "/.../lib/python3.11/site-packages/strawberry/schema/schema_converter.py", line 675, in _async_resolver
    return await await_maybe(
           ^^^^^^^^^^^^^^^^^^
  File "/.../lib/python3.11/site-packages/strawberry/utils/await_maybe.py", line 12, in await_maybe
    return await value
           ^^^^^^^^^^^
  File "/.../lib/python3.11/site-packages/strawberry/permission.py", line 172, in resolve_async
    return await next_(source, info, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: object async_generator can't be used in 'await' expression

Here is sample code to reproduce the bug:

class IsAuthenticated(BasePermission):

    message = "Unauthorized"

    async def has_permission(self, source: Any, info: Info, **kwargs: Any) -> bool:
        return True

async def sample(info: Info) -> AsyncGenerator[int, None]:
    while True:
        yield 1

@strawberry.type
class Subscription:
    sample = strawberry.subscription(
        resolver=sample, permission_classes=[IsAuthenticated]
    )

System Information

Upvote & Fund

Fund with Polar

erikwrede commented 8 months ago

Permissions are powered by FieldExtensions. These currently do not explicitly support subscriptions since we only expect awaitables or non-awaitable values, not for AsyncGenerators. However, since the new stream feature in GraphQL-core also allows to make every resolver an AsyncGenerator, we need to add support for it as part of #2914. I'll create a separate issue to track this in a moment.

erikwrede commented 8 months ago

3318

dvorakj31 commented 8 months ago

Ok, thank you!