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
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import abc
|
|
2
2
|
import json
|
|
3
|
+
from collections.abc import Callable
|
|
3
4
|
from typing import (
|
|
4
|
-
Callable,
|
|
5
5
|
Generic,
|
|
6
6
|
Literal,
|
|
7
|
-
Optional,
|
|
8
|
-
Union,
|
|
9
7
|
)
|
|
10
8
|
|
|
11
9
|
from graphql import GraphQLError
|
|
@@ -39,8 +37,8 @@ class SyncBaseHTTPView(
|
|
|
39
37
|
Generic[Request, Response, SubResponse, Context, RootValue],
|
|
40
38
|
):
|
|
41
39
|
schema: BaseSchema
|
|
42
|
-
graphiql:
|
|
43
|
-
graphql_ide:
|
|
40
|
+
graphiql: bool | None
|
|
41
|
+
graphql_ide: GraphQL_IDE | None
|
|
44
42
|
request_adapter_class: Callable[[Request], SyncHTTPRequestAdapter]
|
|
45
43
|
|
|
46
44
|
# Methods that need to be implemented by individual frameworks
|
|
@@ -56,12 +54,12 @@ class SyncBaseHTTPView(
|
|
|
56
54
|
def get_context(self, request: Request, response: SubResponse) -> Context: ...
|
|
57
55
|
|
|
58
56
|
@abc.abstractmethod
|
|
59
|
-
def get_root_value(self, request: Request) ->
|
|
57
|
+
def get_root_value(self, request: Request) -> RootValue | None: ...
|
|
60
58
|
|
|
61
59
|
@abc.abstractmethod
|
|
62
60
|
def create_response(
|
|
63
61
|
self,
|
|
64
|
-
response_data:
|
|
62
|
+
response_data: GraphQLHTTPResponse | list[GraphQLHTTPResponse],
|
|
65
63
|
sub_response: SubResponse,
|
|
66
64
|
) -> Response: ...
|
|
67
65
|
|
|
@@ -72,9 +70,9 @@ class SyncBaseHTTPView(
|
|
|
72
70
|
self,
|
|
73
71
|
request: Request,
|
|
74
72
|
context: Context,
|
|
75
|
-
root_value:
|
|
73
|
+
root_value: RootValue | None,
|
|
76
74
|
sub_response: SubResponse,
|
|
77
|
-
) ->
|
|
75
|
+
) -> ExecutionResult | list[ExecutionResult]:
|
|
78
76
|
request_adapter = self.request_adapter_class(request)
|
|
79
77
|
|
|
80
78
|
try:
|
|
@@ -119,7 +117,7 @@ class SyncBaseHTTPView(
|
|
|
119
117
|
request_adapter: SyncHTTPRequestAdapter,
|
|
120
118
|
sub_response: SubResponse,
|
|
121
119
|
context: Context,
|
|
122
|
-
root_value:
|
|
120
|
+
root_value: RootValue | None,
|
|
123
121
|
request_data: GraphQLRequestData,
|
|
124
122
|
) -> ExecutionResult:
|
|
125
123
|
allowed_operation_types = OperationType.from_http(request_adapter.method)
|
|
@@ -159,7 +157,7 @@ class SyncBaseHTTPView(
|
|
|
159
157
|
|
|
160
158
|
def parse_http_body(
|
|
161
159
|
self, request: SyncHTTPRequestAdapter
|
|
162
|
-
) ->
|
|
160
|
+
) -> GraphQLRequestData | list[GraphQLRequestData]:
|
|
163
161
|
headers = {key.lower(): value for key, value in request.headers.items()}
|
|
164
162
|
content_type, params = parse_content_type(request.content_type or "")
|
|
165
163
|
accept = headers.get("accept", "")
|
|
@@ -233,7 +231,7 @@ class SyncBaseHTTPView(
|
|
|
233
231
|
self,
|
|
234
232
|
request: Request,
|
|
235
233
|
context: Context = UNSET,
|
|
236
|
-
root_value:
|
|
234
|
+
root_value: RootValue | None = UNSET,
|
|
237
235
|
) -> Response:
|
|
238
236
|
request_adapter = self.request_adapter_class(request)
|
|
239
237
|
|
|
@@ -260,7 +258,7 @@ class SyncBaseHTTPView(
|
|
|
260
258
|
sub_response=sub_response,
|
|
261
259
|
)
|
|
262
260
|
|
|
263
|
-
response_data:
|
|
261
|
+
response_data: GraphQLHTTPResponse | list[GraphQLHTTPResponse]
|
|
264
262
|
|
|
265
263
|
if isinstance(result, list):
|
|
266
264
|
response_data = []
|
strawberry/http/types.py
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
from collections.abc import Mapping
|
|
2
|
-
from typing import Any,
|
|
3
|
-
from typing_extensions import
|
|
2
|
+
from typing import Any, Literal
|
|
3
|
+
from typing_extensions import TypedDict
|
|
4
4
|
|
|
5
5
|
HTTPMethod = Literal[
|
|
6
6
|
"GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS", "TRACE"
|
|
7
7
|
]
|
|
8
8
|
|
|
9
|
-
QueryParams = Mapping[str,
|
|
9
|
+
QueryParams = Mapping[str, str | None]
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class FormData(TypedDict):
|
|
@@ -8,17 +8,13 @@ from datetime import timedelta
|
|
|
8
8
|
from typing import (
|
|
9
9
|
TYPE_CHECKING,
|
|
10
10
|
Any,
|
|
11
|
-
Callable,
|
|
12
11
|
ClassVar,
|
|
13
|
-
|
|
12
|
+
TypeAlias,
|
|
14
13
|
TypedDict,
|
|
15
|
-
|
|
14
|
+
TypeGuard,
|
|
16
15
|
)
|
|
17
|
-
from typing_extensions import TypeGuard
|
|
18
16
|
|
|
19
17
|
from lia import HTTPException, LitestarRequestAdapter
|
|
20
|
-
from msgspec import Struct
|
|
21
|
-
|
|
22
18
|
from litestar import (
|
|
23
19
|
Controller,
|
|
24
20
|
MediaType,
|
|
@@ -38,6 +34,8 @@ from litestar.exceptions import (
|
|
|
38
34
|
)
|
|
39
35
|
from litestar.response.streaming import Stream
|
|
40
36
|
from litestar.status_codes import HTTP_200_OK
|
|
37
|
+
from msgspec import Struct
|
|
38
|
+
|
|
41
39
|
from strawberry.exceptions import InvalidCustomContext
|
|
42
40
|
from strawberry.http.async_base_view import (
|
|
43
41
|
AsyncBaseHTTPView,
|
|
@@ -52,18 +50,25 @@ from strawberry.http.typevars import Context, RootValue
|
|
|
52
50
|
from strawberry.subscriptions import GRAPHQL_TRANSPORT_WS_PROTOCOL, GRAPHQL_WS_PROTOCOL
|
|
53
51
|
|
|
54
52
|
if TYPE_CHECKING:
|
|
55
|
-
from collections.abc import
|
|
53
|
+
from collections.abc import (
|
|
54
|
+
AsyncGenerator,
|
|
55
|
+
AsyncIterator,
|
|
56
|
+
Callable,
|
|
57
|
+
Mapping,
|
|
58
|
+
Sequence,
|
|
59
|
+
)
|
|
56
60
|
|
|
57
61
|
from litestar.types import AnyCallable, Dependencies
|
|
62
|
+
|
|
58
63
|
from strawberry.http import GraphQLHTTPResponse
|
|
59
64
|
from strawberry.http.ides import GraphQL_IDE
|
|
60
65
|
from strawberry.schema import BaseSchema
|
|
61
66
|
|
|
62
67
|
|
|
63
68
|
class BaseContext(Struct, kw_only=True):
|
|
64
|
-
request:
|
|
65
|
-
websocket:
|
|
66
|
-
response:
|
|
69
|
+
request: Request | None = None
|
|
70
|
+
websocket: WebSocket | None = None
|
|
71
|
+
response: Response | None = None
|
|
67
72
|
|
|
68
73
|
|
|
69
74
|
class HTTPContextType:
|
|
@@ -88,9 +93,9 @@ class WebSocketContextDict(TypedDict):
|
|
|
88
93
|
socket: WebSocket
|
|
89
94
|
|
|
90
95
|
|
|
91
|
-
MergedContext =
|
|
92
|
-
BaseContext
|
|
93
|
-
|
|
96
|
+
MergedContext: TypeAlias = (
|
|
97
|
+
BaseContext | WebSocketContextDict | HTTPContextDict | dict[str, Any]
|
|
98
|
+
)
|
|
94
99
|
|
|
95
100
|
|
|
96
101
|
async def _none_custom_context_getter() -> None:
|
|
@@ -102,7 +107,7 @@ async def _none_root_value_getter() -> None:
|
|
|
102
107
|
|
|
103
108
|
|
|
104
109
|
async def _context_getter_ws(
|
|
105
|
-
custom_context:
|
|
110
|
+
custom_context: Any | None, socket: WebSocket
|
|
106
111
|
) -> MergedContext:
|
|
107
112
|
if isinstance(custom_context, BaseContext):
|
|
108
113
|
custom_context.websocket = socket
|
|
@@ -124,7 +129,7 @@ def _response_getter() -> Response:
|
|
|
124
129
|
|
|
125
130
|
|
|
126
131
|
async def _context_getter_http(
|
|
127
|
-
custom_context:
|
|
132
|
+
custom_context: Any | None,
|
|
128
133
|
response: Response,
|
|
129
134
|
request: Request[Any, Any, Any],
|
|
130
135
|
) -> MergedContext:
|
|
@@ -145,9 +150,9 @@ async def _context_getter_http(
|
|
|
145
150
|
|
|
146
151
|
|
|
147
152
|
class GraphQLResource(Struct):
|
|
148
|
-
data:
|
|
149
|
-
errors:
|
|
150
|
-
extensions:
|
|
153
|
+
data: dict[str, object] | None
|
|
154
|
+
errors: list[object] | None
|
|
155
|
+
extensions: dict[str, object] | None
|
|
151
156
|
|
|
152
157
|
|
|
153
158
|
class LitestarWebSocketAdapter(AsyncWebSocketAdapter):
|
|
@@ -208,11 +213,11 @@ class GraphQLController(
|
|
|
208
213
|
}
|
|
209
214
|
|
|
210
215
|
request_adapter_class = LitestarRequestAdapter
|
|
211
|
-
websocket_adapter_class = LitestarWebSocketAdapter
|
|
216
|
+
websocket_adapter_class = LitestarWebSocketAdapter # type: ignore
|
|
212
217
|
|
|
213
218
|
allow_queries_via_get: bool = True
|
|
214
219
|
graphiql_allowed_accept: frozenset[str] = frozenset({"text/html", "*/*"})
|
|
215
|
-
graphql_ide:
|
|
220
|
+
graphql_ide: GraphQL_IDE | None = "graphiql"
|
|
216
221
|
connection_init_wait_timeout: timedelta = timedelta(minutes=1)
|
|
217
222
|
protocols: Sequence[str] = (
|
|
218
223
|
GRAPHQL_TRANSPORT_WS_PROTOCOL,
|
|
@@ -222,18 +227,18 @@ class GraphQLController(
|
|
|
222
227
|
keep_alive_interval: float = 1
|
|
223
228
|
|
|
224
229
|
def is_websocket_request(
|
|
225
|
-
self, request:
|
|
230
|
+
self, request: Request | WebSocket
|
|
226
231
|
) -> TypeGuard[WebSocket]:
|
|
227
232
|
return isinstance(request, WebSocket)
|
|
228
233
|
|
|
229
|
-
async def pick_websocket_subprotocol(self, request: WebSocket) ->
|
|
234
|
+
async def pick_websocket_subprotocol(self, request: WebSocket) -> str | None:
|
|
230
235
|
subprotocols = request.scope["subprotocols"]
|
|
231
236
|
intersection = set(subprotocols) & set(self.protocols)
|
|
232
237
|
sorted_intersection = sorted(intersection, key=subprotocols.index)
|
|
233
238
|
return next(iter(sorted_intersection), None)
|
|
234
239
|
|
|
235
240
|
async def create_websocket_response(
|
|
236
|
-
self, request: WebSocket, subprotocol:
|
|
241
|
+
self, request: WebSocket, subprotocol: str | None
|
|
237
242
|
) -> WebSocket:
|
|
238
243
|
await request.accept(subprotocols=subprotocol)
|
|
239
244
|
return request
|
|
@@ -243,7 +248,7 @@ class GraphQLController(
|
|
|
243
248
|
request: Request[Any, Any, Any],
|
|
244
249
|
context: Any,
|
|
245
250
|
root_value: Any,
|
|
246
|
-
) -> Response[
|
|
251
|
+
) -> Response[GraphQLResource | str]:
|
|
247
252
|
try:
|
|
248
253
|
return await self.run(
|
|
249
254
|
request,
|
|
@@ -264,7 +269,7 @@ class GraphQLController(
|
|
|
264
269
|
|
|
265
270
|
def create_response(
|
|
266
271
|
self,
|
|
267
|
-
response_data:
|
|
272
|
+
response_data: GraphQLHTTPResponse | list[GraphQLHTTPResponse],
|
|
268
273
|
sub_response: Response[bytes],
|
|
269
274
|
) -> Response[bytes]:
|
|
270
275
|
response = Response(
|
|
@@ -305,7 +310,7 @@ class GraphQLController(
|
|
|
305
310
|
context: Any,
|
|
306
311
|
root_value: Any,
|
|
307
312
|
response: Response,
|
|
308
|
-
) -> Response[
|
|
313
|
+
) -> Response[GraphQLResource | str]:
|
|
309
314
|
self.temporal_response = response
|
|
310
315
|
|
|
311
316
|
return await self.execute_request(
|
|
@@ -321,7 +326,7 @@ class GraphQLController(
|
|
|
321
326
|
context: Any,
|
|
322
327
|
root_value: Any,
|
|
323
328
|
response: Response,
|
|
324
|
-
) -> Response[
|
|
329
|
+
) -> Response[GraphQLResource | str]:
|
|
325
330
|
self.temporal_response = response
|
|
326
331
|
|
|
327
332
|
return await self.execute_request(
|
|
@@ -345,14 +350,14 @@ class GraphQLController(
|
|
|
345
350
|
|
|
346
351
|
async def get_context(
|
|
347
352
|
self,
|
|
348
|
-
request:
|
|
349
|
-
response:
|
|
353
|
+
request: Request[Any, Any, Any] | WebSocket,
|
|
354
|
+
response: Response | WebSocket,
|
|
350
355
|
) -> Context: # pragma: no cover
|
|
351
356
|
msg = "`get_context` is not used by Litestar's controller"
|
|
352
357
|
raise ValueError(msg)
|
|
353
358
|
|
|
354
359
|
async def get_root_value(
|
|
355
|
-
self, request:
|
|
360
|
+
self, request: Request[Any, Any, Any] | WebSocket
|
|
356
361
|
) -> RootValue | None: # pragma: no cover
|
|
357
362
|
msg = "`get_root_value` is not used by Litestar's controller"
|
|
358
363
|
raise ValueError(msg)
|
|
@@ -364,15 +369,15 @@ class GraphQLController(
|
|
|
364
369
|
def make_graphql_controller(
|
|
365
370
|
schema: BaseSchema,
|
|
366
371
|
path: str = "",
|
|
367
|
-
graphiql:
|
|
368
|
-
graphql_ide:
|
|
372
|
+
graphiql: bool | None = None,
|
|
373
|
+
graphql_ide: GraphQL_IDE | None = "graphiql",
|
|
369
374
|
allow_queries_via_get: bool = True,
|
|
370
375
|
keep_alive: bool = False,
|
|
371
376
|
keep_alive_interval: float = 1,
|
|
372
377
|
# TODO: root typevar
|
|
373
|
-
root_value_getter:
|
|
378
|
+
root_value_getter: AnyCallable | None = None,
|
|
374
379
|
# TODO: context typevar
|
|
375
|
-
context_getter:
|
|
380
|
+
context_getter: AnyCallable | None = None,
|
|
376
381
|
subscription_protocols: Sequence[str] = (
|
|
377
382
|
GRAPHQL_TRANSPORT_WS_PROTOCOL,
|
|
378
383
|
GRAPHQL_WS_PROTOCOL,
|
|
@@ -392,7 +397,7 @@ def make_graphql_controller(
|
|
|
392
397
|
|
|
393
398
|
schema_: BaseSchema = schema
|
|
394
399
|
allow_queries_via_get_: bool = allow_queries_via_get
|
|
395
|
-
graphql_ide_:
|
|
400
|
+
graphql_ide_: GraphQL_IDE | None
|
|
396
401
|
|
|
397
402
|
if graphiql is not None:
|
|
398
403
|
warnings.warn(
|
strawberry/permission.py
CHANGED
|
@@ -7,8 +7,6 @@ from inspect import iscoroutinefunction
|
|
|
7
7
|
from typing import (
|
|
8
8
|
TYPE_CHECKING,
|
|
9
9
|
Any,
|
|
10
|
-
Optional,
|
|
11
|
-
Union,
|
|
12
10
|
)
|
|
13
11
|
|
|
14
12
|
from strawberry.exceptions import StrawberryGraphQLError
|
|
@@ -50,18 +48,18 @@ class BasePermission(abc.ABC):
|
|
|
50
48
|
```
|
|
51
49
|
"""
|
|
52
50
|
|
|
53
|
-
message:
|
|
51
|
+
message: str | None = None
|
|
54
52
|
|
|
55
|
-
error_extensions:
|
|
53
|
+
error_extensions: GraphQLErrorExtensions | None = None
|
|
56
54
|
|
|
57
55
|
error_class: type[GraphQLError] = StrawberryGraphQLError
|
|
58
56
|
|
|
59
|
-
_schema_directive:
|
|
57
|
+
_schema_directive: object | None = None
|
|
60
58
|
|
|
61
59
|
@abc.abstractmethod
|
|
62
60
|
def has_permission(
|
|
63
61
|
self, source: Any, info: Info, **kwargs: Any
|
|
64
|
-
) ->
|
|
62
|
+
) -> bool | Awaitable[bool]:
|
|
65
63
|
"""Check if the permission should be accepted.
|
|
66
64
|
|
|
67
65
|
This method should be overridden by the subclasses.
|
|
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
import re
|
|
4
4
|
from collections.abc import Mapping
|
|
5
5
|
from math import isfinite
|
|
6
|
-
from typing import TYPE_CHECKING, Any,
|
|
6
|
+
from typing import TYPE_CHECKING, Any, cast
|
|
7
7
|
|
|
8
8
|
from graphql.language import (
|
|
9
9
|
BooleanValueNode,
|
|
@@ -44,9 +44,7 @@ __all__ = ["ast_from_value"]
|
|
|
44
44
|
_re_integer_string = re.compile("^-?(?:0|[1-9][0-9]*)$")
|
|
45
45
|
|
|
46
46
|
|
|
47
|
-
def ast_from_leaf_type(
|
|
48
|
-
serialized: object, type_: Optional[GraphQLInputType]
|
|
49
|
-
) -> ValueNode:
|
|
47
|
+
def ast_from_leaf_type(serialized: object, type_: GraphQLInputType | None) -> ValueNode:
|
|
50
48
|
# Others serialize based on their corresponding Python scalar types.
|
|
51
49
|
if isinstance(serialized, bool):
|
|
52
50
|
return BooleanValueNode(value=serialized)
|
|
@@ -86,7 +84,7 @@ def ast_from_leaf_type(
|
|
|
86
84
|
) # pragma: no cover
|
|
87
85
|
|
|
88
86
|
|
|
89
|
-
def ast_from_value(value: Any, type_: GraphQLInputType) ->
|
|
87
|
+
def ast_from_value(value: Any, type_: GraphQLInputType) -> ValueNode | None:
|
|
90
88
|
# custom ast_from_value that allows to also serialize custom scalar that aren't
|
|
91
89
|
# basic types, namely JSON scalar types
|
|
92
90
|
|
strawberry/printer/printer.py
CHANGED
|
@@ -5,10 +5,7 @@ from itertools import chain
|
|
|
5
5
|
from typing import (
|
|
6
6
|
TYPE_CHECKING,
|
|
7
7
|
Any,
|
|
8
|
-
Callable,
|
|
9
|
-
Optional,
|
|
10
8
|
TypeVar,
|
|
11
|
-
Union,
|
|
12
9
|
cast,
|
|
13
10
|
overload,
|
|
14
11
|
)
|
|
@@ -46,6 +43,8 @@ from strawberry.types.unset import UNSET
|
|
|
46
43
|
from .ast_from_value import ast_from_value
|
|
47
44
|
|
|
48
45
|
if TYPE_CHECKING:
|
|
46
|
+
from collections.abc import Callable
|
|
47
|
+
|
|
49
48
|
from graphql import (
|
|
50
49
|
GraphQLArgument,
|
|
51
50
|
GraphQLEnumType,
|
|
@@ -78,7 +77,7 @@ def _serialize_dataclasses(
|
|
|
78
77
|
|
|
79
78
|
@overload
|
|
80
79
|
def _serialize_dataclasses(
|
|
81
|
-
value:
|
|
80
|
+
value: list[object] | tuple[object],
|
|
82
81
|
*,
|
|
83
82
|
name_converter: Callable[[str], str] | None = None,
|
|
84
83
|
) -> list[object]: ...
|
|
@@ -190,7 +189,7 @@ def print_schema_directive(
|
|
|
190
189
|
|
|
191
190
|
|
|
192
191
|
def print_field_directives(
|
|
193
|
-
field:
|
|
192
|
+
field: StrawberryField | None, schema: BaseSchema, *, extras: PrintExtras
|
|
194
193
|
) -> str:
|
|
195
194
|
if not field:
|
|
196
195
|
return ""
|
|
@@ -363,7 +362,7 @@ def print_extends(type_: GraphQLObjectType, schema: BaseSchema) -> str:
|
|
|
363
362
|
from strawberry.schema.schema_converter import GraphQLCoreConverter
|
|
364
363
|
|
|
365
364
|
strawberry_type = cast(
|
|
366
|
-
"
|
|
365
|
+
"StrawberryObjectDefinition | None",
|
|
367
366
|
type_.extensions
|
|
368
367
|
and type_.extensions.get(GraphQLCoreConverter.DEFINITION_BACKREF),
|
|
369
368
|
)
|
|
@@ -380,7 +379,7 @@ def print_type_directives(
|
|
|
380
379
|
from strawberry.schema.schema_converter import GraphQLCoreConverter
|
|
381
380
|
|
|
382
381
|
strawberry_type = cast(
|
|
383
|
-
"
|
|
382
|
+
"StrawberryObjectDefinition | None",
|
|
384
383
|
type_.extensions
|
|
385
384
|
and type_.extensions.get(GraphQLCoreConverter.DEFINITION_BACKREF),
|
|
386
385
|
)
|
|
@@ -534,9 +533,7 @@ def _all_root_names_are_common_names(schema: BaseSchema) -> bool:
|
|
|
534
533
|
)
|
|
535
534
|
|
|
536
535
|
|
|
537
|
-
def print_schema_definition(
|
|
538
|
-
schema: BaseSchema, *, extras: PrintExtras
|
|
539
|
-
) -> Optional[str]:
|
|
536
|
+
def print_schema_definition(schema: BaseSchema, *, extras: PrintExtras) -> str | None:
|
|
540
537
|
# TODO: add support for description
|
|
541
538
|
|
|
542
539
|
if _all_root_names_are_common_names(schema) and not schema.schema_directives:
|
|
@@ -558,9 +555,7 @@ def print_schema_definition(
|
|
|
558
555
|
return f"schema{directives} {{\n" + "\n".join(operation_types) + "\n}"
|
|
559
556
|
|
|
560
557
|
|
|
561
|
-
def print_directive(
|
|
562
|
-
directive: GraphQLDirective, *, schema: BaseSchema
|
|
563
|
-
) -> Optional[str]:
|
|
558
|
+
def print_directive(directive: GraphQLDirective, *, schema: BaseSchema) -> str | None:
|
|
564
559
|
strawberry_directive = directive.extensions.get("strawberry-definition")
|
|
565
560
|
|
|
566
561
|
if strawberry_directive is None or (
|
strawberry/quart/views.py
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import warnings
|
|
3
|
-
from collections.abc import AsyncGenerator, Mapping, Sequence
|
|
3
|
+
from collections.abc import AsyncGenerator, Callable, Mapping, Sequence
|
|
4
4
|
from datetime import timedelta
|
|
5
5
|
from json.decoder import JSONDecodeError
|
|
6
|
-
from typing import TYPE_CHECKING,
|
|
7
|
-
from typing_extensions import TypeGuard
|
|
6
|
+
from typing import TYPE_CHECKING, ClassVar, TypeGuard, Union
|
|
8
7
|
|
|
9
8
|
from lia import HTTPException, QuartHTTPRequestAdapter
|
|
10
|
-
|
|
11
9
|
from quart import Request, Response, Websocket, request, websocket
|
|
12
10
|
from quart.ctx import has_websocket_context
|
|
13
11
|
from quart.views import View
|
|
12
|
+
|
|
14
13
|
from strawberry.http.async_base_view import (
|
|
15
14
|
AsyncBaseHTTPView,
|
|
16
15
|
AsyncWebSocketAdapter,
|
|
@@ -26,6 +25,7 @@ from strawberry.subscriptions import GRAPHQL_TRANSPORT_WS_PROTOCOL, GRAPHQL_WS_P
|
|
|
26
25
|
|
|
27
26
|
if TYPE_CHECKING:
|
|
28
27
|
from quart.typing import ResponseReturnValue
|
|
28
|
+
|
|
29
29
|
from strawberry.http import GraphQLHTTPResponse
|
|
30
30
|
from strawberry.schema.base import BaseSchema
|
|
31
31
|
|
|
@@ -78,13 +78,13 @@ class GraphQLView(
|
|
|
78
78
|
methods: ClassVar[list[str]] = ["GET", "POST"]
|
|
79
79
|
allow_queries_via_get: bool = True
|
|
80
80
|
request_adapter_class = QuartHTTPRequestAdapter
|
|
81
|
-
websocket_adapter_class = QuartWebSocketAdapter
|
|
81
|
+
websocket_adapter_class = QuartWebSocketAdapter # type: ignore
|
|
82
82
|
|
|
83
83
|
def __init__(
|
|
84
84
|
self,
|
|
85
85
|
schema: "BaseSchema",
|
|
86
|
-
graphiql:
|
|
87
|
-
graphql_ide:
|
|
86
|
+
graphiql: bool | None = None,
|
|
87
|
+
graphql_ide: GraphQL_IDE | None = "graphiql",
|
|
88
88
|
allow_queries_via_get: bool = True,
|
|
89
89
|
keep_alive: bool = True,
|
|
90
90
|
keep_alive_interval: float = 1,
|
|
@@ -126,13 +126,11 @@ class GraphQLView(
|
|
|
126
126
|
return sub_response
|
|
127
127
|
|
|
128
128
|
async def get_context(
|
|
129
|
-
self, request:
|
|
129
|
+
self, request: Request | Websocket, response: Response
|
|
130
130
|
) -> Context:
|
|
131
131
|
return {"request": request, "response": response} # type: ignore
|
|
132
132
|
|
|
133
|
-
async def get_root_value(
|
|
134
|
-
self, request: Union[Request, Websocket]
|
|
135
|
-
) -> Optional[RootValue]:
|
|
133
|
+
async def get_root_value(self, request: Request | Websocket) -> RootValue | None:
|
|
136
134
|
return None
|
|
137
135
|
|
|
138
136
|
async def get_sub_response(self, request: Request) -> Response:
|
|
@@ -166,18 +164,18 @@ class GraphQLView(
|
|
|
166
164
|
)
|
|
167
165
|
|
|
168
166
|
def is_websocket_request(
|
|
169
|
-
self, request:
|
|
167
|
+
self, request: Request | Websocket
|
|
170
168
|
) -> TypeGuard[Websocket]:
|
|
171
169
|
return has_websocket_context()
|
|
172
170
|
|
|
173
|
-
async def pick_websocket_subprotocol(self, request: Websocket) ->
|
|
171
|
+
async def pick_websocket_subprotocol(self, request: Websocket) -> str | None:
|
|
174
172
|
protocols = request.requested_subprotocols
|
|
175
173
|
intersection = set(protocols) & set(self.subscription_protocols)
|
|
176
174
|
sorted_intersection = sorted(intersection, key=protocols.index)
|
|
177
175
|
return next(iter(sorted_intersection), None)
|
|
178
176
|
|
|
179
177
|
async def create_websocket_response(
|
|
180
|
-
self, request: Websocket, subprotocol:
|
|
178
|
+
self, request: Websocket, subprotocol: str | None
|
|
181
179
|
) -> Response:
|
|
182
180
|
await request.accept(subprotocol=subprotocol)
|
|
183
181
|
return Response()
|
strawberry/relay/exceptions.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from functools import cached_property
|
|
4
|
-
from typing import TYPE_CHECKING,
|
|
4
|
+
from typing import TYPE_CHECKING, cast
|
|
5
5
|
|
|
6
6
|
from strawberry.exceptions.exception import StrawberryException
|
|
7
7
|
from strawberry.exceptions.utils.source_finder import SourceFinder
|
|
@@ -32,7 +32,7 @@ class NodeIDAnnotationError(StrawberryException):
|
|
|
32
32
|
super().__init__(self.message)
|
|
33
33
|
|
|
34
34
|
@cached_property
|
|
35
|
-
def exception_source(self) ->
|
|
35
|
+
def exception_source(self) -> ExceptionSource | None:
|
|
36
36
|
if self.cls is None:
|
|
37
37
|
return None # pragma: no cover
|
|
38
38
|
|
|
@@ -63,7 +63,7 @@ class RelayWrongAnnotationError(StrawberryException):
|
|
|
63
63
|
super().__init__(self.message)
|
|
64
64
|
|
|
65
65
|
@cached_property
|
|
66
|
-
def exception_source(self) ->
|
|
66
|
+
def exception_source(self) -> ExceptionSource | None:
|
|
67
67
|
if self.cls is None:
|
|
68
68
|
return None # pragma: no cover
|
|
69
69
|
|
|
@@ -97,7 +97,7 @@ class RelayWrongResolverAnnotationError(StrawberryException):
|
|
|
97
97
|
super().__init__(self.message)
|
|
98
98
|
|
|
99
99
|
@cached_property
|
|
100
|
-
def exception_source(self) ->
|
|
100
|
+
def exception_source(self) -> ExceptionSource | None:
|
|
101
101
|
if self.function is None:
|
|
102
102
|
return None # pragma: no cover
|
|
103
103
|
|