Skip to content

Commit 578453f

Browse files
committed
More improvements
1 parent 3b282e2 commit 578453f

File tree

5 files changed

+38
-51
lines changed

5 files changed

+38
-51
lines changed

src/graphql_server/http/async_base_view.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -327,12 +327,18 @@ async def run(
327327
request = cast("Request", request)
328328

329329
request_adapter = self.request_adapter_class(request)
330+
sub_response = await self.get_sub_response(request)
331+
context = (
332+
await self.get_context(request, response=sub_response)
333+
if context is UNSET
334+
else context
335+
)
330336

331337
if not self.is_request_allowed(request_adapter):
332338
raise HTTPException(405, "GraphQL only supports GET and POST requests.")
333339

334340
try:
335-
request_data = await self.parse_http_body(request_adapter)
341+
request_data = await self.parse_http_body(context, request_adapter)
336342
except json.decoder.JSONDecodeError as e:
337343
raise HTTPException(400, "Unable to parse request body as JSON") from e
338344
# DO this only when doing files
@@ -350,13 +356,6 @@ async def run(
350356
if self.graphql_ide and self.should_render_graphql_ide(request_adapter):
351357
return await self.render_graphql_ide(request, request_data)
352358

353-
sub_response = await self.get_sub_response(request)
354-
context = (
355-
await self.get_context(request, response=sub_response)
356-
if context is UNSET
357-
else context
358-
)
359-
360359
try:
361360
result = await self.execute_operation(
362361
request=request,
@@ -544,6 +543,7 @@ async def parse_multipart_subscriptions(
544543

545544
async def get_graphql_request_data(
546545
self,
546+
context: Context,
547547
data: dict[str, Any],
548548
protocol: Literal["http", "multipart-subscription", "subscription"],
549549
) -> GraphQLRequestData:
@@ -557,7 +557,7 @@ async def get_graphql_request_data(
557557
)
558558

559559
async def parse_http_body(
560-
self, request: AsyncHTTPRequestAdapter
560+
self, context: Context, request: AsyncHTTPRequestAdapter
561561
) -> GraphQLRequestData:
562562
headers = {key.lower(): value for key, value in request.headers.items()}
563563
content_type, _ = parse_content_type(request.content_type or "")
@@ -577,7 +577,7 @@ async def parse_http_body(
577577
else:
578578
raise HTTPException(400, "Unsupported content type")
579579

580-
return await self.get_graphql_request_data(data, protocol)
580+
return await self.get_graphql_request_data(context, data, protocol)
581581

582582
async def process_result(
583583
self, request: Request, result: ExecutionResult

src/graphql_server/http/sync_base_view.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,10 @@ def parse_multipart(self, request: SyncHTTPRequestAdapter) -> dict[str, str]:
131131
raise HTTPException(400, "File(s) missing in form data") from e
132132

133133
def get_graphql_request_data(
134-
self, data: dict[str, Any], protocol: Literal["http", "multipart-subscription"]
134+
self,
135+
context: Context,
136+
data: dict[str, Any],
137+
protocol: Literal["http", "multipart-subscription"],
135138
) -> GraphQLRequestData:
136139
return GraphQLRequestData(
137140
query=data.get("query"),
@@ -142,7 +145,9 @@ def get_graphql_request_data(
142145
protocol=protocol,
143146
)
144147

145-
def parse_http_body(self, request: SyncHTTPRequestAdapter) -> GraphQLRequestData:
148+
def parse_http_body(
149+
self, context: Context, request: SyncHTTPRequestAdapter
150+
) -> GraphQLRequestData:
146151
content_type, params = parse_content_type(request.content_type or "")
147152

148153
if request.method == "GET":
@@ -159,7 +164,7 @@ def parse_http_body(self, request: SyncHTTPRequestAdapter) -> GraphQLRequestData
159164
else:
160165
raise HTTPException(400, "Unsupported content type")
161166

162-
return self.get_graphql_request_data(data, "http")
167+
return self.get_graphql_request_data(context, data, "http")
163168

164169
def _handle_errors(
165170
self, errors: list[GraphQLError], response_data: GraphQLHTTPResponse
@@ -177,8 +182,15 @@ def run(
177182
if not self.is_request_allowed(request_adapter):
178183
raise HTTPException(405, "GraphQL only supports GET and POST requests.")
179184

185+
sub_response = self.get_sub_response(request)
186+
context = (
187+
self.get_context(request, response=sub_response)
188+
if context is UNSET
189+
else context
190+
)
191+
180192
try:
181-
request_data = self.parse_http_body(request_adapter)
193+
request_data = self.parse_http_body(context, request_adapter)
182194
except json.decoder.JSONDecodeError as e:
183195
raise HTTPException(400, "Unable to parse request body as JSON") from e
184196
# DO this only when doing files
@@ -196,12 +208,6 @@ def run(
196208
if self.graphql_ide and self.should_render_graphql_ide(request_adapter):
197209
return self.render_graphql_ide(request, request_data)
198210

199-
sub_response = self.get_sub_response(request)
200-
context = (
201-
self.get_context(request, response=sub_response)
202-
if context is UNSET
203-
else context
204-
)
205211
root_value = self.get_root_value(request) if root_value is UNSET else root_value
206212

207213
try:

src/graphql_server/static/graphiql.html

Lines changed: 11 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -123,35 +123,20 @@
123123

124124
// Collect the URL parameters
125125
var parameters = {};
126-
window.location.search.substr(1).split('&').forEach(function (entry) {
127-
var eq = entry.indexOf('=');
128-
if (eq >= 0) {
129-
parameters[decodeURIComponent(entry.slice(0, eq))] =
130-
decodeURIComponent(entry.slice(eq + 1));
131-
}
132-
});
133-
// Produce a Location query string from a parameter object.
134-
function locationQuery(params) {
135-
return '?' + Object.keys(params).filter(function (key) {
136-
return Boolean(params[key]);
137-
}).map(function (key) {
138-
return encodeURIComponent(key) + '=' +
139-
encodeURIComponent(params[key]);
140-
}).join('&');
141-
}
142126
// Derive a fetch URL from the current URL, sans the GraphQL parameters.
143127
var graphqlParamNames = {
144128
query: true,
145129
variables: true,
146130
operationName: true
147131
};
148-
var otherParams = {};
149-
for (var k in parameters) {
150-
if (parameters.hasOwnProperty(k) && graphqlParamNames[k] !== true) {
151-
otherParams[k] = parameters[k];
132+
var currentURL = new URL(window.location.href);
133+
var newParams = new URLSearchParams();
134+
for (var [k, v] of currentURL.searchParams.entries()) {
135+
if (graphqlParamNames[k] !== true) {
136+
newParams.append(k, v);
152137
}
153138
}
154-
var fetchURL = window.location.pathname + locationQuery(otherParams);
139+
var fetchURL = window.location.pathname + '?' + newParams.toString();
155140

156141
function httpUrlToWebSockeUrl(url) {
157142
const parsedURL = new URL(url, window.location.href);
@@ -208,15 +193,15 @@
208193
defaultEditorToolsVisibility: true,
209194
plugins: [explorerPlugin],
210195
inputValueDeprecation: true,
211-
onEditQuery: onEditQuery,
212-
onEditVariables: onEditVariables,
213-
onEditHeaders: onEditHeaders,
214-
onEditOperationName: onEditOperationName,
215196
query: {{query}},
216-
variables: {{variables}},
197+
variables: '{{variables}}',
217198
headers: parameters.headers,
218199
operationName: {{operation_name}},
219200
defaultQuery: EXAMPLE_QUERY,
201+
onEditQuery: onEditQuery,
202+
onEditVariables: onEditVariables,
203+
onEditHeaders: onEditHeaders,
204+
onEditOperationName: onEditOperationName,
220205
}),
221206
);
222207
</script>

src/graphql_server/subscriptions/protocols/graphql_transport_ws/handlers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ async def handle_subscribe(self, message: SubscribeMessage) -> None:
255255
)
256256

257257
request_data = await self.view.get_graphql_request_data(
258-
message["payload"], "subscription"
258+
self.context, message["payload"], "subscription"
259259
)
260260

261261
operation = Operation(

src/tests/websockets/test_graphql_transport_ws.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,6 @@ async def test_connection_init_timeout_cancellation(
194194
)
195195

196196

197-
@pytest.mark.xfail(reason="This test is flaky")
198197
async def test_close_twice(mocker: MockerFixture, http_client_class: type[HttpClient]):
199198
test_client = http_client_class(
200199
connection_init_wait_timeout=timedelta(seconds=0.25)
@@ -1049,9 +1048,6 @@ async def test_rejects_connection_params_with_wrong_type(
10491048
assert ws.close_reason == "Invalid connection init payload"
10501049

10511050

1052-
# timings can sometimes fail currently. Until this test is rewritten when
1053-
# generator based subscriptions are implemented, mark it as flaky
1054-
@pytest.mark.xfail(reason="This test is flaky, see comment above")
10551051
async def test_subsciption_cancel_finalization_delay(ws: WebSocketClient):
10561052
# Test that when we cancel a subscription, the websocket isn't blocked
10571053
# while some complex finalization takes place.

0 commit comments

Comments
 (0)