strawberry-graphql 0.275.7__py3-none-any.whl → 0.284.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of strawberry-graphql might be problematic. Click here for more details.

Files changed (161) hide show
  1. strawberry/__init__.py +2 -0
  2. strawberry/aiohttp/test/client.py +8 -15
  3. strawberry/aiohttp/views.py +15 -64
  4. strawberry/annotation.py +70 -25
  5. strawberry/asgi/__init__.py +22 -56
  6. strawberry/asgi/test/client.py +6 -6
  7. strawberry/chalice/views.py +13 -79
  8. strawberry/channels/handlers/base.py +7 -8
  9. strawberry/channels/handlers/http_handler.py +50 -32
  10. strawberry/channels/handlers/ws_handler.py +12 -14
  11. strawberry/channels/router.py +3 -4
  12. strawberry/channels/testing.py +7 -9
  13. strawberry/cli/__init__.py +7 -6
  14. strawberry/cli/commands/codegen.py +7 -7
  15. strawberry/cli/commands/dev.py +72 -0
  16. strawberry/cli/commands/schema_codegen.py +1 -2
  17. strawberry/cli/commands/server.py +3 -44
  18. strawberry/cli/commands/upgrade/__init__.py +3 -3
  19. strawberry/cli/commands/upgrade/_run_codemod.py +2 -2
  20. strawberry/cli/constants.py +1 -2
  21. strawberry/cli/{debug_server.py → dev_server.py} +3 -7
  22. strawberry/codegen/plugins/print_operation.py +2 -2
  23. strawberry/codegen/plugins/python.py +2 -2
  24. strawberry/codegen/query_codegen.py +20 -30
  25. strawberry/codegen/types.py +32 -32
  26. strawberry/codemods/__init__.py +9 -0
  27. strawberry/codemods/annotated_unions.py +2 -2
  28. strawberry/codemods/maybe_optional.py +118 -0
  29. strawberry/dataloader.py +28 -24
  30. strawberry/directive.py +6 -7
  31. strawberry/django/test/client.py +3 -3
  32. strawberry/django/views.py +21 -91
  33. strawberry/exceptions/__init__.py +4 -4
  34. strawberry/exceptions/conflicting_arguments.py +2 -2
  35. strawberry/exceptions/duplicated_type_name.py +4 -4
  36. strawberry/exceptions/exception.py +3 -3
  37. strawberry/exceptions/handler.py +8 -7
  38. strawberry/exceptions/invalid_argument_type.py +2 -2
  39. strawberry/exceptions/invalid_superclass_interface.py +2 -2
  40. strawberry/exceptions/invalid_union_type.py +4 -4
  41. strawberry/exceptions/missing_arguments_annotations.py +2 -2
  42. strawberry/exceptions/missing_dependencies.py +2 -4
  43. strawberry/exceptions/missing_field_annotation.py +2 -2
  44. strawberry/exceptions/missing_return_annotation.py +2 -2
  45. strawberry/exceptions/object_is_not_a_class.py +2 -2
  46. strawberry/exceptions/object_is_not_an_enum.py +2 -2
  47. strawberry/exceptions/permission_fail_silently_requires_optional.py +2 -2
  48. strawberry/exceptions/private_strawberry_field.py +2 -2
  49. strawberry/exceptions/scalar_already_registered.py +2 -2
  50. strawberry/exceptions/syntax.py +3 -3
  51. strawberry/exceptions/unresolved_field_type.py +2 -2
  52. strawberry/exceptions/utils/source_finder.py +25 -25
  53. strawberry/experimental/pydantic/_compat.py +8 -7
  54. strawberry/experimental/pydantic/conversion.py +2 -2
  55. strawberry/experimental/pydantic/conversion_types.py +2 -2
  56. strawberry/experimental/pydantic/error_type.py +10 -12
  57. strawberry/experimental/pydantic/fields.py +9 -15
  58. strawberry/experimental/pydantic/object_type.py +17 -25
  59. strawberry/experimental/pydantic/utils.py +1 -2
  60. strawberry/ext/mypy_plugin.py +12 -14
  61. strawberry/extensions/base_extension.py +2 -1
  62. strawberry/extensions/context.py +13 -18
  63. strawberry/extensions/directives.py +9 -3
  64. strawberry/extensions/field_extension.py +4 -4
  65. strawberry/extensions/mask_errors.py +24 -13
  66. strawberry/extensions/max_aliases.py +1 -3
  67. strawberry/extensions/parser_cache.py +1 -2
  68. strawberry/extensions/query_depth_limiter.py +18 -14
  69. strawberry/extensions/runner.py +2 -2
  70. strawberry/extensions/tracing/apollo.py +3 -3
  71. strawberry/extensions/tracing/datadog.py +3 -3
  72. strawberry/extensions/tracing/opentelemetry.py +6 -8
  73. strawberry/extensions/tracing/utils.py +3 -1
  74. strawberry/extensions/utils.py +2 -2
  75. strawberry/extensions/validation_cache.py +2 -3
  76. strawberry/fastapi/context.py +6 -6
  77. strawberry/fastapi/router.py +43 -42
  78. strawberry/federation/argument.py +4 -5
  79. strawberry/federation/enum.py +18 -21
  80. strawberry/federation/field.py +94 -97
  81. strawberry/federation/object_type.py +56 -58
  82. strawberry/federation/scalar.py +27 -35
  83. strawberry/federation/schema.py +15 -16
  84. strawberry/federation/schema_directive.py +7 -6
  85. strawberry/federation/schema_directives.py +11 -11
  86. strawberry/federation/union.py +4 -4
  87. strawberry/flask/views.py +16 -85
  88. strawberry/http/__init__.py +30 -20
  89. strawberry/http/async_base_view.py +208 -89
  90. strawberry/http/base.py +28 -11
  91. strawberry/http/exceptions.py +5 -7
  92. strawberry/http/ides.py +2 -3
  93. strawberry/http/sync_base_view.py +115 -69
  94. strawberry/http/types.py +3 -3
  95. strawberry/litestar/controller.py +43 -77
  96. strawberry/permission.py +4 -6
  97. strawberry/printer/ast_from_value.py +3 -5
  98. strawberry/printer/printer.py +18 -15
  99. strawberry/quart/views.py +16 -48
  100. strawberry/relay/exceptions.py +4 -4
  101. strawberry/relay/fields.py +33 -32
  102. strawberry/relay/types.py +32 -35
  103. strawberry/relay/utils.py +11 -23
  104. strawberry/resolvers.py +2 -1
  105. strawberry/sanic/context.py +1 -0
  106. strawberry/sanic/utils.py +3 -3
  107. strawberry/sanic/views.py +15 -54
  108. strawberry/scalars.py +2 -2
  109. strawberry/schema/_graphql_core.py +55 -0
  110. strawberry/schema/base.py +32 -33
  111. strawberry/schema/compat.py +9 -9
  112. strawberry/schema/config.py +10 -1
  113. strawberry/schema/exceptions.py +1 -3
  114. strawberry/schema/name_converter.py +9 -8
  115. strawberry/schema/schema.py +133 -100
  116. strawberry/schema/schema_converter.py +96 -58
  117. strawberry/schema/types/base_scalars.py +1 -1
  118. strawberry/schema/types/concrete_type.py +5 -5
  119. strawberry/schema/validation_rules/maybe_null.py +136 -0
  120. strawberry/schema_codegen/__init__.py +3 -3
  121. strawberry/schema_directive.py +7 -6
  122. strawberry/static/graphiql.html +5 -5
  123. strawberry/streamable.py +35 -0
  124. strawberry/subscriptions/protocols/graphql_transport_ws/handlers.py +5 -16
  125. strawberry/subscriptions/protocols/graphql_transport_ws/types.py +20 -20
  126. strawberry/subscriptions/protocols/graphql_ws/handlers.py +5 -12
  127. strawberry/subscriptions/protocols/graphql_ws/types.py +14 -14
  128. strawberry/test/client.py +18 -18
  129. strawberry/tools/create_type.py +2 -3
  130. strawberry/types/arguments.py +41 -28
  131. strawberry/types/auto.py +3 -4
  132. strawberry/types/base.py +25 -27
  133. strawberry/types/enum.py +22 -25
  134. strawberry/types/execution.py +21 -16
  135. strawberry/types/field.py +109 -130
  136. strawberry/types/fields/resolver.py +19 -21
  137. strawberry/types/info.py +5 -11
  138. strawberry/types/lazy_type.py +2 -3
  139. strawberry/types/maybe.py +12 -3
  140. strawberry/types/mutation.py +115 -118
  141. strawberry/types/nodes.py +2 -2
  142. strawberry/types/object_type.py +43 -63
  143. strawberry/types/scalar.py +37 -43
  144. strawberry/types/union.py +12 -14
  145. strawberry/utils/aio.py +12 -9
  146. strawberry/utils/await_maybe.py +3 -3
  147. strawberry/utils/deprecations.py +2 -2
  148. strawberry/utils/importer.py +1 -2
  149. strawberry/utils/inspect.py +4 -6
  150. strawberry/utils/logging.py +2 -2
  151. strawberry/utils/operation.py +4 -4
  152. strawberry/utils/typing.py +18 -83
  153. {strawberry_graphql-0.275.7.dist-info → strawberry_graphql-0.284.3.dist-info}/METADATA +14 -8
  154. strawberry_graphql-0.284.3.dist-info/RECORD +243 -0
  155. {strawberry_graphql-0.275.7.dist-info → strawberry_graphql-0.284.3.dist-info}/WHEEL +1 -1
  156. strawberry/utils/dataclasses.py +0 -37
  157. strawberry/utils/debug.py +0 -46
  158. strawberry/utils/graphql_lexer.py +0 -35
  159. strawberry_graphql-0.275.7.dist-info/RECORD +0 -241
  160. {strawberry_graphql-0.275.7.dist-info → strawberry_graphql-0.284.3.dist-info}/entry_points.txt +0 -0
  161. {strawberry_graphql-0.275.7.dist-info → strawberry_graphql-0.284.3.dist-info/licenses}/LICENSE +0 -0
@@ -44,18 +44,17 @@ FederationAny = scalar(NewType("_Any", object), name="_Any") # type: ignore
44
44
  class Schema(BaseSchema):
45
45
  def __init__(
46
46
  self,
47
- query: Optional[type] = None,
48
- mutation: Optional[type] = None,
49
- subscription: Optional[type] = None,
47
+ query: type | None = None,
48
+ mutation: type | None = None,
49
+ subscription: type | None = None,
50
50
  # TODO: we should update directives' type in the main schema
51
51
  directives: Iterable[type] = (),
52
52
  types: Iterable[type] = (),
53
53
  extensions: Iterable[Union[type["SchemaExtension"], "SchemaExtension"]] = (),
54
- execution_context_class: Optional[type["GraphQLExecutionContext"]] = None,
54
+ execution_context_class: type["GraphQLExecutionContext"] | None = None,
55
55
  config: Optional["StrawberryConfig"] = None,
56
- scalar_overrides: Optional[
57
- dict[object, Union[type, "ScalarWrapper", "ScalarDefinition"]]
58
- ] = None,
56
+ scalar_overrides: dict[object, Union[type, "ScalarWrapper", "ScalarDefinition"]]
57
+ | None = None,
59
58
  schema_directives: Iterable[object] = (),
60
59
  enable_federation_2: bool = False,
61
60
  ) -> None:
@@ -85,9 +84,9 @@ class Schema(BaseSchema):
85
84
 
86
85
  def _get_federation_query_type(
87
86
  self,
88
- query: Optional[type[WithStrawberryObjectDefinition]],
89
- mutation: Optional[type[WithStrawberryObjectDefinition]],
90
- subscription: Optional[type[WithStrawberryObjectDefinition]],
87
+ query: type[WithStrawberryObjectDefinition] | None,
88
+ mutation: type[WithStrawberryObjectDefinition] | None,
89
+ subscription: type[WithStrawberryObjectDefinition] | None,
91
90
  additional_types: Iterable[type[WithStrawberryObjectDefinition]],
92
91
  ) -> type:
93
92
  """Returns a new query type that includes the _service field.
@@ -124,7 +123,7 @@ class Schema(BaseSchema):
124
123
 
125
124
  if entity_type:
126
125
  self.entities_resolver.__annotations__["return"] = list[
127
- Optional[entity_type] # type: ignore
126
+ entity_type | None # type: ignore
128
127
  ]
129
128
 
130
129
  entities_field = strawberry.field(
@@ -250,7 +249,7 @@ class Schema(BaseSchema):
250
249
  directive_by_url[import_url].add(f"@{name}")
251
250
 
252
251
  def _add_link_directives(
253
- self, additional_directives: Optional[list[object]] = None
252
+ self, additional_directives: list[object] | None = None
254
253
  ) -> None:
255
254
  from .schema_directives import FederationDirective, Link
256
255
 
@@ -312,11 +311,11 @@ class Schema(BaseSchema):
312
311
 
313
312
 
314
313
  def _get_entity_type(
315
- query: Optional[type[WithStrawberryObjectDefinition]],
316
- mutation: Optional[type[WithStrawberryObjectDefinition]],
317
- subscription: Optional[type[WithStrawberryObjectDefinition]],
314
+ query: type[WithStrawberryObjectDefinition] | None,
315
+ mutation: type[WithStrawberryObjectDefinition] | None,
316
+ subscription: type[WithStrawberryObjectDefinition] | None,
318
317
  additional_types: Iterable[type[WithStrawberryObjectDefinition]],
319
- ) -> Optional[StrawberryUnion]:
318
+ ) -> StrawberryUnion | None:
320
319
  # recursively iterate over the schema to find all types annotated with @key
321
320
  # if no types are annotated with @key, then the _Entity union and Query._entities
322
321
  # field should not be added to the schema
@@ -1,5 +1,6 @@
1
1
  import dataclasses
2
- from typing import Callable, Optional, TypeVar
2
+ from collections.abc import Callable
3
+ from typing import TypeVar
3
4
  from typing_extensions import dataclass_transform
4
5
 
5
6
  from strawberry.directive import directive_field
@@ -11,12 +12,12 @@ from strawberry.types.type_resolver import _get_fields
11
12
 
12
13
  @dataclasses.dataclass
13
14
  class ComposeOptions:
14
- import_url: Optional[str]
15
+ import_url: str | None
15
16
 
16
17
 
17
18
  @dataclasses.dataclass
18
19
  class StrawberryFederationSchemaDirective(StrawberrySchemaDirective):
19
- compose_options: Optional[ComposeOptions] = None
20
+ compose_options: ComposeOptions | None = None
20
21
 
21
22
 
22
23
  T = TypeVar("T", bound=type)
@@ -30,12 +31,12 @@ T = TypeVar("T", bound=type)
30
31
  def schema_directive(
31
32
  *,
32
33
  locations: list[Location],
33
- description: Optional[str] = None,
34
- name: Optional[str] = None,
34
+ description: str | None = None,
35
+ name: str | None = None,
35
36
  repeatable: bool = False,
36
37
  print_definition: bool = True,
37
38
  compose: bool = False,
38
- import_url: Optional[str] = None,
39
+ import_url: str | None = None,
39
40
  ) -> Callable[[T], T]:
40
41
  def _wrap(cls: T) -> T:
41
42
  cls = _wrap_dataclass(cls) # type: ignore
@@ -1,5 +1,5 @@
1
1
  from dataclasses import dataclass
2
- from typing import ClassVar, Optional
2
+ from typing import ClassVar
3
3
 
4
4
  from strawberry import directive_field
5
5
  from strawberry.schema_directive import Location, schema_directive
@@ -59,7 +59,7 @@ class Provides(FederationDirective):
59
59
  )
60
60
  class Key(FederationDirective):
61
61
  fields: FieldSet
62
- resolvable: Optional[bool] = True
62
+ resolvable: bool | None = True
63
63
  imported_from: ClassVar[ImportedFrom] = ImportedFrom(
64
64
  name="key", url="https://specs.apollo.dev/federation/v2.7"
65
65
  )
@@ -81,17 +81,17 @@ class Shareable(FederationDirective):
81
81
  locations=[Location.SCHEMA], name="link", repeatable=True, print_definition=False
82
82
  )
83
83
  class Link:
84
- url: Optional[str]
85
- as_: Optional[str] = directive_field(name="as")
86
- for_: Optional[LinkPurpose] = directive_field(name="for")
87
- import_: Optional[list[Optional[LinkImport]]] = directive_field(name="import")
84
+ url: str | None
85
+ as_: str | None = directive_field(name="as")
86
+ for_: LinkPurpose | None = directive_field(name="for")
87
+ import_: list[LinkImport | None] | None = directive_field(name="import")
88
88
 
89
89
  def __init__(
90
90
  self,
91
- url: Optional[str] = UNSET,
92
- as_: Optional[str] = UNSET,
93
- for_: Optional[LinkPurpose] = UNSET,
94
- import_: Optional[list[Optional[LinkImport]]] = UNSET,
91
+ url: str | None = UNSET,
92
+ as_: str | None = UNSET,
93
+ for_: LinkPurpose | None = UNSET,
94
+ import_: list[LinkImport | None] | None = UNSET,
95
95
  ) -> None:
96
96
  self.url = url
97
97
  self.as_ = as_
@@ -128,7 +128,7 @@ class Tag(FederationDirective):
128
128
  )
129
129
  class Override(FederationDirective):
130
130
  override_from: str = directive_field(name="from")
131
- label: Optional[str] = UNSET
131
+ label: str | None = UNSET
132
132
  imported_from: ClassVar[ImportedFrom] = ImportedFrom(
133
133
  name="override", url="https://specs.apollo.dev/federation/v2.7"
134
134
  )
@@ -1,5 +1,5 @@
1
1
  from collections.abc import Collection, Iterable
2
- from typing import Any, Optional
2
+ from typing import Any
3
3
 
4
4
  from strawberry.types.union import StrawberryUnion
5
5
  from strawberry.types.union import union as base_union
@@ -7,12 +7,12 @@ from strawberry.types.union import union as base_union
7
7
 
8
8
  def union(
9
9
  name: str,
10
- types: Optional[Collection[type[Any]]] = None,
10
+ types: Collection[type[Any]] | None = None,
11
11
  *,
12
- description: Optional[str] = None,
12
+ description: str | None = None,
13
13
  directives: Iterable[object] = (),
14
14
  inaccessible: bool = False,
15
- tags: Optional[Iterable[str]] = (),
15
+ tags: Iterable[str] | None = (),
16
16
  ) -> StrawberryUnion:
17
17
  """Creates a new named Union type.
18
18
 
strawberry/flask/views.py CHANGED
@@ -3,75 +3,34 @@ from __future__ import annotations
3
3
  import warnings
4
4
  from typing import (
5
5
  TYPE_CHECKING,
6
- Any,
7
6
  ClassVar,
8
- Optional,
9
- Union,
10
- cast,
7
+ TypeGuard,
11
8
  )
12
- from typing_extensions import TypeGuard
9
+
10
+ from lia import AsyncFlaskHTTPRequestAdapter, FlaskHTTPRequestAdapter, HTTPException
13
11
 
14
12
  from flask import Request, Response, render_template_string, request
15
13
  from flask.views import View
16
- from strawberry.http.async_base_view import AsyncBaseHTTPView, AsyncHTTPRequestAdapter
17
- from strawberry.http.exceptions import HTTPException
18
- from strawberry.http.sync_base_view import (
19
- SyncBaseHTTPView,
20
- SyncHTTPRequestAdapter,
21
- )
22
- from strawberry.http.types import FormData, HTTPMethod, QueryParams
14
+ from strawberry.http.async_base_view import AsyncBaseHTTPView
15
+ from strawberry.http.sync_base_view import SyncBaseHTTPView
23
16
  from strawberry.http.typevars import Context, RootValue
24
17
 
25
18
  if TYPE_CHECKING:
26
- from collections.abc import Mapping
27
-
28
19
  from flask.typing import ResponseReturnValue
20
+
29
21
  from strawberry.http import GraphQLHTTPResponse
30
22
  from strawberry.http.ides import GraphQL_IDE
31
23
  from strawberry.schema.base import BaseSchema
32
24
 
33
25
 
34
- class FlaskHTTPRequestAdapter(SyncHTTPRequestAdapter):
35
- def __init__(self, request: Request) -> None:
36
- self.request = request
37
-
38
- @property
39
- def query_params(self) -> QueryParams:
40
- return self.request.args.to_dict()
41
-
42
- @property
43
- def body(self) -> Union[str, bytes]:
44
- return self.request.data.decode()
45
-
46
- @property
47
- def method(self) -> HTTPMethod:
48
- return cast("HTTPMethod", self.request.method.upper())
49
-
50
- @property
51
- def headers(self) -> Mapping[str, str]:
52
- return self.request.headers # type: ignore
53
-
54
- @property
55
- def post_data(self) -> Mapping[str, Union[str, bytes]]:
56
- return self.request.form
57
-
58
- @property
59
- def files(self) -> Mapping[str, Any]:
60
- return self.request.files
61
-
62
- @property
63
- def content_type(self) -> Optional[str]:
64
- return self.request.content_type
65
-
66
-
67
26
  class BaseGraphQLView:
68
- graphql_ide: Optional[GraphQL_IDE]
27
+ graphql_ide: GraphQL_IDE | None
69
28
 
70
29
  def __init__(
71
30
  self,
72
31
  schema: BaseSchema,
73
- graphiql: Optional[bool] = None,
74
- graphql_ide: Optional[GraphQL_IDE] = "graphiql",
32
+ graphiql: bool | None = None,
33
+ graphql_ide: GraphQL_IDE | None = "graphiql",
75
34
  allow_queries_via_get: bool = True,
76
35
  multipart_uploads_enabled: bool = False,
77
36
  ) -> None:
@@ -91,7 +50,9 @@ class BaseGraphQLView:
91
50
  self.graphql_ide = graphql_ide
92
51
 
93
52
  def create_response(
94
- self, response_data: GraphQLHTTPResponse, sub_response: Response
53
+ self,
54
+ response_data: GraphQLHTTPResponse | list[GraphQLHTTPResponse],
55
+ sub_response: Response,
95
56
  ) -> Response:
96
57
  sub_response.set_data(self.encode_json(response_data)) # type: ignore
97
58
 
@@ -110,7 +71,7 @@ class GraphQLView(
110
71
  def get_context(self, request: Request, response: Response) -> Context:
111
72
  return {"request": request, "response": response} # type: ignore
112
73
 
113
- def get_root_value(self, request: Request) -> Optional[RootValue]:
74
+ def get_root_value(self, request: Request) -> RootValue | None:
114
75
  return None
115
76
 
116
77
  def get_sub_response(self, request: Request) -> Response:
@@ -129,36 +90,6 @@ class GraphQLView(
129
90
  return render_template_string(self.graphql_ide_html) # type: ignore
130
91
 
131
92
 
132
- class AsyncFlaskHTTPRequestAdapter(AsyncHTTPRequestAdapter):
133
- def __init__(self, request: Request) -> None:
134
- self.request = request
135
-
136
- @property
137
- def query_params(self) -> QueryParams:
138
- return self.request.args.to_dict()
139
-
140
- @property
141
- def method(self) -> HTTPMethod:
142
- return cast("HTTPMethod", self.request.method.upper())
143
-
144
- @property
145
- def content_type(self) -> Optional[str]:
146
- return self.request.content_type
147
-
148
- @property
149
- def headers(self) -> Mapping[str, str]:
150
- return self.request.headers # type: ignore
151
-
152
- async def get_body(self) -> str:
153
- return self.request.data.decode()
154
-
155
- async def get_form_data(self) -> FormData:
156
- return FormData(
157
- files=self.request.files,
158
- form=self.request.form,
159
- )
160
-
161
-
162
93
  class AsyncGraphQLView(
163
94
  BaseGraphQLView,
164
95
  AsyncBaseHTTPView[
@@ -173,7 +104,7 @@ class AsyncGraphQLView(
173
104
  async def get_context(self, request: Request, response: Response) -> Context:
174
105
  return {"request": request, "response": response} # type: ignore
175
106
 
176
- async def get_root_value(self, request: Request) -> Optional[RootValue]:
107
+ async def get_root_value(self, request: Request) -> RootValue | None:
177
108
  return None
178
109
 
179
110
  async def get_sub_response(self, request: Request) -> Response:
@@ -195,11 +126,11 @@ class AsyncGraphQLView(
195
126
  def is_websocket_request(self, request: Request) -> TypeGuard[Request]:
196
127
  return False
197
128
 
198
- async def pick_websocket_subprotocol(self, request: Request) -> Optional[str]:
129
+ async def pick_websocket_subprotocol(self, request: Request) -> str | None:
199
130
  raise NotImplementedError
200
131
 
201
132
  async def create_websocket_response(
202
- self, request: Request, subprotocol: Optional[str]
133
+ self, request: Request, subprotocol: str | None
203
134
  ) -> Response:
204
135
  raise NotImplementedError
205
136
 
@@ -1,26 +1,36 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from dataclasses import dataclass
4
- from typing import TYPE_CHECKING, Any, Optional
5
- from typing_extensions import Literal, TypedDict
4
+ from typing import Any, Literal
5
+ from typing_extensions import TypedDict
6
6
 
7
- if TYPE_CHECKING:
8
- from strawberry.types import ExecutionResult
7
+ from strawberry.schema._graphql_core import (
8
+ GraphQLIncrementalExecutionResults,
9
+ ResultType,
10
+ )
9
11
 
10
12
 
11
13
  class GraphQLHTTPResponse(TypedDict, total=False):
12
- data: Optional[dict[str, object]]
13
- errors: Optional[list[object]]
14
- extensions: Optional[dict[str, object]]
15
-
16
-
17
- def process_result(result: ExecutionResult) -> GraphQLHTTPResponse:
18
- data: GraphQLHTTPResponse = {"data": result.data}
19
-
20
- if result.errors:
21
- data["errors"] = [err.formatted for err in result.errors]
22
- if result.extensions:
23
- data["extensions"] = result.extensions
14
+ data: dict[str, object] | None
15
+ errors: list[object] | None
16
+ extensions: dict[str, object] | None
17
+ hasNext: bool | None
18
+ completed: list[Any] | None
19
+ pending: list[Any] | None
20
+ initial: list[Any] | None
21
+ incremental: list[Any] | None
22
+
23
+
24
+ def process_result(result: ResultType) -> GraphQLHTTPResponse:
25
+ if isinstance(result, GraphQLIncrementalExecutionResults):
26
+ return result
27
+
28
+ errors, extensions = result.errors, result.extensions
29
+ data: GraphQLHTTPResponse = {
30
+ "data": result.data,
31
+ **({"errors": [err.formatted for err in errors]} if errors else {}),
32
+ **({"extensions": extensions} if extensions else {}),
33
+ }
24
34
 
25
35
  return data
26
36
 
@@ -29,10 +39,10 @@ def process_result(result: ExecutionResult) -> GraphQLHTTPResponse:
29
39
  class GraphQLRequestData:
30
40
  # query is optional here as it can be added by an extensions
31
41
  # (for example an extension for persisted queries)
32
- query: Optional[str]
33
- variables: Optional[dict[str, Any]]
34
- operation_name: Optional[str]
35
- extensions: Optional[dict[str, Any]]
42
+ query: str | None
43
+ variables: dict[str, Any] | None
44
+ operation_name: str | None
45
+ extensions: dict[str, Any] | None
36
46
  protocol: Literal["http", "multipart-subscription"] = "http"
37
47
 
38
48