From 42e33b083fb95fc477b89d0462409f0c3e2c4a3f Mon Sep 17 00:00:00 2001 From: Jonathan Ehwald Date: Mon, 7 Oct 2024 00:16:54 +0200 Subject: [PATCH 1/4] Stop conditionally disabling WS support in IDEs --- docs/integrations/channels.md | 2 -- docs/integrations/django.md | 4 --- strawberry/chalice/views.py | 1 - strawberry/channels/handlers/http_handler.py | 3 --- strawberry/django/views.py | 27 +++++--------------- strawberry/flask/views.py | 1 - strawberry/http/base.py | 10 +------- strawberry/http/ides.py | 7 ----- strawberry/quart/views.py | 2 -- strawberry/static/graphiql.html | 5 +--- 10 files changed, 8 insertions(+), 54 deletions(-) diff --git a/docs/integrations/channels.md b/docs/integrations/channels.md index ce4fc70fb6..910e4a1ffc 100644 --- a/docs/integrations/channels.md +++ b/docs/integrations/channels.md @@ -522,8 +522,6 @@ GraphQLWebsocketCommunicator( to disable it by passing `None`. - `allow_queries_via_get`: optional, defaults to `True`, whether to enable queries via `GET` requests -- `subscriptions_enabled`: optional boolean paramenter enabling subscriptions in - the GraphiQL interface, defaults to `True` - `multipart_uploads_enabled`: optional, defaults to `False`, controls whether to enable multipart uploads. Please make sure to consider the [security implications mentioned in the GraphQL Multipart Request Specification](https://github.com/jaydenseric/graphql-multipart-request-spec/blob/master/readme.md#security) diff --git a/docs/integrations/django.md b/docs/integrations/django.md index 2909aba6f9..6a127f055a 100644 --- a/docs/integrations/django.md +++ b/docs/integrations/django.md @@ -39,8 +39,6 @@ The `GraphQLView` accepts the following arguments: to disable it by passing `None`. - `allow_queries_via_get`: optional, defaults to `True`, whether to enable queries via `GET` requests -- `subscriptions_enabled`: optional boolean paramenter enabling subscriptions in - the GraphiQL interface, defaults to `False`. - `multipart_uploads_enabled`: optional, defaults to `False`, controls whether to enable multipart uploads. Please make sure to consider the [security implications mentioned in the GraphQL Multipart Request Specification](https://github.com/jaydenseric/graphql-multipart-request-spec/blob/master/readme.md#security) @@ -182,8 +180,6 @@ The `AsyncGraphQLView` accepts the following arguments: to disable it by passing `None`. - `allow_queries_via_get`: optional, defaults to `True`, whether to enable queries via `GET` requests -- `subscriptions_enabled`: optional boolean paramenter enabling subscriptions in - the GraphiQL interface, defaults to `False`. ## Extending the view diff --git a/strawberry/chalice/views.py b/strawberry/chalice/views.py index 3da2838eaa..9c131f202d 100644 --- a/strawberry/chalice/views.py +++ b/strawberry/chalice/views.py @@ -54,7 +54,6 @@ class GraphQLView( ): allow_queries_via_get: bool = True request_adapter_class = ChaliceHTTPRequestAdapter - _ide_subscription_enabled = False def __init__( self, diff --git a/strawberry/channels/handlers/http_handler.py b/strawberry/channels/handlers/http_handler.py index 8d682eea74..a60bf2789e 100644 --- a/strawberry/channels/handlers/http_handler.py +++ b/strawberry/channels/handlers/http_handler.py @@ -167,14 +167,11 @@ def __init__( graphiql: Optional[bool] = None, graphql_ide: Optional[GraphQL_IDE] = "graphiql", allow_queries_via_get: bool = True, - subscriptions_enabled: bool = True, multipart_uploads_enabled: bool = False, **kwargs: Any, ) -> None: self.schema = schema self.allow_queries_via_get = allow_queries_via_get - self.subscriptions_enabled = subscriptions_enabled - self._ide_subscriptions_enabled = subscriptions_enabled self.multipart_uploads_enabled = multipart_uploads_enabled if graphiql is not None: diff --git a/strawberry/django/views.py b/strawberry/django/views.py index 457314d93b..4cfe773211 100644 --- a/strawberry/django/views.py +++ b/strawberry/django/views.py @@ -137,7 +137,6 @@ async def get_form_data(self) -> FormData: class BaseView: - _ide_replace_variables = False graphql_ide_html: str def __init__( @@ -146,13 +145,11 @@ def __init__( graphiql: Optional[str] = None, graphql_ide: Optional[GraphQL_IDE] = "graphiql", allow_queries_via_get: bool = True, - subscriptions_enabled: bool = False, multipart_uploads_enabled: bool = False, **kwargs: Any, ) -> None: self.schema = schema self.allow_queries_via_get = allow_queries_via_get - self.subscriptions_enabled = subscriptions_enabled self.multipart_uploads_enabled = multipart_uploads_enabled if graphiql is not None: @@ -215,7 +212,6 @@ class GraphQLView( ], View, ): - subscriptions_enabled = False graphiql: Optional[bool] = None graphql_ide: Optional[GraphQL_IDE] = "graphiql" allow_queries_via_get = True @@ -244,16 +240,11 @@ def dispatch( def render_graphql_ide(self, request: HttpRequest) -> HttpResponse: try: - template = Template(render_to_string("graphql/graphiql.html")) + content = render_to_string("graphql/graphiql.html") except TemplateDoesNotExist: - template = Template(self.graphql_ide_html) + content = self.graphql_ide_html - context = {"SUBSCRIPTION_ENABLED": json.dumps(self.subscriptions_enabled)} - - response = TemplateResponse(request=request, template=None, context=context) - response.content = template.render(RequestContext(request, context)) - - return response + return HttpResponse(content) class AsyncGraphQLView( @@ -269,7 +260,6 @@ class AsyncGraphQLView( ], View, ): - subscriptions_enabled = False graphiql: Optional[bool] = None graphql_ide: Optional[GraphQL_IDE] = "graphiql" allow_queries_via_get = True @@ -308,16 +298,11 @@ async def dispatch( # pyright: ignore async def render_graphql_ide(self, request: HttpRequest) -> HttpResponse: try: - template = Template(render_to_string("graphql/graphiql.html")) + content = render_to_string("graphql/graphiql.html") except TemplateDoesNotExist: - template = Template(self.graphql_ide_html) + content = self.graphql_ide_html - context = {"SUBSCRIPTION_ENABLED": json.dumps(self.subscriptions_enabled)} - - response = TemplateResponse(request=request, template=None, context=context) - response.content = template.render(RequestContext(request, context)) - - return response + return HttpResponse(content=content) def is_websocket_request(self, request: HttpRequest) -> TypeGuard[HttpRequest]: return False diff --git a/strawberry/flask/views.py b/strawberry/flask/views.py index 2dc15d6d6c..053003ac91 100644 --- a/strawberry/flask/views.py +++ b/strawberry/flask/views.py @@ -63,7 +63,6 @@ def content_type(self) -> Optional[str]: class BaseGraphQLView: - _ide_subscription_enabled = False graphql_ide: Optional[GraphQL_IDE] def __init__( diff --git a/strawberry/http/base.py b/strawberry/http/base.py index 5ab57ef65d..a906849ddf 100644 --- a/strawberry/http/base.py +++ b/strawberry/http/base.py @@ -25,10 +25,6 @@ class BaseView(Generic[Request]): graphql_ide: Optional[GraphQL_IDE] multipart_uploads_enabled: bool = False - # TODO: we might remove this in future :) - _ide_replace_variables: bool = True - _ide_subscription_enabled: bool = True - def should_render_graphql_ide(self, request: BaseRequestProtocol) -> bool: return ( request.method == "GET" @@ -64,11 +60,7 @@ def parse_query_params(self, params: QueryParams) -> Dict[str, Any]: @property def graphql_ide_html(self) -> str: - return get_graphql_ide_html( - subscription_enabled=self._ide_subscription_enabled, - replace_variables=self._ide_replace_variables, - graphql_ide=self.graphql_ide, - ) + return get_graphql_ide_html(graphql_ide=self.graphql_ide) def _is_multipart_subscriptions( self, content_type: str, params: Dict[str, str] diff --git a/strawberry/http/ides.py b/strawberry/http/ides.py index d9c52fb716..a97be660a6 100644 --- a/strawberry/http/ides.py +++ b/strawberry/http/ides.py @@ -7,8 +7,6 @@ def get_graphql_ide_html( - subscription_enabled: bool = True, - replace_variables: bool = True, graphql_ide: Optional[GraphQL_IDE] = "graphiql", ) -> str: here = pathlib.Path(__file__).parents[1] @@ -22,11 +20,6 @@ def get_graphql_ide_html( template = path.read_text(encoding="utf-8") - if replace_variables: - template = template.replace( - "{{ SUBSCRIPTION_ENABLED }}", json.dumps(subscription_enabled) - ) - return template diff --git a/strawberry/quart/views.py b/strawberry/quart/views.py index c7dc1257fd..528a987abc 100644 --- a/strawberry/quart/views.py +++ b/strawberry/quart/views.py @@ -52,8 +52,6 @@ class GraphQLView( ], View, ): - _ide_subscription_enabled = False - methods = ["GET", "POST"] allow_queries_via_get: bool = True request_adapter_class = QuartHTTPRequestAdapter diff --git a/strawberry/static/graphiql.html b/strawberry/static/graphiql.html index 95e34c1709..b66082a97f 100644 --- a/strawberry/static/graphiql.html +++ b/strawberry/static/graphiql.html @@ -131,10 +131,7 @@ headers["x-csrftoken"] = csrfToken; } - const subscriptionsEnabled = JSON.parse("{{ SUBSCRIPTION_ENABLED }}"); - const subscriptionUrl = subscriptionsEnabled - ? httpUrlToWebSockeUrl(fetchURL) - : null; + const subscriptionUrl = httpUrlToWebSockeUrl(fetchURL); const fetcher = GraphiQL.createFetcher({ url: fetchURL, From 92c5028c03cdd0a7fa63a2a399234bfd05a2df2e Mon Sep 17 00:00:00 2001 From: Jonathan Ehwald Date: Mon, 7 Oct 2024 00:39:44 +0200 Subject: [PATCH 2/4] Add release file --- RELEASE.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 RELEASE.md diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 0000000000..ae000d7c0e --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,4 @@ +Release type: minor + +This release removes the dated `subscriptions_enabled` setting from the Django and Channels integrations. +Instead, WebSocket support is now enabled by default in all GraphQL IDEs. From 72a514ea7b17e586aa52d42b826dee407cde449d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 6 Oct 2024 22:47:42 +0000 Subject: [PATCH 3/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- strawberry/django/views.py | 1 - strawberry/http/ides.py | 1 - 2 files changed, 2 deletions(-) diff --git a/strawberry/django/views.py b/strawberry/django/views.py index 4cfe773211..7b61b611c6 100644 --- a/strawberry/django/views.py +++ b/strawberry/django/views.py @@ -25,7 +25,6 @@ StreamingHttpResponse, ) from django.http.response import HttpResponseBase -from django.template import RequestContext, Template from django.template.exceptions import TemplateDoesNotExist from django.template.loader import render_to_string from django.template.response import TemplateResponse diff --git a/strawberry/http/ides.py b/strawberry/http/ides.py index a97be660a6..9680a0277a 100644 --- a/strawberry/http/ides.py +++ b/strawberry/http/ides.py @@ -1,4 +1,3 @@ -import json import pathlib from typing import Optional from typing_extensions import Literal From 41095a3863ddc3014c11fb9fd5788c14fcb797d5 Mon Sep 17 00:00:00 2001 From: Jonathan Ehwald Date: Mon, 7 Oct 2024 01:44:44 +0200 Subject: [PATCH 4/4] Move import into type-checking block --- strawberry/django/views.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/strawberry/django/views.py b/strawberry/django/views.py index 7b61b611c6..23fa07e886 100644 --- a/strawberry/django/views.py +++ b/strawberry/django/views.py @@ -27,7 +27,6 @@ from django.http.response import HttpResponseBase from django.template.exceptions import TemplateDoesNotExist from django.template.loader import render_to_string -from django.template.response import TemplateResponse from django.utils.decorators import classonlymethod from django.views.generic import View @@ -43,6 +42,8 @@ from .context import StrawberryDjangoContext if TYPE_CHECKING: + from django.template.response import TemplateResponse + from strawberry.http import GraphQLHTTPResponse from strawberry.http.ides import GraphQL_IDE