strawberry-graphql 0.277.1__py3-none-any.whl → 0.278.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/aiohttp/views.py +5 -49
- strawberry/asgi/__init__.py +5 -38
- strawberry/chalice/views.py +7 -40
- strawberry/channels/handlers/http_handler.py +34 -14
- strawberry/channels/handlers/ws_handler.py +3 -1
- strawberry/django/views.py +7 -74
- strawberry/fastapi/router.py +11 -5
- strawberry/flask/views.py +7 -75
- strawberry/http/async_base_view.py +113 -62
- strawberry/http/base.py +19 -1
- strawberry/http/exceptions.py +5 -7
- strawberry/http/sync_base_view.py +110 -62
- strawberry/litestar/controller.py +4 -40
- strawberry/quart/views.py +6 -34
- strawberry/sanic/views.py +8 -44
- strawberry/schema/config.py +6 -1
- {strawberry_graphql-0.277.1.dist-info → strawberry_graphql-0.278.1.dist-info}/METADATA +2 -1
- {strawberry_graphql-0.277.1.dist-info → strawberry_graphql-0.278.1.dist-info}/RECORD +21 -21
- {strawberry_graphql-0.277.1.dist-info → strawberry_graphql-0.278.1.dist-info}/LICENSE +0 -0
- {strawberry_graphql-0.277.1.dist-info → strawberry_graphql-0.278.1.dist-info}/WHEEL +0 -0
- {strawberry_graphql-0.277.1.dist-info → strawberry_graphql-0.278.1.dist-info}/entry_points.txt +0 -0
strawberry/aiohttp/views.py
CHANGED
@@ -3,32 +3,27 @@ from __future__ import annotations
|
|
3
3
|
import asyncio
|
4
4
|
import warnings
|
5
5
|
from datetime import timedelta
|
6
|
-
from io import BytesIO
|
7
6
|
from json.decoder import JSONDecodeError
|
8
7
|
from typing import (
|
9
8
|
TYPE_CHECKING,
|
10
|
-
Any,
|
11
9
|
Callable,
|
12
10
|
Optional,
|
13
11
|
Union,
|
14
|
-
cast,
|
15
12
|
)
|
16
13
|
from typing_extensions import TypeGuard
|
17
14
|
|
15
|
+
from lia import AiohttpHTTPRequestAdapter, HTTPException
|
16
|
+
|
18
17
|
from aiohttp import ClientConnectionResetError, http, web
|
19
|
-
from aiohttp.multipart import BodyPartReader
|
20
18
|
from strawberry.http.async_base_view import (
|
21
19
|
AsyncBaseHTTPView,
|
22
|
-
AsyncHTTPRequestAdapter,
|
23
20
|
AsyncWebSocketAdapter,
|
24
21
|
)
|
25
22
|
from strawberry.http.exceptions import (
|
26
|
-
HTTPException,
|
27
23
|
NonJsonMessageReceived,
|
28
24
|
NonTextMessageReceived,
|
29
25
|
WebSocketDisconnected,
|
30
26
|
)
|
31
|
-
from strawberry.http.types import FormData, HTTPMethod, QueryParams
|
32
27
|
from strawberry.http.typevars import (
|
33
28
|
Context,
|
34
29
|
RootValue,
|
@@ -43,47 +38,6 @@ if TYPE_CHECKING:
|
|
43
38
|
from strawberry.schema import BaseSchema
|
44
39
|
|
45
40
|
|
46
|
-
class AiohttpHTTPRequestAdapter(AsyncHTTPRequestAdapter):
|
47
|
-
def __init__(self, request: web.Request) -> None:
|
48
|
-
self.request = request
|
49
|
-
|
50
|
-
@property
|
51
|
-
def query_params(self) -> QueryParams:
|
52
|
-
return self.request.query.copy() # type: ignore[attr-defined]
|
53
|
-
|
54
|
-
async def get_body(self) -> str:
|
55
|
-
return (await self.request.content.read()).decode()
|
56
|
-
|
57
|
-
@property
|
58
|
-
def method(self) -> HTTPMethod:
|
59
|
-
return cast("HTTPMethod", self.request.method.upper())
|
60
|
-
|
61
|
-
@property
|
62
|
-
def headers(self) -> Mapping[str, str]:
|
63
|
-
return self.request.headers
|
64
|
-
|
65
|
-
async def get_form_data(self) -> FormData:
|
66
|
-
reader = await self.request.multipart()
|
67
|
-
|
68
|
-
data: dict[str, Any] = {}
|
69
|
-
files: dict[str, Any] = {}
|
70
|
-
|
71
|
-
while field := await reader.next():
|
72
|
-
assert isinstance(field, BodyPartReader)
|
73
|
-
assert field.name
|
74
|
-
|
75
|
-
if field.filename:
|
76
|
-
files[field.name] = BytesIO(await field.read(decode=False))
|
77
|
-
else:
|
78
|
-
data[field.name] = await field.text()
|
79
|
-
|
80
|
-
return FormData(files=files, form=data)
|
81
|
-
|
82
|
-
@property
|
83
|
-
def content_type(self) -> Optional[str]:
|
84
|
-
return self.headers.get("content-type")
|
85
|
-
|
86
|
-
|
87
41
|
class AiohttpWebSocketAdapter(AsyncWebSocketAdapter):
|
88
42
|
def __init__(
|
89
43
|
self, view: AsyncBaseHTTPView, request: web.Request, ws: web.WebSocketResponse
|
@@ -210,7 +164,9 @@ class GraphQLView(
|
|
210
164
|
return {"request": request, "response": response} # type: ignore
|
211
165
|
|
212
166
|
def create_response(
|
213
|
-
self,
|
167
|
+
self,
|
168
|
+
response_data: Union[GraphQLHTTPResponse, list[GraphQLHTTPResponse]],
|
169
|
+
sub_response: web.Response,
|
214
170
|
) -> web.Response:
|
215
171
|
sub_response.text = self.encode_json(response_data)
|
216
172
|
sub_response.content_type = "application/json"
|
strawberry/asgi/__init__.py
CHANGED
@@ -8,10 +8,10 @@ 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
|
|
14
|
+
from lia import HTTPException, StarletteRequestAdapter
|
15
15
|
from starlette import status
|
16
16
|
from starlette.requests import Request
|
17
17
|
from starlette.responses import (
|
@@ -24,16 +24,13 @@ from starlette.websockets import WebSocket, WebSocketDisconnect, WebSocketState
|
|
24
24
|
|
25
25
|
from strawberry.http.async_base_view import (
|
26
26
|
AsyncBaseHTTPView,
|
27
|
-
AsyncHTTPRequestAdapter,
|
28
27
|
AsyncWebSocketAdapter,
|
29
28
|
)
|
30
29
|
from strawberry.http.exceptions import (
|
31
|
-
HTTPException,
|
32
30
|
NonJsonMessageReceived,
|
33
31
|
NonTextMessageReceived,
|
34
32
|
WebSocketDisconnected,
|
35
33
|
)
|
36
|
-
from strawberry.http.types import FormData, HTTPMethod, QueryParams
|
37
34
|
from strawberry.http.typevars import (
|
38
35
|
Context,
|
39
36
|
RootValue,
|
@@ -50,38 +47,6 @@ if TYPE_CHECKING:
|
|
50
47
|
from strawberry.schema import BaseSchema
|
51
48
|
|
52
49
|
|
53
|
-
class ASGIRequestAdapter(AsyncHTTPRequestAdapter):
|
54
|
-
def __init__(self, request: Request) -> None:
|
55
|
-
self.request = request
|
56
|
-
|
57
|
-
@property
|
58
|
-
def query_params(self) -> QueryParams:
|
59
|
-
return self.request.query_params
|
60
|
-
|
61
|
-
@property
|
62
|
-
def method(self) -> HTTPMethod:
|
63
|
-
return cast("HTTPMethod", self.request.method.upper())
|
64
|
-
|
65
|
-
@property
|
66
|
-
def headers(self) -> Mapping[str, str]:
|
67
|
-
return self.request.headers
|
68
|
-
|
69
|
-
@property
|
70
|
-
def content_type(self) -> Optional[str]:
|
71
|
-
return self.request.headers.get("content-type")
|
72
|
-
|
73
|
-
async def get_body(self) -> bytes:
|
74
|
-
return await self.request.body()
|
75
|
-
|
76
|
-
async def get_form_data(self) -> FormData:
|
77
|
-
multipart_data = await self.request.form()
|
78
|
-
|
79
|
-
return FormData(
|
80
|
-
files=multipart_data,
|
81
|
-
form=multipart_data,
|
82
|
-
)
|
83
|
-
|
84
|
-
|
85
50
|
class ASGIWebSocketAdapter(AsyncWebSocketAdapter):
|
86
51
|
def __init__(
|
87
52
|
self, view: AsyncBaseHTTPView, request: WebSocket, response: WebSocket
|
@@ -127,7 +92,7 @@ class GraphQL(
|
|
127
92
|
]
|
128
93
|
):
|
129
94
|
allow_queries_via_get = True
|
130
|
-
request_adapter_class =
|
95
|
+
request_adapter_class = StarletteRequestAdapter
|
131
96
|
websocket_adapter_class = ASGIWebSocketAdapter
|
132
97
|
|
133
98
|
def __init__(
|
@@ -205,7 +170,9 @@ class GraphQL(
|
|
205
170
|
return HTMLResponse(self.graphql_ide_html)
|
206
171
|
|
207
172
|
def create_response(
|
208
|
-
self,
|
173
|
+
self,
|
174
|
+
response_data: Union[GraphQLHTTPResponse, list[GraphQLHTTPResponse]],
|
175
|
+
sub_response: Response,
|
209
176
|
) -> Response:
|
210
177
|
response = Response(
|
211
178
|
self.encode_json(response_data),
|
strawberry/chalice/views.py
CHANGED
@@ -1,56 +1,21 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
import warnings
|
4
|
-
from typing import TYPE_CHECKING,
|
4
|
+
from typing import TYPE_CHECKING, Optional, Union
|
5
|
+
|
6
|
+
from lia import ChaliceHTTPRequestAdapter, HTTPException
|
5
7
|
|
6
8
|
from chalice.app import Request, Response
|
7
|
-
from strawberry.http.
|
8
|
-
from strawberry.http.sync_base_view import SyncBaseHTTPView, SyncHTTPRequestAdapter
|
9
|
+
from strawberry.http.sync_base_view import SyncBaseHTTPView
|
9
10
|
from strawberry.http.temporal_response import TemporalResponse
|
10
11
|
from strawberry.http.typevars import Context, RootValue
|
11
12
|
|
12
13
|
if TYPE_CHECKING:
|
13
|
-
from collections.abc import Mapping
|
14
|
-
|
15
14
|
from strawberry.http import GraphQLHTTPResponse
|
16
15
|
from strawberry.http.ides import GraphQL_IDE
|
17
|
-
from strawberry.http.types import HTTPMethod, QueryParams
|
18
16
|
from strawberry.schema import BaseSchema
|
19
17
|
|
20
18
|
|
21
|
-
class ChaliceHTTPRequestAdapter(SyncHTTPRequestAdapter):
|
22
|
-
def __init__(self, request: Request) -> None:
|
23
|
-
self.request = request
|
24
|
-
|
25
|
-
@property
|
26
|
-
def query_params(self) -> QueryParams:
|
27
|
-
return self.request.query_params or {}
|
28
|
-
|
29
|
-
@property
|
30
|
-
def body(self) -> Union[str, bytes]:
|
31
|
-
return self.request.raw_body
|
32
|
-
|
33
|
-
@property
|
34
|
-
def method(self) -> HTTPMethod:
|
35
|
-
return cast("HTTPMethod", self.request.method.upper())
|
36
|
-
|
37
|
-
@property
|
38
|
-
def headers(self) -> Mapping[str, str]:
|
39
|
-
return self.request.headers
|
40
|
-
|
41
|
-
@property
|
42
|
-
def post_data(self) -> Mapping[str, Union[str, bytes]]:
|
43
|
-
raise NotImplementedError
|
44
|
-
|
45
|
-
@property
|
46
|
-
def files(self) -> Mapping[str, Any]:
|
47
|
-
raise NotImplementedError
|
48
|
-
|
49
|
-
@property
|
50
|
-
def content_type(self) -> Optional[str]:
|
51
|
-
return self.request.headers.get("Content-Type", None)
|
52
|
-
|
53
|
-
|
54
19
|
class GraphQLView(
|
55
20
|
SyncBaseHTTPView[Request, Response, TemporalResponse, Context, RootValue]
|
56
21
|
):
|
@@ -114,7 +79,9 @@ class GraphQLView(
|
|
114
79
|
return {"request": request, "response": response} # type: ignore
|
115
80
|
|
116
81
|
def create_response(
|
117
|
-
self,
|
82
|
+
self,
|
83
|
+
response_data: Union[GraphQLHTTPResponse, list[GraphQLHTTPResponse]],
|
84
|
+
sub_response: TemporalResponse,
|
118
85
|
) -> Response:
|
119
86
|
status_code = 200
|
120
87
|
|
@@ -5,27 +5,20 @@ import json
|
|
5
5
|
import warnings
|
6
6
|
from functools import cached_property
|
7
7
|
from io import BytesIO
|
8
|
-
from typing import
|
9
|
-
TYPE_CHECKING,
|
10
|
-
Any,
|
11
|
-
Callable,
|
12
|
-
Optional,
|
13
|
-
Union,
|
14
|
-
)
|
8
|
+
from typing import TYPE_CHECKING, Any, Callable, Optional, Union
|
15
9
|
from typing_extensions import TypeGuard, assert_never
|
16
10
|
from urllib.parse import parse_qs
|
17
11
|
|
18
12
|
from django.conf import settings
|
19
13
|
from django.core.files import uploadhandler
|
20
14
|
from django.http.multipartparser import MultiPartParser
|
15
|
+
from lia import AsyncHTTPRequestAdapter, FormData, HTTPException, SyncHTTPRequestAdapter
|
21
16
|
|
22
17
|
from channels.db import database_sync_to_async
|
23
18
|
from channels.generic.http import AsyncHttpConsumer
|
24
|
-
from strawberry.http.async_base_view import AsyncBaseHTTPView
|
25
|
-
from strawberry.http.
|
26
|
-
from strawberry.http.sync_base_view import SyncBaseHTTPView, SyncHTTPRequestAdapter
|
19
|
+
from strawberry.http.async_base_view import AsyncBaseHTTPView
|
20
|
+
from strawberry.http.sync_base_view import SyncBaseHTTPView
|
27
21
|
from strawberry.http.temporal_response import TemporalResponse
|
28
|
-
from strawberry.http.types import FormData
|
29
22
|
from strawberry.http.typevars import Context, RootValue
|
30
23
|
from strawberry.types.unset import UNSET
|
31
24
|
|
@@ -133,6 +126,28 @@ class BaseChannelsRequestAdapter:
|
|
133
126
|
def content_type(self) -> Optional[str]:
|
134
127
|
return self.request.content_type
|
135
128
|
|
129
|
+
@property
|
130
|
+
def url(self) -> str:
|
131
|
+
scheme = self.request.consumer.scope["scheme"]
|
132
|
+
host = self.headers.get("host", "localhost")
|
133
|
+
path = self.request.consumer.scope["path"]
|
134
|
+
query_string = self.request.consumer.scope["query_string"]
|
135
|
+
url = f"{scheme}://{host}{path}"
|
136
|
+
if query_string:
|
137
|
+
url += f"?{query_string.decode()}"
|
138
|
+
return url
|
139
|
+
|
140
|
+
@property
|
141
|
+
def cookies(self) -> Mapping[str, str]:
|
142
|
+
cookie_header = self.headers.get("cookie", "")
|
143
|
+
cookies = {}
|
144
|
+
if cookie_header:
|
145
|
+
for cookie in cookie_header.split(";"):
|
146
|
+
if "=" in cookie:
|
147
|
+
key, value = cookie.split("=", 1)
|
148
|
+
cookies[key.strip()] = value.strip()
|
149
|
+
return cookies
|
150
|
+
|
136
151
|
|
137
152
|
class ChannelsRequestAdapter(BaseChannelsRequestAdapter, AsyncHTTPRequestAdapter):
|
138
153
|
async def get_body(self) -> bytes:
|
@@ -149,11 +164,14 @@ class SyncChannelsRequestAdapter(BaseChannelsRequestAdapter, SyncHTTPRequestAdap
|
|
149
164
|
|
150
165
|
@property
|
151
166
|
def post_data(self) -> Mapping[str, Union[str, bytes]]:
|
152
|
-
return self.request.form_data
|
167
|
+
return self.request.form_data.form
|
153
168
|
|
154
169
|
@property
|
155
170
|
def files(self) -> Mapping[str, Any]:
|
156
|
-
return self.request.form_data
|
171
|
+
return self.request.form_data.files
|
172
|
+
|
173
|
+
def get_form_data(self) -> FormData:
|
174
|
+
return self.request.form_data
|
157
175
|
|
158
176
|
|
159
177
|
class BaseGraphQLHTTPConsumer(ChannelsConsumer, AsyncHttpConsumer):
|
@@ -186,7 +204,9 @@ class BaseGraphQLHTTPConsumer(ChannelsConsumer, AsyncHttpConsumer):
|
|
186
204
|
super().__init__(**kwargs)
|
187
205
|
|
188
206
|
def create_response(
|
189
|
-
self,
|
207
|
+
self,
|
208
|
+
response_data: Union[GraphQLHTTPResponse, list[GraphQLHTTPResponse]],
|
209
|
+
sub_response: TemporalResponse,
|
190
210
|
) -> ChannelsResponse:
|
191
211
|
return ChannelsResponse(
|
192
212
|
content=json.dumps(response_data).encode(),
|
@@ -164,7 +164,9 @@ class GraphQLWSConsumer(
|
|
164
164
|
raise NotImplementedError
|
165
165
|
|
166
166
|
def create_response(
|
167
|
-
self,
|
167
|
+
self,
|
168
|
+
response_data: Union[GraphQLHTTPResponse, list[GraphQLHTTPResponse]],
|
169
|
+
sub_response: GraphQLWSConsumer,
|
168
170
|
) -> GraphQLWSConsumer:
|
169
171
|
raise NotImplementedError
|
170
172
|
|
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
|
|
@@ -163,7 +94,9 @@ class BaseView:
|
|
163
94
|
super().__init__(**kwargs)
|
164
95
|
|
165
96
|
def create_response(
|
166
|
-
self,
|
97
|
+
self,
|
98
|
+
response_data: Union[GraphQLHTTPResponse, list[GraphQLHTTPResponse]],
|
99
|
+
sub_response: HttpResponse,
|
167
100
|
) -> HttpResponseBase:
|
168
101
|
data = self.encode_json(response_data)
|
169
102
|
|
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
|
@@ -276,7 +280,9 @@ class GraphQLRouter(
|
|
276
280
|
return self.temporal_response
|
277
281
|
|
278
282
|
def create_response(
|
279
|
-
self,
|
283
|
+
self,
|
284
|
+
response_data: Union[GraphQLHTTPResponse, list[GraphQLHTTPResponse]],
|
285
|
+
sub_response: Response,
|
280
286
|
) -> Response:
|
281
287
|
response = Response(
|
282
288
|
self.encode_json(response_data),
|
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
|
|
@@ -91,7 +51,9 @@ class BaseGraphQLView:
|
|
91
51
|
self.graphql_ide = graphql_ide
|
92
52
|
|
93
53
|
def create_response(
|
94
|
-
self,
|
54
|
+
self,
|
55
|
+
response_data: Union[GraphQLHTTPResponse, list[GraphQLHTTPResponse]],
|
56
|
+
sub_response: Response,
|
95
57
|
) -> Response:
|
96
58
|
sub_response.set_data(self.encode_json(response_data)) # type: ignore
|
97
59
|
|
@@ -129,36 +91,6 @@ class GraphQLView(
|
|
129
91
|
return render_template_string(self.graphql_ide_html) # type: ignore
|
130
92
|
|
131
93
|
|
132
|
-
class AsyncFlaskHTTPRequestAdapter(AsyncHTTPRequestAdapter):
|
133
|
-
def __init__(self, request: Request) -> None:
|
134
|
-
self.request = request
|
135
|
-
|
136
|
-
@property
|
137
|
-
def query_params(self) -> QueryParams:
|
138
|
-
return self.request.args.to_dict()
|
139
|
-
|
140
|
-
@property
|
141
|
-
def method(self) -> HTTPMethod:
|
142
|
-
return cast("HTTPMethod", self.request.method.upper())
|
143
|
-
|
144
|
-
@property
|
145
|
-
def content_type(self) -> Optional[str]:
|
146
|
-
return self.request.content_type
|
147
|
-
|
148
|
-
@property
|
149
|
-
def headers(self) -> Mapping[str, str]:
|
150
|
-
return self.request.headers # type: ignore
|
151
|
-
|
152
|
-
async def get_body(self) -> str:
|
153
|
-
return self.request.data.decode()
|
154
|
-
|
155
|
-
async def get_form_data(self) -> FormData:
|
156
|
-
return FormData(
|
157
|
-
files=self.request.files,
|
158
|
-
form=self.request.form,
|
159
|
-
)
|
160
|
-
|
161
|
-
|
162
94
|
class AsyncGraphQLView(
|
163
95
|
BaseGraphQLView,
|
164
96
|
AsyncBaseHTTPView[
|