Skip to content

Commit

Permalink
Some progress
Browse files Browse the repository at this point in the history
  • Loading branch information
patrick91 committed Feb 4, 2025
1 parent 8584404 commit 57c4ac1
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 15 deletions.
13 changes: 11 additions & 2 deletions strawberry/http/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from __future__ import annotations

from dataclasses import dataclass
from typing import TYPE_CHECKING, Any, Optional
from typing import TYPE_CHECKING, Any, Optional, Union
from typing_extensions import Literal, NotRequired, TypedDict

from strawberry.types import InitialIncrementalExecutionResult

if TYPE_CHECKING:
from strawberry.types import ExecutionResult

Expand All @@ -14,14 +16,20 @@ class GraphQLHTTPResponse(TypedDict, total=False):
extensions: Optional[dict[str, object]]


def process_result(result: ExecutionResult) -> GraphQLHTTPResponse:
def process_result(
result: Union[ExecutionResult, InitialIncrementalExecutionResult],
) -> GraphQLHTTPResponse:
data: GraphQLHTTPResponse = {"data": result.data}

if result.errors:
data["errors"] = [err.formatted for err in result.errors]
if result.extensions:
data["extensions"] = result.extensions

if isinstance(result, InitialIncrementalExecutionResult):
data["hasNext"] = result.has_next
data["pending"] = result.pending

return data


Expand All @@ -39,6 +47,7 @@ class IncrementalGraphQLHTTPResponse(TypedDict):
incremental: list[GraphQLHTTPResponse]
hasNext: bool
extensions: NotRequired[dict[str, Any]]
completed: list[GraphQLHTTPResponse]


__all__ = [
Expand Down
22 changes: 14 additions & 8 deletions strawberry/http/async_base_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -578,14 +578,20 @@ async def process_result(
result: Union[ExecutionResult, InitialIncrementalExecutionResult],
) -> GraphQLHTTPResponse:
if isinstance(result, InitialIncrementalExecutionResult):
return {
"data": result.data,
"pending": [
pending_result.formatted for pending_result in result.pending
],
"hasNext": result.has_next,
"extensions": result.extensions,
}
# TODO: fix this mess
from strawberry.types import (
InitialIncrementalExecutionResult as InitialIncrementalExecutionResultType,
)

# TODO: do this where we create ExecutionResult
# or maybe remove our wrappers and just GraphQL core's types
result = InitialIncrementalExecutionResultType(
data=result.data,
pending=[pending_result.formatted for pending_result in result.pending],
has_next=result.has_next,
extensions=result.extensions,
errors=result.errors,
)

result = await self.schema._handle_execution_result(
context=self.schema.execution_context,
Expand Down
3 changes: 2 additions & 1 deletion strawberry/schema/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ def _create_execution_context(
provided_operation_name=operation_name,
)

# TODO: is this the right place to do this?
# TODO: is this the right place to do this?
async def _handle_execution_result(
self,
context: ExecutionContext,
Expand All @@ -319,6 +319,7 @@ async def _handle_execution_result(
if isinstance(result, GraphQLExecutionResult):
result = ExecutionResult(data=result.data, errors=result.errors)

# TODO: not correct when handling incremental results
result.extensions = await extensions_runner.get_extensions_results(context)

context.result = result # type: ignore # mypy failed to deduce correct type.
Expand Down
9 changes: 7 additions & 2 deletions strawberry/types/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
from .base import get_object_definition, has_object_definition
from .execution import ExecutionContext, ExecutionResult, SubscriptionExecutionResult
from .execution import (
ExecutionContext,
ExecutionResult,
InitialIncrementalExecutionResult,
SubscriptionExecutionResult,
)
from .info import Info

__all__ = [
"ExecutionContext",
"ExecutionResult",
"Info",
"Info",
"InitialIncrementalExecutionResult",
"SubscriptionExecutionResult",
"get_object_definition",
"has_object_definition",
Expand Down
9 changes: 9 additions & 0 deletions strawberry/types/execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,15 @@ class ExecutionResult:
extensions: Optional[dict[str, Any]] = None


@dataclasses.dataclass
class InitialIncrementalExecutionResult:
data: Optional[dict[str, Any]]
errors: Optional[list[GraphQLError]]
pending: list[Any]
has_next: bool
extensions: Optional[dict[str, Any]] = None


@dataclasses.dataclass
class PreExecutionError(ExecutionResult):
"""Differentiate between a normal execution result and an immediate error.
Expand Down
3 changes: 1 addition & 2 deletions tests/http/incremental/test_defer.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ async def test_basic_defer(method: Literal["get", "post"], http_client: HttpClie
"data": {"hero": {"id": "1"}},
"hasNext": True,
"pending": [{"path": ["hero"], "id": "0"}],
# TODO: why is this None?
"extensions": None,
"extensions": {"example": "example"},
}

subsequent = await stream.__anext__()
Expand Down

0 comments on commit 57c4ac1

Please sign in to comment.