strawberry-graphql 0.269.0.dev1746905409__py3-none-any.whl → 0.269.0.dev1747164009__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.
strawberry/__init__.py CHANGED
@@ -11,7 +11,6 @@ from .permission import BasePermission
11
11
  from .scalars import ID
12
12
  from .schema import Schema
13
13
  from .schema_directive import schema_directive
14
- from .streamable import Streamable
15
14
  from .types.arguments import argument
16
15
  from .types.auto import auto
17
16
  from .types.cast import cast
@@ -38,7 +37,6 @@ __all__ = [
38
37
  "Private",
39
38
  "Schema",
40
39
  "Some",
41
- "Streamable",
42
40
  "argument",
43
41
  "asdict",
44
42
  "auto",
strawberry/annotation.py CHANGED
@@ -17,7 +17,6 @@ from typing import (
17
17
  )
18
18
  from typing_extensions import Self, get_args, get_origin
19
19
 
20
- from strawberry.streamable import StrawberryStreamable
21
20
  from strawberry.types.base import (
22
21
  StrawberryList,
23
22
  StrawberryMaybe,
@@ -144,8 +143,6 @@ class StrawberryAnnotation:
144
143
 
145
144
  if self._is_lazy_type(evaled_type):
146
145
  return evaled_type
147
- if self._is_streamable(evaled_type, args):
148
- return self.create_list(list[evaled_type])
149
146
  if self._is_list(evaled_type):
150
147
  return self.create_list(evaled_type)
151
148
  if type_of := self._get_maybe_type(evaled_type):
@@ -326,10 +323,6 @@ class StrawberryAnnotation:
326
323
  def _get_maybe_type(cls, annotation: Any) -> type | None:
327
324
  return get_args(annotation)[0] if _annotation_is_maybe(annotation) else None
328
325
 
329
- @classmethod
330
- def _is_streamable(cls, annotation: Any, args: list[Any]) -> bool:
331
- return any(isinstance(arg, StrawberryStreamable) for arg in args)
332
-
333
326
  @classmethod
334
327
  def _is_strawberry_type(cls, evaled_type: Any) -> bool:
335
328
  # Prevent import cycles
@@ -1,13 +1,11 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from dataclasses import dataclass
4
- from typing import Any, Optional
4
+ from typing import TYPE_CHECKING, Any, Optional
5
5
  from typing_extensions import Literal, TypedDict
6
6
 
7
- from strawberry.schema._graphql_core import (
8
- GraphQLIncrementalExecutionResults,
9
- ResultType,
10
- )
7
+ if TYPE_CHECKING:
8
+ from strawberry.types import ExecutionResult
11
9
 
12
10
 
13
11
  class GraphQLHTTPResponse(TypedDict, total=False):
@@ -16,16 +14,13 @@ class GraphQLHTTPResponse(TypedDict, total=False):
16
14
  extensions: Optional[dict[str, object]]
17
15
 
18
16
 
19
- def process_result(result: ResultType) -> GraphQLHTTPResponse:
20
- if isinstance(result, GraphQLIncrementalExecutionResults):
21
- return result
17
+ def process_result(result: ExecutionResult) -> GraphQLHTTPResponse:
18
+ data: GraphQLHTTPResponse = {"data": result.data}
22
19
 
23
- errors, extensions = result.errors, result.extensions
24
- data: GraphQLHTTPResponse = {
25
- "data": result.data,
26
- **({"errors": [err.formatted for err in errors]} if errors else {}),
27
- **({"extensions": extensions} if extensions else {}),
28
- }
20
+ if result.errors:
21
+ data["errors"] = [err.formatted for err in result.errors]
22
+ if result.extensions:
23
+ data["extensions"] = result.extensions
29
24
 
30
25
  return data
31
26
 
@@ -37,6 +32,7 @@ class GraphQLRequestData:
37
32
  query: Optional[str]
38
33
  variables: Optional[dict[str, Any]]
39
34
  operation_name: Optional[str]
35
+ extensions: Optional[dict[str, Any]]
40
36
  protocol: Literal["http", "multipart-subscription"] = "http"
41
37
 
42
38
 
@@ -25,9 +25,6 @@ from strawberry.http import (
25
25
  process_result,
26
26
  )
27
27
  from strawberry.http.ides import GraphQL_IDE
28
- from strawberry.schema._graphql_core import (
29
- GraphQLIncrementalExecutionResults,
30
- )
31
28
  from strawberry.schema.base import BaseSchema
32
29
  from strawberry.schema.exceptions import InvalidOperationTypeError
33
30
  from strawberry.subscriptions import GRAPHQL_TRANSPORT_WS_PROTOCOL, GRAPHQL_WS_PROTOCOL
@@ -207,6 +204,7 @@ class AsyncBaseHTTPView(
207
204
  context_value=context,
208
205
  root_value=root_value,
209
206
  operation_name=request_data.operation_name,
207
+ operation_extensions=request_data.extensions,
210
208
  )
211
209
 
212
210
  return await self.schema.execute(
@@ -216,6 +214,7 @@ class AsyncBaseHTTPView(
216
214
  context_value=context,
217
215
  operation_name=request_data.operation_name,
218
216
  allowed_operation_types=allowed_operation_types,
217
+ operation_extensions=request_data.extensions,
219
218
  )
220
219
 
221
220
  async def parse_multipart(self, request: AsyncHTTPRequestAdapter) -> dict[str, str]:
@@ -261,7 +260,7 @@ class AsyncBaseHTTPView(
261
260
  root_value: Optional[RootValue] = UNSET,
262
261
  ) -> WebSocketResponse: ...
263
262
 
264
- async def run( # noqa: PLR0915
263
+ async def run(
265
264
  self,
266
265
  request: Union[Request, WebSocketRequest],
267
266
  context: Optional[Context] = UNSET,
@@ -352,75 +351,6 @@ class AsyncBaseHTTPView(
352
351
  "Content-Type": "multipart/mixed;boundary=graphql;subscriptionSpec=1.0,application/json",
353
352
  },
354
353
  )
355
- if isinstance(result, GraphQLIncrementalExecutionResults):
356
-
357
- async def stream() -> AsyncGenerator[str, None]:
358
- yield "---"
359
-
360
- response = await self.process_result(request, result.initial_result)
361
-
362
- response["hasNext"] = result.initial_result.has_next
363
- response["pending"] = [
364
- p.formatted for p in result.initial_result.pending
365
- ]
366
- response["extensions"] = result.initial_result.extensions
367
-
368
- yield self.encode_multipart_data(response, "-")
369
-
370
- all_pending = result.initial_result.pending
371
-
372
- async for value in result.subsequent_results:
373
- response = {
374
- "hasNext": value.has_next,
375
- "extensions": value.extensions,
376
- }
377
-
378
- if value.pending:
379
- response["pending"] = [p.formatted for p in value.pending]
380
-
381
- if value.completed:
382
- response["completed"] = [p.formatted for p in value.completed]
383
-
384
- if value.incremental:
385
- incremental = []
386
-
387
- all_pending.extend(value.pending)
388
-
389
- for incremental_value in value.incremental:
390
- pending_value = next(
391
- (
392
- v
393
- for v in all_pending
394
- if v.id == incremental_value.id
395
- ),
396
- None,
397
- )
398
-
399
- assert pending_value
400
-
401
- incremental.append(
402
- {
403
- **incremental_value.formatted,
404
- "path": pending_value.path,
405
- "label": pending_value.label,
406
- }
407
- )
408
-
409
- response["incremental"] = incremental
410
-
411
- yield self.encode_multipart_data(response, "-")
412
-
413
- yield "--\r\n"
414
-
415
- return await self.create_streaming_response(
416
- request,
417
- stream,
418
- sub_response,
419
- headers={
420
- "Transfer-Encoding": "chunked",
421
- "Content-Type": 'multipart/mixed; boundary="-"',
422
- },
423
- )
424
354
 
425
355
  response_data = await self.process_result(request=request, result=result)
426
356
 
@@ -432,16 +362,12 @@ class AsyncBaseHTTPView(
432
362
  )
433
363
 
434
364
  def encode_multipart_data(self, data: Any, separator: str) -> str:
435
- encoded_data = self.encode_json(data)
436
-
437
365
  return "".join(
438
366
  [
439
- "\r\n",
440
- "Content-Type: application/json; charset=utf-8\r\n",
441
- "Content-Length: " + str(len(encoded_data)) + "\r\n",
442
- "\r\n",
443
- encoded_data,
444
- f"\r\n--{separator}",
367
+ f"\r\n--{separator}\r\n",
368
+ "Content-Type: application/json\r\n\r\n",
369
+ self.encode_json(data),
370
+ "\n",
445
371
  ]
446
372
  )
447
373
 
@@ -548,6 +474,7 @@ class AsyncBaseHTTPView(
548
474
  query=data.get("query"),
549
475
  variables=data.get("variables"),
550
476
  operation_name=data.get("operationName"),
477
+ extensions=data.get("extensions"),
551
478
  protocol=protocol,
552
479
  )
553
480
 
strawberry/http/base.py CHANGED
@@ -59,6 +59,12 @@ class BaseView(Generic[Request]):
59
59
  if variables:
60
60
  params["variables"] = self.parse_json(variables)
61
61
 
62
+ if "extensions" in params:
63
+ extensions = params["extensions"]
64
+
65
+ if extensions:
66
+ params["extensions"] = self.parse_json(extensions)
67
+
62
68
  return params
63
69
 
64
70
  @property
@@ -122,6 +122,7 @@ class SyncBaseHTTPView(
122
122
  context_value=context,
123
123
  operation_name=request_data.operation_name,
124
124
  allowed_operation_types=allowed_operation_types,
125
+ operation_extensions=request_data.extensions,
125
126
  )
126
127
 
127
128
  def parse_multipart(self, request: SyncHTTPRequestAdapter) -> dict[str, str]:
@@ -154,6 +155,7 @@ class SyncBaseHTTPView(
154
155
  query=data.get("query"),
155
156
  variables=data.get("variables"),
156
157
  operation_name=data.get("operationName"),
158
+ extensions=data.get("extensions"),
157
159
  )
158
160
 
159
161
  def _handle_errors(
@@ -561,9 +561,9 @@ def print_schema_definition(
561
561
  def print_directive(
562
562
  directive: GraphQLDirective, *, schema: BaseSchema
563
563
  ) -> Optional[str]:
564
- strawberry_directive = directive.extensions.get("strawberry-definition")
564
+ strawberry_directive = directive.extensions["strawberry-definition"]
565
565
 
566
- if strawberry_directive is None or (
566
+ if (
567
567
  isinstance(strawberry_directive, StrawberrySchemaDirective)
568
568
  and not strawberry_directive.print_definition
569
569
  ):
@@ -621,14 +621,6 @@ def print_schema(schema: BaseSchema) -> str:
621
621
  if (printed_directive := print_directive(directive, schema=schema)) is not None
622
622
  ]
623
623
 
624
- if schema.config.enable_experimental_incremental_execution:
625
- directives.append(
626
- "directive @defer(if: Boolean, label: String) on FRAGMENT_SPREAD | INLINE_FRAGMENT"
627
- )
628
- directives.append(
629
- "directive @stream(if: Boolean, label: String, initialCount: Int = 0) on FIELD"
630
- )
631
-
632
624
  def _name_getter(type_: Any) -> str:
633
625
  if hasattr(type_, "name"):
634
626
  return type_.name
strawberry/schema/base.py CHANGED
@@ -47,6 +47,7 @@ class BaseSchema(Protocol):
47
47
  root_value: Optional[Any] = None,
48
48
  operation_name: Optional[str] = None,
49
49
  allowed_operation_types: Optional[Iterable[OperationType]] = None,
50
+ operation_extensions: Optional[dict[str, Any]] = None,
50
51
  ) -> ExecutionResult:
51
52
  raise NotImplementedError
52
53
 
@@ -59,6 +60,7 @@ class BaseSchema(Protocol):
59
60
  root_value: Optional[Any] = None,
60
61
  operation_name: Optional[str] = None,
61
62
  allowed_operation_types: Optional[Iterable[OperationType]] = None,
63
+ operation_extensions: Optional[dict[str, Any]] = None,
62
64
  ) -> ExecutionResult:
63
65
  raise NotImplementedError
64
66
 
@@ -70,6 +72,7 @@ class BaseSchema(Protocol):
70
72
  context_value: Optional[Any] = None,
71
73
  root_value: Optional[Any] = None,
72
74
  operation_name: Optional[str] = None,
75
+ operation_extensions: Optional[dict[str, Any]] = None,
73
76
  ) -> SubscriptionResult:
74
77
  raise NotImplementedError
75
78
 
@@ -17,7 +17,6 @@ class StrawberryConfig:
17
17
  relay_use_legacy_global_id: bool = False
18
18
  disable_field_suggestions: bool = False
19
19
  info_class: type[Info] = Info
20
- enable_experimental_incremental_execution: bool = False
21
20
 
22
21
  def __post_init__(
23
22
  self,
@@ -9,26 +9,34 @@ from typing import (
9
9
  TYPE_CHECKING,
10
10
  Any,
11
11
  Callable,
12
+ NamedTuple,
12
13
  Optional,
13
14
  Union,
14
15
  cast,
15
16
  )
16
17
 
18
+ from graphql import ExecutionContext as GraphQLExecutionContext
17
19
  from graphql import ExecutionResult as GraphQLExecutionResult
18
20
  from graphql import (
19
21
  ExecutionResult as OriginalExecutionResult,
20
22
  )
21
23
  from graphql import (
24
+ FieldNode,
25
+ FragmentDefinitionNode,
22
26
  GraphQLBoolean,
23
27
  GraphQLError,
24
28
  GraphQLField,
25
29
  GraphQLNamedType,
26
30
  GraphQLNonNull,
31
+ GraphQLObjectType,
32
+ GraphQLOutputType,
27
33
  GraphQLSchema,
34
+ OperationDefinitionNode,
28
35
  get_introspection_query,
29
36
  parse,
30
37
  validate_schema,
31
38
  )
39
+ from graphql.execution import execute, subscribe
32
40
  from graphql.execution.middleware import MiddlewareManager
33
41
  from graphql.type.directives import specified_directives
34
42
  from graphql.validation import validate
@@ -56,20 +64,11 @@ from strawberry.types.execution import (
56
64
  PreExecutionError,
57
65
  )
58
66
  from strawberry.types.graphql import OperationType
59
- from strawberry.utils import IS_GQL_32
67
+ from strawberry.utils import IS_GQL_32, IS_GQL_33
60
68
  from strawberry.utils.aio import aclosing
61
69
  from strawberry.utils.await_maybe import await_maybe
62
70
 
63
71
  from . import compat
64
- from ._graphql_core import (
65
- GraphQLExecutionContext,
66
- GraphQLIncrementalExecutionResults,
67
- ResultType,
68
- execute,
69
- experimental_execute_incrementally,
70
- incremental_execution_directives,
71
- subscribe,
72
- )
73
72
  from .base import BaseSchema
74
73
  from .config import StrawberryConfig
75
74
  from .exceptions import InvalidOperationTypeError
@@ -78,8 +77,10 @@ if TYPE_CHECKING:
78
77
  from collections.abc import Iterable, Mapping
79
78
  from typing_extensions import TypeAlias
80
79
 
81
- from graphql import ExecutionContext as GraphQLExecutionContext
80
+ from graphql.execution.collect_fields import FieldGroup # type: ignore
82
81
  from graphql.language import DocumentNode
82
+ from graphql.pyutils import Path
83
+ from graphql.type import GraphQLResolveInfo
83
84
  from graphql.validation import ASTValidationRule
84
85
 
85
86
  from strawberry.directive import StrawberryDirective
@@ -98,7 +99,6 @@ OriginSubscriptionResult = Union[
98
99
  AsyncIterator[OriginalExecutionResult],
99
100
  ]
100
101
 
101
-
102
102
  DEFAULT_ALLOWED_OPERATION_TYPES = {
103
103
  OperationType.QUERY,
104
104
  OperationType.MUTATION,
@@ -144,6 +144,62 @@ def _coerce_error(error: Union[GraphQLError, Exception]) -> GraphQLError:
144
144
  return GraphQLError(str(error), original_error=error)
145
145
 
146
146
 
147
+ class _OperationContextAwareGraphQLResolveInfo(NamedTuple): # pyright: ignore
148
+ field_name: str
149
+ field_nodes: list[FieldNode]
150
+ return_type: GraphQLOutputType
151
+ parent_type: GraphQLObjectType
152
+ path: Path
153
+ schema: GraphQLSchema
154
+ fragments: dict[str, FragmentDefinitionNode]
155
+ root_value: Any
156
+ operation: OperationDefinitionNode
157
+ variable_values: dict[str, Any]
158
+ context: Any
159
+ is_awaitable: Callable[[Any], bool]
160
+ operation_extensions: dict[str, Any]
161
+
162
+
163
+ class StrawberryGraphQLCoreExecutionContext(GraphQLExecutionContext):
164
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
165
+ operation_extensions = kwargs.pop("operation_extensions", None)
166
+
167
+ super().__init__(*args, **kwargs)
168
+
169
+ self.operation_extensions = operation_extensions
170
+
171
+ def build_resolve_info(
172
+ self,
173
+ field_def: GraphQLField,
174
+ field_group: FieldGroup,
175
+ parent_type: GraphQLObjectType,
176
+ path: Path,
177
+ ) -> GraphQLResolveInfo:
178
+ if IS_GQL_33:
179
+ return _OperationContextAwareGraphQLResolveInfo( # type: ignore
180
+ field_group.fields[0].node.name.value,
181
+ field_group.to_nodes(),
182
+ field_def.type,
183
+ parent_type,
184
+ path,
185
+ self.schema,
186
+ self.fragments,
187
+ self.root_value,
188
+ self.operation,
189
+ self.variable_values,
190
+ self.context_value,
191
+ self.is_awaitable,
192
+ self.operation_extensions,
193
+ )
194
+
195
+ return super().build_resolve_info(
196
+ field_def,
197
+ field_group,
198
+ parent_type,
199
+ path,
200
+ )
201
+
202
+
147
203
  class Schema(BaseSchema):
148
204
  def __init__(
149
205
  self,
@@ -203,7 +259,9 @@ class Schema(BaseSchema):
203
259
 
204
260
  self.extensions = extensions
205
261
  self._cached_middleware_manager: MiddlewareManager | None = None
206
- self.execution_context_class = execution_context_class
262
+ self.execution_context_class = (
263
+ execution_context_class or StrawberryGraphQLCoreExecutionContext
264
+ )
207
265
  self.config = config or StrawberryConfig()
208
266
 
209
267
  self.schema_converter = GraphQLCoreConverter(
@@ -263,16 +321,11 @@ class Schema(BaseSchema):
263
321
  graphql_types.append(graphql_type)
264
322
 
265
323
  try:
266
- directives = specified_directives + tuple(graphql_directives)
267
-
268
- if self.config.enable_experimental_incremental_execution:
269
- directives = tuple(directives) + tuple(incremental_execution_directives)
270
-
271
324
  self._schema = GraphQLSchema(
272
325
  query=query_type,
273
326
  mutation=mutation_type,
274
327
  subscription=subscription_type if subscription else None,
275
- directives=directives,
328
+ directives=specified_directives + tuple(graphql_directives),
276
329
  types=graphql_types,
277
330
  extensions={
278
331
  GraphQLCoreConverter.DEFINITION_BACKREF: self,
@@ -333,6 +386,14 @@ class Schema(BaseSchema):
333
386
  extensions=extensions,
334
387
  )
335
388
 
389
+ def _get_custom_context_kwargs(
390
+ self, operation_extensions: Optional[dict[str, Any]] = None
391
+ ) -> dict[str, Any]:
392
+ if not IS_GQL_33:
393
+ return {}
394
+
395
+ return {"operation_extensions": operation_extensions}
396
+
336
397
  def _get_middleware_manager(
337
398
  self, extensions: list[SchemaExtension]
338
399
  ) -> MiddlewareManager:
@@ -450,16 +511,12 @@ class Schema(BaseSchema):
450
511
  async def _handle_execution_result(
451
512
  self,
452
513
  context: ExecutionContext,
453
- result: ResultType,
514
+ result: Union[GraphQLExecutionResult, ExecutionResult],
454
515
  extensions_runner: SchemaExtensionsRunner,
455
516
  *,
456
517
  # TODO: can we remove this somehow, see comment in execute
457
518
  skip_process_errors: bool = False,
458
519
  ) -> ExecutionResult:
459
- # TODO: handle this, also, why do we have both GraphQLExecutionResult and ExecutionResult?
460
- if isinstance(result, GraphQLIncrementalExecutionResults):
461
- return result
462
-
463
520
  # Set errors on the context so that it's easier
464
521
  # to access in extensions
465
522
  if result.errors:
@@ -480,6 +537,7 @@ class Schema(BaseSchema):
480
537
  root_value: Optional[Any] = None,
481
538
  operation_name: Optional[str] = None,
482
539
  allowed_operation_types: Optional[Iterable[OperationType]] = None,
540
+ operation_extensions: Optional[dict[str, Any]] = None,
483
541
  ) -> ExecutionResult:
484
542
  if allowed_operation_types is None:
485
543
  allowed_operation_types = DEFAULT_ALLOWED_OPERATION_TYPES
@@ -500,16 +558,7 @@ class Schema(BaseSchema):
500
558
  extensions_runner = self.create_extensions_runner(execution_context, extensions)
501
559
  middleware_manager = self._get_middleware_manager(extensions)
502
560
 
503
- execute_function = execute
504
-
505
- if self.config.enable_experimental_incremental_execution:
506
- execute_function = experimental_execute_incrementally
507
-
508
- if execute_function is None:
509
- raise RuntimeError(
510
- "Incremental execution is enabled but experimental_execute_incrementally is not available, "
511
- "please install graphql-core>=3.3.0"
512
- )
561
+ custom_context_kwargs = self._get_custom_context_kwargs(operation_extensions)
513
562
 
514
563
  try:
515
564
  async with extensions_runner.operation():
@@ -529,7 +578,7 @@ class Schema(BaseSchema):
529
578
  async with extensions_runner.executing():
530
579
  if not execution_context.result:
531
580
  result = await await_maybe(
532
- execute_function(
581
+ execute(
533
582
  self._schema,
534
583
  execution_context.graphql_document,
535
584
  root_value=execution_context.root_value,
@@ -538,6 +587,7 @@ class Schema(BaseSchema):
538
587
  operation_name=execution_context.operation_name,
539
588
  context_value=execution_context.context,
540
589
  execution_context_class=self.execution_context_class,
590
+ **custom_context_kwargs,
541
591
  )
542
592
  )
543
593
  execution_context.result = result
@@ -545,9 +595,7 @@ class Schema(BaseSchema):
545
595
  result = execution_context.result
546
596
  # Also set errors on the execution_context so that it's easier
547
597
  # to access in extensions
548
-
549
- # TODO: maybe here use the first result from incremental execution if it exists
550
- if isinstance(result, GraphQLExecutionResult) and result.errors:
598
+ if result.errors:
551
599
  execution_context.errors = result.errors
552
600
 
553
601
  # Run the `Schema.process_errors` function here before
@@ -577,6 +625,7 @@ class Schema(BaseSchema):
577
625
  root_value: Optional[Any] = None,
578
626
  operation_name: Optional[str] = None,
579
627
  allowed_operation_types: Optional[Iterable[OperationType]] = None,
628
+ operation_extensions: Optional[dict[str, Any]] = None,
580
629
  ) -> ExecutionResult:
581
630
  if allowed_operation_types is None:
582
631
  allowed_operation_types = DEFAULT_ALLOWED_OPERATION_TYPES
@@ -597,16 +646,8 @@ class Schema(BaseSchema):
597
646
  extensions_runner = self.create_extensions_runner(execution_context, extensions)
598
647
  middleware_manager = self._get_middleware_manager(extensions)
599
648
 
600
- execute_function = execute
601
-
602
- if self.config.enable_experimental_incremental_execution:
603
- execute_function = experimental_execute_incrementally
649
+ custom_context_kwargs = self._get_custom_context_kwargs(operation_extensions)
604
650
 
605
- if execute_function is None:
606
- raise RuntimeError(
607
- "Incremental execution is enabled but experimental_execute_incrementally is not available, "
608
- "please install graphql-core>=3.3.0"
609
- )
610
651
  try:
611
652
  with extensions_runner.operation():
612
653
  # Note: In graphql-core the schema would be validated here but in
@@ -648,7 +689,7 @@ class Schema(BaseSchema):
648
689
 
649
690
  with extensions_runner.executing():
650
691
  if not execution_context.result:
651
- result = execute_function(
692
+ result = execute(
652
693
  self._schema,
653
694
  execution_context.graphql_document,
654
695
  root_value=execution_context.root_value,
@@ -657,6 +698,7 @@ class Schema(BaseSchema):
657
698
  operation_name=execution_context.operation_name,
658
699
  context_value=execution_context.context,
659
700
  execution_context_class=self.execution_context_class,
701
+ **custom_context_kwargs,
660
702
  )
661
703
 
662
704
  if isawaitable(result):
@@ -701,6 +743,7 @@ class Schema(BaseSchema):
701
743
  extensions_runner: SchemaExtensionsRunner,
702
744
  middleware_manager: MiddlewareManager,
703
745
  execution_context_class: type[GraphQLExecutionContext] | None = None,
746
+ operation_extensions: Optional[dict[str, Any]] = None,
704
747
  ) -> AsyncGenerator[ExecutionResult, None]:
705
748
  async with extensions_runner.operation():
706
749
  if initial_error := await self._parse_and_validate_async(
@@ -719,6 +762,7 @@ class Schema(BaseSchema):
719
762
  gql_33_kwargs = {
720
763
  "middleware": middleware_manager,
721
764
  "execution_context_class": execution_context_class,
765
+ "operation_extensions": operation_extensions,
722
766
  }
723
767
  try:
724
768
  # Might not be awaitable for pre-execution errors.
@@ -783,6 +827,7 @@ class Schema(BaseSchema):
783
827
  context_value: Optional[Any] = None,
784
828
  root_value: Optional[Any] = None,
785
829
  operation_name: Optional[str] = None,
830
+ operation_extensions: Optional[dict[str, Any]] = None,
786
831
  ) -> SubscriptionResult:
787
832
  execution_context = self._create_execution_context(
788
833
  query=query,
@@ -804,6 +849,7 @@ class Schema(BaseSchema):
804
849
  ),
805
850
  middleware_manager=self._get_middleware_manager(extensions),
806
851
  execution_context_class=self.execution_context_class,
852
+ operation_extensions=operation_extensions,
807
853
  )
808
854
 
809
855
  def _resolve_node_ids(self) -> None:
@@ -817,9 +817,9 @@ class GraphQLCoreConverter:
817
817
 
818
818
  scalar_name = self.config.name_converter.from_type(scalar_definition)
819
819
 
820
- if scalar_name not in self.type_map:
821
- from strawberry.relay import GlobalID
820
+ from strawberry.relay import GlobalID
822
821
 
822
+ if scalar_name not in self.type_map:
823
823
  if scalar is GlobalID and hasattr(GraphQLNamedType, "reserved_types"):
824
824
  GraphQLNamedType.reserved_types.pop("ID")
825
825
 
@@ -841,7 +841,17 @@ class GraphQLCoreConverter:
841
841
  # TODO: the other definition might not be a scalar, we should
842
842
  # handle this case better, since right now we assume it is a scalar
843
843
 
844
- if other_definition != scalar_definition:
844
+ # special case to allow GlobalID to be used as an ID scalar
845
+ # TODO: we need to find a better way to handle this, might be
846
+ # worth reworking our scalar implementation.
847
+ if (
848
+ hasattr(other_definition, "origin")
849
+ and hasattr(scalar_definition, "origin")
850
+ and other_definition.origin == GlobalID
851
+ and scalar_definition.origin == GraphQLID
852
+ ):
853
+ pass
854
+ elif other_definition != scalar_definition:
845
855
  other_definition = cast("ScalarDefinition", other_definition)
846
856
 
847
857
  raise ScalarAlreadyRegisteredError(scalar_definition, other_definition)
@@ -40,6 +40,7 @@ def _make_scalar_definition(scalar_type: GraphQLScalarType) -> ScalarDefinition:
40
40
  parse_literal=scalar_type.parse_literal,
41
41
  parse_value=scalar_type.parse_value,
42
42
  implementation=scalar_type,
43
+ origin=scalar_type,
43
44
  )
44
45
 
45
46
 
@@ -1,4 +1,4 @@
1
- <!doctype html>
1
+ <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
4
  <title>Strawberry GraphiQL</title>
@@ -61,8 +61,8 @@
61
61
  <link
62
62
  crossorigin
63
63
  rel="stylesheet"
64
- href="https://unpkg.com/graphiql@3.8.3/graphiql.min.css"
65
- integrity="sha384-Mq3vbRBY71jfjQAt/DcjxUIYY33ksal4cgdRt9U/hNPvHBCaT2JfJ/PTRiPKf0aM"
64
+ href="https://unpkg.com/graphiql@3.0.9/graphiql.min.css"
65
+ integrity="sha384-yz3/sqpuplkA7msMo0FE4ekg0xdwdvZ8JX9MVZREsxipqjU4h8IRfmAMRcb1QpUy"
66
66
  />
67
67
 
68
68
  <link
@@ -77,8 +77,8 @@
77
77
  <div id="graphiql" class="graphiql-container">Loading...</div>
78
78
  <script
79
79
  crossorigin
80
- src="https://unpkg.com/graphiql@3.8.3/graphiql.min.js"
81
- integrity="sha384-HbRVEFG0JGJZeAHCJ9Xm2+tpknBQ7QZmNlO/DgZtkZ0aJSypT96YYGRNod99l9Ie"
80
+ src="https://unpkg.com/graphiql@3.0.9/graphiql.min.js"
81
+ integrity="sha384-Mjte+vxCWz1ZYCzszGHiJqJa5eAxiqI4mc3BErq7eDXnt+UGLXSEW7+i0wmfPiji"
82
82
  ></script>
83
83
  <script
84
84
  crossorigin
strawberry/types/info.py CHANGED
@@ -113,6 +113,11 @@ class Info(Generic[ContextType, RootValueType]):
113
113
  """The context passed to the query execution."""
114
114
  return self._raw_info.context
115
115
 
116
+ @property
117
+ def input_extensions(self) -> dict[str, Any]:
118
+ """The input extensions passed to the query execution."""
119
+ return self._raw_info.operation_extensions # type: ignore
120
+
116
121
  @property
117
122
  def root_value(self) -> RootValueType:
118
123
  """The root value passed to the query execution."""
@@ -43,6 +43,7 @@ class ScalarDefinition(StrawberryType):
43
43
  parse_value: Optional[Callable]
44
44
  parse_literal: Optional[Callable]
45
45
  directives: Iterable[object] = ()
46
+ origin: Optional[GraphQLScalarType | type] = None
46
47
 
47
48
  # Optionally store the GraphQLScalarType instance so that we don't get
48
49
  # duplicates
@@ -115,6 +116,7 @@ def _process_scalar(
115
116
  parse_literal=parse_literal,
116
117
  parse_value=parse_value,
117
118
  directives=directives,
119
+ origin=cls, # type: ignore[arg-type]
118
120
  _source_file=_source_file,
119
121
  _source_line=_source_line,
120
122
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: strawberry-graphql
3
- Version: 0.269.0.dev1746905409
3
+ Version: 0.269.0.dev1747164009
4
4
  Summary: A library for creating GraphQL APIs
5
5
  License: MIT
6
6
  Keywords: graphql,api,rest,starlette,async
@@ -1,10 +1,10 @@
1
- strawberry/__init__.py,sha256=tavG4mNFBNHhGBoFR2T7fhiCQ7P-ITHify10nkKBOJE,1544
1
+ strawberry/__init__.py,sha256=-K---AYIgHvBVYF_9oovgEPNBbymXH673bntlV9sOeU,1491
2
2
  strawberry/__main__.py,sha256=3U77Eu21mJ-LY27RG-JEnpbh6Z63wGOom4i-EoLtUcY,59
3
3
  strawberry/aiohttp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  strawberry/aiohttp/test/__init__.py,sha256=4xxdUZtIISSOwjrcnmox7AvT4WWjowCm5bUuPdQneMg,71
5
5
  strawberry/aiohttp/test/client.py,sha256=8FKZTnvawxYpgEICOri-34O3wHRHLhRpjH_Ktp2EupQ,1801
6
6
  strawberry/aiohttp/views.py,sha256=AQVBbZTBa127TbQRwoBelTHrVdZnJeGdMYcTfNmoaSc,7887
7
- strawberry/annotation.py,sha256=YGauf-nyuW-RGdjEu5RBxgcYV31cHx3pDLwqqjlgKv8,13822
7
+ strawberry/annotation.py,sha256=iqSXtJ4pTTLDZRPyil0f-yzpcCm8UYRiwvFWkD5LgpQ,13498
8
8
  strawberry/asgi/__init__.py,sha256=psdKl_52LGkxKKbzZlmwNGZ9jz2FLyLSC7fUhys4FqY,8169
9
9
  strawberry/asgi/test/__init__.py,sha256=4xxdUZtIISSOwjrcnmox7AvT4WWjowCm5bUuPdQneMg,71
10
10
  strawberry/asgi/test/client.py,sha256=kp2O5znHWuAB5VVYO8p4XPSTEDDXBSjNz5WHqW0r6GM,1473
@@ -130,13 +130,13 @@ strawberry/file_uploads/scalars.py,sha256=NRDeB7j8aotqIkz9r62ISTf4DrxQxEZYUuHsX5
130
130
  strawberry/file_uploads/utils.py,sha256=-c6TbqUI-Dkb96hWCrZabh6TL2OabBuQNkCarOqgDm4,1181
131
131
  strawberry/flask/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
132
132
  strawberry/flask/views.py,sha256=MCvAsNgTZLU8RvTYKWfnLU2w7Wv1ZZpxW9W3TyTZuPY,6355
133
- strawberry/http/__init__.py,sha256=nvy1c7CGHMJlOE9rSiTl6D7eiqWixC1G6x4evgIEKgk,1275
134
- strawberry/http/async_base_view.py,sha256=hDHVAS9ZVsY0apn109oMX-HLNbMiQinPrp8iYYf6rBQ,19151
135
- strawberry/http/base.py,sha256=Lz-u5SWg2uQp3l5GMKZDPQuJOR42LXHgjV1PZHwiapE,2373
133
+ strawberry/http/__init__.py,sha256=ytAirKk7K7D5knY21tpCGeZ-sCPgwMsijL5AxmOy-94,1163
134
+ strawberry/http/async_base_view.py,sha256=NnFYHy_3b6WtxRZoLCWDeOXDqEz2VxzG6jlKcIwrM4E,16519
135
+ strawberry/http/base.py,sha256=MiX0-RqOkhRvlfpmuvgTHp4tygbUmG8fnLc0uCrOllU,2550
136
136
  strawberry/http/exceptions.py,sha256=9E2dreS1crRoJVUEPuHyx23NcDELDHNzkAOa-rGv-8I,348
137
137
  strawberry/http/ides.py,sha256=WjU0nsMDgr3Bd1ebWkUEkO2d1hk0dI16mLqXyCHqklA,613
138
138
  strawberry/http/parse_content_type.py,sha256=CYHO8F9b9DP1gJ1xxPjc9L2GkBwsyC1O_GCEp1QOuG0,381
139
- strawberry/http/sync_base_view.py,sha256=iKcc9bDu7wQnOTfcCEW56I-Y35xdkb1P_sP3-y7RTh8,7180
139
+ strawberry/http/sync_base_view.py,sha256=x_RQ7XdzwPmMl1vCh3bmgVvShQp28azSEkVMCX2o6Mc,7285
140
140
  strawberry/http/temporal_response.py,sha256=HTt65g-YxqlPGxjqvH5bzGoU1b3CctVR-9cmCRo5dUo,196
141
141
  strawberry/http/types.py,sha256=H0wGOdCO-5tNKZM_6cAtNRwZAjoEXnAC5N0Q7b70AtU,398
142
142
  strawberry/http/typevars.py,sha256=Uu6NkKe3h7o29ZWwldq6sJy4ioSSeXODTCDRvY2hUpE,489
@@ -146,7 +146,7 @@ strawberry/parent.py,sha256=JYFp-HGCgwbH2oB4uLSiIO4cVsoPaxX6lfYmxOKPkSg,1362
146
146
  strawberry/permission.py,sha256=dSRJMjSCmTlXfvfC24kCSrAk0txTjYKTJ5ZVU5IW91Y,7537
147
147
  strawberry/printer/__init__.py,sha256=DmepjmgtkdF5RxK_7yC6qUyRWn56U-9qeZMbkztYB9w,62
148
148
  strawberry/printer/ast_from_value.py,sha256=Tkme60qlykbN2m3dNPNMOe65X-wj6EmcDQwgQv7gUkc,4987
149
- strawberry/printer/printer.py,sha256=5E9w0wDsUv1hvkeXof12277NLMiCVy5MgJ6gSo_NJhQ,19177
149
+ strawberry/printer/printer.py,sha256=49u3QwttTGvh13HXZtbTnkZzBwL1k5SLf8rXQLiTpl4,18814
150
150
  strawberry/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
151
151
  strawberry/quart/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
152
152
  strawberry/quart/views.py,sha256=Hjm93A9j9fy--DQVhsPQ_PakqYtajyWeuH7wUnSLYoA,4449
@@ -162,27 +162,25 @@ strawberry/sanic/utils.py,sha256=XjUVBFuBWfECBCZbx_YtrjQnFTUyIGTo7aISIeB22Gc,100
162
162
  strawberry/sanic/views.py,sha256=F5ZrKt-R3135evKLfhQuPd1isOexI0Lrzevm_6Te4Eg,7069
163
163
  strawberry/scalars.py,sha256=CGkG8CIfurXiYhidmW3qwy6M5BF_Mhih3wAEcWx_iBU,2278
164
164
  strawberry/schema/__init__.py,sha256=u1QCyDVQExUVDA20kyosKPz3TS5HMCN2NrXclhiFAL4,92
165
- strawberry/schema/_graphql_core.py,sha256=XHsNZLkCyiH55jANK4XJIjq6VCMhN_MgZBEFWEYj5Jc,1237
166
- strawberry/schema/base.py,sha256=q5UAw6do4Ele5Cf8dNAouiPjNmZoCBNFqh5Vl05caCI,3864
165
+ strawberry/schema/base.py,sha256=wqvEOQ_aVkfebk9SlG9zg1YXl3MlwxGZhxFRoIkAxu0,4053
167
166
  strawberry/schema/compat.py,sha256=xNpOEDfi-MODpplMGaKuKeQIVcr-tcAaKaU3TlBc1Zs,1873
168
- strawberry/schema/config.py,sha256=zQLJSF6FoUIur6MJSMz3NHqxDCYqcHL3fu6H5NA4hmI,1029
167
+ strawberry/schema/config.py,sha256=KeZ1Pc1gvYK0fOx9Aghx7m0Av8sWexycl3HJGFgHPvg,969
169
168
  strawberry/schema/exceptions.py,sha256=rqVNb_oYrKM0dHPgvAemqCG6Um282LPPu4zwQ5cZqs4,584
170
169
  strawberry/schema/name_converter.py,sha256=xFOXEgqldFkxXRkIQvsJN1dPkWbEUaIrTYNOMYSEVwQ,6945
171
- strawberry/schema/schema.py,sha256=So_T5IqyADhIrj_OSoLt3UlFwuRppeOY39JSChEZ7k0,35704
172
- strawberry/schema/schema_converter.py,sha256=yuYafNwa9zs6l-GmuGtxdjYwawxjiU6zmwIgJ-aLhV4,39308
170
+ strawberry/schema/schema.py,sha256=zRIv4mpVEFjFWv-MmfjO9v7OsuSFZ2xghr_ekIAuZI4,37113
171
+ strawberry/schema/schema_converter.py,sha256=u12Og8eUX8SNMtJB6LYkj9zEpoQs-rDOXpN7tU8JG7k,39785
173
172
  strawberry/schema/types/__init__.py,sha256=oHO3COWhL3L1KLYCJNY1XFf5xt2GGtHiMC-UaYbFfnA,68
174
173
  strawberry/schema/types/base_scalars.py,sha256=JRUq0WjEkR9dFewstZnqnZKp0uOEipo4UXNF5dzRf4M,1971
175
174
  strawberry/schema/types/concrete_type.py,sha256=axIyFZgdwNv-XYkiqX67464wuFX6Vp0jYATwnBZSUvM,750
176
- strawberry/schema/types/scalar.py,sha256=X_9R7tLDINcs9UeExUUqq3_U2JkhCVJBeEhDFDUt3Tc,2347
175
+ strawberry/schema/types/scalar.py,sha256=bg9AumdmYUBuvaKoEZtP9YKJ7lwMtDMCWFTsZQwpdQY,2375
177
176
  strawberry/schema/validation_rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
178
177
  strawberry/schema/validation_rules/one_of.py,sha256=fPuYzCyLT7p9y7dHF_sWTImArTQaEhyF664lZijB1Gw,2629
179
178
  strawberry/schema_codegen/__init__.py,sha256=mN4Qmu5Iakht6nHpRpt9hCs8e--oTPlVtDJZJpzgHR4,24364
180
179
  strawberry/schema_directive.py,sha256=CbjdX54EIeWGkJu4SgiLR8mph5_8wyNsgJk2oLoQK_0,2023
181
180
  strawberry/schema_directives.py,sha256=KGKFWCODjm1Ah9qNV_bBwbic7Mld4qLWnWQkev-PG8A,175
182
181
  strawberry/static/apollo-sandbox.html,sha256=2XzkbE0dqsFHqehE-jul9_J9TFOpwA6Ylrlo0Kdx_9w,973
183
- strawberry/static/graphiql.html,sha256=0e3pvTnAet-lNEqA_pgJ8Ak2CdMt34zPKMMMzpAkEVU,4257
182
+ strawberry/static/graphiql.html,sha256=BkiqZlC63f1sHBDs_UpMzcibcNrHKh7K41Sp23yttfo,4257
184
183
  strawberry/static/pathfinder.html,sha256=0DPx9AmJ2C_sJstFXnWOz9k5tVQHeHaK7qdVY4lAlmk,1547
185
- strawberry/streamable.py,sha256=ylfMt5lfX7RRKGi86wWokvIgYQk5jZCvQVc3shK0epk,645
186
184
  strawberry/subscriptions/__init__.py,sha256=1VGmiCzFepqRFyCikagkUoHHdoTG3XYlFu9GafoQMws,170
187
185
  strawberry/subscriptions/protocols/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
188
186
  strawberry/subscriptions/protocols/graphql_transport_ws/__init__.py,sha256=wN6dkMu6WiaIZTE19PGoN9xXpIN_RdDE_q7F7ZgjCxk,138
@@ -207,14 +205,14 @@ strawberry/types/field.py,sha256=vxb7JvkHfRmDCYsjhDmVnO2lMbtSOteQm3jQUeSFu6g,216
207
205
  strawberry/types/fields/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
208
206
  strawberry/types/fields/resolver.py,sha256=b6lxfw6AMOUFWm7vs7a9KzNkpR8b_S110DoIosrrWDQ,14679
209
207
  strawberry/types/graphql.py,sha256=gXKzawwKiow7hvoJhq5ApNJOMUCnKmvTiHaKY5CK1Lw,867
210
- strawberry/types/info.py,sha256=bPP7XTQQScmskJcmVv36iqLAWpdGmF2nhYjI1pJ-csI,4709
208
+ strawberry/types/info.py,sha256=V3DQMd97tkWSdPIhp7HcelQ2h94-HSCI5zJ7cRO7i58,4907
211
209
  strawberry/types/lazy_type.py,sha256=dlP9VcMjZc9sdgriiQGzOZa0TToB6Ee7zpIP8h7TLC0,5079
212
210
  strawberry/types/maybe.py,sha256=Zdv4pAJwgUmaFNU8WKlwjk50qwgYEzT90WteURZBzAo,1174
213
211
  strawberry/types/mutation.py,sha256=cg-_O2WWnZ-GSwOIv0toSdxlGeY2lhBBxZ24AifJuSM,11978
214
212
  strawberry/types/nodes.py,sha256=RwZB43OT9BS3Cqjgq4AazqOfyq_y0GD2ysC86EDBv5U,5134
215
213
  strawberry/types/object_type.py,sha256=SZOzxaS318079G-pr-1PM5iMoTddxdw8KD4cI67IhzI,15579
216
214
  strawberry/types/private.py,sha256=DhJs50XVGtOXlxWZFkRpMxQ5_6oki0-x_WQsV1bGUxk,518
217
- strawberry/types/scalar.py,sha256=CM24Ixg4DKxxI1C6hTNGYVitohJibs8BpGtntRZvMXw,6284
215
+ strawberry/types/scalar.py,sha256=vUWGwAYgcfY26jQUdBJ1tGOvrBq92V0p9L8AWXM7bkk,6384
218
216
  strawberry/types/type_resolver.py,sha256=fH2ZOK4dAGgu8AMPi-JAXe_kEAbvvw2MCYXqbpx-kTc,6529
219
217
  strawberry/types/union.py,sha256=rwZoJcMdUxJBlYMwx3ONByv6BylhvXT0Bflem6xzMM4,10090
220
218
  strawberry/types/unset.py,sha256=7DVK-WWxVLo41agvavTvIbphE42BmY8UpGolXfasIvw,1682
@@ -231,8 +229,8 @@ strawberry/utils/logging.py,sha256=U1cseHGquN09YFhFmRkiphfASKCyK0HUZREImPgVb0c,7
231
229
  strawberry/utils/operation.py,sha256=s7ajvLg_q6v2mg47kEMQPjO_J-XluMKTCwo4d47mGvE,1195
232
230
  strawberry/utils/str_converters.py,sha256=-eH1Cl16IO_wrBlsGM-km4IY0IKsjhjnSNGRGOwQjVM,897
233
231
  strawberry/utils/typing.py,sha256=SDvX-Du-9HAV3-XXjqi7Q5f5qPDDFd_gASIITiwBQT4,14073
234
- strawberry_graphql-0.269.0.dev1746905409.dist-info/LICENSE,sha256=m-XnIVUKqlG_AWnfi9NReh9JfKhYOB-gJfKE45WM1W8,1072
235
- strawberry_graphql-0.269.0.dev1746905409.dist-info/METADATA,sha256=sHIySmlxBSdlyOX75pzZ4cMZfQM-ohxJHrN7hVhYGkw,7693
236
- strawberry_graphql-0.269.0.dev1746905409.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
237
- strawberry_graphql-0.269.0.dev1746905409.dist-info/entry_points.txt,sha256=Nk7-aT3_uEwCgyqtHESV9H6Mc31cK-VAvhnQNTzTb4k,49
238
- strawberry_graphql-0.269.0.dev1746905409.dist-info/RECORD,,
232
+ strawberry_graphql-0.269.0.dev1747164009.dist-info/LICENSE,sha256=m-XnIVUKqlG_AWnfi9NReh9JfKhYOB-gJfKE45WM1W8,1072
233
+ strawberry_graphql-0.269.0.dev1747164009.dist-info/METADATA,sha256=JpVEXkg2xDj9vjnGUpAV7_XvnIg6LV74yCj9xo6ZAR4,7693
234
+ strawberry_graphql-0.269.0.dev1747164009.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
235
+ strawberry_graphql-0.269.0.dev1747164009.dist-info/entry_points.txt,sha256=Nk7-aT3_uEwCgyqtHESV9H6Mc31cK-VAvhnQNTzTb4k,49
236
+ strawberry_graphql-0.269.0.dev1747164009.dist-info/RECORD,,
@@ -1,46 +0,0 @@
1
- from typing import Union
2
-
3
- from graphql.execution import ExecutionContext as GraphQLExecutionContext
4
- from graphql.execution import ExecutionResult as GraphQLExecutionResult
5
- from graphql.execution import execute, subscribe
6
-
7
- from strawberry.types import ExecutionResult
8
-
9
- try:
10
- from graphql import (
11
- ExperimentalIncrementalExecutionResults as GraphQLIncrementalExecutionResults,
12
- )
13
- from graphql.execution import experimental_execute_incrementally
14
- from graphql.type.directives import (
15
- GraphQLDeferDirective,
16
- GraphQLStreamDirective,
17
- )
18
-
19
- incremental_execution_directives = (
20
- GraphQLDeferDirective,
21
- GraphQLStreamDirective,
22
- )
23
-
24
- except ImportError:
25
- GraphQLIncrementalExecutionResults = type(None)
26
-
27
- incremental_execution_directives = []
28
- experimental_execute_incrementally = None
29
-
30
-
31
- # TODO: give this a better name, maybe also a better place
32
- ResultType = Union[
33
- GraphQLExecutionResult,
34
- GraphQLIncrementalExecutionResults,
35
- ExecutionResult,
36
- ]
37
-
38
- __all__ = [
39
- "GraphQLExecutionContext",
40
- "GraphQLIncrementalExecutionResults",
41
- "ResultType",
42
- "execute",
43
- "experimental_execute_incrementally",
44
- "incremental_execution_directives",
45
- "subscribe",
46
- ]
strawberry/streamable.py DELETED
@@ -1,36 +0,0 @@
1
- from collections.abc import AsyncGenerator
2
- from typing import Annotated, TypeVar
3
-
4
-
5
- class StrawberryStreamable: ...
6
-
7
-
8
- T = TypeVar("T")
9
-
10
- Streamable = Annotated[AsyncGenerator[T, None], StrawberryStreamable()]
11
- """Represents a list that can be streamed using @stream.
12
-
13
- Example:
14
-
15
- ```python
16
- import strawberry
17
- from dataclasses import dataclass
18
-
19
-
20
- @strawberry.type
21
- class Comment:
22
- id: strawberry.ID
23
- content: str
24
-
25
-
26
- @strawberry.type
27
- class Article:
28
- @strawberry.field
29
- @staticmethod
30
- async def comments() -> strawberry.Streamable[Comment]:
31
- for comment in fetch_comments():
32
- yield comment
33
- ```
34
- """
35
-
36
- __all__ = ["Streamable"]