strawberry-graphql 0.283.0__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/aiohttp/test/client.py +8 -15
- strawberry/aiohttp/views.py +12 -15
- strawberry/annotation.py +19 -23
- strawberry/asgi/__init__.py +18 -17
- strawberry/asgi/test/client.py +6 -6
- strawberry/chalice/views.py +6 -6
- strawberry/channels/handlers/base.py +7 -8
- strawberry/channels/handlers/http_handler.py +18 -20
- strawberry/channels/handlers/ws_handler.py +10 -12
- strawberry/channels/router.py +3 -4
- strawberry/channels/testing.py +7 -9
- strawberry/cli/commands/codegen.py +7 -7
- strawberry/cli/commands/schema_codegen.py +1 -2
- strawberry/cli/commands/upgrade/__init__.py +1 -3
- strawberry/cli/commands/upgrade/_run_codemod.py +2 -2
- 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/annotated_unions.py +2 -2
- strawberry/dataloader.py +28 -24
- strawberry/directive.py +6 -7
- strawberry/django/test/client.py +3 -3
- strawberry/django/views.py +16 -19
- 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 +15 -23
- 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 +3 -1
- strawberry/extensions/field_extension.py +4 -4
- 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 +1 -2
- strawberry/fastapi/context.py +6 -6
- strawberry/fastapi/router.py +33 -36
- 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 +10 -11
- strawberry/http/__init__.py +14 -14
- strawberry/http/async_base_view.py +23 -28
- strawberry/http/base.py +11 -12
- strawberry/http/ides.py +2 -3
- strawberry/http/sync_base_view.py +11 -13
- strawberry/http/types.py +3 -3
- strawberry/litestar/controller.py +40 -35
- strawberry/permission.py +4 -6
- strawberry/printer/ast_from_value.py +3 -5
- strawberry/printer/printer.py +8 -13
- strawberry/quart/views.py +12 -14
- strawberry/relay/exceptions.py +4 -4
- strawberry/relay/fields.py +33 -32
- strawberry/relay/types.py +31 -34
- strawberry/relay/utils.py +2 -2
- strawberry/resolvers.py +2 -1
- strawberry/sanic/context.py +1 -0
- strawberry/sanic/utils.py +3 -3
- strawberry/sanic/views.py +11 -14
- strawberry/scalars.py +2 -2
- strawberry/schema/_graphql_core.py +5 -5
- strawberry/schema/base.py +32 -33
- strawberry/schema/compat.py +9 -9
- strawberry/schema/config.py +5 -2
- strawberry/schema/exceptions.py +1 -3
- strawberry/schema/name_converter.py +6 -6
- strawberry/schema/schema.py +55 -60
- strawberry/schema/schema_converter.py +27 -22
- strawberry/schema/types/base_scalars.py +1 -1
- strawberry/schema/types/concrete_type.py +5 -5
- strawberry/schema_codegen/__init__.py +3 -3
- strawberry/schema_directive.py +7 -6
- strawberry/subscriptions/protocols/graphql_transport_ws/handlers.py +5 -6
- strawberry/subscriptions/protocols/graphql_transport_ws/types.py +20 -20
- strawberry/subscriptions/protocols/graphql_ws/handlers.py +5 -6
- 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 +25 -26
- strawberry/types/auto.py +3 -4
- strawberry/types/base.py +25 -27
- strawberry/types/enum.py +22 -25
- strawberry/types/execution.py +14 -15
- strawberry/types/field.py +108 -108
- 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.283.0.dist-info → strawberry_graphql-0.284.3.dist-info}/METADATA +2 -2
- strawberry_graphql-0.284.3.dist-info/RECORD +243 -0
- strawberry/utils/dataclasses.py +0 -37
- strawberry_graphql-0.283.0.dist-info/RECORD +0 -244
- {strawberry_graphql-0.283.0.dist-info → strawberry_graphql-0.284.3.dist-info}/WHEEL +0 -0
- {strawberry_graphql-0.283.0.dist-info → strawberry_graphql-0.284.3.dist-info}/entry_points.txt +0 -0
- {strawberry_graphql-0.283.0.dist-info → strawberry_graphql-0.284.3.dist-info}/licenses/LICENSE +0 -0
strawberry/relay/fields.py
CHANGED
|
@@ -8,6 +8,7 @@ from collections.abc import (
|
|
|
8
8
|
AsyncIterable,
|
|
9
9
|
AsyncIterator,
|
|
10
10
|
Awaitable,
|
|
11
|
+
Callable,
|
|
11
12
|
Iterable,
|
|
12
13
|
Iterator,
|
|
13
14
|
Mapping,
|
|
@@ -17,13 +18,12 @@ from typing import (
|
|
|
17
18
|
TYPE_CHECKING,
|
|
18
19
|
Annotated,
|
|
19
20
|
Any,
|
|
20
|
-
Callable,
|
|
21
21
|
ForwardRef,
|
|
22
22
|
Optional,
|
|
23
|
-
Union,
|
|
24
23
|
cast,
|
|
24
|
+
get_args,
|
|
25
|
+
get_origin,
|
|
25
26
|
)
|
|
26
|
-
from typing_extensions import get_args, get_origin
|
|
27
27
|
|
|
28
28
|
from strawberry.annotation import StrawberryAnnotation
|
|
29
29
|
from strawberry.extensions.field_extension import (
|
|
@@ -47,7 +47,7 @@ from strawberry.utils.typing import eval_type, is_generic_alias, is_optional, is
|
|
|
47
47
|
from .types import Connection, GlobalID, Node
|
|
48
48
|
|
|
49
49
|
if TYPE_CHECKING:
|
|
50
|
-
from
|
|
50
|
+
from typing import Literal
|
|
51
51
|
|
|
52
52
|
from strawberry.permission import BasePermission
|
|
53
53
|
from strawberry.types.info import Info
|
|
@@ -81,14 +81,14 @@ class NodeExtension(FieldExtension):
|
|
|
81
81
|
|
|
82
82
|
def get_node_resolver(
|
|
83
83
|
self, field: StrawberryField
|
|
84
|
-
) -> Callable[[Info, GlobalID],
|
|
84
|
+
) -> Callable[[Info, GlobalID], Node | None | Awaitable[Node | None]]:
|
|
85
85
|
type_ = field.type
|
|
86
86
|
is_optional = isinstance(type_, StrawberryOptional)
|
|
87
87
|
|
|
88
88
|
def resolver(
|
|
89
89
|
info: Info,
|
|
90
90
|
id: Annotated[GlobalID, argument(description="The ID of the object.")],
|
|
91
|
-
) ->
|
|
91
|
+
) -> Node | None | Awaitable[Node | None]:
|
|
92
92
|
node_type = id.resolve_type(info)
|
|
93
93
|
resolved_node = node_type.resolve_node(
|
|
94
94
|
id.node_id,
|
|
@@ -114,7 +114,7 @@ class NodeExtension(FieldExtension):
|
|
|
114
114
|
|
|
115
115
|
def get_node_list_resolver(
|
|
116
116
|
self, field: StrawberryField
|
|
117
|
-
) -> Callable[[Info, list[GlobalID]],
|
|
117
|
+
) -> Callable[[Info, list[GlobalID]], list[Node] | Awaitable[list[Node]]]:
|
|
118
118
|
type_ = field.type
|
|
119
119
|
assert isinstance(type_, StrawberryList)
|
|
120
120
|
is_optional = isinstance(type_.of_type, StrawberryOptional)
|
|
@@ -124,7 +124,7 @@ class NodeExtension(FieldExtension):
|
|
|
124
124
|
ids: Annotated[
|
|
125
125
|
list[GlobalID], argument(description="The IDs of the objects.")
|
|
126
126
|
],
|
|
127
|
-
) ->
|
|
127
|
+
) -> list[Node] | Awaitable[list[Node]]:
|
|
128
128
|
nodes_map: defaultdict[type[Node], list[str]] = defaultdict(list)
|
|
129
129
|
# Store the index of the node in the list of nodes of the same type
|
|
130
130
|
# so that we can return them in the same order while also supporting
|
|
@@ -180,6 +180,7 @@ class NodeExtension(FieldExtension):
|
|
|
180
180
|
for nodes in asyncgen_nodes.values()
|
|
181
181
|
),
|
|
182
182
|
),
|
|
183
|
+
strict=True,
|
|
183
184
|
)
|
|
184
185
|
)
|
|
185
186
|
|
|
@@ -207,7 +208,7 @@ class NodeExtension(FieldExtension):
|
|
|
207
208
|
class ConnectionExtension(FieldExtension):
|
|
208
209
|
connection_type: type[Connection[Node]]
|
|
209
210
|
|
|
210
|
-
def __init__(self, max_results:
|
|
211
|
+
def __init__(self, max_results: int | None = None) -> None:
|
|
211
212
|
self.max_results = max_results
|
|
212
213
|
|
|
213
214
|
def apply(self, field: StrawberryField) -> None:
|
|
@@ -216,7 +217,7 @@ class ConnectionExtension(FieldExtension):
|
|
|
216
217
|
StrawberryArgument(
|
|
217
218
|
python_name="before",
|
|
218
219
|
graphql_name=None,
|
|
219
|
-
type_annotation=StrawberryAnnotation(Optional[str]),
|
|
220
|
+
type_annotation=StrawberryAnnotation(Optional[str]), # noqa: UP045
|
|
220
221
|
description=(
|
|
221
222
|
"Returns the items in the list that come before the "
|
|
222
223
|
"specified cursor."
|
|
@@ -226,7 +227,7 @@ class ConnectionExtension(FieldExtension):
|
|
|
226
227
|
StrawberryArgument(
|
|
227
228
|
python_name="after",
|
|
228
229
|
graphql_name=None,
|
|
229
|
-
type_annotation=StrawberryAnnotation(Optional[str]),
|
|
230
|
+
type_annotation=StrawberryAnnotation(Optional[str]), # noqa: UP045
|
|
230
231
|
description=(
|
|
231
232
|
"Returns the items in the list that come after the "
|
|
232
233
|
"specified cursor."
|
|
@@ -236,14 +237,14 @@ class ConnectionExtension(FieldExtension):
|
|
|
236
237
|
StrawberryArgument(
|
|
237
238
|
python_name="first",
|
|
238
239
|
graphql_name=None,
|
|
239
|
-
type_annotation=StrawberryAnnotation(Optional[int]),
|
|
240
|
+
type_annotation=StrawberryAnnotation(Optional[int]), # noqa: UP045
|
|
240
241
|
description="Returns the first n items from the list.",
|
|
241
242
|
default=None,
|
|
242
243
|
),
|
|
243
244
|
StrawberryArgument(
|
|
244
245
|
python_name="last",
|
|
245
246
|
graphql_name=None,
|
|
246
|
-
type_annotation=StrawberryAnnotation(Optional[int]),
|
|
247
|
+
type_annotation=StrawberryAnnotation(Optional[int]), # noqa: UP045
|
|
247
248
|
description=(
|
|
248
249
|
"Returns the items in the list that come after the "
|
|
249
250
|
"specified cursor."
|
|
@@ -307,10 +308,10 @@ class ConnectionExtension(FieldExtension):
|
|
|
307
308
|
source: Any,
|
|
308
309
|
info: Info,
|
|
309
310
|
*,
|
|
310
|
-
before:
|
|
311
|
-
after:
|
|
312
|
-
first:
|
|
313
|
-
last:
|
|
311
|
+
before: str | None = None,
|
|
312
|
+
after: str | None = None,
|
|
313
|
+
first: int | None = None,
|
|
314
|
+
last: int | None = None,
|
|
314
315
|
**kwargs: Any,
|
|
315
316
|
) -> Any:
|
|
316
317
|
assert self.connection_type is not None
|
|
@@ -330,10 +331,10 @@ class ConnectionExtension(FieldExtension):
|
|
|
330
331
|
source: Any,
|
|
331
332
|
info: Info,
|
|
332
333
|
*,
|
|
333
|
-
before:
|
|
334
|
-
after:
|
|
335
|
-
first:
|
|
336
|
-
last:
|
|
334
|
+
before: str | None = None,
|
|
335
|
+
after: str | None = None,
|
|
336
|
+
first: int | None = None,
|
|
337
|
+
last: int | None = None,
|
|
337
338
|
**kwargs: Any,
|
|
338
339
|
) -> Any:
|
|
339
340
|
assert self.connection_type is not None
|
|
@@ -379,24 +380,24 @@ ConnectionGraphQLType = Any
|
|
|
379
380
|
|
|
380
381
|
|
|
381
382
|
def connection(
|
|
382
|
-
graphql_type:
|
|
383
|
+
graphql_type: ConnectionGraphQLType | None = None,
|
|
383
384
|
*,
|
|
384
|
-
resolver:
|
|
385
|
-
name:
|
|
385
|
+
resolver: _RESOLVER_TYPE[Any] | None = None,
|
|
386
|
+
name: str | None = None,
|
|
386
387
|
is_subscription: bool = False,
|
|
387
|
-
description:
|
|
388
|
-
permission_classes:
|
|
389
|
-
deprecation_reason:
|
|
388
|
+
description: str | None = None,
|
|
389
|
+
permission_classes: list[type[BasePermission]] | None = None,
|
|
390
|
+
deprecation_reason: str | None = None,
|
|
390
391
|
default: Any = dataclasses.MISSING,
|
|
391
|
-
default_factory:
|
|
392
|
-
metadata:
|
|
393
|
-
directives:
|
|
392
|
+
default_factory: Callable[..., object] | object = dataclasses.MISSING,
|
|
393
|
+
metadata: Mapping[Any, Any] | None = None,
|
|
394
|
+
directives: Sequence[object] | None = (),
|
|
394
395
|
extensions: list[FieldExtension] | None = None,
|
|
395
|
-
max_results:
|
|
396
|
+
max_results: int | None = None,
|
|
396
397
|
# This init parameter is used by pyright to determine whether this field
|
|
397
398
|
# is added in the constructor or not. It is not used to change
|
|
398
399
|
# any behaviour at the moment.
|
|
399
|
-
init: Literal[True, False
|
|
400
|
+
init: Literal[True, False] | None = None,
|
|
400
401
|
) -> Any:
|
|
401
402
|
"""Annotate a property or a method to create a relay connection field.
|
|
402
403
|
|
strawberry/relay/types.py
CHANGED
|
@@ -19,13 +19,16 @@ from typing import (
|
|
|
19
19
|
ClassVar,
|
|
20
20
|
ForwardRef,
|
|
21
21
|
Generic,
|
|
22
|
-
|
|
22
|
+
Literal,
|
|
23
|
+
TypeAlias,
|
|
23
24
|
TypeVar,
|
|
24
25
|
Union,
|
|
25
26
|
cast,
|
|
27
|
+
get_args,
|
|
28
|
+
get_origin,
|
|
26
29
|
overload,
|
|
27
30
|
)
|
|
28
|
-
from typing_extensions import
|
|
31
|
+
from typing_extensions import Self
|
|
29
32
|
|
|
30
33
|
from strawberry.relay.exceptions import NodeIDAnnotationError
|
|
31
34
|
from strawberry.types.base import (
|
|
@@ -56,12 +59,9 @@ if TYPE_CHECKING:
|
|
|
56
59
|
|
|
57
60
|
_T = TypeVar("_T")
|
|
58
61
|
|
|
59
|
-
NodeIterableType: TypeAlias =
|
|
60
|
-
Iterator[_T]
|
|
61
|
-
|
|
62
|
-
AsyncIterator[_T],
|
|
63
|
-
AsyncIterable[_T],
|
|
64
|
-
]
|
|
62
|
+
NodeIterableType: TypeAlias = (
|
|
63
|
+
Iterator[_T] | Iterable[_T] | AsyncIterator[_T] | AsyncIterable[_T]
|
|
64
|
+
)
|
|
65
65
|
NodeType = TypeVar("NodeType", bound="Node")
|
|
66
66
|
|
|
67
67
|
PREFIX = "arrayconnection"
|
|
@@ -110,7 +110,7 @@ class GlobalID:
|
|
|
110
110
|
return to_base64(self.type_name, self.node_id)
|
|
111
111
|
|
|
112
112
|
@classmethod
|
|
113
|
-
def from_id(cls, value:
|
|
113
|
+
def from_id(cls, value: str | ID) -> Self:
|
|
114
114
|
"""Create a new GlobalID from parsing the given value.
|
|
115
115
|
|
|
116
116
|
Args:
|
|
@@ -158,7 +158,7 @@ class GlobalID:
|
|
|
158
158
|
*,
|
|
159
159
|
required: bool = ...,
|
|
160
160
|
ensure_type: None = ...,
|
|
161
|
-
) ->
|
|
161
|
+
) -> Node | None: ...
|
|
162
162
|
|
|
163
163
|
async def resolve_node(self, info, *, required=False, ensure_type=None) -> Any:
|
|
164
164
|
"""Resolve the type name and node id info to the node itself.
|
|
@@ -268,7 +268,7 @@ class GlobalID:
|
|
|
268
268
|
*,
|
|
269
269
|
required: bool = ...,
|
|
270
270
|
ensure_type: None = ...,
|
|
271
|
-
) ->
|
|
271
|
+
) -> Node | None: ...
|
|
272
272
|
|
|
273
273
|
def resolve_node_sync(self, info, *, required=False, ensure_type=None) -> Any:
|
|
274
274
|
"""Resolve the type name and node id info to the node itself.
|
|
@@ -378,7 +378,7 @@ class Node:
|
|
|
378
378
|
```
|
|
379
379
|
"""
|
|
380
380
|
|
|
381
|
-
_id_attr: ClassVar[
|
|
381
|
+
_id_attr: ClassVar[str | None] = None
|
|
382
382
|
|
|
383
383
|
@field(name="id", description="The Globally Unique ID of this object")
|
|
384
384
|
@classmethod
|
|
@@ -513,7 +513,7 @@ class Node:
|
|
|
513
513
|
info: Info,
|
|
514
514
|
node_ids: Iterable[str],
|
|
515
515
|
required: Literal[False] = ...,
|
|
516
|
-
) -> AwaitableOrValue[Iterable[
|
|
516
|
+
) -> AwaitableOrValue[Iterable[Self | None]]: ...
|
|
517
517
|
|
|
518
518
|
@overload
|
|
519
519
|
@classmethod
|
|
@@ -523,10 +523,7 @@ class Node:
|
|
|
523
523
|
info: Info,
|
|
524
524
|
node_ids: Iterable[str],
|
|
525
525
|
required: bool,
|
|
526
|
-
) ->
|
|
527
|
-
AwaitableOrValue[Iterable[Self]],
|
|
528
|
-
AwaitableOrValue[Iterable[Optional[Self]]],
|
|
529
|
-
]: ...
|
|
526
|
+
) -> AwaitableOrValue[Iterable[Self]] | AwaitableOrValue[Iterable[Self | None]]: ...
|
|
530
527
|
|
|
531
528
|
@classmethod
|
|
532
529
|
def resolve_nodes(
|
|
@@ -577,7 +574,7 @@ class Node:
|
|
|
577
574
|
*,
|
|
578
575
|
info: Info,
|
|
579
576
|
required: Literal[False] = ...,
|
|
580
|
-
) -> AwaitableOrValue[
|
|
577
|
+
) -> AwaitableOrValue[Self | None]: ...
|
|
581
578
|
|
|
582
579
|
@overload
|
|
583
580
|
@classmethod
|
|
@@ -587,7 +584,7 @@ class Node:
|
|
|
587
584
|
*,
|
|
588
585
|
info: Info,
|
|
589
586
|
required: bool,
|
|
590
|
-
) -> AwaitableOrValue[
|
|
587
|
+
) -> AwaitableOrValue[Self | None]: ...
|
|
591
588
|
|
|
592
589
|
@classmethod
|
|
593
590
|
def resolve_node(
|
|
@@ -596,7 +593,7 @@ class Node:
|
|
|
596
593
|
*,
|
|
597
594
|
info: Info,
|
|
598
595
|
required: bool = False,
|
|
599
|
-
) -> AwaitableOrValue[
|
|
596
|
+
) -> AwaitableOrValue[Self | None]:
|
|
600
597
|
"""Resolve a node given its id.
|
|
601
598
|
|
|
602
599
|
This method is a convenience method that calls `resolve_nodes` for
|
|
@@ -641,10 +638,10 @@ class PageInfo:
|
|
|
641
638
|
has_previous_page: bool = field(
|
|
642
639
|
description="When paginating backwards, are there more items?",
|
|
643
640
|
)
|
|
644
|
-
start_cursor:
|
|
641
|
+
start_cursor: str | None = field(
|
|
645
642
|
description="When paginating backwards, the cursor to continue.",
|
|
646
643
|
)
|
|
647
|
-
end_cursor:
|
|
644
|
+
end_cursor: str | None = field(
|
|
648
645
|
description="When paginating forwards, the cursor to continue.",
|
|
649
646
|
)
|
|
650
647
|
|
|
@@ -715,11 +712,11 @@ class Connection(Generic[NodeType]):
|
|
|
715
712
|
nodes: NodeIterableType[NodeType],
|
|
716
713
|
*,
|
|
717
714
|
info: Info,
|
|
718
|
-
before:
|
|
719
|
-
after:
|
|
720
|
-
first:
|
|
721
|
-
last:
|
|
722
|
-
max_results:
|
|
715
|
+
before: str | None = None,
|
|
716
|
+
after: str | None = None,
|
|
717
|
+
first: int | None = None,
|
|
718
|
+
last: int | None = None,
|
|
719
|
+
max_results: int | None = None,
|
|
723
720
|
**kwargs: Any,
|
|
724
721
|
) -> AwaitableOrValue[Self]:
|
|
725
722
|
"""Resolve a connection from nodes.
|
|
@@ -767,11 +764,11 @@ class ListConnection(Connection[NodeType]):
|
|
|
767
764
|
nodes: NodeIterableType[NodeType],
|
|
768
765
|
*,
|
|
769
766
|
info: Info,
|
|
770
|
-
before:
|
|
771
|
-
after:
|
|
772
|
-
first:
|
|
773
|
-
last:
|
|
774
|
-
max_results:
|
|
767
|
+
before: str | None = None,
|
|
768
|
+
after: str | None = None,
|
|
769
|
+
first: int | None = None,
|
|
770
|
+
last: int | None = None,
|
|
771
|
+
max_results: int | None = None,
|
|
775
772
|
**kwargs: Any,
|
|
776
773
|
) -> AwaitableOrValue[Self]:
|
|
777
774
|
"""Resolve a connection from the list of nodes.
|
|
@@ -820,7 +817,7 @@ class ListConnection(Connection[NodeType]):
|
|
|
820
817
|
async def resolver() -> Self:
|
|
821
818
|
try:
|
|
822
819
|
iterator = cast(
|
|
823
|
-
"
|
|
820
|
+
"AsyncIterator[NodeType] | AsyncIterable[NodeType]",
|
|
824
821
|
cast("Sequence", nodes)[
|
|
825
822
|
slice_metadata.start : slice_metadata.overfetch
|
|
826
823
|
],
|
|
@@ -886,7 +883,7 @@ class ListConnection(Connection[NodeType]):
|
|
|
886
883
|
|
|
887
884
|
try:
|
|
888
885
|
iterator = cast(
|
|
889
|
-
"
|
|
886
|
+
"Iterator[NodeType] | Iterable[NodeType]",
|
|
890
887
|
cast("Sequence", nodes)[
|
|
891
888
|
slice_metadata.start : slice_metadata.overfetch
|
|
892
889
|
],
|
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
|
|
7
7
|
from typing_extensions import Self, assert_never
|
|
8
8
|
|
|
9
9
|
from strawberry.types.base import StrawberryObjectDefinition
|
|
@@ -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:
|
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,17 +5,14 @@ import warnings
|
|
|
5
5
|
from typing import (
|
|
6
6
|
TYPE_CHECKING,
|
|
7
7
|
Any,
|
|
8
|
-
|
|
9
|
-
Optional,
|
|
10
|
-
Union,
|
|
8
|
+
TypeGuard,
|
|
11
9
|
)
|
|
12
|
-
from typing_extensions import TypeGuard
|
|
13
10
|
|
|
14
11
|
from lia import HTTPException, SanicHTTPRequestAdapter
|
|
15
|
-
|
|
16
12
|
from sanic.request import Request
|
|
17
13
|
from sanic.response import HTTPResponse, html
|
|
18
14
|
from sanic.views import HTTPMethodView
|
|
15
|
+
|
|
19
16
|
from strawberry.http.async_base_view import AsyncBaseHTTPView
|
|
20
17
|
from strawberry.http.temporal_response import TemporalResponse
|
|
21
18
|
from strawberry.http.typevars import (
|
|
@@ -24,7 +21,7 @@ from strawberry.http.typevars import (
|
|
|
24
21
|
)
|
|
25
22
|
|
|
26
23
|
if TYPE_CHECKING:
|
|
27
|
-
from collections.abc import AsyncGenerator
|
|
24
|
+
from collections.abc import AsyncGenerator, Callable
|
|
28
25
|
|
|
29
26
|
from strawberry.http import GraphQLHTTPResponse
|
|
30
27
|
from strawberry.http.ides import GraphQL_IDE
|
|
@@ -66,11 +63,11 @@ class GraphQLView(
|
|
|
66
63
|
def __init__(
|
|
67
64
|
self,
|
|
68
65
|
schema: BaseSchema,
|
|
69
|
-
graphiql:
|
|
70
|
-
graphql_ide:
|
|
66
|
+
graphiql: bool | None = None,
|
|
67
|
+
graphql_ide: GraphQL_IDE | None = "graphiql",
|
|
71
68
|
allow_queries_via_get: bool = True,
|
|
72
|
-
json_encoder:
|
|
73
|
-
json_dumps_params:
|
|
69
|
+
json_encoder: type[json.JSONEncoder] | None = None,
|
|
70
|
+
json_dumps_params: dict[str, Any] | None = None,
|
|
74
71
|
multipart_uploads_enabled: bool = False,
|
|
75
72
|
) -> None:
|
|
76
73
|
self.schema = schema
|
|
@@ -105,7 +102,7 @@ class GraphQLView(
|
|
|
105
102
|
else:
|
|
106
103
|
self.graphql_ide = graphql_ide
|
|
107
104
|
|
|
108
|
-
async def get_root_value(self, request: Request) ->
|
|
105
|
+
async def get_root_value(self, request: Request) -> RootValue | None:
|
|
109
106
|
return None
|
|
110
107
|
|
|
111
108
|
async def get_context(
|
|
@@ -121,7 +118,7 @@ class GraphQLView(
|
|
|
121
118
|
|
|
122
119
|
def create_response(
|
|
123
120
|
self,
|
|
124
|
-
response_data:
|
|
121
|
+
response_data: GraphQLHTTPResponse | list[GraphQLHTTPResponse],
|
|
125
122
|
sub_response: TemporalResponse,
|
|
126
123
|
) -> HTTPResponse:
|
|
127
124
|
status_code = sub_response.status_code
|
|
@@ -180,11 +177,11 @@ class GraphQLView(
|
|
|
180
177
|
def is_websocket_request(self, request: Request) -> TypeGuard[Request]:
|
|
181
178
|
return False
|
|
182
179
|
|
|
183
|
-
async def pick_websocket_subprotocol(self, request: Request) ->
|
|
180
|
+
async def pick_websocket_subprotocol(self, request: Request) -> str | None:
|
|
184
181
|
raise NotImplementedError
|
|
185
182
|
|
|
186
183
|
async def create_websocket_response(
|
|
187
|
-
self, request: Request, subprotocol:
|
|
184
|
+
self, request: Request, subprotocol: str | None
|
|
188
185
|
) -> TemporalResponse:
|
|
189
186
|
raise NotImplementedError
|
|
190
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
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Union
|
|
1
|
+
from typing import TypeAlias, Union
|
|
2
2
|
|
|
3
3
|
from graphql.execution import ExecutionContext as GraphQLExecutionContext
|
|
4
4
|
from graphql.execution import ExecutionResult as OriginalGraphQLExecutionResult
|
|
@@ -24,9 +24,9 @@ try:
|
|
|
24
24
|
GraphQLStreamDirective,
|
|
25
25
|
)
|
|
26
26
|
|
|
27
|
-
GraphQLExecutionResult =
|
|
28
|
-
OriginalGraphQLExecutionResult
|
|
29
|
-
|
|
27
|
+
GraphQLExecutionResult: TypeAlias = (
|
|
28
|
+
OriginalGraphQLExecutionResult | InitialIncrementalExecutionResult
|
|
29
|
+
)
|
|
30
30
|
|
|
31
31
|
except ImportError:
|
|
32
32
|
GraphQLIncrementalExecutionResults = type(None)
|
|
@@ -37,7 +37,7 @@ except ImportError:
|
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
# TODO: give this a better name, maybe also a better place
|
|
40
|
-
ResultType = Union[
|
|
40
|
+
ResultType = Union[ # noqa: UP007
|
|
41
41
|
OriginalGraphQLExecutionResult,
|
|
42
42
|
GraphQLIncrementalExecutionResults,
|
|
43
43
|
ExecutionResult,
|
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)
|