strawberry-graphql 0.243.1__py3-none-any.whl → 0.244.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.
Files changed (36) hide show
  1. strawberry/aiohttp/views.py +58 -44
  2. strawberry/asgi/__init__.py +62 -61
  3. strawberry/channels/__init__.py +1 -6
  4. strawberry/channels/handlers/base.py +2 -2
  5. strawberry/channels/handlers/http_handler.py +18 -1
  6. strawberry/channels/handlers/ws_handler.py +113 -58
  7. strawberry/django/views.py +19 -1
  8. strawberry/fastapi/router.py +27 -45
  9. strawberry/flask/views.py +15 -1
  10. strawberry/http/async_base_view.py +136 -16
  11. strawberry/http/exceptions.py +4 -0
  12. strawberry/http/typevars.py +11 -1
  13. strawberry/litestar/controller.py +77 -86
  14. strawberry/quart/views.py +15 -1
  15. strawberry/sanic/views.py +21 -1
  16. strawberry/subscriptions/protocols/graphql_transport_ws/handlers.py +41 -40
  17. strawberry/subscriptions/protocols/graphql_ws/handlers.py +46 -45
  18. {strawberry_graphql-0.243.1.dist-info → strawberry_graphql-0.244.0.dist-info}/METADATA +1 -1
  19. {strawberry_graphql-0.243.1.dist-info → strawberry_graphql-0.244.0.dist-info}/RECORD +22 -36
  20. strawberry/aiohttp/handlers/__init__.py +0 -6
  21. strawberry/aiohttp/handlers/graphql_transport_ws_handler.py +0 -62
  22. strawberry/aiohttp/handlers/graphql_ws_handler.py +0 -69
  23. strawberry/asgi/handlers/__init__.py +0 -6
  24. strawberry/asgi/handlers/graphql_transport_ws_handler.py +0 -66
  25. strawberry/asgi/handlers/graphql_ws_handler.py +0 -71
  26. strawberry/channels/handlers/graphql_transport_ws_handler.py +0 -62
  27. strawberry/channels/handlers/graphql_ws_handler.py +0 -72
  28. strawberry/fastapi/handlers/__init__.py +0 -6
  29. strawberry/fastapi/handlers/graphql_transport_ws_handler.py +0 -20
  30. strawberry/fastapi/handlers/graphql_ws_handler.py +0 -18
  31. strawberry/litestar/handlers/__init__.py +0 -0
  32. strawberry/litestar/handlers/graphql_transport_ws_handler.py +0 -60
  33. strawberry/litestar/handlers/graphql_ws_handler.py +0 -66
  34. {strawberry_graphql-0.243.1.dist-info → strawberry_graphql-0.244.0.dist-info}/LICENSE +0 -0
  35. {strawberry_graphql-0.243.1.dist-info → strawberry_graphql-0.244.0.dist-info}/WHEEL +0 -0
  36. {strawberry_graphql-0.243.1.dist-info → strawberry_graphql-0.244.0.dist-info}/entry_points.txt +0 -0
strawberry/quart/views.py CHANGED
@@ -1,6 +1,7 @@
1
1
  import warnings
2
2
  from collections.abc import Mapping
3
3
  from typing import TYPE_CHECKING, AsyncGenerator, Callable, Dict, Optional, cast
4
+ from typing_extensions import TypeGuard
4
5
 
5
6
  from quart import Request, Response, request
6
7
  from quart.views import View
@@ -46,7 +47,9 @@ class QuartHTTPRequestAdapter(AsyncHTTPRequestAdapter):
46
47
 
47
48
 
48
49
  class GraphQLView(
49
- AsyncBaseHTTPView[Request, Response, Response, Context, RootValue],
50
+ AsyncBaseHTTPView[
51
+ Request, Response, Response, Request, Response, Context, RootValue
52
+ ],
50
53
  View,
51
54
  ):
52
55
  _ide_subscription_enabled = False
@@ -121,5 +124,16 @@ class GraphQLView(
121
124
  },
122
125
  )
123
126
 
127
+ def is_websocket_request(self, request: Request) -> TypeGuard[Request]:
128
+ return False
129
+
130
+ async def pick_websocket_subprotocol(self, request: Request) -> Optional[str]:
131
+ raise NotImplementedError
132
+
133
+ async def create_websocket_response(
134
+ self, request: Request, subprotocol: Optional[str]
135
+ ) -> Response:
136
+ raise NotImplementedError
137
+
124
138
 
125
139
  __all__ = ["GraphQLView"]
strawberry/sanic/views.py CHANGED
@@ -13,6 +13,7 @@ from typing import (
13
13
  Type,
14
14
  cast,
15
15
  )
16
+ from typing_extensions import TypeGuard
16
17
 
17
18
  from sanic.request import Request
18
19
  from sanic.response import HTTPResponse, html
@@ -71,7 +72,15 @@ class SanicHTTPRequestAdapter(AsyncHTTPRequestAdapter):
71
72
 
72
73
 
73
74
  class GraphQLView(
74
- AsyncBaseHTTPView[Request, HTTPResponse, TemporalResponse, Context, RootValue],
75
+ AsyncBaseHTTPView[
76
+ Request,
77
+ HTTPResponse,
78
+ TemporalResponse,
79
+ Request,
80
+ TemporalResponse,
81
+ Context,
82
+ RootValue,
83
+ ],
75
84
  HTTPMethodView,
76
85
  ):
77
86
  """Class based view to handle GraphQL HTTP Requests.
@@ -206,5 +215,16 @@ class GraphQLView(
206
215
  # corner case
207
216
  return None # type: ignore
208
217
 
218
+ def is_websocket_request(self, request: Request) -> TypeGuard[Request]:
219
+ return False
220
+
221
+ async def pick_websocket_subprotocol(self, request: Request) -> Optional[str]:
222
+ raise NotImplementedError
223
+
224
+ async def create_websocket_response(
225
+ self, request: Request, subprotocol: Optional[str]
226
+ ) -> TemporalResponse:
227
+ raise NotImplementedError
228
+
209
229
 
210
230
  __all__ = ["GraphQLView"]
@@ -2,7 +2,6 @@ from __future__ import annotations
2
2
 
3
3
  import asyncio
4
4
  import logging
5
- from abc import ABC, abstractmethod
6
5
  from contextlib import suppress
7
6
  from typing import (
8
7
  TYPE_CHECKING,
@@ -16,6 +15,7 @@ from typing import (
16
15
 
17
16
  from graphql import GraphQLError, GraphQLSyntaxError, parse
18
17
 
18
+ from strawberry.http.exceptions import NonJsonMessageReceived
19
19
  from strawberry.subscriptions.protocols.graphql_transport_ws.types import (
20
20
  CompleteMessage,
21
21
  ConnectionAckMessage,
@@ -38,6 +38,7 @@ from strawberry.utils.operation import get_operation_type
38
38
  if TYPE_CHECKING:
39
39
  from datetime import timedelta
40
40
 
41
+ from strawberry.http.async_base_view import AsyncWebSocketAdapter
41
42
  from strawberry.schema import BaseSchema
42
43
  from strawberry.schema.subscribe import SubscriptionResult
43
44
  from strawberry.subscriptions.protocols.graphql_transport_ws.types import (
@@ -45,15 +46,21 @@ if TYPE_CHECKING:
45
46
  )
46
47
 
47
48
 
48
- class BaseGraphQLTransportWSHandler(ABC):
49
+ class BaseGraphQLTransportWSHandler:
49
50
  task_logger: logging.Logger = logging.getLogger("strawberry.ws.task")
50
51
 
51
52
  def __init__(
52
53
  self,
54
+ websocket: AsyncWebSocketAdapter,
55
+ context: object,
56
+ root_value: object,
53
57
  schema: BaseSchema,
54
58
  debug: bool,
55
59
  connection_init_wait_timeout: timedelta,
56
60
  ) -> None:
61
+ self.websocket = websocket
62
+ self.context = context
63
+ self.root_value = root_value
57
64
  self.schema = schema
58
65
  self.debug = debug
59
66
  self.connection_init_wait_timeout = connection_init_wait_timeout
@@ -65,28 +72,16 @@ class BaseGraphQLTransportWSHandler(ABC):
65
72
  self.completed_tasks: List[asyncio.Task] = []
66
73
  self.connection_params: Optional[Dict[str, Any]] = None
67
74
 
68
- @abstractmethod
69
- async def get_context(self) -> Any:
70
- """Return the operations context."""
71
-
72
- @abstractmethod
73
- async def get_root_value(self) -> Any:
74
- """Return the schemas root value."""
75
-
76
- @abstractmethod
77
- async def send_json(self, data: dict) -> None:
78
- """Send the data JSON encoded to the WebSocket client."""
79
-
80
- @abstractmethod
81
- async def close(self, code: int, reason: str) -> None:
82
- """Close the WebSocket with the passed code and reason."""
83
-
84
- @abstractmethod
85
- async def handle_request(self) -> Any:
86
- """Handle the request this instance was created for."""
87
-
88
75
  async def handle(self) -> Any:
89
- return await self.handle_request()
76
+ self.on_request_accepted()
77
+
78
+ try:
79
+ async for message in self.websocket.iter_json():
80
+ await self.handle_message(message)
81
+ except NonJsonMessageReceived:
82
+ await self.handle_invalid_message("WebSocket message type must be text")
83
+ finally:
84
+ await self.shutdown()
90
85
 
91
86
  async def shutdown(self) -> None:
92
87
  if self.connection_init_timeout_task:
@@ -118,7 +113,7 @@ class BaseGraphQLTransportWSHandler(ABC):
118
113
 
119
114
  self.connection_timed_out = True
120
115
  reason = "Connection initialisation timeout"
121
- await self.close(code=4408, reason=reason)
116
+ await self.websocket.close(code=4408, reason=reason)
122
117
  except Exception as error:
123
118
  await self.handle_task_exception(error) # pragma: no cover
124
119
  finally:
@@ -189,14 +184,16 @@ class BaseGraphQLTransportWSHandler(ABC):
189
184
  )
190
185
 
191
186
  if not isinstance(payload, dict):
192
- await self.close(code=4400, reason="Invalid connection init payload")
187
+ await self.websocket.close(
188
+ code=4400, reason="Invalid connection init payload"
189
+ )
193
190
  return
194
191
 
195
192
  self.connection_params = payload
196
193
 
197
194
  if self.connection_init_received:
198
195
  reason = "Too many initialisation requests"
199
- await self.close(code=4429, reason=reason)
196
+ await self.websocket.close(code=4429, reason=reason)
200
197
  return
201
198
 
202
199
  self.connection_init_received = True
@@ -211,13 +208,13 @@ class BaseGraphQLTransportWSHandler(ABC):
211
208
 
212
209
  async def handle_subscribe(self, message: SubscribeMessage) -> None:
213
210
  if not self.connection_acknowledged:
214
- await self.close(code=4401, reason="Unauthorized")
211
+ await self.websocket.close(code=4401, reason="Unauthorized")
215
212
  return
216
213
 
217
214
  try:
218
215
  graphql_document = parse(message.payload.query)
219
216
  except GraphQLSyntaxError as exc:
220
- await self.close(code=4400, reason=exc.message)
217
+ await self.websocket.close(code=4400, reason=exc.message)
221
218
  return
222
219
 
223
220
  try:
@@ -225,12 +222,14 @@ class BaseGraphQLTransportWSHandler(ABC):
225
222
  graphql_document, message.payload.operationName
226
223
  )
227
224
  except RuntimeError:
228
- await self.close(code=4400, reason="Can't get GraphQL operation type")
225
+ await self.websocket.close(
226
+ code=4400, reason="Can't get GraphQL operation type"
227
+ )
229
228
  return
230
229
 
231
230
  if message.id in self.operations:
232
231
  reason = f"Subscriber for {message.id} already exists"
233
- await self.close(code=4409, reason=reason)
232
+ await self.websocket.close(code=4409, reason=reason)
234
233
  return
235
234
 
236
235
  if self.debug: # pragma: no cover
@@ -240,26 +239,28 @@ class BaseGraphQLTransportWSHandler(ABC):
240
239
  message.payload.variables,
241
240
  )
242
241
 
243
- context = await self.get_context()
244
- if isinstance(context, dict):
245
- context["connection_params"] = self.connection_params
246
- root_value = await self.get_root_value()
242
+ if isinstance(self.context, dict):
243
+ self.context["connection_params"] = self.connection_params
244
+ elif hasattr(self.context, "connection_params"):
245
+ self.context.connection_params = self.connection_params
246
+
247
247
  result_source: Awaitable[ExecutionResult] | Awaitable[SubscriptionResult]
248
+
248
249
  # Get an AsyncGenerator yielding the results
249
250
  if operation_type == OperationType.SUBSCRIPTION:
250
251
  result_source = self.schema.subscribe(
251
252
  query=message.payload.query,
252
253
  variable_values=message.payload.variables,
253
254
  operation_name=message.payload.operationName,
254
- context_value=context,
255
- root_value=root_value,
255
+ context_value=self.context,
256
+ root_value=self.root_value,
256
257
  )
257
258
  else:
258
259
  result_source = self.schema.execute(
259
260
  query=message.payload.query,
260
261
  variable_values=message.payload.variables,
261
- context_value=context,
262
- root_value=root_value,
262
+ context_value=self.context,
263
+ root_value=self.root_value,
263
264
  operation_name=message.payload.operationName,
264
265
  )
265
266
 
@@ -312,11 +313,11 @@ class BaseGraphQLTransportWSHandler(ABC):
312
313
  await self.cleanup_operation(operation_id=message.id)
313
314
 
314
315
  async def handle_invalid_message(self, error_message: str) -> None:
315
- await self.close(code=4400, reason=error_message)
316
+ await self.websocket.close(code=4400, reason=error_message)
316
317
 
317
318
  async def send_message(self, message: GraphQLTransportMessage) -> None:
318
319
  data = message.as_dict()
319
- await self.send_json(data)
320
+ await self.websocket.send_json(data)
320
321
 
321
322
  async def cleanup_operation(self, operation_id: str) -> None:
322
323
  if operation_id not in self.operations:
@@ -1,11 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import asyncio
4
- from abc import ABC, abstractmethod
5
4
  from contextlib import suppress
6
5
  from typing import (
7
6
  TYPE_CHECKING,
8
- Any,
9
7
  AsyncGenerator,
10
8
  Awaitable,
11
9
  Dict,
@@ -13,6 +11,7 @@ from typing import (
13
11
  cast,
14
12
  )
15
13
 
14
+ from strawberry.http.exceptions import NonJsonMessageReceived
16
15
  from strawberry.subscriptions.protocols.graphql_ws import (
17
16
  GQL_COMPLETE,
18
17
  GQL_CONNECTION_ACK,
@@ -25,29 +24,36 @@ from strawberry.subscriptions.protocols.graphql_ws import (
25
24
  GQL_START,
26
25
  GQL_STOP,
27
26
  )
27
+ from strawberry.subscriptions.protocols.graphql_ws.types import (
28
+ ConnectionInitPayload,
29
+ DataPayload,
30
+ OperationMessage,
31
+ OperationMessagePayload,
32
+ StartPayload,
33
+ )
28
34
  from strawberry.types.execution import ExecutionResult, PreExecutionError
29
35
  from strawberry.utils.debug import pretty_print_graphql_operation
30
36
 
31
37
  if TYPE_CHECKING:
38
+ from strawberry.http.async_base_view import AsyncWebSocketAdapter
32
39
  from strawberry.schema import BaseSchema
33
40
  from strawberry.schema.subscribe import SubscriptionResult
34
- from strawberry.subscriptions.protocols.graphql_ws.types import (
35
- ConnectionInitPayload,
36
- DataPayload,
37
- OperationMessage,
38
- OperationMessagePayload,
39
- StartPayload,
40
- )
41
41
 
42
42
 
43
- class BaseGraphQLWSHandler(ABC):
43
+ class BaseGraphQLWSHandler:
44
44
  def __init__(
45
45
  self,
46
+ websocket: AsyncWebSocketAdapter,
47
+ context: object,
48
+ root_value: object,
46
49
  schema: BaseSchema,
47
50
  debug: bool,
48
51
  keep_alive: bool,
49
- keep_alive_interval: float,
52
+ keep_alive_interval: Optional[float],
50
53
  ) -> None:
54
+ self.websocket = websocket
55
+ self.context = context
56
+ self.root_value = root_value
51
57
  self.schema = schema
52
58
  self.debug = debug
53
59
  self.keep_alive = keep_alive
@@ -57,28 +63,22 @@ class BaseGraphQLWSHandler(ABC):
57
63
  self.tasks: Dict[str, asyncio.Task] = {}
58
64
  self.connection_params: Optional[ConnectionInitPayload] = None
59
65
 
60
- @abstractmethod
61
- async def get_context(self) -> Any:
62
- """Return the operations context."""
63
-
64
- @abstractmethod
65
- async def get_root_value(self) -> Any:
66
- """Return the schemas root value."""
67
-
68
- @abstractmethod
69
- async def send_json(self, data: OperationMessage) -> None:
70
- """Send the data JSON encoded to the WebSocket client."""
71
-
72
- @abstractmethod
73
- async def close(self, code: int = 1000, reason: Optional[str] = None) -> None:
74
- """Close the WebSocket with the passed code and reason."""
75
-
76
- @abstractmethod
77
- async def handle_request(self) -> Any:
78
- """Handle the request this instance was created for."""
79
-
80
- async def handle(self) -> Any:
81
- return await self.handle_request()
66
+ async def handle(self) -> None:
67
+ try:
68
+ async for message in self.websocket.iter_json():
69
+ await self.handle_message(cast(OperationMessage, message))
70
+ except NonJsonMessageReceived:
71
+ await self.websocket.close(
72
+ code=1002, reason="WebSocket message type must be text"
73
+ )
74
+ finally:
75
+ if self.keep_alive_task:
76
+ self.keep_alive_task.cancel()
77
+ with suppress(BaseException):
78
+ await self.keep_alive_task
79
+
80
+ for operation_id in list(self.subscriptions.keys()):
81
+ await self.cleanup_operation(operation_id)
82
82
 
83
83
  async def handle_message(
84
84
  self,
@@ -99,22 +99,22 @@ class BaseGraphQLWSHandler(ABC):
99
99
  payload = message.get("payload")
100
100
  if payload is not None and not isinstance(payload, dict):
101
101
  error_message: OperationMessage = {"type": GQL_CONNECTION_ERROR}
102
- await self.send_json(error_message)
103
- await self.close()
102
+ await self.websocket.send_json(error_message)
103
+ await self.websocket.close(code=1000, reason="")
104
104
  return
105
105
 
106
106
  payload = cast(Optional["ConnectionInitPayload"], payload)
107
107
  self.connection_params = payload
108
108
 
109
109
  acknowledge_message: OperationMessage = {"type": GQL_CONNECTION_ACK}
110
- await self.send_json(acknowledge_message)
110
+ await self.websocket.send_json(acknowledge_message)
111
111
 
112
112
  if self.keep_alive:
113
113
  keep_alive_handler = self.handle_keep_alive()
114
114
  self.keep_alive_task = asyncio.create_task(keep_alive_handler)
115
115
 
116
116
  async def handle_connection_terminate(self, message: OperationMessage) -> None:
117
- await self.close()
117
+ await self.websocket.close(code=1000, reason="")
118
118
 
119
119
  async def handle_start(self, message: OperationMessage) -> None:
120
120
  operation_id = message["id"]
@@ -123,10 +123,10 @@ class BaseGraphQLWSHandler(ABC):
123
123
  operation_name = payload.get("operationName")
124
124
  variables = payload.get("variables")
125
125
 
126
- context = await self.get_context()
127
- if isinstance(context, dict):
128
- context["connection_params"] = self.connection_params
129
- root_value = await self.get_root_value()
126
+ if isinstance(self.context, dict):
127
+ self.context["connection_params"] = self.connection_params
128
+ elif hasattr(self.context, "connection_params"):
129
+ self.context.connection_params = self.connection_params
130
130
 
131
131
  if self.debug:
132
132
  pretty_print_graphql_operation(operation_name, query, variables)
@@ -135,8 +135,8 @@ class BaseGraphQLWSHandler(ABC):
135
135
  query=query,
136
136
  variable_values=variables,
137
137
  operation_name=operation_name,
138
- context_value=context,
139
- root_value=root_value,
138
+ context_value=self.context,
139
+ root_value=self.root_value,
140
140
  )
141
141
 
142
142
  result_handler = self.handle_async_results(result_source, operation_id)
@@ -147,9 +147,10 @@ class BaseGraphQLWSHandler(ABC):
147
147
  await self.cleanup_operation(operation_id)
148
148
 
149
149
  async def handle_keep_alive(self) -> None:
150
+ assert self.keep_alive_interval
150
151
  while True:
151
152
  data: OperationMessage = {"type": GQL_CONNECTION_KEEP_ALIVE}
152
- await self.send_json(data)
153
+ await self.websocket.send_json(data)
153
154
  await asyncio.sleep(self.keep_alive_interval)
154
155
 
155
156
  async def handle_async_results(
@@ -191,7 +192,7 @@ class BaseGraphQLWSHandler(ABC):
191
192
  data: OperationMessage = {"type": type_, "id": operation_id}
192
193
  if payload is not None:
193
194
  data["payload"] = payload
194
- await self.send_json(data)
195
+ await self.websocket.send_json(data)
195
196
 
196
197
  async def send_data(
197
198
  self, execution_result: ExecutionResult, operation_id: str
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: strawberry-graphql
3
- Version: 0.243.1
3
+ Version: 0.244.0
4
4
  Summary: A library for creating GraphQL APIs
5
5
  Home-page: https://strawberry.rocks/
6
6
  License: MIT
@@ -1,28 +1,20 @@
1
1
  strawberry/__init__.py,sha256=tJOqxIEg3DYPe48P952sMjF3IxxZqZfIY-kNRlbwBNg,1374
2
2
  strawberry/__main__.py,sha256=3U77Eu21mJ-LY27RG-JEnpbh6Z63wGOom4i-EoLtUcY,59
3
3
  strawberry/aiohttp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- strawberry/aiohttp/handlers/__init__.py,sha256=7EeGIIwrgJYHAS9XJnZLfRGL_GHrligKm39rrVt7qDA,241
5
- strawberry/aiohttp/handlers/graphql_transport_ws_handler.py,sha256=-dihpF3pueV6jcd0x4k0GF-3VtG_IvfyKQ1ZVgg1T4U,2092
6
- strawberry/aiohttp/handlers/graphql_ws_handler.py,sha256=3U-E-o_QcLGoVaHE2oAPN3tTTIRwqGH0_688kbOtT7I,2437
7
4
  strawberry/aiohttp/test/__init__.py,sha256=4xxdUZtIISSOwjrcnmox7AvT4WWjowCm5bUuPdQneMg,71
8
5
  strawberry/aiohttp/test/client.py,sha256=4vjTDxtNVfpa74GfUUO7efPI6Ssh1vzfCYp3tPA-SLk,1357
9
- strawberry/aiohttp/views.py,sha256=z9T3hJU9m410VjcZlxiatirh04-4-bPSzW7eCGqO0dc,7052
6
+ strawberry/aiohttp/views.py,sha256=wbJkcQ1u98tuHa3_mq8OCGzSm57Nnw4DnS5qkILHlEo,7487
10
7
  strawberry/annotation.py,sha256=ftSxGZQUk4C5_5YRM_wNJFVVnZi0XOp71kD7zv4oxbU,13077
11
- strawberry/asgi/__init__.py,sha256=7YmrcQuD7fEPWo1Q60GVvVZdvMCNrTaic1y4pA_NpF4,7642
12
- strawberry/asgi/handlers/__init__.py,sha256=rz5Gth2eJUn7tDq2--99KSNFeMdDPpLFCkfA7vge0cI,235
13
- strawberry/asgi/handlers/graphql_transport_ws_handler.py,sha256=_5N58XdtCZndU81ky1f5cwG9E4NhysxP4uHlqqZNzn4,2147
14
- strawberry/asgi/handlers/graphql_ws_handler.py,sha256=UnjkjyEen2P4Ld9AuazcZ2qY-VRdBubunb4JHtAP89o,2443
8
+ strawberry/asgi/__init__.py,sha256=aFM74LpXxTruW5a00Ry9rIi3vz7hgnELJvZqPwJnhcY,7645
15
9
  strawberry/asgi/test/__init__.py,sha256=4xxdUZtIISSOwjrcnmox7AvT4WWjowCm5bUuPdQneMg,71
16
10
  strawberry/asgi/test/client.py,sha256=VolupxMna9ktF1lYgV_dUQAIN53DNzVyWTeWTbwsxqE,1448
17
11
  strawberry/chalice/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
12
  strawberry/chalice/views.py,sha256=VXXOfR3JIEf5CsPMZe0sXBnsH097uPyPe_CdqwESVv4,4770
19
- strawberry/channels/__init__.py,sha256=9oRdAT7uIYETF-23gZ5NteOXSjwkUtwRmwu3YCFv1tw,671
13
+ strawberry/channels/__init__.py,sha256=-9ENTIu1AILbqffJ663qH6AwpZgLrJx_kaokS7RrCnA,433
20
14
  strawberry/channels/handlers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
- strawberry/channels/handlers/base.py,sha256=DlMmzuZl-feceZZ7UHLW-zBSNVxHvaWTqwyWDP-e1Dg,7861
22
- strawberry/channels/handlers/graphql_transport_ws_handler.py,sha256=jMWmZ4Haoo3bf_bcM4ZheAjkreuhZBhwMhEX6GZ0Ue4,1995
23
- strawberry/channels/handlers/graphql_ws_handler.py,sha256=ulkMQP7h5cFDDLVBWV-10fYa9GS2pFg3FdS0Axtov-U,2583
24
- strawberry/channels/handlers/http_handler.py,sha256=KMvbsU6aYGkOnBVLdhWNIv5HJxD41qdx9OkFZnn8m0I,11258
25
- strawberry/channels/handlers/ws_handler.py,sha256=hpgXSWsUMWP3ylJtHGFcLtNpSKgPMWJTfnUTKElBBzA,4747
15
+ strawberry/channels/handlers/base.py,sha256=KV4KA0eF5NRtikV9m4ssoPI5pmCZvDuRkfoTxwh42qI,7853
16
+ strawberry/channels/handlers/http_handler.py,sha256=HPxAddsVPaPS293CTvgYaxS8ot32B2t_BqSJPtywVjQ,11744
17
+ strawberry/channels/handlers/ws_handler.py,sha256=mkfYKtGQO7So4BVBcUHQqG0vUVWIx55vHbJq-D5kz5Y,5924
26
18
  strawberry/channels/router.py,sha256=DKIbl4zuRBhfvViUVpyu0Rf_WRT41E6uZC-Yic9Ltvo,2024
27
19
  strawberry/channels/testing.py,sha256=GZqYu_rhrT1gLHmdI219L1fctVDmrv7AMHs0bwhXitc,6166
28
20
  strawberry/cli/__init__.py,sha256=byS5VrEiTJatAH6YS4V1Kd4SOwMRAQO2M1oJdIddivg,585
@@ -57,7 +49,7 @@ strawberry/django/apps.py,sha256=ZWw3Mzv1Cgy0T9xT8Jr2_dkCTZjT5WQABb34iqnu5pc,135
57
49
  strawberry/django/context.py,sha256=XL85jDGAVnb2pwgm5uRUvIXwlGia3i-8ZVfKihf0T24,655
58
50
  strawberry/django/test/__init__.py,sha256=4xxdUZtIISSOwjrcnmox7AvT4WWjowCm5bUuPdQneMg,71
59
51
  strawberry/django/test/client.py,sha256=6dorWECd0wdn8fu3dabE-dfGK3uza58mGrdJ-xPct-w,626
60
- strawberry/django/views.py,sha256=Is20K6DVqClY7HSpjgoc668qL5HlxZBpMnNYz0DDpBk,9810
52
+ strawberry/django/views.py,sha256=OMjjUFdlQeDUsF89cqmxU-k1e5kYp0omVoFgu96KjBE,10332
61
53
  strawberry/exceptions/__init__.py,sha256=DgdOJUs2xXHWcakr4tN6iIogltPi0MNnpu6MM6K0p5k,6347
62
54
  strawberry/exceptions/conflicting_arguments.py,sha256=68f6kMSXdjuEjZkoe8o2I9PSIjwTS1kXsSGaQBPk_hI,1587
63
55
  strawberry/exceptions/duplicated_type_name.py,sha256=-FG5qG_Mvkd7ROdOxCB9bijf8QR6Olryf07mbAFC0-U,2210
@@ -120,10 +112,7 @@ strawberry/extensions/utils.py,sha256=YPiacKNLQXvpYj-HI6fR5ORFdM9RrcdabGeM7F8vBG
120
112
  strawberry/extensions/validation_cache.py,sha256=CZ-brPYA1grL_lW38Rq4TxEVKlHM2n1DC6q9BHlSF4g,1398
121
113
  strawberry/fastapi/__init__.py,sha256=p5qg9AlkYjNOWKcT4uRiebIpR6pIb1HqDMiDfF5O3tg,147
122
114
  strawberry/fastapi/context.py,sha256=07991DShQoYMBVyQl9Mh5xvXQSNQI2RXT2ZQ5fWiga4,690
123
- strawberry/fastapi/handlers/__init__.py,sha256=TziBHyibYBOGiidjpCkjNThYbVY7K_nt0hnRLVHVh3I,241
124
- strawberry/fastapi/handlers/graphql_transport_ws_handler.py,sha256=5ivH7DJup0ZyGawAcj-n9VE_exBTje9Hou0_GIZCyD4,591
125
- strawberry/fastapi/handlers/graphql_ws_handler.py,sha256=OTloVUvEgXDpqjOlBAT1FnaNWRAglQgAt613YH06roc,537
126
- strawberry/fastapi/router.py,sha256=B2_FjFAD27_yZKR2PoMUNfW7If9huPyzd5f-Bwbz6ZI,13054
115
+ strawberry/fastapi/router.py,sha256=XdVgpNKyUfwNiqVSheXyWTNoODIbyxXY3imrLBZ_bYU,12242
127
116
  strawberry/federation/__init__.py,sha256=FeUxLiBVuk9TKBmJJi51SeUaI8c80rS8hbl9No-hjII,535
128
117
  strawberry/federation/argument.py,sha256=2m_wgp7uFQDimTDDCBBqSoWeTop4MD1-KjjYrumEJIw,833
129
118
  strawberry/federation/enum.py,sha256=1rx50FiSMS-NjEFErhRSYB5no8TPsGMA_cH7hVbxAFI,3015
@@ -142,22 +131,19 @@ strawberry/file_uploads/__init__.py,sha256=v2-6FGBqnTnMPSUTFOiXpIutDMl-ga0PFtw5t
142
131
  strawberry/file_uploads/scalars.py,sha256=NRDeB7j8aotqIkz9r62ISTf4DrxQxEZYUuHsX5K16aU,161
143
132
  strawberry/file_uploads/utils.py,sha256=2zsXg3QsKgGLD7of2dW-vgQn_Naf7I3Men9PhEAFYwM,1160
144
133
  strawberry/flask/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
145
- strawberry/flask/views.py,sha256=Tc9Y1WwQyXR90-F2MEPpNkIcxuBri5iYCG69OnpbSe8,5772
134
+ strawberry/flask/views.py,sha256=dbYDuZKOiC7fFKLtU1x32utgfi6SLqJtAqPtDvUxcq4,6215
146
135
  strawberry/http/__init__.py,sha256=GSvHUDXl1cHfLnb37PXOAnxfoXhvz0f467P1O8uDatM,1620
147
- strawberry/http/async_base_view.py,sha256=moI28qAGNqoKgWq5ZfmgNxmY97E8UF_Wk3PYFPeVh-g,11805
136
+ strawberry/http/async_base_view.py,sha256=ZWxxLNCISinp9nc7878_0FjRt8y-giQbtJgSF-Q4ZF0,15688
148
137
  strawberry/http/base.py,sha256=swbBPIl1SYwX7gPq25ad4SyXg2Nl7ccM-0CrLFGT_FI,2613
149
- strawberry/http/exceptions.py,sha256=WdWO3RvZDax_yAdD0zlVex9tQgwNx7tjz8_A8kP4YHo,193
138
+ strawberry/http/exceptions.py,sha256=-mRC6RALAj3XCaKeYvHNDiIRAMbE_GbVd7TEAgqRocA,245
150
139
  strawberry/http/ides.py,sha256=3dqFRY8_9ZqyIYR_EyRdPZ1zhL3lxRYT2MPk84O_Tk8,874
151
140
  strawberry/http/parse_content_type.py,sha256=sgtcOO_ZOFg7WWWibYyLc4SU58K-SErcW56kQczQmKU,412
152
141
  strawberry/http/sync_base_view.py,sha256=qA9o-Ic4ZcTXiKF02lBsrN7ET6VeXGYWf9m9mjhlfWU,7199
153
142
  strawberry/http/temporal_response.py,sha256=QrGYSg7Apu7Mh-X_uPKDZby-UicXw2J_ywxaqhS8a_4,220
154
143
  strawberry/http/types.py,sha256=cAuaiUuvaMI_XhZ2Ey6Ej23WyQKqMGFxzzpVHDjVazY,371
155
- strawberry/http/typevars.py,sha256=flx5KPWnTwYju7VwRSVhMmx15Rl1pQT1K57_GnK72Hg,282
144
+ strawberry/http/typevars.py,sha256=8hK5PfNPZXb2EhZmqlobYyfwJJcO2Wb96T91MlLEVJs,450
156
145
  strawberry/litestar/__init__.py,sha256=zsXzg-mglCGUVO9iNXLm-yadoDSCK7k-zuyRqyvAh1w,237
157
- strawberry/litestar/controller.py,sha256=0t4BZ69sBYYndEqbLVm7TP7gLYSdY1tfJnYI7mccE9A,14184
158
- strawberry/litestar/handlers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
159
- strawberry/litestar/handlers/graphql_transport_ws_handler.py,sha256=rDE-I02_fCov4FfpdBJBE2Xt-4FSNU8xJuQ6xedMF6E,2050
160
- strawberry/litestar/handlers/graphql_ws_handler.py,sha256=b4gz9aEKtpXUcdyB3o9PzmINcuNReIshJM1bfPXH14Q,2347
146
+ strawberry/litestar/controller.py,sha256=oKjio86UsFjvdwxx80YqX_-WWnw51Sd7saMulQ0ihIQ,13519
161
147
  strawberry/parent.py,sha256=sXURm0lauSpjUADsmfNGY-Zl7kHs0A67BFcWuWKzRxw,771
162
148
  strawberry/permission.py,sha256=NsYq-c4AgDCDBsYXsJN94yWJjuwYkvytpqXE4BIf_vc,7226
163
149
  strawberry/printer/__init__.py,sha256=DmepjmgtkdF5RxK_7yC6qUyRWn56U-9qeZMbkztYB9w,62
@@ -165,7 +151,7 @@ strawberry/printer/ast_from_value.py,sha256=LgM5g2qvBOnAIf9znbiMEcRX0PGSQohR3Vr3
165
151
  strawberry/printer/printer.py,sha256=GntTBivg3fb_zPM41Q8DtWMiRmkmM9xwTF-aFWvnqTg,17524
166
152
  strawberry/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
167
153
  strawberry/quart/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
168
- strawberry/quart/views.py,sha256=wuc5ESBPNKhY8QliZDPmOzk2WsdUvItnSv_-vVPBcLU,4002
154
+ strawberry/quart/views.py,sha256=-yjbFlXN1CLJqPrAgynGK_WwATTqsfBF-Kh_bJQ4JYs,4445
169
155
  strawberry/relay/__init__.py,sha256=Vi4btvA_g6Cj9Tk_F9GCSegapIf2WqkOWV8y3P0cTCs,553
170
156
  strawberry/relay/exceptions.py,sha256=KZSRJYlfutrAQALtBPnzJHRIMK6GZSnKAT_H4wIzGcI,4035
171
157
  strawberry/relay/fields.py,sha256=qrpDxDQ_bdzDUKtd8gxo9P3Oermxbux3yjFvHvHC1Ho,16927
@@ -175,7 +161,7 @@ strawberry/resolvers.py,sha256=Vdidc3YFc4-olSQZD_xQ1icyAFbyzqs_8I3eSpMFlA4,260
175
161
  strawberry/sanic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
176
162
  strawberry/sanic/context.py,sha256=qN7I9K_qIqgdbG_FbDl8XMb9aM1PyjIxSo8IAg2Uq8o,844
177
163
  strawberry/sanic/utils.py,sha256=r-tCX0JzELAdupF7fFy65JWAxj6pABSntNbGNaGZT8o,1080
178
- strawberry/sanic/views.py,sha256=YfTDowINXBz8P_zHH6-u1_agCG1okbWAURdvP4HG3eQ,6581
164
+ strawberry/sanic/views.py,sha256=O4w67pDn0ecefcbbuytCfvZARI4IbXhTPfRzo6MLMQg,7089
179
165
  strawberry/scalars.py,sha256=c3y8EOmX-KUxSgRqk1TNercMA6_rgBHhQPp0z3C2zBU,2240
180
166
  strawberry/schema/__init__.py,sha256=u1QCyDVQExUVDA20kyosKPz3TS5HMCN2NrXclhiFAL4,92
181
167
  strawberry/schema/base.py,sha256=yarj62fhfCp0kToJPpWlNcCjyZV2CafbfpZ-yamjNVg,3730
@@ -202,10 +188,10 @@ strawberry/static/pathfinder.html,sha256=0DPx9AmJ2C_sJstFXnWOz9k5tVQHeHaK7qdVY4l
202
188
  strawberry/subscriptions/__init__.py,sha256=1VGmiCzFepqRFyCikagkUoHHdoTG3XYlFu9GafoQMws,170
203
189
  strawberry/subscriptions/protocols/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
204
190
  strawberry/subscriptions/protocols/graphql_transport_ws/__init__.py,sha256=wN6dkMu6WiaIZTE19PGoN9xXpIN_RdDE_q7F7ZgjCxk,138
205
- strawberry/subscriptions/protocols/graphql_transport_ws/handlers.py,sha256=qTz1yN0B9KRl01MZPOwgCvli5S9OIG2y7BJLGDLJHgA,14219
191
+ strawberry/subscriptions/protocols/graphql_transport_ws/handlers.py,sha256=oh1XUlhl3lZx0bAU1Ta7cC9f9nuDbJGFnxRlm1z6ud8,14388
206
192
  strawberry/subscriptions/protocols/graphql_transport_ws/types.py,sha256=udYxzGtwjETYvY5f23org0t-aY4cimTjEGFYUR3idaY,2596
207
193
  strawberry/subscriptions/protocols/graphql_ws/__init__.py,sha256=ijn1A1O0Fzv5p9n-jw3T5H7M3oxbN4gbxRaepN7HyJk,553
208
- strawberry/subscriptions/protocols/graphql_ws/handlers.py,sha256=UfCvmVve26HzhixP-CeKHEjvQGsAx5_iizt_Mww2uNc,7175
194
+ strawberry/subscriptions/protocols/graphql_ws/handlers.py,sha256=QxCribyj-EP9SFblbUd4GxK4dMdJe-P8TsjYPwaXf-8,7556
209
195
  strawberry/subscriptions/protocols/graphql_ws/types.py,sha256=CKm4Hy95p6H9u_-QyWdxipwzNeeDIWtilP3RRp8vjPw,1050
210
196
  strawberry/test/__init__.py,sha256=U3B5Ng7C_H8GpCpfvgZZcfADMw6cor5hm78gS3nDdMI,115
211
197
  strawberry/test/client.py,sha256=-V_5DakR0NJ_Kd5ww4leIhMnIJ-Pf274HkNqYtGVfl8,6044
@@ -245,8 +231,8 @@ strawberry/utils/logging.py,sha256=U1cseHGquN09YFhFmRkiphfASKCyK0HUZREImPgVb0c,7
245
231
  strawberry/utils/operation.py,sha256=SSXxN-vMqdHO6W2OZtip-1z7y4_A-eTVFdhDvhKeLCk,1193
246
232
  strawberry/utils/str_converters.py,sha256=KGd7QH90RevaJjH6SQEkiVVsb8KuhJr_wv5AsI7UzQk,897
247
233
  strawberry/utils/typing.py,sha256=3xws5kxSQGsp8BnYyUwClvxXNzZakMAuOPoq1rjHRuk,14252
248
- strawberry_graphql-0.243.1.dist-info/LICENSE,sha256=m-XnIVUKqlG_AWnfi9NReh9JfKhYOB-gJfKE45WM1W8,1072
249
- strawberry_graphql-0.243.1.dist-info/METADATA,sha256=pUMQj5rzTkjqWbNbKuzGnpZWoNaWKyyhKnkyKwzsvx0,7707
250
- strawberry_graphql-0.243.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
251
- strawberry_graphql-0.243.1.dist-info/entry_points.txt,sha256=Nk7-aT3_uEwCgyqtHESV9H6Mc31cK-VAvhnQNTzTb4k,49
252
- strawberry_graphql-0.243.1.dist-info/RECORD,,
234
+ strawberry_graphql-0.244.0.dist-info/LICENSE,sha256=m-XnIVUKqlG_AWnfi9NReh9JfKhYOB-gJfKE45WM1W8,1072
235
+ strawberry_graphql-0.244.0.dist-info/METADATA,sha256=_wi272Ggv0fWFmLb4bUKPgxvJKoF2bzk4f4NKWCw43E,7707
236
+ strawberry_graphql-0.244.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
237
+ strawberry_graphql-0.244.0.dist-info/entry_points.txt,sha256=Nk7-aT3_uEwCgyqtHESV9H6Mc31cK-VAvhnQNTzTb4k,49
238
+ strawberry_graphql-0.244.0.dist-info/RECORD,,
@@ -1,6 +0,0 @@
1
- from strawberry.aiohttp.handlers.graphql_transport_ws_handler import (
2
- GraphQLTransportWSHandler,
3
- )
4
- from strawberry.aiohttp.handlers.graphql_ws_handler import GraphQLWSHandler
5
-
6
- __all__ = ["GraphQLTransportWSHandler", "GraphQLWSHandler"]
@@ -1,62 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from typing import TYPE_CHECKING, Any, Callable, Dict
4
-
5
- from aiohttp import http, web
6
- from strawberry.subscriptions import GRAPHQL_TRANSPORT_WS_PROTOCOL
7
- from strawberry.subscriptions.protocols.graphql_transport_ws.handlers import (
8
- BaseGraphQLTransportWSHandler,
9
- )
10
-
11
- if TYPE_CHECKING:
12
- from datetime import timedelta
13
-
14
- from strawberry.schema import BaseSchema
15
-
16
-
17
- class GraphQLTransportWSHandler(BaseGraphQLTransportWSHandler):
18
- def __init__(
19
- self,
20
- schema: BaseSchema,
21
- debug: bool,
22
- connection_init_wait_timeout: timedelta,
23
- get_context: Callable[..., Dict[str, Any]],
24
- get_root_value: Any,
25
- request: web.Request,
26
- ) -> None:
27
- super().__init__(schema, debug, connection_init_wait_timeout)
28
- self._get_context = get_context
29
- self._get_root_value = get_root_value
30
- self._request = request
31
- self._ws = web.WebSocketResponse(protocols=[GRAPHQL_TRANSPORT_WS_PROTOCOL])
32
-
33
- async def get_context(self) -> Any:
34
- return await self._get_context(request=self._request, response=self._ws) # type: ignore
35
-
36
- async def get_root_value(self) -> Any:
37
- return await self._get_root_value(request=self._request)
38
-
39
- async def send_json(self, data: dict) -> None:
40
- await self._ws.send_json(data)
41
-
42
- async def close(self, code: int, reason: str) -> None:
43
- await self._ws.close(code=code, message=reason.encode())
44
-
45
- async def handle_request(self) -> web.StreamResponse:
46
- await self._ws.prepare(self._request)
47
- self.on_request_accepted()
48
-
49
- try:
50
- async for ws_message in self._ws: # type: http.WSMessage
51
- if ws_message.type == http.WSMsgType.TEXT:
52
- await self.handle_message(ws_message.json())
53
- else:
54
- error_message = "WebSocket message type must be text"
55
- await self.handle_invalid_message(error_message)
56
- finally:
57
- await self.shutdown()
58
-
59
- return self._ws
60
-
61
-
62
- __all__ = ["GraphQLTransportWSHandler"]