Skip to content

Commit 7795355

Browse files
committed
Added GraphQLRequestData argument to the render_graphql_ide method
1 parent c121529 commit 7795355

File tree

13 files changed

+116
-51
lines changed

13 files changed

+116
-51
lines changed

src/graphql_server/aiohttp/views.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
NonTextMessageReceived,
2929
WebSocketDisconnected,
3030
)
31+
from graphql_server.http import GraphQLRequestData
3132
from graphql_server.http.types import FormData, HTTPMethod, QueryParams
3233
from graphql_server.http.typevars import (
3334
Context,
@@ -174,7 +175,9 @@ def __init__(
174175
else:
175176
self.graphql_ide = graphql_ide
176177

177-
async def render_graphql_ide(self, request: web.Request) -> web.Response:
178+
async def render_graphql_ide(
179+
self, request: web.Request, request_data: GraphQLRequestData
180+
) -> web.Response:
178181
return web.Response(text=self.graphql_ide_html, content_type="text/html")
179182

180183
async def get_sub_response(self, request: web.Request) -> web.Response:

src/graphql_server/asgi/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
)
2323
from starlette.websockets import WebSocket, WebSocketDisconnect, WebSocketState
2424

25+
from graphql_server.http import GraphQLRequestData
2526
from graphql_server.http.async_base_view import (
2627
AsyncBaseHTTPView,
2728
AsyncHTTPRequestAdapter,
@@ -204,7 +205,9 @@ async def get_sub_response(
204205

205206
return sub_response
206207

207-
async def render_graphql_ide(self, request: Request) -> Response:
208+
async def render_graphql_ide(
209+
self, request: Request, request_data: GraphQLRequestData
210+
) -> Response:
208211
return HTMLResponse(self.graphql_ide_html)
209212

210213
def create_response(

src/graphql_server/chalice/views.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from typing import TYPE_CHECKING, Any, Optional, Union, cast
55

66
from chalice.app import Request, Response
7+
from graphql_server.http import GraphQLRequestData
78
from graphql_server.http.exceptions import HTTPException
89
from graphql_server.http.sync_base_view import SyncBaseHTTPView, SyncHTTPRequestAdapter
910
from graphql_server.http.temporal_response import TemporalResponse
@@ -80,7 +81,9 @@ def __init__(
8081
def get_root_value(self, request: Request) -> Optional[RootValue]:
8182
return None
8283

83-
def render_graphql_ide(self, request: Request) -> Response:
84+
def render_graphql_ide(
85+
self, request: Request, request_data: GraphQLRequestData
86+
) -> Response:
8487
return Response(
8588
self.graphql_ide_html,
8689
headers={"Content-Type": "text/html"},

src/graphql_server/channels/handlers/http_handler.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
AsyncBaseHTTPView,
2626
AsyncHTTPRequestAdapter,
2727
)
28+
from graphql_server.http import GraphQLRequestData
2829
from graphql_server.http.exceptions import HTTPException
2930
from graphql_server.http.sync_base_view import SyncBaseHTTPView, SyncHTTPRequestAdapter
3031
from graphql_server.http.temporal_response import TemporalResponse
@@ -295,7 +296,9 @@ async def create_streaming_response(
295296
stream=stream, status=status, headers=response_headers
296297
)
297298

298-
async def render_graphql_ide(self, request: ChannelsRequest) -> ChannelsResponse:
299+
async def render_graphql_ide(
300+
self, request: ChannelsRequest, request_data: GraphQLRequestData
301+
) -> ChannelsResponse:
299302
return ChannelsResponse(
300303
content=self.graphql_ide_html.encode(),
301304
content_type="text/html; charset=utf-8",
@@ -351,7 +354,9 @@ def get_context(
351354
def get_sub_response(self, request: ChannelsRequest) -> TemporalResponse:
352355
return TemporalResponse()
353356

354-
def render_graphql_ide(self, request: ChannelsRequest) -> ChannelsResponse:
357+
def render_graphql_ide(
358+
self, request: ChannelsRequest, request_data: GraphQLRequestData
359+
) -> ChannelsResponse:
355360
return ChannelsResponse(
356361
content=self.graphql_ide_html.encode(),
357362
content_type="text/html; charset=utf-8",

src/graphql_server/channels/handlers/ws_handler.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
)
1212
from typing_extensions import TypeGuard
1313

14+
from graphql_server.http import GraphQLRequestData
1415
from graphql_server.http.async_base_view import AsyncBaseHTTPView, AsyncWebSocketAdapter
1516
from graphql_server.http.exceptions import (
1617
NonJsonMessageReceived,
@@ -175,7 +176,9 @@ def create_response(
175176
) -> GraphQLWSConsumer:
176177
raise NotImplementedError
177178

178-
async def render_graphql_ide(self, request: GraphQLWSConsumer) -> GraphQLWSConsumer:
179+
async def render_graphql_ide(
180+
self, request: GraphQLWSConsumer, request_data: GraphQLRequestData
181+
) -> GraphQLWSConsumer:
179182
raise NotImplementedError
180183

181184
def is_websocket_request(

src/graphql_server/django/views.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from django.utils.decorators import classonlymethod
2828
from django.views.generic import View
2929

30+
from graphql_server.http import GraphQLRequestData
3031
from graphql_server.http.async_base_view import (
3132
AsyncBaseHTTPView,
3233
AsyncHTTPRequestAdapter,
@@ -240,7 +241,9 @@ def dispatch(
240241
status=e.status_code,
241242
)
242243

243-
def render_graphql_ide(self, request: HttpRequest) -> HttpResponse:
244+
def render_graphql_ide(
245+
self, request: HttpRequest, request_data: GraphQLRequestData
246+
) -> HttpResponse:
244247
try:
245248
content = render_to_string("graphql/graphiql.html", request=request)
246249
except TemplateDoesNotExist:
@@ -300,7 +303,9 @@ async def dispatch( # pyright: ignore
300303
status=e.status_code,
301304
)
302305

303-
async def render_graphql_ide(self, request: HttpRequest) -> HttpResponse:
306+
async def render_graphql_ide(
307+
self, request: HttpRequest, request_data: GraphQLRequestData
308+
) -> HttpResponse:
304309
try:
305310
content = render_to_string("graphql/graphiql.html", request=request)
306311
except TemplateDoesNotExist:

src/graphql_server/fastapi/router.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
from fastapi.datastructures import Default
3030
from fastapi.routing import APIRoute
3131
from fastapi.utils import generate_unique_id
32+
from graphql_server.http import GraphQLRequestData
3233
from graphql_server.asgi import ASGIRequestAdapter, ASGIWebSocketAdapter
3334
from graphql_server.fastapi.context import BaseContext, CustomContext
3435
from graphql_server.http.async_base_view import AsyncBaseHTTPView
@@ -261,7 +262,9 @@ async def websocket_endpoint( # pyright: ignore
261262
) -> None:
262263
await self.run(request=websocket, context=context, root_value=root_value)
263264

264-
async def render_graphql_ide(self, request: Request) -> HTMLResponse:
265+
async def render_graphql_ide(
266+
self, request: Request, request_data: GraphQLRequestData
267+
) -> HTMLResponse:
265268
return HTMLResponse(self.graphql_ide_html)
266269

267270
async def get_context(

src/graphql_server/flask/views.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
from flask import Request, Response, render_template_string, request
1515
from flask.views import View
16+
from graphql_server.http import GraphQLRequestData
1617
from graphql_server.http.async_base_view import (
1718
AsyncBaseHTTPView,
1819
AsyncHTTPRequestAdapter,
@@ -129,7 +130,9 @@ def dispatch_request(self) -> ResponseReturnValue:
129130
status=e.status_code,
130131
)
131132

132-
def render_graphql_ide(self, request: Request) -> Response:
133+
def render_graphql_ide(
134+
self, request: Request, request_data: GraphQLRequestData
135+
) -> Response:
133136
return render_template_string(self.graphql_ide_html) # type: ignore
134137

135138

@@ -192,7 +195,9 @@ async def dispatch_request(self) -> ResponseReturnValue: # type: ignore
192195
status=e.status_code,
193196
)
194197

195-
async def render_graphql_ide(self, request: Request) -> Response:
198+
async def render_graphql_ide(
199+
self, request: Request, request_data: GraphQLRequestData
200+
) -> Response:
196201
content = render_template_string(self.graphql_ide_html)
197202
return Response(content, status=200, content_type="text/html")
198203

src/graphql_server/http/async_base_view.py

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from typing_extensions import Literal, TypeGuard
1717

1818
from graphql import ExecutionResult, GraphQLError
19-
from graphql.language import OperationType
19+
from graphql.language import OperationType, DocumentNode
2020
from graphql.type import GraphQLSchema
2121

2222
from graphql_server import execute, subscribe
@@ -171,7 +171,9 @@ def create_response(
171171
) -> Response: ...
172172

173173
@abc.abstractmethod
174-
async def render_graphql_ide(self, request: Request) -> Response: ...
174+
async def render_graphql_ide(
175+
self, request: Request, request_data: GraphQLRequestData
176+
) -> Response: ...
175177

176178
async def create_streaming_response(
177179
self,
@@ -198,18 +200,14 @@ async def create_websocket_response(
198200
) -> WebSocketResponse: ...
199201

200202
async def execute_operation(
201-
self, request: Request, context: Context, root_value: Optional[RootValue]
203+
self,
204+
request: Request,
205+
request_data: GraphQLRequestData,
206+
context: Context,
207+
root_value: Optional[RootValue],
202208
) -> ExecutionResult:
203209
request_adapter = self.request_adapter_class(request)
204210

205-
try:
206-
request_data = await self.parse_http_body(request_adapter)
207-
except json.decoder.JSONDecodeError as e:
208-
raise HTTPException(400, "Unable to parse request body as JSON") from e
209-
# DO this only when doing files
210-
except KeyError as e:
211-
raise HTTPException(400, "File(s) missing in form data") from e
212-
213211
allowed_operation_types = operation_type_from_http(request_adapter.method)
214212

215213
if not self.allow_queries_via_get and request_adapter.method == "GET":
@@ -343,14 +341,25 @@ async def run(
343341
if not self.is_request_allowed(request_adapter):
344342
raise HTTPException(405, "GraphQL only supports GET and POST requests.")
345343

344+
try:
345+
request_data = await self.parse_http_body(request_adapter)
346+
except json.decoder.JSONDecodeError as e:
347+
raise HTTPException(400, "Unable to parse request body as JSON") from e
348+
# DO this only when doing files
349+
except KeyError as e:
350+
raise HTTPException(400, "File(s) missing in form data") from e
351+
346352
if self.should_render_graphql_ide(request_adapter):
347353
if self.graphql_ide:
348-
return await self.render_graphql_ide(request)
354+
return await self.render_graphql_ide(request, request_data)
349355
raise HTTPException(404, "Not Found")
350356

351357
try:
352358
result = await self.execute_operation(
353-
request=request, context=context, root_value=root_value
359+
request=request,
360+
request_data=request_data,
361+
context=context,
362+
root_value=root_value,
354363
)
355364
except GraphQLValidationError as e:
356365
result = ExecutionResult(data=None, errors=e.errors)
@@ -529,6 +538,17 @@ async def parse_multipart_subscriptions(
529538

530539
return self.parse_json(await request.get_body())
531540

541+
async def get_graphql_request_data(
542+
self, data: dict[str, Any], protocol: Literal["http", "multipart-subscription"]
543+
) -> GraphQLRequestData:
544+
return GraphQLRequestData(
545+
query=data.get("query"),
546+
variables=data.get("variables"),
547+
operation_name=data.get("operationName"),
548+
extensions=data.get("extensions"),
549+
protocol=protocol,
550+
)
551+
532552
async def parse_http_body(
533553
self, request: AsyncHTTPRequestAdapter
534554
) -> GraphQLRequestData:
@@ -550,13 +570,7 @@ async def parse_http_body(
550570
else:
551571
raise HTTPException(400, "Unsupported content type")
552572

553-
return GraphQLRequestData(
554-
query=data.get("query"),
555-
variables=data.get("variables"),
556-
operation_name=data.get("operationName"),
557-
extensions=data.get("extensions"),
558-
protocol=protocol,
559-
)
573+
return await self.get_graphql_request_data(data, protocol)
560574

561575
async def process_result(
562576
self, request: Request, result: ExecutionResult

src/graphql_server/http/sync_base_view.py

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
Generic,
88
Optional,
99
Union,
10+
Literal,
1011
)
1112

1213
from graphql import ExecutionResult, GraphQLError
@@ -93,21 +94,19 @@ def create_response(
9394
) -> Response: ...
9495

9596
@abc.abstractmethod
96-
def render_graphql_ide(self, request: Request) -> Response: ...
97+
def render_graphql_ide(
98+
self, request: Request, request_data: GraphQLRequestData
99+
) -> Response: ...
97100

98101
def execute_operation(
99-
self, request: Request, context: Context, root_value: Optional[RootValue]
102+
self,
103+
request: Request,
104+
request_data: GraphQLRequestData,
105+
context: Context,
106+
root_value: Optional[RootValue],
100107
) -> ExecutionResult:
101108
request_adapter = self.request_adapter_class(request)
102109

103-
try:
104-
request_data = self.parse_http_body(request_adapter)
105-
except json.decoder.JSONDecodeError as e:
106-
raise HTTPException(400, "Unable to parse request body as JSON") from e
107-
# DO this only when doing files
108-
except KeyError as e:
109-
raise HTTPException(400, "File(s) missing in form data") from e
110-
111110
allowed_operation_types = operation_type_from_http(request_adapter.method)
112111

113112
if not self.allow_queries_via_get and request_adapter.method == "GET":
@@ -135,6 +134,17 @@ def parse_multipart(self, request: SyncHTTPRequestAdapter) -> dict[str, str]:
135134
except KeyError as e:
136135
raise HTTPException(400, "File(s) missing in form data") from e
137136

137+
def get_graphql_request_data(
138+
self, data: dict[str, Any], protocol: Literal["http", "multipart-subscription"]
139+
) -> GraphQLRequestData:
140+
return GraphQLRequestData(
141+
query=data.get("query"),
142+
variables=data.get("variables"),
143+
operation_name=data.get("operationName"),
144+
extensions=data.get("extensions"),
145+
protocol=protocol,
146+
)
147+
138148
def parse_http_body(self, request: SyncHTTPRequestAdapter) -> GraphQLRequestData:
139149
content_type, params = parse_content_type(request.content_type or "")
140150

@@ -152,12 +162,7 @@ def parse_http_body(self, request: SyncHTTPRequestAdapter) -> GraphQLRequestData
152162
else:
153163
raise HTTPException(400, "Unsupported content type")
154164

155-
return GraphQLRequestData(
156-
query=data.get("query"),
157-
variables=data.get("variables"),
158-
operation_name=data.get("operationName"),
159-
extensions=data.get("extensions"),
160-
)
165+
return self.get_graphql_request_data(data, "http")
161166

162167
def _handle_errors(
163168
self, errors: list[GraphQLError], response_data: GraphQLHTTPResponse
@@ -175,9 +180,17 @@ def run(
175180
if not self.is_request_allowed(request_adapter):
176181
raise HTTPException(405, "GraphQL only supports GET and POST requests.")
177182

183+
try:
184+
request_data = self.parse_http_body(request_adapter)
185+
except json.decoder.JSONDecodeError as e:
186+
raise HTTPException(400, "Unable to parse request body as JSON") from e
187+
# DO this only when doing files
188+
except KeyError as e:
189+
raise HTTPException(400, "File(s) missing in form data") from e
190+
178191
if self.should_render_graphql_ide(request_adapter):
179192
if self.graphql_ide:
180-
return self.render_graphql_ide(request)
193+
return self.render_graphql_ide(request, request_data)
181194
raise HTTPException(404, "Not Found")
182195

183196
sub_response = self.get_sub_response(request)
@@ -191,6 +204,7 @@ def run(
191204
try:
192205
result = self.execute_operation(
193206
request=request,
207+
request_data=request_data,
194208
context=context,
195209
root_value=root_value,
196210
)

0 commit comments

Comments
 (0)