strawberry-graphql 0.279.0.dev1754159379__py3-none-any.whl → 0.281.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of strawberry-graphql might be problematic. Click here for more details.
- strawberry/__init__.py +1 -2
- strawberry/aiohttp/views.py +2 -50
- strawberry/asgi/__init__.py +2 -39
- strawberry/chalice/views.py +7 -75
- strawberry/channels/handlers/http_handler.py +30 -6
- strawberry/channels/handlers/ws_handler.py +0 -2
- strawberry/cli/commands/server.py +1 -11
- strawberry/cli/commands/upgrade/__init__.py +2 -0
- strawberry/cli/constants.py +0 -1
- strawberry/cli/debug_server.py +2 -6
- strawberry/codemods/__init__.py +9 -0
- strawberry/codemods/maybe_optional.py +118 -0
- strawberry/django/views.py +4 -73
- strawberry/experimental/pydantic/_compat.py +1 -0
- strawberry/experimental/pydantic/error_type.py +1 -0
- strawberry/experimental/pydantic/fields.py +1 -0
- strawberry/experimental/pydantic/utils.py +1 -0
- strawberry/fastapi/router.py +8 -6
- strawberry/flask/views.py +4 -74
- strawberry/http/async_base_view.py +5 -34
- strawberry/http/base.py +2 -1
- strawberry/http/exceptions.py +5 -7
- strawberry/http/sync_base_view.py +1 -34
- strawberry/litestar/controller.py +1 -42
- strawberry/quart/views.py +3 -35
- strawberry/relay/utils.py +9 -21
- strawberry/sanic/views.py +4 -43
- strawberry/schema/schema.py +2 -0
- strawberry/schema/schema_converter.py +15 -38
- strawberry/schema/validation_rules/maybe_null.py +136 -0
- strawberry/subscriptions/protocols/graphql_transport_ws/handlers.py +0 -10
- strawberry/subscriptions/protocols/graphql_ws/handlers.py +0 -6
- strawberry/types/arguments.py +16 -2
- strawberry/types/maybe.py +1 -1
- {strawberry_graphql-0.279.0.dev1754159379.dist-info → strawberry_graphql-0.281.0.dist-info}/METADATA +2 -1
- {strawberry_graphql-0.279.0.dev1754159379.dist-info → strawberry_graphql-0.281.0.dist-info}/RECORD +39 -42
- strawberry/pydantic/__init__.py +0 -22
- strawberry/pydantic/error.py +0 -51
- strawberry/pydantic/fields.py +0 -202
- strawberry/pydantic/object_type.py +0 -348
- strawberry/utils/debug.py +0 -46
- {strawberry_graphql-0.279.0.dev1754159379.dist-info → strawberry_graphql-0.281.0.dist-info}/LICENSE +0 -0
- {strawberry_graphql-0.279.0.dev1754159379.dist-info → strawberry_graphql-0.281.0.dist-info}/WHEEL +0 -0
- {strawberry_graphql-0.279.0.dev1754159379.dist-info → strawberry_graphql-0.281.0.dist-info}/entry_points.txt +0 -0
strawberry/django/views.py
CHANGED
|
@@ -8,7 +8,6 @@ from typing import (
|
|
|
8
8
|
Callable,
|
|
9
9
|
Optional,
|
|
10
10
|
Union,
|
|
11
|
-
cast,
|
|
12
11
|
)
|
|
13
12
|
from typing_extensions import TypeGuard
|
|
14
13
|
|
|
@@ -26,11 +25,10 @@ from django.template.exceptions import TemplateDoesNotExist
|
|
|
26
25
|
from django.template.loader import render_to_string
|
|
27
26
|
from django.utils.decorators import classonlymethod
|
|
28
27
|
from django.views.generic import View
|
|
28
|
+
from lia import AsyncDjangoHTTPRequestAdapter, DjangoHTTPRequestAdapter, HTTPException
|
|
29
29
|
|
|
30
|
-
from strawberry.http.async_base_view import AsyncBaseHTTPView
|
|
31
|
-
from strawberry.http.
|
|
32
|
-
from strawberry.http.sync_base_view import SyncBaseHTTPView, SyncHTTPRequestAdapter
|
|
33
|
-
from strawberry.http.types import FormData, HTTPMethod, QueryParams
|
|
30
|
+
from strawberry.http.async_base_view import AsyncBaseHTTPView
|
|
31
|
+
from strawberry.http.sync_base_view import SyncBaseHTTPView
|
|
34
32
|
from strawberry.http.typevars import (
|
|
35
33
|
Context,
|
|
36
34
|
RootValue,
|
|
@@ -39,7 +37,7 @@ from strawberry.http.typevars import (
|
|
|
39
37
|
from .context import StrawberryDjangoContext
|
|
40
38
|
|
|
41
39
|
if TYPE_CHECKING:
|
|
42
|
-
from collections.abc import AsyncIterator
|
|
40
|
+
from collections.abc import AsyncIterator
|
|
43
41
|
|
|
44
42
|
from django.template.response import TemplateResponse
|
|
45
43
|
|
|
@@ -67,73 +65,6 @@ class TemporalHttpResponse(JsonResponse):
|
|
|
67
65
|
)
|
|
68
66
|
|
|
69
67
|
|
|
70
|
-
class DjangoHTTPRequestAdapter(SyncHTTPRequestAdapter):
|
|
71
|
-
def __init__(self, request: HttpRequest) -> None:
|
|
72
|
-
self.request = request
|
|
73
|
-
|
|
74
|
-
@property
|
|
75
|
-
def query_params(self) -> QueryParams:
|
|
76
|
-
return self.request.GET.dict()
|
|
77
|
-
|
|
78
|
-
@property
|
|
79
|
-
def body(self) -> Union[str, bytes]:
|
|
80
|
-
return self.request.body.decode()
|
|
81
|
-
|
|
82
|
-
@property
|
|
83
|
-
def method(self) -> HTTPMethod:
|
|
84
|
-
assert self.request.method is not None
|
|
85
|
-
|
|
86
|
-
return cast("HTTPMethod", self.request.method.upper())
|
|
87
|
-
|
|
88
|
-
@property
|
|
89
|
-
def headers(self) -> Mapping[str, str]:
|
|
90
|
-
return self.request.headers
|
|
91
|
-
|
|
92
|
-
@property
|
|
93
|
-
def post_data(self) -> Mapping[str, Union[str, bytes]]:
|
|
94
|
-
return self.request.POST
|
|
95
|
-
|
|
96
|
-
@property
|
|
97
|
-
def files(self) -> Mapping[str, Any]:
|
|
98
|
-
return self.request.FILES
|
|
99
|
-
|
|
100
|
-
@property
|
|
101
|
-
def content_type(self) -> Optional[str]:
|
|
102
|
-
return self.request.content_type
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
class AsyncDjangoHTTPRequestAdapter(AsyncHTTPRequestAdapter):
|
|
106
|
-
def __init__(self, request: HttpRequest) -> None:
|
|
107
|
-
self.request = request
|
|
108
|
-
|
|
109
|
-
@property
|
|
110
|
-
def query_params(self) -> QueryParams:
|
|
111
|
-
return self.request.GET.dict()
|
|
112
|
-
|
|
113
|
-
@property
|
|
114
|
-
def method(self) -> HTTPMethod:
|
|
115
|
-
assert self.request.method is not None
|
|
116
|
-
|
|
117
|
-
return cast("HTTPMethod", self.request.method.upper())
|
|
118
|
-
|
|
119
|
-
@property
|
|
120
|
-
def headers(self) -> Mapping[str, str]:
|
|
121
|
-
return self.request.headers
|
|
122
|
-
|
|
123
|
-
@property
|
|
124
|
-
def content_type(self) -> Optional[str]:
|
|
125
|
-
return self.headers.get("Content-type")
|
|
126
|
-
|
|
127
|
-
async def get_body(self) -> str:
|
|
128
|
-
return self.request.body.decode()
|
|
129
|
-
|
|
130
|
-
async def get_form_data(self) -> FormData:
|
|
131
|
-
return FormData(
|
|
132
|
-
files=self.request.FILES,
|
|
133
|
-
form=self.request.POST,
|
|
134
|
-
)
|
|
135
|
-
|
|
136
|
-
|
|
137
68
|
class BaseView:
|
|
138
69
|
graphql_ide_html: str
|
|
139
70
|
|
strawberry/fastapi/router.py
CHANGED
|
@@ -13,6 +13,7 @@ from typing import (
|
|
|
13
13
|
)
|
|
14
14
|
from typing_extensions import TypeGuard
|
|
15
15
|
|
|
16
|
+
from lia import HTTPException, StarletteRequestAdapter
|
|
16
17
|
from starlette import status
|
|
17
18
|
from starlette.background import BackgroundTasks # noqa: TC002
|
|
18
19
|
from starlette.requests import HTTPConnection, Request
|
|
@@ -29,16 +30,19 @@ from fastapi import APIRouter, Depends, params
|
|
|
29
30
|
from fastapi.datastructures import Default
|
|
30
31
|
from fastapi.routing import APIRoute
|
|
31
32
|
from fastapi.utils import generate_unique_id
|
|
32
|
-
from strawberry.asgi import
|
|
33
|
+
from strawberry.asgi import ASGIWebSocketAdapter
|
|
33
34
|
from strawberry.exceptions import InvalidCustomContext
|
|
34
35
|
from strawberry.fastapi.context import BaseContext, CustomContext
|
|
35
36
|
from strawberry.http.async_base_view import AsyncBaseHTTPView
|
|
36
|
-
from strawberry.http.exceptions import HTTPException
|
|
37
37
|
from strawberry.http.typevars import Context, RootValue
|
|
38
38
|
from strawberry.subscriptions import GRAPHQL_TRANSPORT_WS_PROTOCOL, GRAPHQL_WS_PROTOCOL
|
|
39
39
|
|
|
40
40
|
if TYPE_CHECKING:
|
|
41
|
-
from collections.abc import
|
|
41
|
+
from collections.abc import (
|
|
42
|
+
AsyncIterator,
|
|
43
|
+
Awaitable,
|
|
44
|
+
Sequence,
|
|
45
|
+
)
|
|
42
46
|
from enum import Enum
|
|
43
47
|
|
|
44
48
|
from starlette.routing import BaseRoute
|
|
@@ -57,7 +61,7 @@ class GraphQLRouter(
|
|
|
57
61
|
APIRouter,
|
|
58
62
|
):
|
|
59
63
|
allow_queries_via_get = True
|
|
60
|
-
request_adapter_class =
|
|
64
|
+
request_adapter_class = StarletteRequestAdapter
|
|
61
65
|
websocket_adapter_class = ASGIWebSocketAdapter
|
|
62
66
|
|
|
63
67
|
@staticmethod
|
|
@@ -123,7 +127,6 @@ class GraphQLRouter(
|
|
|
123
127
|
allow_queries_via_get: bool = True,
|
|
124
128
|
keep_alive: bool = False,
|
|
125
129
|
keep_alive_interval: float = 1,
|
|
126
|
-
debug: bool = False,
|
|
127
130
|
root_value_getter: Optional[Callable[[], RootValue]] = None,
|
|
128
131
|
context_getter: Optional[
|
|
129
132
|
Callable[..., Union[Optional[Context], Awaitable[Optional[Context]]]]
|
|
@@ -179,7 +182,6 @@ class GraphQLRouter(
|
|
|
179
182
|
self.allow_queries_via_get = allow_queries_via_get
|
|
180
183
|
self.keep_alive = keep_alive
|
|
181
184
|
self.keep_alive_interval = keep_alive_interval
|
|
182
|
-
self.debug = debug
|
|
183
185
|
self.root_value_getter = root_value_getter or self.__get_root_value
|
|
184
186
|
# TODO: clean this type up
|
|
185
187
|
self.context_getter = self.__get_context_getter(
|
strawberry/flask/views.py
CHANGED
|
@@ -3,67 +3,27 @@ from __future__ import annotations
|
|
|
3
3
|
import warnings
|
|
4
4
|
from typing import (
|
|
5
5
|
TYPE_CHECKING,
|
|
6
|
-
Any,
|
|
7
6
|
ClassVar,
|
|
8
7
|
Optional,
|
|
9
8
|
Union,
|
|
10
|
-
cast,
|
|
11
9
|
)
|
|
12
10
|
from typing_extensions import TypeGuard
|
|
13
11
|
|
|
12
|
+
from lia import AsyncFlaskHTTPRequestAdapter, FlaskHTTPRequestAdapter, HTTPException
|
|
13
|
+
|
|
14
14
|
from flask import Request, Response, render_template_string, request
|
|
15
15
|
from flask.views import View
|
|
16
|
-
from strawberry.http.async_base_view import AsyncBaseHTTPView
|
|
17
|
-
from strawberry.http.
|
|
18
|
-
from strawberry.http.sync_base_view import (
|
|
19
|
-
SyncBaseHTTPView,
|
|
20
|
-
SyncHTTPRequestAdapter,
|
|
21
|
-
)
|
|
22
|
-
from strawberry.http.types import FormData, HTTPMethod, QueryParams
|
|
16
|
+
from strawberry.http.async_base_view import AsyncBaseHTTPView
|
|
17
|
+
from strawberry.http.sync_base_view import SyncBaseHTTPView
|
|
23
18
|
from strawberry.http.typevars import Context, RootValue
|
|
24
19
|
|
|
25
20
|
if TYPE_CHECKING:
|
|
26
|
-
from collections.abc import Mapping
|
|
27
|
-
|
|
28
21
|
from flask.typing import ResponseReturnValue
|
|
29
22
|
from strawberry.http import GraphQLHTTPResponse
|
|
30
23
|
from strawberry.http.ides import GraphQL_IDE
|
|
31
24
|
from strawberry.schema.base import BaseSchema
|
|
32
25
|
|
|
33
26
|
|
|
34
|
-
class FlaskHTTPRequestAdapter(SyncHTTPRequestAdapter):
|
|
35
|
-
def __init__(self, request: Request) -> None:
|
|
36
|
-
self.request = request
|
|
37
|
-
|
|
38
|
-
@property
|
|
39
|
-
def query_params(self) -> QueryParams:
|
|
40
|
-
return self.request.args.to_dict()
|
|
41
|
-
|
|
42
|
-
@property
|
|
43
|
-
def body(self) -> Union[str, bytes]:
|
|
44
|
-
return self.request.data.decode()
|
|
45
|
-
|
|
46
|
-
@property
|
|
47
|
-
def method(self) -> HTTPMethod:
|
|
48
|
-
return cast("HTTPMethod", self.request.method.upper())
|
|
49
|
-
|
|
50
|
-
@property
|
|
51
|
-
def headers(self) -> Mapping[str, str]:
|
|
52
|
-
return self.request.headers # type: ignore
|
|
53
|
-
|
|
54
|
-
@property
|
|
55
|
-
def post_data(self) -> Mapping[str, Union[str, bytes]]:
|
|
56
|
-
return self.request.form
|
|
57
|
-
|
|
58
|
-
@property
|
|
59
|
-
def files(self) -> Mapping[str, Any]:
|
|
60
|
-
return self.request.files
|
|
61
|
-
|
|
62
|
-
@property
|
|
63
|
-
def content_type(self) -> Optional[str]:
|
|
64
|
-
return self.request.content_type
|
|
65
|
-
|
|
66
|
-
|
|
67
27
|
class BaseGraphQLView:
|
|
68
28
|
graphql_ide: Optional[GraphQL_IDE]
|
|
69
29
|
|
|
@@ -131,36 +91,6 @@ class GraphQLView(
|
|
|
131
91
|
return render_template_string(self.graphql_ide_html) # type: ignore
|
|
132
92
|
|
|
133
93
|
|
|
134
|
-
class AsyncFlaskHTTPRequestAdapter(AsyncHTTPRequestAdapter):
|
|
135
|
-
def __init__(self, request: Request) -> None:
|
|
136
|
-
self.request = request
|
|
137
|
-
|
|
138
|
-
@property
|
|
139
|
-
def query_params(self) -> QueryParams:
|
|
140
|
-
return self.request.args.to_dict()
|
|
141
|
-
|
|
142
|
-
@property
|
|
143
|
-
def method(self) -> HTTPMethod:
|
|
144
|
-
return cast("HTTPMethod", self.request.method.upper())
|
|
145
|
-
|
|
146
|
-
@property
|
|
147
|
-
def content_type(self) -> Optional[str]:
|
|
148
|
-
return self.request.content_type
|
|
149
|
-
|
|
150
|
-
@property
|
|
151
|
-
def headers(self) -> Mapping[str, str]:
|
|
152
|
-
return self.request.headers # type: ignore
|
|
153
|
-
|
|
154
|
-
async def get_body(self) -> str:
|
|
155
|
-
return self.request.data.decode()
|
|
156
|
-
|
|
157
|
-
async def get_form_data(self) -> FormData:
|
|
158
|
-
return FormData(
|
|
159
|
-
files=self.request.files,
|
|
160
|
-
form=self.request.form,
|
|
161
|
-
)
|
|
162
|
-
|
|
163
|
-
|
|
164
94
|
class AsyncGraphQLView(
|
|
165
95
|
BaseGraphQLView,
|
|
166
96
|
AsyncBaseHTTPView[
|
|
@@ -17,6 +17,7 @@ from typing import (
|
|
|
17
17
|
from typing_extensions import TypeGuard
|
|
18
18
|
|
|
19
19
|
from graphql import GraphQLError
|
|
20
|
+
from lia import AsyncHTTPRequestAdapter, HTTPException
|
|
20
21
|
|
|
21
22
|
from strawberry.exceptions import MissingQueryError
|
|
22
23
|
from strawberry.file_uploads.utils import replace_placeholders_with_files
|
|
@@ -44,9 +45,7 @@ from strawberry.types.graphql import OperationType
|
|
|
44
45
|
from strawberry.types.unset import UNSET, UnsetType
|
|
45
46
|
|
|
46
47
|
from .base import BaseView
|
|
47
|
-
from .exceptions import HTTPException
|
|
48
48
|
from .parse_content_type import parse_content_type
|
|
49
|
-
from .types import FormData, HTTPMethod, QueryParams
|
|
50
49
|
from .typevars import (
|
|
51
50
|
Context,
|
|
52
51
|
Request,
|
|
@@ -58,30 +57,6 @@ from .typevars import (
|
|
|
58
57
|
)
|
|
59
58
|
|
|
60
59
|
|
|
61
|
-
class AsyncHTTPRequestAdapter(abc.ABC):
|
|
62
|
-
@property
|
|
63
|
-
@abc.abstractmethod
|
|
64
|
-
def query_params(self) -> QueryParams: ...
|
|
65
|
-
|
|
66
|
-
@property
|
|
67
|
-
@abc.abstractmethod
|
|
68
|
-
def method(self) -> HTTPMethod: ...
|
|
69
|
-
|
|
70
|
-
@property
|
|
71
|
-
@abc.abstractmethod
|
|
72
|
-
def headers(self) -> Mapping[str, str]: ...
|
|
73
|
-
|
|
74
|
-
@property
|
|
75
|
-
@abc.abstractmethod
|
|
76
|
-
def content_type(self) -> Optional[str]: ...
|
|
77
|
-
|
|
78
|
-
@abc.abstractmethod
|
|
79
|
-
async def get_body(self) -> Union[str, bytes]: ...
|
|
80
|
-
|
|
81
|
-
@abc.abstractmethod
|
|
82
|
-
async def get_form_data(self) -> FormData: ...
|
|
83
|
-
|
|
84
|
-
|
|
85
60
|
class AsyncWebSocketAdapter(abc.ABC):
|
|
86
61
|
def __init__(self, view: "AsyncBaseHTTPView") -> None:
|
|
87
62
|
self.view = view
|
|
@@ -113,7 +88,6 @@ class AsyncBaseHTTPView(
|
|
|
113
88
|
):
|
|
114
89
|
schema: BaseSchema
|
|
115
90
|
graphql_ide: Optional[GraphQL_IDE]
|
|
116
|
-
debug: bool
|
|
117
91
|
keep_alive = False
|
|
118
92
|
keep_alive_interval: Optional[float] = None
|
|
119
93
|
connection_init_wait_timeout: timedelta = timedelta(minutes=1)
|
|
@@ -284,8 +258,9 @@ class AsyncBaseHTTPView(
|
|
|
284
258
|
except ValueError as e:
|
|
285
259
|
raise HTTPException(400, "Unable to parse the multipart body") from e
|
|
286
260
|
|
|
287
|
-
operations = form_data
|
|
288
|
-
files_map = form_data
|
|
261
|
+
operations = form_data.form.get("operations", "{}")
|
|
262
|
+
files_map = form_data.form.get("map", "{}")
|
|
263
|
+
files = form_data.files
|
|
289
264
|
|
|
290
265
|
if isinstance(operations, (bytes, str)):
|
|
291
266
|
operations = self.parse_json(operations)
|
|
@@ -294,9 +269,7 @@ class AsyncBaseHTTPView(
|
|
|
294
269
|
files_map = self.parse_json(files_map)
|
|
295
270
|
|
|
296
271
|
try:
|
|
297
|
-
return replace_placeholders_with_files(
|
|
298
|
-
operations, files_map, form_data["files"]
|
|
299
|
-
)
|
|
272
|
+
return replace_placeholders_with_files(operations, files_map, files)
|
|
300
273
|
except KeyError as e:
|
|
301
274
|
raise HTTPException(400, "File(s) missing in form data") from e
|
|
302
275
|
|
|
@@ -351,7 +324,6 @@ class AsyncBaseHTTPView(
|
|
|
351
324
|
context=context,
|
|
352
325
|
root_value=root_value,
|
|
353
326
|
schema=self.schema,
|
|
354
|
-
debug=self.debug,
|
|
355
327
|
connection_init_wait_timeout=self.connection_init_wait_timeout,
|
|
356
328
|
).handle()
|
|
357
329
|
elif websocket_subprotocol == GRAPHQL_WS_PROTOCOL:
|
|
@@ -361,7 +333,6 @@ class AsyncBaseHTTPView(
|
|
|
361
333
|
context=context,
|
|
362
334
|
root_value=root_value,
|
|
363
335
|
schema=self.schema,
|
|
364
|
-
debug=self.debug,
|
|
365
336
|
keep_alive=self.keep_alive,
|
|
366
337
|
keep_alive_interval=self.keep_alive_interval,
|
|
367
338
|
).handle()
|
strawberry/http/base.py
CHANGED
|
@@ -3,12 +3,13 @@ from collections.abc import Mapping
|
|
|
3
3
|
from typing import Any, Generic, Optional, Union
|
|
4
4
|
from typing_extensions import Protocol
|
|
5
5
|
|
|
6
|
+
from lia import HTTPException
|
|
7
|
+
|
|
6
8
|
from strawberry.http import GraphQLRequestData
|
|
7
9
|
from strawberry.http.ides import GraphQL_IDE, get_graphql_ide_html
|
|
8
10
|
from strawberry.http.types import HTTPMethod, QueryParams
|
|
9
11
|
from strawberry.schema.base import BaseSchema
|
|
10
12
|
|
|
11
|
-
from .exceptions import HTTPException
|
|
12
13
|
from .typevars import Request
|
|
13
14
|
|
|
14
15
|
|
strawberry/http/exceptions.py
CHANGED
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
class HTTPException(Exception):
|
|
2
|
-
def __init__(self, status_code: int, reason: str) -> None:
|
|
3
|
-
self.status_code = status_code
|
|
4
|
-
self.reason = reason
|
|
5
|
-
|
|
6
|
-
|
|
7
1
|
class NonTextMessageReceived(Exception):
|
|
8
2
|
pass
|
|
9
3
|
|
|
@@ -16,4 +10,8 @@ class WebSocketDisconnected(Exception):
|
|
|
16
10
|
pass
|
|
17
11
|
|
|
18
12
|
|
|
19
|
-
__all__ = [
|
|
13
|
+
__all__ = [
|
|
14
|
+
"NonJsonMessageReceived",
|
|
15
|
+
"NonTextMessageReceived",
|
|
16
|
+
"WebSocketDisconnected",
|
|
17
|
+
]
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import abc
|
|
2
2
|
import json
|
|
3
|
-
from collections.abc import Mapping
|
|
4
3
|
from typing import (
|
|
5
|
-
Any,
|
|
6
4
|
Callable,
|
|
7
5
|
Generic,
|
|
8
6
|
Literal,
|
|
@@ -11,6 +9,7 @@ from typing import (
|
|
|
11
9
|
)
|
|
12
10
|
|
|
13
11
|
from graphql import GraphQLError
|
|
12
|
+
from lia import HTTPException, SyncHTTPRequestAdapter
|
|
14
13
|
|
|
15
14
|
from strawberry.exceptions import MissingQueryError
|
|
16
15
|
from strawberry.file_uploads.utils import replace_placeholders_with_files
|
|
@@ -30,42 +29,10 @@ from strawberry.types.graphql import OperationType
|
|
|
30
29
|
from strawberry.types.unset import UNSET
|
|
31
30
|
|
|
32
31
|
from .base import BaseView
|
|
33
|
-
from .exceptions import HTTPException
|
|
34
32
|
from .parse_content_type import parse_content_type
|
|
35
|
-
from .types import HTTPMethod, QueryParams
|
|
36
33
|
from .typevars import Context, Request, Response, RootValue, SubResponse
|
|
37
34
|
|
|
38
35
|
|
|
39
|
-
class SyncHTTPRequestAdapter(abc.ABC):
|
|
40
|
-
@property
|
|
41
|
-
@abc.abstractmethod
|
|
42
|
-
def query_params(self) -> QueryParams: ...
|
|
43
|
-
|
|
44
|
-
@property
|
|
45
|
-
@abc.abstractmethod
|
|
46
|
-
def body(self) -> Union[str, bytes]: ...
|
|
47
|
-
|
|
48
|
-
@property
|
|
49
|
-
@abc.abstractmethod
|
|
50
|
-
def method(self) -> HTTPMethod: ...
|
|
51
|
-
|
|
52
|
-
@property
|
|
53
|
-
@abc.abstractmethod
|
|
54
|
-
def headers(self) -> Mapping[str, str]: ...
|
|
55
|
-
|
|
56
|
-
@property
|
|
57
|
-
@abc.abstractmethod
|
|
58
|
-
def content_type(self) -> Optional[str]: ...
|
|
59
|
-
|
|
60
|
-
@property
|
|
61
|
-
@abc.abstractmethod
|
|
62
|
-
def post_data(self) -> Mapping[str, Union[str, bytes]]: ...
|
|
63
|
-
|
|
64
|
-
@property
|
|
65
|
-
@abc.abstractmethod
|
|
66
|
-
def files(self) -> Mapping[str, Any]: ...
|
|
67
|
-
|
|
68
|
-
|
|
69
36
|
class SyncBaseHTTPView(
|
|
70
37
|
abc.ABC,
|
|
71
38
|
BaseView[Request],
|
|
@@ -13,10 +13,10 @@ from typing import (
|
|
|
13
13
|
Optional,
|
|
14
14
|
TypedDict,
|
|
15
15
|
Union,
|
|
16
|
-
cast,
|
|
17
16
|
)
|
|
18
17
|
from typing_extensions import TypeGuard
|
|
19
18
|
|
|
19
|
+
from lia import HTTPException, LitestarRequestAdapter
|
|
20
20
|
from msgspec import Struct
|
|
21
21
|
|
|
22
22
|
from litestar import (
|
|
@@ -41,16 +41,13 @@ from litestar.status_codes import HTTP_200_OK
|
|
|
41
41
|
from strawberry.exceptions import InvalidCustomContext
|
|
42
42
|
from strawberry.http.async_base_view import (
|
|
43
43
|
AsyncBaseHTTPView,
|
|
44
|
-
AsyncHTTPRequestAdapter,
|
|
45
44
|
AsyncWebSocketAdapter,
|
|
46
45
|
)
|
|
47
46
|
from strawberry.http.exceptions import (
|
|
48
|
-
HTTPException,
|
|
49
47
|
NonJsonMessageReceived,
|
|
50
48
|
NonTextMessageReceived,
|
|
51
49
|
WebSocketDisconnected,
|
|
52
50
|
)
|
|
53
|
-
from strawberry.http.types import FormData, HTTPMethod, QueryParams
|
|
54
51
|
from strawberry.http.typevars import Context, RootValue
|
|
55
52
|
from strawberry.subscriptions import GRAPHQL_TRANSPORT_WS_PROTOCOL, GRAPHQL_WS_PROTOCOL
|
|
56
53
|
|
|
@@ -153,41 +150,6 @@ class GraphQLResource(Struct):
|
|
|
153
150
|
extensions: Optional[dict[str, object]]
|
|
154
151
|
|
|
155
152
|
|
|
156
|
-
class LitestarRequestAdapter(AsyncHTTPRequestAdapter):
|
|
157
|
-
def __init__(self, request: Request[Any, Any, Any]) -> None:
|
|
158
|
-
self.request = request
|
|
159
|
-
|
|
160
|
-
@property
|
|
161
|
-
def query_params(self) -> QueryParams:
|
|
162
|
-
return self.request.query_params
|
|
163
|
-
|
|
164
|
-
@property
|
|
165
|
-
def method(self) -> HTTPMethod:
|
|
166
|
-
return cast("HTTPMethod", self.request.method.upper())
|
|
167
|
-
|
|
168
|
-
@property
|
|
169
|
-
def headers(self) -> Mapping[str, str]:
|
|
170
|
-
return self.request.headers
|
|
171
|
-
|
|
172
|
-
@property
|
|
173
|
-
def content_type(self) -> Optional[str]:
|
|
174
|
-
content_type, params = self.request.content_type
|
|
175
|
-
|
|
176
|
-
# combine content type and params
|
|
177
|
-
if params:
|
|
178
|
-
content_type += "; " + "; ".join(f"{k}={v}" for k, v in params.items())
|
|
179
|
-
|
|
180
|
-
return content_type
|
|
181
|
-
|
|
182
|
-
async def get_body(self) -> bytes:
|
|
183
|
-
return await self.request.body()
|
|
184
|
-
|
|
185
|
-
async def get_form_data(self) -> FormData:
|
|
186
|
-
multipart_data = await self.request.form()
|
|
187
|
-
|
|
188
|
-
return FormData(form=multipart_data, files=multipart_data)
|
|
189
|
-
|
|
190
|
-
|
|
191
153
|
class LitestarWebSocketAdapter(AsyncWebSocketAdapter):
|
|
192
154
|
def __init__(
|
|
193
155
|
self, view: AsyncBaseHTTPView, request: WebSocket, response: WebSocket
|
|
@@ -251,7 +213,6 @@ class GraphQLController(
|
|
|
251
213
|
allow_queries_via_get: bool = True
|
|
252
214
|
graphiql_allowed_accept: frozenset[str] = frozenset({"text/html", "*/*"})
|
|
253
215
|
graphql_ide: Optional[GraphQL_IDE] = "graphiql"
|
|
254
|
-
debug: bool = False
|
|
255
216
|
connection_init_wait_timeout: timedelta = timedelta(minutes=1)
|
|
256
217
|
protocols: Sequence[str] = (
|
|
257
218
|
GRAPHQL_TRANSPORT_WS_PROTOCOL,
|
|
@@ -408,7 +369,6 @@ def make_graphql_controller(
|
|
|
408
369
|
allow_queries_via_get: bool = True,
|
|
409
370
|
keep_alive: bool = False,
|
|
410
371
|
keep_alive_interval: float = 1,
|
|
411
|
-
debug: bool = False,
|
|
412
372
|
# TODO: root typevar
|
|
413
373
|
root_value_getter: Optional[AnyCallable] = None,
|
|
414
374
|
# TODO: context typevar
|
|
@@ -458,7 +418,6 @@ def make_graphql_controller(
|
|
|
458
418
|
|
|
459
419
|
_GraphQLController.keep_alive = keep_alive
|
|
460
420
|
_GraphQLController.keep_alive_interval = keep_alive_interval
|
|
461
|
-
_GraphQLController.debug = debug
|
|
462
421
|
_GraphQLController.protocols = subscription_protocols
|
|
463
422
|
_GraphQLController.connection_init_wait_timeout = connection_init_wait_timeout
|
|
464
423
|
_GraphQLController.graphiql_allowed_accept = frozenset({"text/html", "*/*"})
|
strawberry/quart/views.py
CHANGED
|
@@ -3,25 +3,24 @@ import warnings
|
|
|
3
3
|
from collections.abc import AsyncGenerator, Mapping, Sequence
|
|
4
4
|
from datetime import timedelta
|
|
5
5
|
from json.decoder import JSONDecodeError
|
|
6
|
-
from typing import TYPE_CHECKING, Callable, ClassVar, Optional, Union
|
|
6
|
+
from typing import TYPE_CHECKING, Callable, ClassVar, Optional, Union
|
|
7
7
|
from typing_extensions import TypeGuard
|
|
8
8
|
|
|
9
|
+
from lia import HTTPException, QuartHTTPRequestAdapter
|
|
10
|
+
|
|
9
11
|
from quart import Request, Response, Websocket, request, websocket
|
|
10
12
|
from quart.ctx import has_websocket_context
|
|
11
13
|
from quart.views import View
|
|
12
14
|
from strawberry.http.async_base_view import (
|
|
13
15
|
AsyncBaseHTTPView,
|
|
14
|
-
AsyncHTTPRequestAdapter,
|
|
15
16
|
AsyncWebSocketAdapter,
|
|
16
17
|
)
|
|
17
18
|
from strawberry.http.exceptions import (
|
|
18
|
-
HTTPException,
|
|
19
19
|
NonJsonMessageReceived,
|
|
20
20
|
NonTextMessageReceived,
|
|
21
21
|
WebSocketDisconnected,
|
|
22
22
|
)
|
|
23
23
|
from strawberry.http.ides import GraphQL_IDE
|
|
24
|
-
from strawberry.http.types import FormData, HTTPMethod, QueryParams
|
|
25
24
|
from strawberry.http.typevars import Context, RootValue
|
|
26
25
|
from strawberry.subscriptions import GRAPHQL_TRANSPORT_WS_PROTOCOL, GRAPHQL_WS_PROTOCOL
|
|
27
26
|
|
|
@@ -31,35 +30,6 @@ if TYPE_CHECKING:
|
|
|
31
30
|
from strawberry.schema.base import BaseSchema
|
|
32
31
|
|
|
33
32
|
|
|
34
|
-
class QuartHTTPRequestAdapter(AsyncHTTPRequestAdapter):
|
|
35
|
-
def __init__(self, request: Request) -> None:
|
|
36
|
-
self.request = request
|
|
37
|
-
|
|
38
|
-
@property
|
|
39
|
-
def query_params(self) -> QueryParams:
|
|
40
|
-
return self.request.args.to_dict()
|
|
41
|
-
|
|
42
|
-
@property
|
|
43
|
-
def method(self) -> HTTPMethod:
|
|
44
|
-
return cast("HTTPMethod", self.request.method.upper())
|
|
45
|
-
|
|
46
|
-
@property
|
|
47
|
-
def content_type(self) -> Optional[str]:
|
|
48
|
-
return self.request.content_type
|
|
49
|
-
|
|
50
|
-
@property
|
|
51
|
-
def headers(self) -> Mapping[str, str]:
|
|
52
|
-
return self.request.headers # type: ignore
|
|
53
|
-
|
|
54
|
-
async def get_body(self) -> str:
|
|
55
|
-
return (await self.request.data).decode()
|
|
56
|
-
|
|
57
|
-
async def get_form_data(self) -> FormData:
|
|
58
|
-
files = await self.request.files
|
|
59
|
-
form = await self.request.form
|
|
60
|
-
return FormData(files=files, form=form)
|
|
61
|
-
|
|
62
|
-
|
|
63
33
|
class QuartWebSocketAdapter(AsyncWebSocketAdapter):
|
|
64
34
|
def __init__(
|
|
65
35
|
self, view: AsyncBaseHTTPView, request: Websocket, response: Response
|
|
@@ -118,7 +88,6 @@ class GraphQLView(
|
|
|
118
88
|
allow_queries_via_get: bool = True,
|
|
119
89
|
keep_alive: bool = True,
|
|
120
90
|
keep_alive_interval: float = 1,
|
|
121
|
-
debug: bool = False,
|
|
122
91
|
subscription_protocols: Sequence[str] = (
|
|
123
92
|
GRAPHQL_TRANSPORT_WS_PROTOCOL,
|
|
124
93
|
GRAPHQL_WS_PROTOCOL,
|
|
@@ -130,7 +99,6 @@ class GraphQLView(
|
|
|
130
99
|
self.allow_queries_via_get = allow_queries_via_get
|
|
131
100
|
self.keep_alive = keep_alive
|
|
132
101
|
self.keep_alive_interval = keep_alive_interval
|
|
133
|
-
self.debug = debug
|
|
134
102
|
self.subscription_protocols = subscription_protocols
|
|
135
103
|
self.connection_init_wait_timeout = connection_init_wait_timeout
|
|
136
104
|
self.multipart_uploads_enabled = multipart_uploads_enabled
|