Yesterday I was playing around with implementing support for @stream
(and indirectly, for @defer
)
Firstly, the work will be based on #3076, since it adds quite all the fundamentals we need for delivering incremental updates (the Multipart Subscription protocol is very similar to what we need for @stream
and @defer
). We'd probably need some refactoring, but the base is there :)
@stream
, strawberry.Streamable
, AsyncGenerator and listsIn GraphQL, @stream
can only be used on fields that return a list of items, meanwhile in Python we need to use an AsyncGenerator
to enable streaming, this is how a simple resolver would look like:
import strawberry
from typing import AsyncGenerator
def count() -> AsyncGenerator[int]:
yield 1
yield 2
We are already using AsyncGenerator
for subscription (and in subscription you don't need to use lists for values), so I thought of introducing a new type (which is just an alias to AsyncGenerator
): strawberry.Streamable
The usage would look like this:
import strawberry
@strawberry.type
class Query:
@strawberry.field
def count() -> strawberry.Streamable[int]:
yield 1
yield 2
when using strawberry.Streamable[X]
, Strawberry knows to convert this to a list of X
, so the GraphQL schema will be correct.
My only issue with this is that we are hiding the fact that count is a list in GraphQL, but I think it is worth the tradeoff, especially because we can't really do much else while keeping the typing working fine.
And having a dedicated type could allow us to raise proper errors when using @stream
with lists that are not actually streamable (I don't think it would make sense in that case, no?)
What do you all think?
Pay now to fund the work behind this issue.
Get updates on progress being made.
Maintainer is rewarded once the issue is completed.
You're funding impactful open source efforts
You want to contribute to this effort
You want to get funding like this too