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.
- strawberry/__init__.py +2 -0
- strawberry/aiohttp/test/client.py +8 -15
- strawberry/aiohttp/views.py +15 -64
- strawberry/annotation.py +70 -25
- strawberry/asgi/__init__.py +22 -56
- strawberry/asgi/test/client.py +6 -6
- strawberry/chalice/views.py +13 -79
- strawberry/channels/handlers/base.py +7 -8
- strawberry/channels/handlers/http_handler.py +50 -32
- strawberry/channels/handlers/ws_handler.py +12 -14
- strawberry/channels/router.py +3 -4
- strawberry/channels/testing.py +7 -9
- strawberry/cli/__init__.py +7 -6
- strawberry/cli/commands/codegen.py +7 -7
- strawberry/cli/commands/dev.py +72 -0
- strawberry/cli/commands/schema_codegen.py +1 -2
- strawberry/cli/commands/server.py +3 -44
- strawberry/cli/commands/upgrade/__init__.py +3 -3
- strawberry/cli/commands/upgrade/_run_codemod.py +2 -2
- strawberry/cli/constants.py +1 -2
- strawberry/cli/{debug_server.py → dev_server.py} +3 -7
- strawberry/codegen/plugins/print_operation.py +2 -2
- strawberry/codegen/plugins/python.py +2 -2
- strawberry/codegen/query_codegen.py +20 -30
- strawberry/codegen/types.py +32 -32
- strawberry/codemods/__init__.py +9 -0
- strawberry/codemods/annotated_unions.py +2 -2
- strawberry/codemods/maybe_optional.py +118 -0
- strawberry/dataloader.py +28 -24
- strawberry/directive.py +6 -7
- strawberry/django/test/client.py +3 -3
- strawberry/django/views.py +21 -91
- strawberry/exceptions/__init__.py +4 -4
- strawberry/exceptions/conflicting_arguments.py +2 -2
- strawberry/exceptions/duplicated_type_name.py +4 -4
- strawberry/exceptions/exception.py +3 -3
- strawberry/exceptions/handler.py +8 -7
- strawberry/exceptions/invalid_argument_type.py +2 -2
- strawberry/exceptions/invalid_superclass_interface.py +2 -2
- strawberry/exceptions/invalid_union_type.py +4 -4
- strawberry/exceptions/missing_arguments_annotations.py +2 -2
- strawberry/exceptions/missing_dependencies.py +2 -4
- strawberry/exceptions/missing_field_annotation.py +2 -2
- strawberry/exceptions/missing_return_annotation.py +2 -2
- strawberry/exceptions/object_is_not_a_class.py +2 -2
- strawberry/exceptions/object_is_not_an_enum.py +2 -2
- strawberry/exceptions/permission_fail_silently_requires_optional.py +2 -2
- strawberry/exceptions/private_strawberry_field.py +2 -2
- strawberry/exceptions/scalar_already_registered.py +2 -2
- strawberry/exceptions/syntax.py +3 -3
- strawberry/exceptions/unresolved_field_type.py +2 -2
- strawberry/exceptions/utils/source_finder.py +25 -25
- strawberry/experimental/pydantic/_compat.py +8 -7
- strawberry/experimental/pydantic/conversion.py +2 -2
- strawberry/experimental/pydantic/conversion_types.py +2 -2
- strawberry/experimental/pydantic/error_type.py +10 -12
- strawberry/experimental/pydantic/fields.py +9 -15
- strawberry/experimental/pydantic/object_type.py +17 -25
- strawberry/experimental/pydantic/utils.py +1 -2
- strawberry/ext/mypy_plugin.py +12 -14
- strawberry/extensions/base_extension.py +2 -1
- strawberry/extensions/context.py +13 -18
- strawberry/extensions/directives.py +9 -3
- strawberry/extensions/field_extension.py +4 -4
- strawberry/extensions/mask_errors.py +24 -13
- strawberry/extensions/max_aliases.py +1 -3
- strawberry/extensions/parser_cache.py +1 -2
- strawberry/extensions/query_depth_limiter.py +18 -14
- strawberry/extensions/runner.py +2 -2
- strawberry/extensions/tracing/apollo.py +3 -3
- strawberry/extensions/tracing/datadog.py +3 -3
- strawberry/extensions/tracing/opentelemetry.py +6 -8
- strawberry/extensions/tracing/utils.py +3 -1
- strawberry/extensions/utils.py +2 -2
- strawberry/extensions/validation_cache.py +2 -3
- strawberry/fastapi/context.py +6 -6
- strawberry/fastapi/router.py +43 -42
- strawberry/federation/argument.py +4 -5
- strawberry/federation/enum.py +18 -21
- strawberry/federation/field.py +94 -97
- strawberry/federation/object_type.py +56 -58
- strawberry/federation/scalar.py +27 -35
- strawberry/federation/schema.py +15 -16
- strawberry/federation/schema_directive.py +7 -6
- strawberry/federation/schema_directives.py +11 -11
- strawberry/federation/union.py +4 -4
- strawberry/flask/views.py +16 -85
- strawberry/http/__init__.py +30 -20
- strawberry/http/async_base_view.py +208 -89
- strawberry/http/base.py +28 -11
- strawberry/http/exceptions.py +5 -7
- strawberry/http/ides.py +2 -3
- strawberry/http/sync_base_view.py +115 -69
- strawberry/http/types.py +3 -3
- strawberry/litestar/controller.py +43 -77
- strawberry/permission.py +4 -6
- strawberry/printer/ast_from_value.py +3 -5
- strawberry/printer/printer.py +18 -15
- strawberry/quart/views.py +16 -48
- strawberry/relay/exceptions.py +4 -4
- strawberry/relay/fields.py +33 -32
- strawberry/relay/types.py +32 -35
- strawberry/relay/utils.py +11 -23
- strawberry/resolvers.py +2 -1
- strawberry/sanic/context.py +1 -0
- strawberry/sanic/utils.py +3 -3
- strawberry/sanic/views.py +15 -54
- strawberry/scalars.py +2 -2
- strawberry/schema/_graphql_core.py +55 -0
- strawberry/schema/base.py +32 -33
- strawberry/schema/compat.py +9 -9
- strawberry/schema/config.py +10 -1
- strawberry/schema/exceptions.py +1 -3
- strawberry/schema/name_converter.py +9 -8
- strawberry/schema/schema.py +133 -100
- strawberry/schema/schema_converter.py +96 -58
- strawberry/schema/types/base_scalars.py +1 -1
- strawberry/schema/types/concrete_type.py +5 -5
- strawberry/schema/validation_rules/maybe_null.py +136 -0
- strawberry/schema_codegen/__init__.py +3 -3
- strawberry/schema_directive.py +7 -6
- strawberry/static/graphiql.html +5 -5
- strawberry/streamable.py +35 -0
- strawberry/subscriptions/protocols/graphql_transport_ws/handlers.py +5 -16
- strawberry/subscriptions/protocols/graphql_transport_ws/types.py +20 -20
- strawberry/subscriptions/protocols/graphql_ws/handlers.py +5 -12
- strawberry/subscriptions/protocols/graphql_ws/types.py +14 -14
- strawberry/test/client.py +18 -18
- strawberry/tools/create_type.py +2 -3
- strawberry/types/arguments.py +41 -28
- strawberry/types/auto.py +3 -4
- strawberry/types/base.py +25 -27
- strawberry/types/enum.py +22 -25
- strawberry/types/execution.py +21 -16
- strawberry/types/field.py +109 -130
- strawberry/types/fields/resolver.py +19 -21
- strawberry/types/info.py +5 -11
- strawberry/types/lazy_type.py +2 -3
- strawberry/types/maybe.py +12 -3
- strawberry/types/mutation.py +115 -118
- strawberry/types/nodes.py +2 -2
- strawberry/types/object_type.py +43 -63
- strawberry/types/scalar.py +37 -43
- strawberry/types/union.py +12 -14
- strawberry/utils/aio.py +12 -9
- strawberry/utils/await_maybe.py +3 -3
- strawberry/utils/deprecations.py +2 -2
- strawberry/utils/importer.py +1 -2
- strawberry/utils/inspect.py +4 -6
- strawberry/utils/logging.py +2 -2
- strawberry/utils/operation.py +4 -4
- strawberry/utils/typing.py +18 -83
- {strawberry_graphql-0.275.7.dist-info → strawberry_graphql-0.284.3.dist-info}/METADATA +14 -8
- strawberry_graphql-0.284.3.dist-info/RECORD +243 -0
- {strawberry_graphql-0.275.7.dist-info → strawberry_graphql-0.284.3.dist-info}/WHEEL +1 -1
- strawberry/utils/dataclasses.py +0 -37
- strawberry/utils/debug.py +0 -46
- strawberry/utils/graphql_lexer.py +0 -35
- strawberry_graphql-0.275.7.dist-info/RECORD +0 -241
- {strawberry_graphql-0.275.7.dist-info → strawberry_graphql-0.284.3.dist-info}/entry_points.txt +0 -0
- {strawberry_graphql-0.275.7.dist-info → strawberry_graphql-0.284.3.dist-info/licenses}/LICENSE +0 -0
strawberry/relay/utils.py
CHANGED
|
@@ -3,11 +3,11 @@ 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
|
|
7
7
|
from typing_extensions import Self, assert_never
|
|
8
8
|
|
|
9
9
|
from strawberry.types.base import StrawberryObjectDefinition
|
|
10
|
-
from strawberry.types.nodes import InlineFragment
|
|
10
|
+
from strawberry.types.nodes import InlineFragment
|
|
11
11
|
|
|
12
12
|
if TYPE_CHECKING:
|
|
13
13
|
from strawberry.types.info import Info
|
|
@@ -39,7 +39,7 @@ def from_base64(value: str) -> tuple[str, str]:
|
|
|
39
39
|
return res[0], res[1]
|
|
40
40
|
|
|
41
41
|
|
|
42
|
-
def to_base64(type_:
|
|
42
|
+
def to_base64(type_: str | type | StrawberryObjectDefinition, node_id: Any) -> str:
|
|
43
43
|
"""Encode the type name and node id to a base64 string.
|
|
44
44
|
|
|
45
45
|
Args:
|
|
@@ -83,31 +83,19 @@ def should_resolve_list_connection_edges(info: Info) -> bool:
|
|
|
83
83
|
|
|
84
84
|
"""
|
|
85
85
|
resolve_for_field_names = {"edges", "pageInfo"}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
Returns:
|
|
94
|
-
bool: True if the user requested to resolve the `edges` field of a connection, False otherwise.
|
|
95
|
-
"""
|
|
86
|
+
# Recursively inspect the selection to check if the user requested to resolve the `edges` field.
|
|
87
|
+
stack = []
|
|
88
|
+
for selection_field in info.selected_fields:
|
|
89
|
+
stack.extend(selection_field.selections)
|
|
90
|
+
while stack:
|
|
91
|
+
selection = stack.pop()
|
|
96
92
|
if (
|
|
97
93
|
not isinstance(selection, InlineFragment)
|
|
98
94
|
and selection.name in resolve_for_field_names
|
|
99
95
|
):
|
|
100
96
|
return True
|
|
101
|
-
if selection
|
|
102
|
-
|
|
103
|
-
_check_selection(selection) for selection in selection.selections
|
|
104
|
-
)
|
|
105
|
-
return False
|
|
106
|
-
|
|
107
|
-
for selection_field in info.selected_fields:
|
|
108
|
-
for selection in selection_field.selections:
|
|
109
|
-
if _check_selection(selection):
|
|
110
|
-
return True
|
|
97
|
+
if nested_selections := getattr(selection, "selections", None):
|
|
98
|
+
stack.extend(nested_selections)
|
|
111
99
|
return False
|
|
112
100
|
|
|
113
101
|
|
strawberry/resolvers.py
CHANGED
strawberry/sanic/context.py
CHANGED
strawberry/sanic/utils.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import TYPE_CHECKING, Any,
|
|
3
|
+
from typing import TYPE_CHECKING, Any, cast
|
|
4
4
|
|
|
5
5
|
if TYPE_CHECKING:
|
|
6
6
|
from sanic.request import File, Request
|
|
@@ -21,12 +21,12 @@ def convert_request_to_files_dict(request: Request) -> dict[str, Any]:
|
|
|
21
21
|
|
|
22
22
|
Note that the dictionary entries are lists.
|
|
23
23
|
"""
|
|
24
|
-
request_files = cast("
|
|
24
|
+
request_files = cast("dict[str, list[File]] | None", request.files)
|
|
25
25
|
|
|
26
26
|
if not request_files:
|
|
27
27
|
return {}
|
|
28
28
|
|
|
29
|
-
files_dict: dict[str,
|
|
29
|
+
files_dict: dict[str, File | list[File]] = {}
|
|
30
30
|
|
|
31
31
|
for field_name, file_list in request_files.items():
|
|
32
32
|
assert len(file_list) == 1
|
strawberry/sanic/views.py
CHANGED
|
@@ -5,70 +5,29 @@ import warnings
|
|
|
5
5
|
from typing import (
|
|
6
6
|
TYPE_CHECKING,
|
|
7
7
|
Any,
|
|
8
|
-
|
|
9
|
-
Optional,
|
|
10
|
-
cast,
|
|
8
|
+
TypeGuard,
|
|
11
9
|
)
|
|
12
|
-
from typing_extensions import TypeGuard
|
|
13
10
|
|
|
11
|
+
from lia import HTTPException, SanicHTTPRequestAdapter
|
|
14
12
|
from sanic.request import Request
|
|
15
13
|
from sanic.response import HTTPResponse, html
|
|
16
14
|
from sanic.views import HTTPMethodView
|
|
17
|
-
|
|
18
|
-
from strawberry.http.
|
|
15
|
+
|
|
16
|
+
from strawberry.http.async_base_view import AsyncBaseHTTPView
|
|
19
17
|
from strawberry.http.temporal_response import TemporalResponse
|
|
20
|
-
from strawberry.http.types import FormData, HTTPMethod, QueryParams
|
|
21
18
|
from strawberry.http.typevars import (
|
|
22
19
|
Context,
|
|
23
20
|
RootValue,
|
|
24
21
|
)
|
|
25
|
-
from strawberry.sanic.utils import convert_request_to_files_dict
|
|
26
22
|
|
|
27
23
|
if TYPE_CHECKING:
|
|
28
|
-
from collections.abc import AsyncGenerator,
|
|
24
|
+
from collections.abc import AsyncGenerator, Callable
|
|
29
25
|
|
|
30
26
|
from strawberry.http import GraphQLHTTPResponse
|
|
31
27
|
from strawberry.http.ides import GraphQL_IDE
|
|
32
28
|
from strawberry.schema import BaseSchema
|
|
33
29
|
|
|
34
30
|
|
|
35
|
-
class SanicHTTPRequestAdapter(AsyncHTTPRequestAdapter):
|
|
36
|
-
def __init__(self, request: Request) -> None:
|
|
37
|
-
self.request = request
|
|
38
|
-
|
|
39
|
-
@property
|
|
40
|
-
def query_params(self) -> QueryParams:
|
|
41
|
-
# Just a heads up, Sanic's request.args uses urllib.parse.parse_qs
|
|
42
|
-
# to parse query string parameters. This returns a dictionary where
|
|
43
|
-
# the keys are the unique variable names and the values are lists
|
|
44
|
-
# of values for each variable name. To ensure consistency, we're
|
|
45
|
-
# enforcing the use of the first value in each list.
|
|
46
|
-
args = self.request.get_args(keep_blank_values=True)
|
|
47
|
-
return {k: args.get(k, None) for k in args}
|
|
48
|
-
|
|
49
|
-
@property
|
|
50
|
-
def method(self) -> HTTPMethod:
|
|
51
|
-
return cast("HTTPMethod", self.request.method.upper())
|
|
52
|
-
|
|
53
|
-
@property
|
|
54
|
-
def headers(self) -> Mapping[str, str]:
|
|
55
|
-
return self.request.headers
|
|
56
|
-
|
|
57
|
-
@property
|
|
58
|
-
def content_type(self) -> Optional[str]:
|
|
59
|
-
return self.request.content_type
|
|
60
|
-
|
|
61
|
-
async def get_body(self) -> str:
|
|
62
|
-
return self.request.body.decode()
|
|
63
|
-
|
|
64
|
-
async def get_form_data(self) -> FormData:
|
|
65
|
-
assert self.request.form is not None
|
|
66
|
-
|
|
67
|
-
files = convert_request_to_files_dict(self.request)
|
|
68
|
-
|
|
69
|
-
return FormData(form=self.request.form, files=files)
|
|
70
|
-
|
|
71
|
-
|
|
72
31
|
class GraphQLView(
|
|
73
32
|
AsyncBaseHTTPView[
|
|
74
33
|
Request,
|
|
@@ -104,11 +63,11 @@ class GraphQLView(
|
|
|
104
63
|
def __init__(
|
|
105
64
|
self,
|
|
106
65
|
schema: BaseSchema,
|
|
107
|
-
graphiql:
|
|
108
|
-
graphql_ide:
|
|
66
|
+
graphiql: bool | None = None,
|
|
67
|
+
graphql_ide: GraphQL_IDE | None = "graphiql",
|
|
109
68
|
allow_queries_via_get: bool = True,
|
|
110
|
-
json_encoder:
|
|
111
|
-
json_dumps_params:
|
|
69
|
+
json_encoder: type[json.JSONEncoder] | None = None,
|
|
70
|
+
json_dumps_params: dict[str, Any] | None = None,
|
|
112
71
|
multipart_uploads_enabled: bool = False,
|
|
113
72
|
) -> None:
|
|
114
73
|
self.schema = schema
|
|
@@ -143,7 +102,7 @@ class GraphQLView(
|
|
|
143
102
|
else:
|
|
144
103
|
self.graphql_ide = graphql_ide
|
|
145
104
|
|
|
146
|
-
async def get_root_value(self, request: Request) ->
|
|
105
|
+
async def get_root_value(self, request: Request) -> RootValue | None:
|
|
147
106
|
return None
|
|
148
107
|
|
|
149
108
|
async def get_context(
|
|
@@ -158,7 +117,9 @@ class GraphQLView(
|
|
|
158
117
|
return TemporalResponse()
|
|
159
118
|
|
|
160
119
|
def create_response(
|
|
161
|
-
self,
|
|
120
|
+
self,
|
|
121
|
+
response_data: GraphQLHTTPResponse | list[GraphQLHTTPResponse],
|
|
122
|
+
sub_response: TemporalResponse,
|
|
162
123
|
) -> HTTPResponse:
|
|
163
124
|
status_code = sub_response.status_code
|
|
164
125
|
|
|
@@ -216,11 +177,11 @@ class GraphQLView(
|
|
|
216
177
|
def is_websocket_request(self, request: Request) -> TypeGuard[Request]:
|
|
217
178
|
return False
|
|
218
179
|
|
|
219
|
-
async def pick_websocket_subprotocol(self, request: Request) ->
|
|
180
|
+
async def pick_websocket_subprotocol(self, request: Request) -> str | None:
|
|
220
181
|
raise NotImplementedError
|
|
221
182
|
|
|
222
183
|
async def create_websocket_response(
|
|
223
|
-
self, request: Request, subprotocol:
|
|
184
|
+
self, request: Request, subprotocol: str | None
|
|
224
185
|
) -> TemporalResponse:
|
|
225
186
|
raise NotImplementedError
|
|
226
187
|
|
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, NewType
|
|
4
|
+
from typing import TYPE_CHECKING, Any, NewType
|
|
5
5
|
|
|
6
6
|
from strawberry.types.scalar import scalar
|
|
7
7
|
|
|
@@ -59,7 +59,7 @@ Base64 = scalar(
|
|
|
59
59
|
|
|
60
60
|
def is_scalar(
|
|
61
61
|
annotation: Any,
|
|
62
|
-
scalar_registry: Mapping[object,
|
|
62
|
+
scalar_registry: Mapping[object, ScalarWrapper | ScalarDefinition],
|
|
63
63
|
) -> bool:
|
|
64
64
|
if annotation in scalar_registry:
|
|
65
65
|
return True
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
from typing import TypeAlias, Union
|
|
2
|
+
|
|
3
|
+
from graphql.execution import ExecutionContext as GraphQLExecutionContext
|
|
4
|
+
from graphql.execution import ExecutionResult as OriginalGraphQLExecutionResult
|
|
5
|
+
from graphql.execution import execute, subscribe
|
|
6
|
+
|
|
7
|
+
from strawberry.types import ExecutionResult
|
|
8
|
+
|
|
9
|
+
try:
|
|
10
|
+
from graphql import ( # type: ignore[attr-defined]
|
|
11
|
+
ExperimentalIncrementalExecutionResults as GraphQLIncrementalExecutionResults,
|
|
12
|
+
)
|
|
13
|
+
from graphql.execution import ( # type: ignore[attr-defined]
|
|
14
|
+
InitialIncrementalExecutionResult,
|
|
15
|
+
experimental_execute_incrementally,
|
|
16
|
+
)
|
|
17
|
+
from graphql.type.directives import ( # type: ignore[attr-defined]
|
|
18
|
+
GraphQLDeferDirective,
|
|
19
|
+
GraphQLStreamDirective,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
incremental_execution_directives = (
|
|
23
|
+
GraphQLDeferDirective,
|
|
24
|
+
GraphQLStreamDirective,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
GraphQLExecutionResult: TypeAlias = (
|
|
28
|
+
OriginalGraphQLExecutionResult | InitialIncrementalExecutionResult
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
except ImportError:
|
|
32
|
+
GraphQLIncrementalExecutionResults = type(None)
|
|
33
|
+
GraphQLExecutionResult = OriginalGraphQLExecutionResult # type: ignore
|
|
34
|
+
|
|
35
|
+
incremental_execution_directives = () # type: ignore
|
|
36
|
+
experimental_execute_incrementally = None
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
# TODO: give this a better name, maybe also a better place
|
|
40
|
+
ResultType = Union[ # noqa: UP007
|
|
41
|
+
OriginalGraphQLExecutionResult,
|
|
42
|
+
GraphQLIncrementalExecutionResults,
|
|
43
|
+
ExecutionResult,
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
__all__ = [
|
|
47
|
+
"GraphQLExecutionContext",
|
|
48
|
+
"GraphQLExecutionResult",
|
|
49
|
+
"GraphQLIncrementalExecutionResults",
|
|
50
|
+
"ResultType",
|
|
51
|
+
"execute",
|
|
52
|
+
"experimental_execute_incrementally",
|
|
53
|
+
"incremental_execution_directives",
|
|
54
|
+
"subscribe",
|
|
55
|
+
]
|
strawberry/schema/base.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from abc import abstractmethod
|
|
4
|
-
from typing import TYPE_CHECKING, Any
|
|
4
|
+
from typing import TYPE_CHECKING, Any
|
|
5
5
|
from typing_extensions import Protocol
|
|
6
6
|
|
|
7
7
|
from strawberry.utils.logging import StrawberryLogger
|
|
@@ -34,33 +34,33 @@ class BaseSchema(Protocol):
|
|
|
34
34
|
config: StrawberryConfig
|
|
35
35
|
schema_converter: GraphQLCoreConverter
|
|
36
36
|
query: type[WithStrawberryObjectDefinition]
|
|
37
|
-
mutation:
|
|
38
|
-
subscription:
|
|
37
|
+
mutation: type[WithStrawberryObjectDefinition] | None
|
|
38
|
+
subscription: type[WithStrawberryObjectDefinition] | None
|
|
39
39
|
schema_directives: list[object]
|
|
40
40
|
|
|
41
41
|
@abstractmethod
|
|
42
42
|
async def execute(
|
|
43
43
|
self,
|
|
44
|
-
query:
|
|
45
|
-
variable_values:
|
|
46
|
-
context_value:
|
|
47
|
-
root_value:
|
|
48
|
-
operation_name:
|
|
49
|
-
allowed_operation_types:
|
|
50
|
-
operation_extensions:
|
|
44
|
+
query: str | None,
|
|
45
|
+
variable_values: dict[str, Any] | None = None,
|
|
46
|
+
context_value: Any | None = None,
|
|
47
|
+
root_value: Any | None = None,
|
|
48
|
+
operation_name: str | None = None,
|
|
49
|
+
allowed_operation_types: Iterable[OperationType] | None = None,
|
|
50
|
+
operation_extensions: dict[str, Any] | None = None,
|
|
51
51
|
) -> ExecutionResult:
|
|
52
52
|
raise NotImplementedError
|
|
53
53
|
|
|
54
54
|
@abstractmethod
|
|
55
55
|
def execute_sync(
|
|
56
56
|
self,
|
|
57
|
-
query:
|
|
58
|
-
variable_values:
|
|
59
|
-
context_value:
|
|
60
|
-
root_value:
|
|
61
|
-
operation_name:
|
|
62
|
-
allowed_operation_types:
|
|
63
|
-
operation_extensions:
|
|
57
|
+
query: str | None,
|
|
58
|
+
variable_values: dict[str, Any] | None = None,
|
|
59
|
+
context_value: Any | None = None,
|
|
60
|
+
root_value: Any | None = None,
|
|
61
|
+
operation_name: str | None = None,
|
|
62
|
+
allowed_operation_types: Iterable[OperationType] | None = None,
|
|
63
|
+
operation_extensions: dict[str, Any] | None = None,
|
|
64
64
|
) -> ExecutionResult:
|
|
65
65
|
raise NotImplementedError
|
|
66
66
|
|
|
@@ -68,29 +68,28 @@ class BaseSchema(Protocol):
|
|
|
68
68
|
async def subscribe(
|
|
69
69
|
self,
|
|
70
70
|
query: str,
|
|
71
|
-
variable_values:
|
|
72
|
-
context_value:
|
|
73
|
-
root_value:
|
|
74
|
-
operation_name:
|
|
75
|
-
operation_extensions:
|
|
71
|
+
variable_values: dict[str, Any] | None = None,
|
|
72
|
+
context_value: Any | None = None,
|
|
73
|
+
root_value: Any | None = None,
|
|
74
|
+
operation_name: str | None = None,
|
|
75
|
+
operation_extensions: dict[str, Any] | None = None,
|
|
76
76
|
) -> SubscriptionResult:
|
|
77
77
|
raise NotImplementedError
|
|
78
78
|
|
|
79
79
|
@abstractmethod
|
|
80
80
|
def get_type_by_name(
|
|
81
81
|
self, name: str
|
|
82
|
-
) ->
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
]:
|
|
82
|
+
) -> (
|
|
83
|
+
StrawberryObjectDefinition
|
|
84
|
+
| ScalarDefinition
|
|
85
|
+
| EnumDefinition
|
|
86
|
+
| StrawberryUnion
|
|
87
|
+
| None
|
|
88
|
+
):
|
|
90
89
|
raise NotImplementedError
|
|
91
90
|
|
|
92
91
|
@abstractmethod
|
|
93
|
-
def get_directive_by_name(self, graphql_name: str) ->
|
|
92
|
+
def get_directive_by_name(self, graphql_name: str) -> StrawberryDirective | None:
|
|
94
93
|
raise NotImplementedError
|
|
95
94
|
|
|
96
95
|
@abstractmethod
|
|
@@ -108,7 +107,7 @@ class BaseSchema(Protocol):
|
|
|
108
107
|
def _process_errors(
|
|
109
108
|
self,
|
|
110
109
|
errors: list[GraphQLError],
|
|
111
|
-
execution_context:
|
|
110
|
+
execution_context: ExecutionContext | None = None,
|
|
112
111
|
) -> None:
|
|
113
112
|
if self.config.disable_field_suggestions:
|
|
114
113
|
for error in errors:
|
|
@@ -119,7 +118,7 @@ class BaseSchema(Protocol):
|
|
|
119
118
|
def process_errors(
|
|
120
119
|
self,
|
|
121
120
|
errors: list[GraphQLError],
|
|
122
|
-
execution_context:
|
|
121
|
+
execution_context: ExecutionContext | None = None,
|
|
123
122
|
) -> None:
|
|
124
123
|
for error in errors:
|
|
125
124
|
StrawberryLogger.error(error, execution_context)
|
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
|
|
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
|
|
@@ -11,40 +11,40 @@ from strawberry.types.base import StrawberryType, has_object_definition
|
|
|
11
11
|
|
|
12
12
|
if TYPE_CHECKING:
|
|
13
13
|
from collections.abc import Mapping
|
|
14
|
-
from
|
|
14
|
+
from typing import TypeGuard
|
|
15
15
|
|
|
16
16
|
from strawberry.types.scalar import ScalarDefinition, ScalarWrapper
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
def is_input_type(type_:
|
|
19
|
+
def is_input_type(type_: StrawberryType | type) -> TypeGuard[type]:
|
|
20
20
|
if not has_object_definition(type_):
|
|
21
21
|
return False
|
|
22
22
|
return type_.__strawberry_definition__.is_input
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
def is_interface_type(type_:
|
|
25
|
+
def is_interface_type(type_: StrawberryType | type) -> TypeGuard[type]:
|
|
26
26
|
if not has_object_definition(type_):
|
|
27
27
|
return False
|
|
28
28
|
return type_.__strawberry_definition__.is_interface
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
def is_scalar(
|
|
32
|
-
type_:
|
|
33
|
-
scalar_registry: Mapping[object,
|
|
32
|
+
type_: StrawberryType | type,
|
|
33
|
+
scalar_registry: Mapping[object, ScalarWrapper | ScalarDefinition],
|
|
34
34
|
) -> TypeGuard[type]:
|
|
35
35
|
return is_strawberry_scalar(type_, scalar_registry)
|
|
36
36
|
|
|
37
37
|
|
|
38
|
-
def is_enum(type_:
|
|
38
|
+
def is_enum(type_: StrawberryType | type) -> TypeGuard[type]:
|
|
39
39
|
return hasattr(type_, "_enum_definition")
|
|
40
40
|
|
|
41
41
|
|
|
42
|
-
def is_schema_directive(type_:
|
|
42
|
+
def is_schema_directive(type_: StrawberryType | type) -> TypeGuard[type]:
|
|
43
43
|
return hasattr(type_, "__strawberry_directive__")
|
|
44
44
|
|
|
45
45
|
|
|
46
46
|
# TODO: do we still need this?
|
|
47
|
-
def is_graphql_generic(type_:
|
|
47
|
+
def is_graphql_generic(type_: StrawberryType | type) -> bool:
|
|
48
48
|
if has_object_definition(type_):
|
|
49
49
|
return type_.__strawberry_definition__.is_graphql_generic
|
|
50
50
|
|
strawberry/schema/config.py
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from dataclasses import InitVar, dataclass, field
|
|
4
|
-
from typing import Any,
|
|
4
|
+
from typing import TYPE_CHECKING, Any, TypedDict
|
|
5
5
|
|
|
6
6
|
from strawberry.types.info import Info
|
|
7
7
|
|
|
8
8
|
from .name_converter import NameConverter
|
|
9
9
|
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from collections.abc import Callable
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class BatchingConfig(TypedDict):
|
|
15
|
+
max_operations: int
|
|
16
|
+
|
|
10
17
|
|
|
11
18
|
@dataclass
|
|
12
19
|
class StrawberryConfig:
|
|
@@ -17,7 +24,9 @@ class StrawberryConfig:
|
|
|
17
24
|
relay_use_legacy_global_id: bool = False
|
|
18
25
|
disable_field_suggestions: bool = False
|
|
19
26
|
info_class: type[Info] = Info
|
|
27
|
+
enable_experimental_incremental_execution: bool = False
|
|
20
28
|
_unsafe_disable_same_type_validation: bool = False
|
|
29
|
+
batching_config: BatchingConfig | None = None
|
|
21
30
|
|
|
22
31
|
def __post_init__(
|
|
23
32
|
self,
|
strawberry/schema/exceptions.py
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
from typing import Optional
|
|
2
|
-
|
|
3
1
|
from strawberry.types.graphql import OperationType
|
|
4
2
|
|
|
5
3
|
|
|
6
4
|
class CannotGetOperationTypeError(Exception):
|
|
7
5
|
"""Internal error raised when we cannot get the operation type from a GraphQL document."""
|
|
8
6
|
|
|
9
|
-
def __init__(self, operation_name:
|
|
7
|
+
def __init__(self, operation_name: str | None) -> None:
|
|
10
8
|
self.operation_name = operation_name
|
|
11
9
|
|
|
12
10
|
def as_http_error_reason(self) -> str:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import TYPE_CHECKING,
|
|
3
|
+
from typing import TYPE_CHECKING, cast
|
|
4
4
|
from typing_extensions import Protocol
|
|
5
5
|
|
|
6
6
|
from strawberry.directive import StrawberryDirective
|
|
@@ -26,7 +26,7 @@ if TYPE_CHECKING:
|
|
|
26
26
|
|
|
27
27
|
class HasGraphQLName(Protocol):
|
|
28
28
|
python_name: str
|
|
29
|
-
graphql_name:
|
|
29
|
+
graphql_name: str | None
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
class NameConverter:
|
|
@@ -41,7 +41,7 @@ class NameConverter:
|
|
|
41
41
|
|
|
42
42
|
def from_type(
|
|
43
43
|
self,
|
|
44
|
-
type_:
|
|
44
|
+
type_: StrawberryType | StrawberryDirective,
|
|
45
45
|
) -> str:
|
|
46
46
|
if isinstance(type_, (StrawberryDirective, StrawberrySchemaDirective)):
|
|
47
47
|
return self.from_directive(type_)
|
|
@@ -85,7 +85,7 @@ class NameConverter:
|
|
|
85
85
|
return enum_value.name
|
|
86
86
|
|
|
87
87
|
def from_directive(
|
|
88
|
-
self, directive:
|
|
88
|
+
self, directive: StrawberryDirective | StrawberrySchemaDirective
|
|
89
89
|
) -> str:
|
|
90
90
|
name = self.get_graphql_name(directive)
|
|
91
91
|
|
|
@@ -134,7 +134,7 @@ class NameConverter:
|
|
|
134
134
|
def from_generic(
|
|
135
135
|
self,
|
|
136
136
|
generic_type: StrawberryObjectDefinition,
|
|
137
|
-
types: list[
|
|
137
|
+
types: list[StrawberryType | type],
|
|
138
138
|
) -> str:
|
|
139
139
|
generic_type_name = generic_type.name
|
|
140
140
|
|
|
@@ -146,12 +146,13 @@ class NameConverter:
|
|
|
146
146
|
|
|
147
147
|
return "".join(names) + generic_type_name
|
|
148
148
|
|
|
149
|
-
def get_name_from_type(self, type_:
|
|
149
|
+
def get_name_from_type(self, type_: StrawberryType | type) -> str:
|
|
150
150
|
type_ = eval_type(type_)
|
|
151
151
|
|
|
152
152
|
if isinstance(type_, LazyType):
|
|
153
|
-
|
|
154
|
-
|
|
153
|
+
type_ = type_.resolve_type()
|
|
154
|
+
|
|
155
|
+
if isinstance(type_, EnumDefinition):
|
|
155
156
|
name = type_.name
|
|
156
157
|
elif isinstance(type_, StrawberryUnion):
|
|
157
158
|
name = type_.graphql_name if type_.graphql_name else self.from_union(type_)
|