Skip to content

Instantly share code, notes, and snippets.

@erikwrede
Created July 2, 2023 21:31
Show Gist options
  • Save erikwrede/993e1fc174ee75b11c491210e4a9136b to your computer and use it in GitHub Desktop.
Save erikwrede/993e1fc174ee75b11c491210e4a9136b to your computer and use it in GitHub Desktop.
Stream Defer playground @ Strawberry GraphQL
import asyncio
import random
import typing
from graphql.execution import ExperimentalIncrementalExecutionResults, IncrementalStreamResult, IncrementalDeferResult
from graphql.execution import experimental_execute_incrementally
from graphql.language import parse
import strawberry
from strawberry.types import Info
from strawberry.utils.await_maybe import await_maybe
from strawberry.dataloader import DataLoader
async def load_long_runner_fn(keys):
print("load function called")
print(keys)
await asyncio.sleep(0)
return [1 for _ in keys]
friends_loader = DataLoader(load_fn=load_long_runner_fn)
@strawberry.type
class Friend:
@strawberry.field
async def long_runner(self) -> int:
return await friends_loader.load(random.choice([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]))
@strawberry.type
class Person:
name: str = strawberry.field(default="John Doe")
age: int = strawberry.field(default=18)
@strawberry.field
def age(self) -> int:
return random.choice([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
@strawberry.field
async def age2(self) -> int:
await asyncio.sleep(10)
return random.choice([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
@strawberry.field
async def friends(self, info: Info) -> list[Friend]:
print(info._raw_info)
my_freidns = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
return [Friend() for _ in my_freidns]
# for friend in my_freidns:
# yield friend
@strawberry.type
class Query:
@strawberry.field
def hello(self) -> Person:
return Person()
schema = strawberry.Schema(query=Query)
#
async def exec() -> typing.Any:
query_old = """
query {
hello {
... on Person @defer {
name
age
}
}
hello2: hello {
... on Person @defer {
name
age2
}
}
hello3: hello {
friends @stream(label: "friends")
}
}
"""
query = """
query {
hello {
friends @stream(label: "friends"){
longRunner
}
}
}
"""
document = parse(query)
result: ExperimentalIncrementalExecutionResults = await await_maybe(
experimental_execute_incrementally(schema._schema, document))
# print(result.data)
initial_result = await await_maybe(result.initial_result)
print(initial_result.data)
print("Deferred results")
async for deferred_result in result.subsequent_results:
awaited_result = await await_maybe(deferred_result)
print(deferred_result)
for incremental_result in awaited_result.incremental:
if isinstance(incremental_result, IncrementalStreamResult):
print("Stream result")
print(incremental_result.items)
if isinstance(incremental_result, IncrementalDeferResult):
print("Defer result")
print(incremental_result.data)
print(incremental_result.path)
event_loop = asyncio.new_event_loop()
event_loop.run_until_complete(exec())
# print(timeit.timeit(lambda: asyncio.run(exec()), number=1000))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment