strawberry-graphql 0.255.0__py3-none-any.whl → 0.256.1__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 +9 -9
- strawberry/aiohttp/test/client.py +10 -8
- strawberry/aiohttp/views.py +5 -7
- strawberry/annotation.py +12 -15
- strawberry/asgi/__init__.py +3 -6
- strawberry/asgi/test/client.py +9 -8
- strawberry/chalice/views.py +4 -2
- strawberry/channels/__init__.py +1 -1
- strawberry/channels/handlers/base.py +3 -7
- strawberry/channels/handlers/http_handler.py +5 -6
- strawberry/channels/handlers/ws_handler.py +3 -4
- strawberry/channels/testing.py +5 -9
- strawberry/cli/commands/codegen.py +9 -9
- strawberry/cli/commands/upgrade/__init__.py +2 -3
- strawberry/cli/commands/upgrade/_run_codemod.py +7 -5
- strawberry/codegen/exceptions.py +2 -2
- strawberry/codegen/plugins/print_operation.py +6 -6
- strawberry/codegen/plugins/python.py +6 -6
- strawberry/codegen/plugins/typescript.py +3 -3
- strawberry/codegen/query_codegen.py +29 -34
- strawberry/codegen/types.py +35 -34
- strawberry/codemods/annotated_unions.py +5 -2
- strawberry/dataloader.py +13 -20
- strawberry/directive.py +12 -5
- strawberry/django/test/client.py +4 -4
- strawberry/django/views.py +4 -5
- strawberry/exceptions/__init__.py +24 -24
- strawberry/exceptions/conflicting_arguments.py +2 -2
- strawberry/exceptions/duplicated_type_name.py +3 -3
- strawberry/exceptions/handler.py +7 -7
- strawberry/exceptions/invalid_union_type.py +2 -2
- strawberry/exceptions/missing_arguments_annotations.py +2 -2
- strawberry/exceptions/missing_field_annotation.py +2 -2
- strawberry/exceptions/object_is_not_an_enum.py +2 -2
- strawberry/exceptions/private_strawberry_field.py +2 -2
- strawberry/exceptions/syntax.py +4 -4
- strawberry/exceptions/utils/source_finder.py +7 -6
- strawberry/experimental/pydantic/__init__.py +3 -3
- strawberry/experimental/pydantic/_compat.py +14 -14
- strawberry/experimental/pydantic/conversion.py +2 -2
- strawberry/experimental/pydantic/conversion_types.py +3 -3
- strawberry/experimental/pydantic/error_type.py +18 -16
- strawberry/experimental/pydantic/exceptions.py +5 -5
- strawberry/experimental/pydantic/fields.py +2 -13
- strawberry/experimental/pydantic/object_type.py +20 -22
- strawberry/experimental/pydantic/utils.py +6 -10
- strawberry/ext/dataclasses/dataclasses.py +3 -3
- strawberry/ext/mypy_plugin.py +6 -9
- strawberry/extensions/__init__.py +7 -8
- strawberry/extensions/add_validation_rules.py +5 -3
- strawberry/extensions/base_extension.py +4 -4
- strawberry/extensions/context.py +15 -14
- strawberry/extensions/directives.py +2 -2
- strawberry/extensions/disable_validation.py +1 -1
- strawberry/extensions/field_extension.py +2 -1
- strawberry/extensions/mask_errors.py +3 -2
- strawberry/extensions/max_aliases.py +2 -2
- strawberry/extensions/max_tokens.py +1 -1
- strawberry/extensions/parser_cache.py +2 -1
- strawberry/extensions/pyinstrument.py +5 -2
- strawberry/extensions/query_depth_limiter.py +13 -13
- strawberry/extensions/runner.py +7 -7
- strawberry/extensions/tracing/apollo.py +11 -9
- strawberry/extensions/tracing/datadog.py +3 -1
- strawberry/extensions/tracing/opentelemetry.py +7 -10
- strawberry/extensions/utils.py +3 -3
- strawberry/extensions/validation_cache.py +2 -1
- strawberry/fastapi/context.py +3 -3
- strawberry/fastapi/router.py +9 -14
- strawberry/federation/__init__.py +4 -4
- strawberry/federation/argument.py +2 -1
- strawberry/federation/enum.py +8 -8
- strawberry/federation/field.py +25 -28
- strawberry/federation/object_type.py +24 -26
- strawberry/federation/scalar.py +7 -8
- strawberry/federation/schema.py +30 -36
- strawberry/federation/schema_directive.py +5 -5
- strawberry/federation/schema_directives.py +14 -14
- strawberry/federation/union.py +3 -2
- strawberry/field_extensions/input_mutation.py +1 -2
- strawberry/file_uploads/utils.py +4 -3
- strawberry/flask/views.py +3 -2
- strawberry/http/__init__.py +6 -6
- strawberry/http/async_base_view.py +9 -14
- strawberry/http/base.py +5 -4
- strawberry/http/ides.py +1 -1
- strawberry/http/parse_content_type.py +1 -2
- strawberry/http/sync_base_view.py +3 -5
- strawberry/http/temporal_response.py +1 -2
- strawberry/http/types.py +3 -2
- strawberry/litestar/controller.py +8 -14
- strawberry/parent.py +1 -2
- strawberry/permission.py +6 -8
- strawberry/printer/ast_from_value.py +2 -1
- strawberry/printer/printer.py +50 -30
- strawberry/quart/views.py +3 -3
- strawberry/relay/exceptions.py +4 -4
- strawberry/relay/fields.py +22 -24
- strawberry/relay/types.py +29 -27
- strawberry/relay/utils.py +4 -4
- strawberry/sanic/utils.py +4 -4
- strawberry/sanic/views.py +5 -7
- strawberry/scalars.py +2 -2
- strawberry/schema/base.py +16 -11
- strawberry/schema/compat.py +4 -4
- strawberry/schema/execute.py +6 -10
- strawberry/schema/name_converter.py +3 -3
- strawberry/schema/schema.py +37 -25
- strawberry/schema/schema_converter.py +22 -24
- strawberry/schema/subscribe.py +4 -3
- strawberry/schema/types/base_scalars.py +1 -1
- strawberry/schema/types/concrete_type.py +2 -2
- strawberry/schema/types/scalar.py +3 -4
- strawberry/schema_codegen/__init__.py +4 -4
- strawberry/schema_directive.py +8 -8
- strawberry/subscriptions/protocols/graphql_transport_ws/handlers.py +8 -9
- strawberry/subscriptions/protocols/graphql_transport_ws/types.py +16 -16
- strawberry/subscriptions/protocols/graphql_ws/handlers.py +6 -5
- strawberry/subscriptions/protocols/graphql_ws/types.py +13 -13
- strawberry/test/__init__.py +1 -1
- strawberry/test/client.py +21 -19
- strawberry/tools/create_type.py +4 -3
- strawberry/tools/merge_types.py +1 -2
- strawberry/types/__init__.py +1 -1
- strawberry/types/arguments.py +10 -12
- strawberry/types/auto.py +2 -2
- strawberry/types/base.py +17 -21
- strawberry/types/enum.py +3 -5
- strawberry/types/execution.py +8 -12
- strawberry/types/field.py +26 -31
- strawberry/types/fields/resolver.py +15 -17
- strawberry/types/graphql.py +2 -2
- strawberry/types/info.py +5 -9
- strawberry/types/lazy_type.py +3 -5
- strawberry/types/mutation.py +25 -28
- strawberry/types/nodes.py +11 -9
- strawberry/types/object_type.py +14 -16
- strawberry/types/private.py +1 -2
- strawberry/types/scalar.py +2 -2
- strawberry/types/type_resolver.py +5 -5
- strawberry/types/union.py +8 -11
- strawberry/types/unset.py +3 -3
- strawberry/utils/aio.py +3 -8
- strawberry/utils/await_maybe.py +3 -2
- strawberry/utils/debug.py +2 -2
- strawberry/utils/deprecations.py +2 -2
- strawberry/utils/inspect.py +3 -5
- strawberry/utils/str_converters.py +1 -1
- strawberry/utils/typing.py +38 -67
- {strawberry_graphql-0.255.0.dist-info → strawberry_graphql-0.256.1.dist-info}/METADATA +3 -6
- strawberry_graphql-0.256.1.dist-info/RECORD +236 -0
- strawberry_graphql-0.255.0.dist-info/RECORD +0 -236
- {strawberry_graphql-0.255.0.dist-info → strawberry_graphql-0.256.1.dist-info}/LICENSE +0 -0
- {strawberry_graphql-0.255.0.dist-info → strawberry_graphql-0.256.1.dist-info}/WHEEL +0 -0
- {strawberry_graphql-0.255.0.dist-info → strawberry_graphql-0.256.1.dist-info}/entry_points.txt +0 -0
strawberry/relay/types.py
CHANGED
@@ -4,27 +4,28 @@ import dataclasses
|
|
4
4
|
import inspect
|
5
5
|
import itertools
|
6
6
|
import sys
|
7
|
-
from
|
8
|
-
TYPE_CHECKING,
|
9
|
-
Any,
|
7
|
+
from collections.abc import (
|
10
8
|
AsyncIterable,
|
11
9
|
AsyncIterator,
|
12
10
|
Awaitable,
|
11
|
+
Iterable,
|
12
|
+
Iterator,
|
13
|
+
Sequence,
|
14
|
+
)
|
15
|
+
from typing import (
|
16
|
+
TYPE_CHECKING,
|
17
|
+
Annotated,
|
18
|
+
Any,
|
13
19
|
ClassVar,
|
14
20
|
ForwardRef,
|
15
21
|
Generic,
|
16
|
-
Iterable,
|
17
|
-
Iterator,
|
18
|
-
List,
|
19
22
|
Optional,
|
20
|
-
Sequence,
|
21
|
-
Type,
|
22
23
|
TypeVar,
|
23
24
|
Union,
|
24
25
|
cast,
|
25
26
|
overload,
|
26
27
|
)
|
27
|
-
from typing_extensions import
|
28
|
+
from typing_extensions import Literal, Self, TypeAlias, get_args, get_origin
|
28
29
|
|
29
30
|
from strawberry.relay.exceptions import NodeIDAnnotationError
|
30
31
|
from strawberry.types.base import (
|
@@ -33,9 +34,10 @@ from strawberry.types.base import (
|
|
33
34
|
get_object_definition,
|
34
35
|
)
|
35
36
|
from strawberry.types.field import field
|
36
|
-
from strawberry.types.info import Info # noqa:
|
37
|
+
from strawberry.types.info import Info # noqa: TC001
|
37
38
|
from strawberry.types.lazy_type import LazyType
|
38
|
-
from strawberry.types.object_type import interface
|
39
|
+
from strawberry.types.object_type import interface
|
40
|
+
from strawberry.types.object_type import type as strawberry_type
|
39
41
|
from strawberry.types.private import StrawberryPrivate
|
40
42
|
from strawberry.utils.aio import aenumerate, aislice, resolve_awaitable
|
41
43
|
from strawberry.utils.inspect import in_async_context
|
@@ -137,7 +139,7 @@ class GlobalID:
|
|
137
139
|
info: Info,
|
138
140
|
*,
|
139
141
|
required: Literal[True] = ...,
|
140
|
-
ensure_type:
|
142
|
+
ensure_type: type[_T],
|
141
143
|
) -> _T: ...
|
142
144
|
|
143
145
|
@overload
|
@@ -211,7 +213,7 @@ class GlobalID:
|
|
211
213
|
|
212
214
|
return node
|
213
215
|
|
214
|
-
def resolve_type(self, info: Info) ->
|
216
|
+
def resolve_type(self, info: Info) -> type[Node]:
|
215
217
|
"""Resolve the internal type name to its type itself.
|
216
218
|
|
217
219
|
Args:
|
@@ -247,7 +249,7 @@ class GlobalID:
|
|
247
249
|
info: Info,
|
248
250
|
*,
|
249
251
|
required: Literal[True] = ...,
|
250
|
-
ensure_type:
|
252
|
+
ensure_type: type[_T],
|
251
253
|
) -> _T: ...
|
252
254
|
|
253
255
|
@overload
|
@@ -391,7 +393,7 @@ class Node:
|
|
391
393
|
parent_type = info._raw_info.parent_type
|
392
394
|
type_def = info.schema.get_type_by_name(parent_type.name)
|
393
395
|
assert isinstance(type_def, StrawberryObjectDefinition)
|
394
|
-
origin = cast(
|
396
|
+
origin = cast(type[Node], type_def.origin)
|
395
397
|
resolve_id = origin.resolve_id
|
396
398
|
resolve_typename = origin.resolve_typename
|
397
399
|
|
@@ -618,7 +620,7 @@ class Node:
|
|
618
620
|
return next(iter(cast(Iterable[Self], retval)))
|
619
621
|
|
620
622
|
|
621
|
-
@
|
623
|
+
@strawberry_type(description="Information to aid in pagination.")
|
622
624
|
class PageInfo:
|
623
625
|
"""Information to aid in pagination.
|
624
626
|
|
@@ -647,7 +649,7 @@ class PageInfo:
|
|
647
649
|
)
|
648
650
|
|
649
651
|
|
650
|
-
@
|
652
|
+
@strawberry_type(description="An edge in a connection.")
|
651
653
|
class Edge(Generic[NodeType]):
|
652
654
|
"""An edge in a connection.
|
653
655
|
|
@@ -666,7 +668,7 @@ class Edge(Generic[NodeType]):
|
|
666
668
|
return cls(cursor=to_base64(PREFIX, cursor), node=node)
|
667
669
|
|
668
670
|
|
669
|
-
@
|
671
|
+
@strawberry_type(description="A connection to a list of items.")
|
670
672
|
class Connection(Generic[NodeType]):
|
671
673
|
"""A connection to a list of items.
|
672
674
|
|
@@ -679,7 +681,7 @@ class Connection(Generic[NodeType]):
|
|
679
681
|
"""
|
680
682
|
|
681
683
|
page_info: PageInfo = field(description="Pagination data for this connection")
|
682
|
-
edges:
|
684
|
+
edges: list[Edge[NodeType]] = field(
|
683
685
|
description="Contains the nodes in this connection"
|
684
686
|
)
|
685
687
|
|
@@ -738,7 +740,7 @@ class Connection(Generic[NodeType]):
|
|
738
740
|
raise NotImplementedError
|
739
741
|
|
740
742
|
|
741
|
-
@
|
743
|
+
@strawberry_type(name="Connection", description="A connection to a list of items.")
|
742
744
|
class ListConnection(Connection[NodeType]):
|
743
745
|
"""A connection to a list of items.
|
744
746
|
|
@@ -751,7 +753,7 @@ class ListConnection(Connection[NodeType]):
|
|
751
753
|
"""
|
752
754
|
|
753
755
|
page_info: PageInfo = field(description="Pagination data for this connection")
|
754
|
-
edges:
|
756
|
+
edges: list[Edge[NodeType]] = field(
|
755
757
|
description="Contains the nodes in this connection"
|
756
758
|
)
|
757
759
|
|
@@ -827,7 +829,7 @@ class ListConnection(Connection[NodeType]):
|
|
827
829
|
# The slice above might return an object that now is not async
|
828
830
|
# iterable anymore (e.g. an already cached django queryset)
|
829
831
|
if isinstance(iterator, (AsyncIterator, AsyncIterable)):
|
830
|
-
edges:
|
832
|
+
edges: list[Edge] = [
|
831
833
|
edge_class.resolve_edge(
|
832
834
|
cls.resolve_node(v, info=info, **kwargs),
|
833
835
|
cursor=slice_metadata.start + i,
|
@@ -835,7 +837,7 @@ class ListConnection(Connection[NodeType]):
|
|
835
837
|
async for i, v in aenumerate(iterator)
|
836
838
|
]
|
837
839
|
else:
|
838
|
-
edges:
|
840
|
+
edges: list[Edge] = [ # type: ignore[no-redef]
|
839
841
|
edge_class.resolve_edge(
|
840
842
|
cls.resolve_node(v, info=info, **kwargs),
|
841
843
|
cursor=slice_metadata.start + i,
|
@@ -935,17 +937,17 @@ class ListConnection(Connection[NodeType]):
|
|
935
937
|
|
936
938
|
|
937
939
|
__all__ = [
|
940
|
+
"PREFIX",
|
941
|
+
"Connection",
|
942
|
+
"Edge",
|
938
943
|
"GlobalID",
|
939
944
|
"GlobalIDValueError",
|
945
|
+
"ListConnection",
|
940
946
|
"Node",
|
941
947
|
"NodeID",
|
942
948
|
"NodeIDAnnotationError",
|
943
949
|
"NodeIDPrivate",
|
944
950
|
"NodeIterableType",
|
945
951
|
"NodeType",
|
946
|
-
"PREFIX",
|
947
|
-
"Connection",
|
948
|
-
"Edge",
|
949
952
|
"PageInfo",
|
950
|
-
"ListConnection",
|
951
953
|
]
|
strawberry/relay/utils.py
CHANGED
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
3
3
|
import base64
|
4
4
|
import dataclasses
|
5
5
|
import sys
|
6
|
-
from typing import TYPE_CHECKING, Any,
|
6
|
+
from typing import TYPE_CHECKING, Any, Union
|
7
7
|
from typing_extensions import Self, assert_never
|
8
8
|
|
9
9
|
from strawberry.types.base import StrawberryObjectDefinition
|
@@ -13,7 +13,7 @@ if TYPE_CHECKING:
|
|
13
13
|
from strawberry.types.info import Info
|
14
14
|
|
15
15
|
|
16
|
-
def from_base64(value: str) ->
|
16
|
+
def from_base64(value: str) -> tuple[str, str]:
|
17
17
|
"""Parse the base64 encoded relay value.
|
18
18
|
|
19
19
|
Args:
|
@@ -191,8 +191,8 @@ class SliceMetadata:
|
|
191
191
|
|
192
192
|
|
193
193
|
__all__ = [
|
194
|
+
"SliceMetadata",
|
194
195
|
"from_base64",
|
195
|
-
"to_base64",
|
196
196
|
"should_resolve_list_connection_edges",
|
197
|
-
"
|
197
|
+
"to_base64",
|
198
198
|
]
|
strawberry/sanic/utils.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
from io import BytesIO
|
4
|
-
from typing import TYPE_CHECKING, Any,
|
4
|
+
from typing import TYPE_CHECKING, Any, Optional, Union, cast
|
5
5
|
|
6
6
|
from sanic.request import File
|
7
7
|
|
@@ -9,7 +9,7 @@ if TYPE_CHECKING:
|
|
9
9
|
from sanic.request import Request
|
10
10
|
|
11
11
|
|
12
|
-
def convert_request_to_files_dict(request: Request) ->
|
12
|
+
def convert_request_to_files_dict(request: Request) -> dict[str, Any]:
|
13
13
|
"""Converts the request.files dictionary to a dictionary of BytesIO objects.
|
14
14
|
|
15
15
|
`request.files` has the following format, even if only a single file is uploaded:
|
@@ -24,12 +24,12 @@ def convert_request_to_files_dict(request: Request) -> Dict[str, Any]:
|
|
24
24
|
|
25
25
|
Note that the dictionary entries are lists.
|
26
26
|
"""
|
27
|
-
request_files = cast(Optional[
|
27
|
+
request_files = cast(Optional[dict[str, list[File]]], request.files)
|
28
28
|
|
29
29
|
if not request_files:
|
30
30
|
return {}
|
31
31
|
|
32
|
-
files_dict:
|
32
|
+
files_dict: dict[str, Union[BytesIO, list[BytesIO]]] = {}
|
33
33
|
|
34
34
|
for field_name, file_list in request_files.items():
|
35
35
|
assert len(file_list) == 1
|
strawberry/sanic/views.py
CHANGED
@@ -5,12 +5,8 @@ import warnings
|
|
5
5
|
from typing import (
|
6
6
|
TYPE_CHECKING,
|
7
7
|
Any,
|
8
|
-
AsyncGenerator,
|
9
8
|
Callable,
|
10
|
-
Dict,
|
11
|
-
Mapping,
|
12
9
|
Optional,
|
13
|
-
Type,
|
14
10
|
cast,
|
15
11
|
)
|
16
12
|
from typing_extensions import TypeGuard
|
@@ -29,6 +25,8 @@ from strawberry.http.typevars import (
|
|
29
25
|
from strawberry.sanic.utils import convert_request_to_files_dict
|
30
26
|
|
31
27
|
if TYPE_CHECKING:
|
28
|
+
from collections.abc import AsyncGenerator, Mapping
|
29
|
+
|
32
30
|
from strawberry.http import GraphQLHTTPResponse
|
33
31
|
from strawberry.http.ides import GraphQL_IDE
|
34
32
|
from strawberry.schema import BaseSchema
|
@@ -109,8 +107,8 @@ class GraphQLView(
|
|
109
107
|
graphiql: Optional[bool] = None,
|
110
108
|
graphql_ide: Optional[GraphQL_IDE] = "graphiql",
|
111
109
|
allow_queries_via_get: bool = True,
|
112
|
-
json_encoder: Optional[
|
113
|
-
json_dumps_params: Optional[
|
110
|
+
json_encoder: Optional[type[json.JSONEncoder]] = None,
|
111
|
+
json_dumps_params: Optional[dict[str, Any]] = None,
|
114
112
|
multipart_uploads_enabled: bool = False,
|
115
113
|
) -> None:
|
116
114
|
self.schema = schema
|
@@ -194,7 +192,7 @@ class GraphQLView(
|
|
194
192
|
request: Request,
|
195
193
|
stream: Callable[[], AsyncGenerator[str, None]],
|
196
194
|
sub_response: TemporalResponse,
|
197
|
-
headers:
|
195
|
+
headers: dict[str, str],
|
198
196
|
) -> HTTPResponse:
|
199
197
|
response = await self.request.respond(
|
200
198
|
status=sub_response.status_code,
|
strawberry/scalars.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
import base64
|
4
|
-
from typing import TYPE_CHECKING, Any,
|
4
|
+
from typing import TYPE_CHECKING, Any, NewType, Union
|
5
5
|
|
6
6
|
from strawberry.types.scalar import scalar
|
7
7
|
|
@@ -57,7 +57,7 @@ Base64 = scalar(
|
|
57
57
|
|
58
58
|
def is_scalar(
|
59
59
|
annotation: Any,
|
60
|
-
scalar_registry:
|
60
|
+
scalar_registry: dict[object, Union[ScalarWrapper, ScalarDefinition]],
|
61
61
|
) -> bool:
|
62
62
|
if annotation in scalar_registry:
|
63
63
|
return True
|
strawberry/schema/base.py
CHANGED
@@ -2,12 +2,14 @@ from __future__ import annotations
|
|
2
2
|
|
3
3
|
from abc import abstractmethod
|
4
4
|
from functools import lru_cache
|
5
|
-
from typing import TYPE_CHECKING, Any,
|
5
|
+
from typing import TYPE_CHECKING, Any, Optional, Union
|
6
6
|
from typing_extensions import Protocol
|
7
7
|
|
8
8
|
from strawberry.utils.logging import StrawberryLogger
|
9
9
|
|
10
10
|
if TYPE_CHECKING:
|
11
|
+
from collections.abc import Iterable
|
12
|
+
|
11
13
|
from graphql import GraphQLError
|
12
14
|
|
13
15
|
from strawberry.directive import StrawberryDirective
|
@@ -16,7 +18,10 @@ if TYPE_CHECKING:
|
|
16
18
|
ExecutionContext,
|
17
19
|
ExecutionResult,
|
18
20
|
)
|
19
|
-
from strawberry.types.base import
|
21
|
+
from strawberry.types.base import (
|
22
|
+
StrawberryObjectDefinition,
|
23
|
+
WithStrawberryObjectDefinition,
|
24
|
+
)
|
20
25
|
from strawberry.types.enum import EnumDefinition
|
21
26
|
from strawberry.types.graphql import OperationType
|
22
27
|
from strawberry.types.scalar import ScalarDefinition
|
@@ -29,16 +34,16 @@ if TYPE_CHECKING:
|
|
29
34
|
class BaseSchema(Protocol):
|
30
35
|
config: StrawberryConfig
|
31
36
|
schema_converter: GraphQLCoreConverter
|
32
|
-
query:
|
33
|
-
mutation: Optional[
|
34
|
-
subscription: Optional[
|
35
|
-
schema_directives:
|
37
|
+
query: type[WithStrawberryObjectDefinition]
|
38
|
+
mutation: Optional[type[WithStrawberryObjectDefinition]]
|
39
|
+
subscription: Optional[type[WithStrawberryObjectDefinition]]
|
40
|
+
schema_directives: list[object]
|
36
41
|
|
37
42
|
@abstractmethod
|
38
43
|
async def execute(
|
39
44
|
self,
|
40
45
|
query: Optional[str],
|
41
|
-
variable_values: Optional[
|
46
|
+
variable_values: Optional[dict[str, Any]] = None,
|
42
47
|
context_value: Optional[Any] = None,
|
43
48
|
root_value: Optional[Any] = None,
|
44
49
|
operation_name: Optional[str] = None,
|
@@ -50,7 +55,7 @@ class BaseSchema(Protocol):
|
|
50
55
|
def execute_sync(
|
51
56
|
self,
|
52
57
|
query: Optional[str],
|
53
|
-
variable_values: Optional[
|
58
|
+
variable_values: Optional[dict[str, Any]] = None,
|
54
59
|
context_value: Optional[Any] = None,
|
55
60
|
root_value: Optional[Any] = None,
|
56
61
|
operation_name: Optional[str] = None,
|
@@ -62,7 +67,7 @@ class BaseSchema(Protocol):
|
|
62
67
|
async def subscribe(
|
63
68
|
self,
|
64
69
|
query: str,
|
65
|
-
variable_values: Optional[
|
70
|
+
variable_values: Optional[dict[str, Any]] = None,
|
66
71
|
context_value: Optional[Any] = None,
|
67
72
|
root_value: Optional[Any] = None,
|
68
73
|
operation_name: Optional[str] = None,
|
@@ -101,7 +106,7 @@ class BaseSchema(Protocol):
|
|
101
106
|
|
102
107
|
def _process_errors(
|
103
108
|
self,
|
104
|
-
errors:
|
109
|
+
errors: list[GraphQLError],
|
105
110
|
execution_context: Optional[ExecutionContext] = None,
|
106
111
|
) -> None:
|
107
112
|
if self.config.disable_field_suggestions:
|
@@ -112,7 +117,7 @@ class BaseSchema(Protocol):
|
|
112
117
|
|
113
118
|
def process_errors(
|
114
119
|
self,
|
115
|
-
errors:
|
120
|
+
errors: list[GraphQLError],
|
116
121
|
execution_context: Optional[ExecutionContext] = None,
|
117
122
|
) -> None:
|
118
123
|
for error in errors:
|
strawberry/schema/compat.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
from typing import TYPE_CHECKING,
|
3
|
+
from typing import TYPE_CHECKING, Union
|
4
4
|
|
5
5
|
from strawberry.scalars import is_scalar as is_strawberry_scalar
|
6
6
|
from strawberry.types.base import StrawberryType, has_object_definition
|
@@ -29,7 +29,7 @@ def is_interface_type(type_: Union[StrawberryType, type]) -> TypeGuard[type]:
|
|
29
29
|
|
30
30
|
def is_scalar(
|
31
31
|
type_: Union[StrawberryType, type],
|
32
|
-
scalar_registry:
|
32
|
+
scalar_registry: dict[object, Union[ScalarWrapper, ScalarDefinition]],
|
33
33
|
) -> TypeGuard[type]:
|
34
34
|
return is_strawberry_scalar(type_, scalar_registry)
|
35
35
|
|
@@ -54,10 +54,10 @@ def is_graphql_generic(type_: Union[StrawberryType, type]) -> bool:
|
|
54
54
|
|
55
55
|
|
56
56
|
__all__ = [
|
57
|
+
"is_enum",
|
58
|
+
"is_graphql_generic",
|
57
59
|
"is_input_type",
|
58
60
|
"is_interface_type",
|
59
61
|
"is_scalar",
|
60
|
-
"is_enum",
|
61
62
|
"is_schema_directive",
|
62
|
-
"is_graphql_generic",
|
63
63
|
]
|
strawberry/schema/execute.py
CHANGED
@@ -1,16 +1,12 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
from asyncio import ensure_future
|
4
|
+
from collections.abc import Awaitable, Iterable
|
4
5
|
from inspect import isawaitable
|
5
6
|
from typing import (
|
6
7
|
TYPE_CHECKING,
|
7
|
-
Awaitable,
|
8
8
|
Callable,
|
9
|
-
Iterable,
|
10
|
-
List,
|
11
9
|
Optional,
|
12
|
-
Tuple,
|
13
|
-
Type,
|
14
10
|
TypedDict,
|
15
11
|
Union,
|
16
12
|
cast,
|
@@ -49,7 +45,7 @@ class ParseOptions(TypedDict):
|
|
49
45
|
|
50
46
|
|
51
47
|
ProcessErrors: TypeAlias = (
|
52
|
-
"Callable[[
|
48
|
+
"Callable[[list[GraphQLError], Optional[ExecutionContext]], None]"
|
53
49
|
)
|
54
50
|
|
55
51
|
|
@@ -60,8 +56,8 @@ def parse_document(query: str, **kwargs: Unpack[ParseOptions]) -> DocumentNode:
|
|
60
56
|
def validate_document(
|
61
57
|
schema: GraphQLSchema,
|
62
58
|
document: DocumentNode,
|
63
|
-
validation_rules:
|
64
|
-
) ->
|
59
|
+
validation_rules: tuple[type[ASTValidationRule], ...],
|
60
|
+
) -> list[GraphQLError]:
|
65
61
|
validation_rules = (
|
66
62
|
*validation_rules,
|
67
63
|
OneOfInputValidationRule,
|
@@ -150,7 +146,7 @@ async def execute(
|
|
150
146
|
extensions_runner: SchemaExtensionsRunner,
|
151
147
|
process_errors: ProcessErrors,
|
152
148
|
middleware_manager: MiddlewareManager,
|
153
|
-
execution_context_class: Optional[
|
149
|
+
execution_context_class: Optional[type[GraphQLExecutionContext]] = None,
|
154
150
|
) -> ExecutionResult | PreExecutionError:
|
155
151
|
try:
|
156
152
|
async with extensions_runner.operation():
|
@@ -214,7 +210,7 @@ def execute_sync(
|
|
214
210
|
allowed_operation_types: Iterable[OperationType],
|
215
211
|
extensions_runner: SchemaExtensionsRunner,
|
216
212
|
execution_context: ExecutionContext,
|
217
|
-
execution_context_class: Optional[
|
213
|
+
execution_context_class: Optional[type[GraphQLExecutionContext]] = None,
|
218
214
|
process_errors: ProcessErrors,
|
219
215
|
middleware_manager: MiddlewareManager,
|
220
216
|
) -> ExecutionResult:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
from typing import TYPE_CHECKING,
|
3
|
+
from typing import TYPE_CHECKING, Optional, Union, cast
|
4
4
|
from typing_extensions import Protocol
|
5
5
|
|
6
6
|
from strawberry.directive import StrawberryDirective
|
@@ -126,11 +126,11 @@ class NameConverter:
|
|
126
126
|
def from_generic(
|
127
127
|
self,
|
128
128
|
generic_type: StrawberryObjectDefinition,
|
129
|
-
types:
|
129
|
+
types: list[Union[StrawberryType, type]],
|
130
130
|
) -> str:
|
131
131
|
generic_type_name = generic_type.name
|
132
132
|
|
133
|
-
names:
|
133
|
+
names: list[str] = []
|
134
134
|
|
135
135
|
for type_ in types:
|
136
136
|
name = self.get_from_type(type_)
|
strawberry/schema/schema.py
CHANGED
@@ -5,11 +5,7 @@ from functools import cached_property, lru_cache
|
|
5
5
|
from typing import (
|
6
6
|
TYPE_CHECKING,
|
7
7
|
Any,
|
8
|
-
Dict,
|
9
|
-
Iterable,
|
10
|
-
List,
|
11
8
|
Optional,
|
12
|
-
Type,
|
13
9
|
Union,
|
14
10
|
cast,
|
15
11
|
)
|
@@ -37,7 +33,11 @@ from strawberry.extensions.runner import SchemaExtensionsRunner
|
|
37
33
|
from strawberry.schema.schema_converter import GraphQLCoreConverter
|
38
34
|
from strawberry.schema.types.scalar import DEFAULT_SCALAR_REGISTRY
|
39
35
|
from strawberry.types import ExecutionContext
|
40
|
-
from strawberry.types.base import
|
36
|
+
from strawberry.types.base import (
|
37
|
+
StrawberryObjectDefinition,
|
38
|
+
WithStrawberryObjectDefinition,
|
39
|
+
has_object_definition,
|
40
|
+
)
|
41
41
|
from strawberry.types.graphql import OperationType
|
42
42
|
|
43
43
|
from ..printer import print_schema
|
@@ -48,6 +48,8 @@ from .execute import execute, execute_sync
|
|
48
48
|
from .subscribe import SubscriptionResult, subscribe
|
49
49
|
|
50
50
|
if TYPE_CHECKING:
|
51
|
+
from collections.abc import Iterable
|
52
|
+
|
51
53
|
from graphql import ExecutionContext as GraphQLExecutionContext
|
52
54
|
|
53
55
|
from strawberry.directive import StrawberryDirective
|
@@ -70,16 +72,16 @@ class Schema(BaseSchema):
|
|
70
72
|
self,
|
71
73
|
# TODO: can we make sure we only allow to pass
|
72
74
|
# something that has been decorated?
|
73
|
-
query:
|
74
|
-
mutation: Optional[
|
75
|
-
subscription: Optional[
|
75
|
+
query: type,
|
76
|
+
mutation: Optional[type] = None,
|
77
|
+
subscription: Optional[type] = None,
|
76
78
|
directives: Iterable[StrawberryDirective] = (),
|
77
|
-
types: Iterable[Union[
|
78
|
-
extensions: Iterable[Union[
|
79
|
-
execution_context_class: Optional[
|
79
|
+
types: Iterable[Union[type, StrawberryType]] = (),
|
80
|
+
extensions: Iterable[Union[type[SchemaExtension], SchemaExtension]] = (),
|
81
|
+
execution_context_class: Optional[type[GraphQLExecutionContext]] = None,
|
80
82
|
config: Optional[StrawberryConfig] = None,
|
81
83
|
scalar_overrides: Optional[
|
82
|
-
|
84
|
+
dict[object, Union[type, ScalarWrapper, ScalarDefinition]],
|
83
85
|
] = None,
|
84
86
|
schema_directives: Iterable[object] = (),
|
85
87
|
) -> None:
|
@@ -127,7 +129,7 @@ class Schema(BaseSchema):
|
|
127
129
|
self.execution_context_class = execution_context_class
|
128
130
|
self.config = config or StrawberryConfig()
|
129
131
|
|
130
|
-
SCALAR_OVERRIDES_DICT_TYPE =
|
132
|
+
SCALAR_OVERRIDES_DICT_TYPE = dict[
|
131
133
|
object, Union["ScalarWrapper", "ScalarDefinition"]
|
132
134
|
]
|
133
135
|
|
@@ -142,14 +144,24 @@ class Schema(BaseSchema):
|
|
142
144
|
self.directives = directives
|
143
145
|
self.schema_directives = list(schema_directives)
|
144
146
|
|
145
|
-
query_type = self.schema_converter.from_object(
|
147
|
+
query_type = self.schema_converter.from_object(
|
148
|
+
cast(type[WithStrawberryObjectDefinition], query).__strawberry_definition__
|
149
|
+
)
|
146
150
|
mutation_type = (
|
147
|
-
self.schema_converter.from_object(
|
151
|
+
self.schema_converter.from_object(
|
152
|
+
cast(
|
153
|
+
type[WithStrawberryObjectDefinition], mutation
|
154
|
+
).__strawberry_definition__
|
155
|
+
)
|
148
156
|
if mutation
|
149
157
|
else None
|
150
158
|
)
|
151
159
|
subscription_type = (
|
152
|
-
self.schema_converter.from_object(
|
160
|
+
self.schema_converter.from_object(
|
161
|
+
cast(
|
162
|
+
type[WithStrawberryObjectDefinition], subscription
|
163
|
+
).__strawberry_definition__
|
164
|
+
)
|
153
165
|
if subscription
|
154
166
|
else None
|
155
167
|
)
|
@@ -213,7 +225,7 @@ class Schema(BaseSchema):
|
|
213
225
|
formatted_errors = "\n\n".join(f"❌ {error.message}" for error in errors)
|
214
226
|
raise ValueError(f"Invalid Schema. Errors:\n\n{formatted_errors}")
|
215
227
|
|
216
|
-
def get_extensions(self, sync: bool = False) ->
|
228
|
+
def get_extensions(self, sync: bool = False) -> list[SchemaExtension]:
|
217
229
|
extensions = []
|
218
230
|
if self.directives:
|
219
231
|
extensions = [
|
@@ -227,11 +239,11 @@ class Schema(BaseSchema):
|
|
227
239
|
]
|
228
240
|
|
229
241
|
@cached_property
|
230
|
-
def _sync_extensions(self) ->
|
242
|
+
def _sync_extensions(self) -> list[SchemaExtension]:
|
231
243
|
return self.get_extensions(sync=True)
|
232
244
|
|
233
245
|
@cached_property
|
234
|
-
def _async_extensions(self) ->
|
246
|
+
def _async_extensions(self) -> list[SchemaExtension]:
|
235
247
|
return self.get_extensions(sync=False)
|
236
248
|
|
237
249
|
def create_extensions_runner(
|
@@ -256,7 +268,7 @@ class Schema(BaseSchema):
|
|
256
268
|
self,
|
257
269
|
query: Optional[str],
|
258
270
|
allowed_operation_types: Iterable[OperationType],
|
259
|
-
variable_values: Optional[
|
271
|
+
variable_values: Optional[dict[str, Any]] = None,
|
260
272
|
context_value: Optional[Any] = None,
|
261
273
|
root_value: Optional[Any] = None,
|
262
274
|
operation_name: Optional[str] = None,
|
@@ -320,13 +332,13 @@ class Schema(BaseSchema):
|
|
320
332
|
|
321
333
|
def get_fields(
|
322
334
|
self, type_definition: StrawberryObjectDefinition
|
323
|
-
) ->
|
335
|
+
) -> list[StrawberryField]:
|
324
336
|
return type_definition.fields
|
325
337
|
|
326
338
|
async def execute(
|
327
339
|
self,
|
328
340
|
query: Optional[str],
|
329
|
-
variable_values: Optional[
|
341
|
+
variable_values: Optional[dict[str, Any]] = None,
|
330
342
|
context_value: Optional[Any] = None,
|
331
343
|
root_value: Optional[Any] = None,
|
332
344
|
operation_name: Optional[str] = None,
|
@@ -361,7 +373,7 @@ class Schema(BaseSchema):
|
|
361
373
|
def execute_sync(
|
362
374
|
self,
|
363
375
|
query: Optional[str],
|
364
|
-
variable_values: Optional[
|
376
|
+
variable_values: Optional[dict[str, Any]] = None,
|
365
377
|
context_value: Optional[Any] = None,
|
366
378
|
root_value: Optional[Any] = None,
|
367
379
|
operation_name: Optional[str] = None,
|
@@ -397,7 +409,7 @@ class Schema(BaseSchema):
|
|
397
409
|
async def subscribe(
|
398
410
|
self,
|
399
411
|
query: Optional[str],
|
400
|
-
variable_values: Optional[
|
412
|
+
variable_values: Optional[dict[str, Any]] = None,
|
401
413
|
context_value: Optional[Any] = None,
|
402
414
|
root_value: Optional[Any] = None,
|
403
415
|
operation_name: Optional[str] = None,
|
@@ -495,7 +507,7 @@ class Schema(BaseSchema):
|
|
495
507
|
|
496
508
|
__str__ = as_str
|
497
509
|
|
498
|
-
def introspect(self) ->
|
510
|
+
def introspect(self) -> dict[str, Any]:
|
499
511
|
"""Return the introspection query result for the current schema.
|
500
512
|
|
501
513
|
Raises:
|