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
@@ -1,11 +1,9 @@
|
|
1
|
+
import builtins
|
2
|
+
from collections.abc import Iterable, Sequence
|
1
3
|
from typing import (
|
2
4
|
TYPE_CHECKING,
|
3
5
|
Callable,
|
4
|
-
Iterable,
|
5
|
-
List,
|
6
6
|
Optional,
|
7
|
-
Sequence,
|
8
|
-
Type,
|
9
7
|
TypeVar,
|
10
8
|
Union,
|
11
9
|
overload,
|
@@ -23,7 +21,7 @@ if TYPE_CHECKING:
|
|
23
21
|
from .schema_directives import Key
|
24
22
|
|
25
23
|
|
26
|
-
T = TypeVar("T", bound=
|
24
|
+
T = TypeVar("T", bound=builtins.type)
|
27
25
|
|
28
26
|
|
29
27
|
def _impl_type(
|
@@ -38,8 +36,8 @@ def _impl_type(
|
|
38
36
|
extend: bool = False,
|
39
37
|
shareable: bool = False,
|
40
38
|
inaccessible: bool = UNSET,
|
41
|
-
policy: Optional[
|
42
|
-
requires_scopes: Optional[
|
39
|
+
policy: Optional[list[list[str]]] = None,
|
40
|
+
requires_scopes: Optional[list[list[str]]] = None,
|
43
41
|
tags: Iterable[str] = (),
|
44
42
|
is_input: bool = False,
|
45
43
|
is_interface: bool = False,
|
@@ -115,8 +113,8 @@ def type(
|
|
115
113
|
extend: bool = False,
|
116
114
|
inaccessible: bool = UNSET,
|
117
115
|
keys: Iterable[Union["Key", str]] = (),
|
118
|
-
policy: Optional[
|
119
|
-
requires_scopes: Optional[
|
116
|
+
policy: Optional[list[list[str]]] = None,
|
117
|
+
requires_scopes: Optional[list[list[str]]] = None,
|
120
118
|
shareable: bool = False,
|
121
119
|
tags: Iterable[str] = (),
|
122
120
|
) -> T: ...
|
@@ -137,8 +135,8 @@ def type(
|
|
137
135
|
extend: bool = False,
|
138
136
|
inaccessible: bool = UNSET,
|
139
137
|
keys: Iterable[Union["Key", str]] = (),
|
140
|
-
policy: Optional[
|
141
|
-
requires_scopes: Optional[
|
138
|
+
policy: Optional[list[list[str]]] = None,
|
139
|
+
requires_scopes: Optional[list[list[str]]] = None,
|
142
140
|
shareable: bool = False,
|
143
141
|
tags: Iterable[str] = (),
|
144
142
|
) -> Callable[[T], T]: ...
|
@@ -154,8 +152,8 @@ def type(
|
|
154
152
|
extend: bool = False,
|
155
153
|
inaccessible: bool = UNSET,
|
156
154
|
keys: Iterable[Union["Key", str]] = (),
|
157
|
-
policy: Optional[
|
158
|
-
requires_scopes: Optional[
|
155
|
+
policy: Optional[list[list[str]]] = None,
|
156
|
+
requires_scopes: Optional[list[list[str]]] = None,
|
159
157
|
shareable: bool = False,
|
160
158
|
tags: Iterable[str] = (),
|
161
159
|
):
|
@@ -247,8 +245,8 @@ def interface(
|
|
247
245
|
authenticated: bool = False,
|
248
246
|
inaccessible: bool = UNSET,
|
249
247
|
keys: Iterable[Union["Key", str]] = (),
|
250
|
-
policy: Optional[
|
251
|
-
requires_scopes: Optional[
|
248
|
+
policy: Optional[list[list[str]]] = None,
|
249
|
+
requires_scopes: Optional[list[list[str]]] = None,
|
252
250
|
tags: Iterable[str] = (),
|
253
251
|
) -> T: ...
|
254
252
|
|
@@ -267,8 +265,8 @@ def interface(
|
|
267
265
|
authenticated: bool = False,
|
268
266
|
inaccessible: bool = UNSET,
|
269
267
|
keys: Iterable[Union["Key", str]] = (),
|
270
|
-
policy: Optional[
|
271
|
-
requires_scopes: Optional[
|
268
|
+
policy: Optional[list[list[str]]] = None,
|
269
|
+
requires_scopes: Optional[list[list[str]]] = None,
|
272
270
|
tags: Iterable[str] = (),
|
273
271
|
) -> Callable[[T], T]: ...
|
274
272
|
|
@@ -282,8 +280,8 @@ def interface(
|
|
282
280
|
authenticated: bool = False,
|
283
281
|
inaccessible: bool = UNSET,
|
284
282
|
keys: Iterable[Union["Key", str]] = (),
|
285
|
-
policy: Optional[
|
286
|
-
requires_scopes: Optional[
|
283
|
+
policy: Optional[list[list[str]]] = None,
|
284
|
+
requires_scopes: Optional[list[list[str]]] = None,
|
287
285
|
tags: Iterable[str] = (),
|
288
286
|
):
|
289
287
|
return _impl_type(
|
@@ -316,8 +314,8 @@ def interface_object(
|
|
316
314
|
authenticated: bool = False,
|
317
315
|
inaccessible: bool = UNSET,
|
318
316
|
keys: Iterable[Union["Key", str]] = (),
|
319
|
-
policy: Optional[
|
320
|
-
requires_scopes: Optional[
|
317
|
+
policy: Optional[list[list[str]]] = None,
|
318
|
+
requires_scopes: Optional[list[list[str]]] = None,
|
321
319
|
tags: Iterable[str] = (),
|
322
320
|
) -> T: ...
|
323
321
|
|
@@ -336,8 +334,8 @@ def interface_object(
|
|
336
334
|
authenticated: bool = False,
|
337
335
|
inaccessible: bool = UNSET,
|
338
336
|
keys: Iterable[Union["Key", str]] = (),
|
339
|
-
policy: Optional[
|
340
|
-
requires_scopes: Optional[
|
337
|
+
policy: Optional[list[list[str]]] = None,
|
338
|
+
requires_scopes: Optional[list[list[str]]] = None,
|
341
339
|
tags: Iterable[str] = (),
|
342
340
|
) -> Callable[[T], T]: ...
|
343
341
|
|
@@ -351,8 +349,8 @@ def interface_object(
|
|
351
349
|
authenticated: bool = False,
|
352
350
|
inaccessible: bool = UNSET,
|
353
351
|
keys: Iterable[Union["Key", str]] = (),
|
354
|
-
policy: Optional[
|
355
|
-
requires_scopes: Optional[
|
352
|
+
policy: Optional[list[list[str]]] = None,
|
353
|
+
requires_scopes: Optional[list[list[str]]] = None,
|
356
354
|
tags: Iterable[str] = (),
|
357
355
|
):
|
358
356
|
return _impl_type(
|
@@ -371,4 +369,4 @@ def interface_object(
|
|
371
369
|
)
|
372
370
|
|
373
371
|
|
374
|
-
__all__ = ["
|
372
|
+
__all__ = ["input", "interface", "interface_object", "type"]
|
strawberry/federation/scalar.py
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
import sys
|
2
|
+
from collections.abc import Iterable
|
2
3
|
from typing import (
|
3
4
|
Any,
|
4
5
|
Callable,
|
5
|
-
Iterable,
|
6
|
-
List,
|
7
6
|
NewType,
|
8
7
|
Optional,
|
9
8
|
TypeVar,
|
@@ -36,8 +35,8 @@ def scalar(
|
|
36
35
|
directives: Iterable[object] = (),
|
37
36
|
authenticated: bool = False,
|
38
37
|
inaccessible: bool = False,
|
39
|
-
policy: Optional[
|
40
|
-
requires_scopes: Optional[
|
38
|
+
policy: Optional[list[list[str]]] = None,
|
39
|
+
requires_scopes: Optional[list[list[str]]] = None,
|
41
40
|
tags: Optional[Iterable[str]] = (),
|
42
41
|
) -> Callable[[_T], _T]: ...
|
43
42
|
|
@@ -55,8 +54,8 @@ def scalar(
|
|
55
54
|
directives: Iterable[object] = (),
|
56
55
|
authenticated: bool = False,
|
57
56
|
inaccessible: bool = False,
|
58
|
-
policy: Optional[
|
59
|
-
requires_scopes: Optional[
|
57
|
+
policy: Optional[list[list[str]]] = None,
|
58
|
+
requires_scopes: Optional[list[list[str]]] = None,
|
60
59
|
tags: Optional[Iterable[str]] = (),
|
61
60
|
) -> _T: ...
|
62
61
|
|
@@ -73,8 +72,8 @@ def scalar(
|
|
73
72
|
directives: Iterable[object] = (),
|
74
73
|
authenticated: bool = False,
|
75
74
|
inaccessible: bool = False,
|
76
|
-
policy: Optional[
|
77
|
-
requires_scopes: Optional[
|
75
|
+
policy: Optional[list[list[str]]] = None,
|
76
|
+
requires_scopes: Optional[list[list[str]]] = None,
|
78
77
|
tags: Optional[Iterable[str]] = (),
|
79
78
|
) -> Any:
|
80
79
|
"""Annotates a class or type as a GraphQL custom scalar.
|
strawberry/federation/schema.py
CHANGED
@@ -1,18 +1,12 @@
|
|
1
1
|
from collections import defaultdict
|
2
|
+
from collections.abc import Iterable, Mapping
|
2
3
|
from functools import cached_property
|
3
4
|
from itertools import chain
|
4
5
|
from typing import (
|
5
6
|
TYPE_CHECKING,
|
6
7
|
Any,
|
7
|
-
DefaultDict,
|
8
|
-
Dict,
|
9
|
-
Iterable,
|
10
|
-
List,
|
11
|
-
Mapping,
|
12
8
|
NewType,
|
13
9
|
Optional,
|
14
|
-
Set,
|
15
|
-
Type,
|
16
10
|
Union,
|
17
11
|
cast,
|
18
12
|
)
|
@@ -50,17 +44,17 @@ FederationAny = scalar(NewType("_Any", object), name="_Any") # type: ignore
|
|
50
44
|
class Schema(BaseSchema):
|
51
45
|
def __init__(
|
52
46
|
self,
|
53
|
-
query: Optional[
|
54
|
-
mutation: Optional[
|
55
|
-
subscription: Optional[
|
47
|
+
query: Optional[type] = None,
|
48
|
+
mutation: Optional[type] = None,
|
49
|
+
subscription: Optional[type] = None,
|
56
50
|
# TODO: we should update directives' type in the main schema
|
57
|
-
directives: Iterable[
|
58
|
-
types: Iterable[
|
59
|
-
extensions: Iterable[Union[
|
60
|
-
execution_context_class: Optional[
|
51
|
+
directives: Iterable[type] = (),
|
52
|
+
types: Iterable[type] = (),
|
53
|
+
extensions: Iterable[Union[type["SchemaExtension"], "SchemaExtension"]] = (),
|
54
|
+
execution_context_class: Optional[type["GraphQLExecutionContext"]] = None,
|
61
55
|
config: Optional["StrawberryConfig"] = None,
|
62
56
|
scalar_overrides: Optional[
|
63
|
-
|
57
|
+
dict[object, Union[type, "ScalarWrapper", "ScalarDefinition"]]
|
64
58
|
] = None,
|
65
59
|
schema_directives: Iterable[object] = (),
|
66
60
|
enable_federation_2: bool = False,
|
@@ -91,11 +85,11 @@ class Schema(BaseSchema):
|
|
91
85
|
|
92
86
|
def _get_federation_query_type(
|
93
87
|
self,
|
94
|
-
query: Optional[
|
95
|
-
mutation: Optional[
|
96
|
-
subscription: Optional[
|
97
|
-
additional_types: Iterable[
|
98
|
-
) ->
|
88
|
+
query: Optional[type[WithStrawberryObjectDefinition]],
|
89
|
+
mutation: Optional[type[WithStrawberryObjectDefinition]],
|
90
|
+
subscription: Optional[type[WithStrawberryObjectDefinition]],
|
91
|
+
additional_types: Iterable[type[WithStrawberryObjectDefinition]],
|
92
|
+
) -> type:
|
99
93
|
"""Returns a new query type that includes the _service field.
|
100
94
|
|
101
95
|
If the query type is provided, it will be used as the base for the new
|
@@ -129,7 +123,7 @@ class Schema(BaseSchema):
|
|
129
123
|
entity_type = _get_entity_type(query, mutation, subscription, additional_types)
|
130
124
|
|
131
125
|
if entity_type:
|
132
|
-
self.entities_resolver.__annotations__["return"] =
|
126
|
+
self.entities_resolver.__annotations__["return"] = list[
|
133
127
|
Optional[entity_type] # type: ignore
|
134
128
|
]
|
135
129
|
|
@@ -156,8 +150,8 @@ class Schema(BaseSchema):
|
|
156
150
|
return query_type
|
157
151
|
|
158
152
|
def entities_resolver(
|
159
|
-
self, info: Info, representations:
|
160
|
-
) ->
|
153
|
+
self, info: Info, representations: list[FederationAny]
|
154
|
+
) -> list[FederationAny]:
|
161
155
|
results = []
|
162
156
|
|
163
157
|
for representation in representations:
|
@@ -212,10 +206,10 @@ class Schema(BaseSchema):
|
|
212
206
|
directive.resolvable = UNSET
|
213
207
|
|
214
208
|
@cached_property
|
215
|
-
def schema_directives_in_use(self) ->
|
209
|
+
def schema_directives_in_use(self) -> list[object]:
|
216
210
|
all_graphql_types = self._schema.type_map.values()
|
217
211
|
|
218
|
-
directives:
|
212
|
+
directives: list[object] = []
|
219
213
|
|
220
214
|
for type_ in all_graphql_types:
|
221
215
|
strawberry_definition = type_.extensions.get("strawberry-definition")
|
@@ -236,7 +230,7 @@ class Schema(BaseSchema):
|
|
236
230
|
def _add_link_for_composed_directive(
|
237
231
|
self,
|
238
232
|
directive: "StrawberrySchemaDirective",
|
239
|
-
directive_by_url: Mapping[str,
|
233
|
+
directive_by_url: Mapping[str, set[str]],
|
240
234
|
) -> None:
|
241
235
|
if not isinstance(directive, StrawberryFederationSchemaDirective):
|
242
236
|
return
|
@@ -256,11 +250,11 @@ class Schema(BaseSchema):
|
|
256
250
|
directive_by_url[import_url].add(f"@{name}")
|
257
251
|
|
258
252
|
def _add_link_directives(
|
259
|
-
self, additional_directives: Optional[
|
253
|
+
self, additional_directives: Optional[list[object]] = None
|
260
254
|
) -> None:
|
261
255
|
from .schema_directives import FederationDirective, Link
|
262
256
|
|
263
|
-
directive_by_url:
|
257
|
+
directive_by_url: defaultdict[str, set[str]] = defaultdict(set)
|
264
258
|
|
265
259
|
additional_directives = additional_directives or []
|
266
260
|
|
@@ -274,7 +268,7 @@ class Schema(BaseSchema):
|
|
274
268
|
f"@{directive.imported_from.name}"
|
275
269
|
)
|
276
270
|
|
277
|
-
link_directives:
|
271
|
+
link_directives: list[object] = [
|
278
272
|
Link(
|
279
273
|
url=url,
|
280
274
|
import_=list(sorted(directives)),
|
@@ -284,10 +278,10 @@ class Schema(BaseSchema):
|
|
284
278
|
|
285
279
|
self.schema_directives = self.schema_directives + link_directives
|
286
280
|
|
287
|
-
def _add_compose_directives(self) ->
|
281
|
+
def _add_compose_directives(self) -> list["ComposeDirective"]:
|
288
282
|
from .schema_directives import ComposeDirective
|
289
283
|
|
290
|
-
compose_directives:
|
284
|
+
compose_directives: list[ComposeDirective] = []
|
291
285
|
|
292
286
|
for directive in self.schema_directives_in_use:
|
293
287
|
definition = directive.__strawberry_directive__ # type: ignore
|
@@ -318,10 +312,10 @@ class Schema(BaseSchema):
|
|
318
312
|
|
319
313
|
|
320
314
|
def _get_entity_type(
|
321
|
-
query: Optional[
|
322
|
-
mutation: Optional[
|
323
|
-
subscription: Optional[
|
324
|
-
additional_types: Iterable[
|
315
|
+
query: Optional[type[WithStrawberryObjectDefinition]],
|
316
|
+
mutation: Optional[type[WithStrawberryObjectDefinition]],
|
317
|
+
subscription: Optional[type[WithStrawberryObjectDefinition]],
|
318
|
+
additional_types: Iterable[type[WithStrawberryObjectDefinition]],
|
325
319
|
) -> Optional[StrawberryUnion]:
|
326
320
|
# recursively iterate over the schema to find all types annotated with @key
|
327
321
|
# if no types are annotated with @key, then the _Entity union and Query._entities
|
@@ -330,7 +324,7 @@ def _get_entity_type(
|
|
330
324
|
entity_types = set()
|
331
325
|
|
332
326
|
# need a stack to keep track of the types we need to visit
|
333
|
-
stack:
|
327
|
+
stack: list[Any] = [query, mutation, subscription, *additional_types]
|
334
328
|
|
335
329
|
seen = set()
|
336
330
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import dataclasses
|
2
|
-
from typing import Callable,
|
2
|
+
from typing import Callable, Optional, TypeVar
|
3
3
|
from typing_extensions import dataclass_transform
|
4
4
|
|
5
5
|
from strawberry.directive import directive_field
|
@@ -19,7 +19,7 @@ class StrawberryFederationSchemaDirective(StrawberrySchemaDirective):
|
|
19
19
|
compose_options: Optional[ComposeOptions] = None
|
20
20
|
|
21
21
|
|
22
|
-
T = TypeVar("T", bound=
|
22
|
+
T = TypeVar("T", bound=type)
|
23
23
|
|
24
24
|
|
25
25
|
@dataclass_transform(
|
@@ -29,19 +29,19 @@ T = TypeVar("T", bound=Type)
|
|
29
29
|
)
|
30
30
|
def schema_directive(
|
31
31
|
*,
|
32
|
-
locations:
|
32
|
+
locations: list[Location],
|
33
33
|
description: Optional[str] = None,
|
34
34
|
name: Optional[str] = None,
|
35
35
|
repeatable: bool = False,
|
36
36
|
print_definition: bool = True,
|
37
37
|
compose: bool = False,
|
38
38
|
import_url: Optional[str] = None,
|
39
|
-
) -> Callable[
|
39
|
+
) -> Callable[[T], T]:
|
40
40
|
def _wrap(cls: T) -> T:
|
41
41
|
cls = _wrap_dataclass(cls) # type: ignore
|
42
42
|
fields = _get_fields(cls, {})
|
43
43
|
|
44
|
-
cls.__strawberry_directive__ = StrawberryFederationSchemaDirective(
|
44
|
+
cls.__strawberry_directive__ = StrawberryFederationSchemaDirective( # type: ignore[attr-defined]
|
45
45
|
python_name=cls.__name__,
|
46
46
|
graphql_name=name,
|
47
47
|
locations=locations,
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from dataclasses import dataclass
|
2
|
-
from typing import ClassVar,
|
2
|
+
from typing import ClassVar, Optional
|
3
3
|
|
4
4
|
from strawberry import directive_field
|
5
5
|
from strawberry.schema_directive import Location, schema_directive
|
@@ -84,14 +84,14 @@ class Link:
|
|
84
84
|
url: Optional[str]
|
85
85
|
as_: Optional[str] = directive_field(name="as")
|
86
86
|
for_: Optional[LinkPurpose] = directive_field(name="for")
|
87
|
-
import_: Optional[
|
87
|
+
import_: Optional[list[Optional[LinkImport]]] = directive_field(name="import")
|
88
88
|
|
89
89
|
def __init__(
|
90
90
|
self,
|
91
91
|
url: Optional[str] = UNSET,
|
92
92
|
as_: Optional[str] = UNSET,
|
93
93
|
for_: Optional[LinkPurpose] = UNSET,
|
94
|
-
import_: Optional[
|
94
|
+
import_: Optional[list[Optional[LinkImport]]] = UNSET,
|
95
95
|
) -> None:
|
96
96
|
self.url = url
|
97
97
|
self.as_ = as_
|
@@ -204,7 +204,7 @@ class Authenticated(FederationDirective):
|
|
204
204
|
print_definition=False,
|
205
205
|
)
|
206
206
|
class RequiresScopes(FederationDirective):
|
207
|
-
scopes: "
|
207
|
+
scopes: "list[list[str]]"
|
208
208
|
imported_from: ClassVar[ImportedFrom] = ImportedFrom(
|
209
209
|
name="requiresScopes", url="https://specs.apollo.dev/federation/v2.7"
|
210
210
|
)
|
@@ -222,25 +222,25 @@ class RequiresScopes(FederationDirective):
|
|
222
222
|
print_definition=False,
|
223
223
|
)
|
224
224
|
class Policy(FederationDirective):
|
225
|
-
policies: "
|
225
|
+
policies: "list[list[str]]"
|
226
226
|
imported_from: ClassVar[ImportedFrom] = ImportedFrom(
|
227
227
|
name="policy", url="https://specs.apollo.dev/federation/v2.7"
|
228
228
|
)
|
229
229
|
|
230
230
|
|
231
231
|
__all__ = [
|
232
|
+
"Authenticated",
|
233
|
+
"ComposeDirective",
|
232
234
|
"External",
|
233
|
-
"
|
234
|
-
"
|
235
|
+
"Inaccessible",
|
236
|
+
"InterfaceObject",
|
235
237
|
"Key",
|
236
|
-
"Shareable",
|
237
238
|
"Link",
|
238
|
-
"Tag",
|
239
239
|
"Override",
|
240
|
-
"Inaccessible",
|
241
|
-
"ComposeDirective",
|
242
|
-
"InterfaceObject",
|
243
|
-
"Authenticated",
|
244
|
-
"RequiresScopes",
|
245
240
|
"Policy",
|
241
|
+
"Provides",
|
242
|
+
"Requires",
|
243
|
+
"RequiresScopes",
|
244
|
+
"Shareable",
|
245
|
+
"Tag",
|
246
246
|
]
|
strawberry/federation/union.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
from
|
1
|
+
from collections.abc import Collection, Iterable
|
2
|
+
from typing import Any, Optional
|
2
3
|
|
3
4
|
from strawberry.types.union import StrawberryUnion
|
4
5
|
from strawberry.types.union import union as base_union
|
@@ -6,7 +7,7 @@ from strawberry.types.union import union as base_union
|
|
6
7
|
|
7
8
|
def union(
|
8
9
|
name: str,
|
9
|
-
types: Optional[Collection[
|
10
|
+
types: Optional[Collection[type[Any]]] = None,
|
10
11
|
*,
|
11
12
|
description: Optional[str] = None,
|
12
13
|
directives: Iterable[object] = (),
|
@@ -3,7 +3,6 @@ from __future__ import annotations
|
|
3
3
|
from typing import (
|
4
4
|
TYPE_CHECKING,
|
5
5
|
Any,
|
6
|
-
Dict,
|
7
6
|
)
|
8
7
|
|
9
8
|
import strawberry
|
@@ -27,7 +26,7 @@ class InputMutationExtension(FieldExtension):
|
|
27
26
|
assert resolver
|
28
27
|
|
29
28
|
name = field.graphql_name or to_camel_case(resolver.name)
|
30
|
-
type_dict:
|
29
|
+
type_dict: dict[str, Any] = {
|
31
30
|
"__doc__": f"Input data for `{name}` mutation",
|
32
31
|
"__annotations__": {},
|
33
32
|
}
|
strawberry/file_uploads/utils.py
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
import copy
|
2
|
-
from
|
2
|
+
from collections.abc import Mapping
|
3
|
+
from typing import Any
|
3
4
|
|
4
5
|
|
5
6
|
def replace_placeholders_with_files(
|
6
|
-
operations_with_placeholders:
|
7
|
+
operations_with_placeholders: dict[str, Any],
|
7
8
|
files_map: Mapping[str, Any],
|
8
9
|
files: Mapping[str, Any],
|
9
|
-
) ->
|
10
|
+
) -> dict[str, Any]:
|
10
11
|
# TODO: test this with missing variables in operations_with_placeholders
|
11
12
|
operations = copy.deepcopy(operations_with_placeholders)
|
12
13
|
|
strawberry/flask/views.py
CHANGED
@@ -4,7 +4,6 @@ import warnings
|
|
4
4
|
from typing import (
|
5
5
|
TYPE_CHECKING,
|
6
6
|
Any,
|
7
|
-
Mapping,
|
8
7
|
Optional,
|
9
8
|
Union,
|
10
9
|
cast,
|
@@ -23,6 +22,8 @@ from strawberry.http.types import FormData, HTTPMethod, QueryParams
|
|
23
22
|
from strawberry.http.typevars import Context, RootValue
|
24
23
|
|
25
24
|
if TYPE_CHECKING:
|
25
|
+
from collections.abc import Mapping
|
26
|
+
|
26
27
|
from flask.typing import ResponseReturnValue
|
27
28
|
from strawberry.http import GraphQLHTTPResponse
|
28
29
|
from strawberry.http.ides import GraphQL_IDE
|
@@ -203,6 +204,6 @@ class AsyncGraphQLView(
|
|
203
204
|
|
204
205
|
|
205
206
|
__all__ = [
|
206
|
-
"GraphQLView",
|
207
207
|
"AsyncGraphQLView",
|
208
|
+
"GraphQLView",
|
208
209
|
]
|
strawberry/http/__init__.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
from dataclasses import dataclass
|
4
|
-
from typing import TYPE_CHECKING, Any,
|
4
|
+
from typing import TYPE_CHECKING, Any, Optional
|
5
5
|
from typing_extensions import Literal, TypedDict
|
6
6
|
|
7
7
|
if TYPE_CHECKING:
|
@@ -9,9 +9,9 @@ if TYPE_CHECKING:
|
|
9
9
|
|
10
10
|
|
11
11
|
class GraphQLHTTPResponse(TypedDict, total=False):
|
12
|
-
data: Optional[
|
13
|
-
errors: Optional[
|
14
|
-
extensions: Optional[
|
12
|
+
data: Optional[dict[str, object]]
|
13
|
+
errors: Optional[list[object]]
|
14
|
+
extensions: Optional[dict[str, object]]
|
15
15
|
|
16
16
|
|
17
17
|
def process_result(result: ExecutionResult) -> GraphQLHTTPResponse:
|
@@ -30,13 +30,13 @@ class GraphQLRequestData:
|
|
30
30
|
# query is optional here as it can be added by an extensions
|
31
31
|
# (for example an extension for persisted queries)
|
32
32
|
query: Optional[str]
|
33
|
-
variables: Optional[
|
33
|
+
variables: Optional[dict[str, Any]]
|
34
34
|
operation_name: Optional[str]
|
35
35
|
protocol: Literal["http", "multipart-subscription"] = "http"
|
36
36
|
|
37
37
|
|
38
38
|
__all__ = [
|
39
39
|
"GraphQLHTTPResponse",
|
40
|
-
"process_result",
|
41
40
|
"GraphQLRequestData",
|
41
|
+
"process_result",
|
42
42
|
]
|
@@ -2,18 +2,13 @@ import abc
|
|
2
2
|
import asyncio
|
3
3
|
import contextlib
|
4
4
|
import json
|
5
|
+
from collections.abc import AsyncGenerator, Mapping
|
5
6
|
from datetime import timedelta
|
6
7
|
from typing import (
|
7
8
|
Any,
|
8
|
-
AsyncGenerator,
|
9
9
|
Callable,
|
10
|
-
Dict,
|
11
10
|
Generic,
|
12
|
-
List,
|
13
|
-
Mapping,
|
14
11
|
Optional,
|
15
|
-
Tuple,
|
16
|
-
Type,
|
17
12
|
Union,
|
18
13
|
cast,
|
19
14
|
overload,
|
@@ -124,10 +119,10 @@ class AsyncBaseHTTPView(
|
|
124
119
|
],
|
125
120
|
AsyncWebSocketAdapter,
|
126
121
|
]
|
127
|
-
graphql_transport_ws_handler_class:
|
122
|
+
graphql_transport_ws_handler_class: type[
|
128
123
|
BaseGraphQLTransportWSHandler[Context, RootValue]
|
129
124
|
] = BaseGraphQLTransportWSHandler[Context, RootValue]
|
130
|
-
graphql_ws_handler_class:
|
125
|
+
graphql_ws_handler_class: type[BaseGraphQLWSHandler[Context, RootValue]] = (
|
131
126
|
BaseGraphQLWSHandler[Context, RootValue]
|
132
127
|
)
|
133
128
|
|
@@ -163,7 +158,7 @@ class AsyncBaseHTTPView(
|
|
163
158
|
request: Request,
|
164
159
|
stream: Callable[[], AsyncGenerator[str, None]],
|
165
160
|
sub_response: SubResponse,
|
166
|
-
headers:
|
161
|
+
headers: dict[str, str],
|
167
162
|
) -> Response:
|
168
163
|
raise ValueError("Multipart responses are not supported")
|
169
164
|
|
@@ -220,7 +215,7 @@ class AsyncBaseHTTPView(
|
|
220
215
|
allowed_operation_types=allowed_operation_types,
|
221
216
|
)
|
222
217
|
|
223
|
-
async def parse_multipart(self, request: AsyncHTTPRequestAdapter) ->
|
218
|
+
async def parse_multipart(self, request: AsyncHTTPRequestAdapter) -> dict[str, str]:
|
224
219
|
try:
|
225
220
|
form_data = await request.get_form_data()
|
226
221
|
except ValueError as e:
|
@@ -243,7 +238,7 @@ class AsyncBaseHTTPView(
|
|
243
238
|
raise HTTPException(400, "File(s) missing in form data") from e
|
244
239
|
|
245
240
|
def _handle_errors(
|
246
|
-
self, errors:
|
241
|
+
self, errors: list[GraphQLError], response_data: GraphQLHTTPResponse
|
247
242
|
) -> None:
|
248
243
|
"""Hook to allow custom handling of errors, used by the Sentry Integration."""
|
249
244
|
|
@@ -380,7 +375,7 @@ class AsyncBaseHTTPView(
|
|
380
375
|
self, stream: Callable[[], AsyncGenerator[str, None]]
|
381
376
|
) -> Callable[[], AsyncGenerator[str, None]]:
|
382
377
|
"""Adds a heartbeat to the stream, to prevent the connection from closing when there are no messages being sent."""
|
383
|
-
queue: asyncio.Queue[
|
378
|
+
queue: asyncio.Queue[tuple[bool, Any]] = asyncio.Queue(1)
|
384
379
|
|
385
380
|
cancelling = False
|
386
381
|
|
@@ -448,7 +443,7 @@ class AsyncBaseHTTPView(
|
|
448
443
|
|
449
444
|
async def parse_multipart_subscriptions(
|
450
445
|
self, request: AsyncHTTPRequestAdapter
|
451
|
-
) ->
|
446
|
+
) -> dict[str, str]:
|
452
447
|
if request.method == "GET":
|
453
448
|
return self.parse_query_params(request.query_params)
|
454
449
|
|
@@ -489,7 +484,7 @@ class AsyncBaseHTTPView(
|
|
489
484
|
|
490
485
|
async def on_ws_connect(
|
491
486
|
self, context: Context
|
492
|
-
) -> Union[UnsetType, None,
|
487
|
+
) -> Union[UnsetType, None, dict[str, object]]:
|
493
488
|
return UNSET
|
494
489
|
|
495
490
|
|
strawberry/http/base.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import json
|
2
|
-
from
|
2
|
+
from collections.abc import Mapping
|
3
|
+
from typing import Any, Generic, Optional, Union
|
3
4
|
from typing_extensions import Protocol
|
4
5
|
|
5
6
|
from strawberry.http.ides import GraphQL_IDE, get_graphql_ide_html
|
@@ -11,7 +12,7 @@ from .typevars import Request
|
|
11
12
|
|
12
13
|
class BaseRequestProtocol(Protocol):
|
13
14
|
@property
|
14
|
-
def query_params(self) -> Mapping[str, Optional[Union[str,
|
15
|
+
def query_params(self) -> Mapping[str, Optional[Union[str, list[str]]]]: ...
|
15
16
|
|
16
17
|
@property
|
17
18
|
def method(self) -> HTTPMethod: ...
|
@@ -49,7 +50,7 @@ class BaseView(Generic[Request]):
|
|
49
50
|
def encode_json(self, data: object) -> str:
|
50
51
|
return json.dumps(data)
|
51
52
|
|
52
|
-
def parse_query_params(self, params: QueryParams) ->
|
53
|
+
def parse_query_params(self, params: QueryParams) -> dict[str, Any]:
|
53
54
|
params = dict(params)
|
54
55
|
|
55
56
|
if "variables" in params:
|
@@ -65,7 +66,7 @@ class BaseView(Generic[Request]):
|
|
65
66
|
return get_graphql_ide_html(graphql_ide=self.graphql_ide)
|
66
67
|
|
67
68
|
def _is_multipart_subscriptions(
|
68
|
-
self, content_type: str, params:
|
69
|
+
self, content_type: str, params: dict[str, str]
|
69
70
|
) -> bool:
|
70
71
|
if content_type != "multipart/mixed":
|
71
72
|
return False
|