strawberry-graphql 0.247.0__py3-none-any.whl → 0.247.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.
@@ -30,6 +30,7 @@ from strawberry.http.exceptions import (
30
30
  HTTPException,
31
31
  NonJsonMessageReceived,
32
32
  NonTextMessageReceived,
33
+ WebSocketDisconnected,
33
34
  )
34
35
  from strawberry.http.types import FormData, HTTPMethod, QueryParams
35
36
  from strawberry.http.typevars import (
@@ -105,7 +106,10 @@ class AioHTTPWebSocketAdapter(AsyncWebSocketAdapter):
105
106
  raise NonTextMessageReceived()
106
107
 
107
108
  async def send_json(self, message: Mapping[str, object]) -> None:
108
- await self.ws.send_json(message)
109
+ try:
110
+ await self.ws.send_json(message)
111
+ except RuntimeError as exc:
112
+ raise WebSocketDisconnected from exc
109
113
 
110
114
  async def close(self, code: int, reason: str) -> None:
111
115
  await self.ws.close(code=code, message=reason.encode())
@@ -37,6 +37,7 @@ from strawberry.http.exceptions import (
37
37
  HTTPException,
38
38
  NonJsonMessageReceived,
39
39
  NonTextMessageReceived,
40
+ WebSocketDisconnected,
40
41
  )
41
42
  from strawberry.http.types import FormData, HTTPMethod, QueryParams
42
43
  from strawberry.http.typevars import (
@@ -105,7 +106,10 @@ class ASGIWebSocketAdapter(AsyncWebSocketAdapter):
105
106
  pass
106
107
 
107
108
  async def send_json(self, message: Mapping[str, object]) -> None:
108
- await self.ws.send_json(message)
109
+ try:
110
+ await self.ws.send_json(message)
111
+ except WebSocketDisconnect as exc:
112
+ raise WebSocketDisconnected from exc
109
113
 
110
114
  async def close(self, code: int, reason: str) -> None:
111
115
  await self.ws.close(code=code, reason=reason)
@@ -12,4 +12,8 @@ class NonJsonMessageReceived(Exception):
12
12
  pass
13
13
 
14
14
 
15
+ class WebSocketDisconnected(Exception):
16
+ pass
17
+
18
+
15
19
  __all__ = ["HTTPException"]
@@ -53,6 +53,7 @@ from strawberry.http.exceptions import (
53
53
  HTTPException,
54
54
  NonJsonMessageReceived,
55
55
  NonTextMessageReceived,
56
+ WebSocketDisconnected,
56
57
  )
57
58
  from strawberry.http.types import FormData, HTTPMethod, QueryParams
58
59
  from strawberry.http.typevars import Context, RootValue
@@ -216,7 +217,10 @@ class LitestarWebSocketAdapter(AsyncWebSocketAdapter):
216
217
  pass
217
218
 
218
219
  async def send_json(self, message: Mapping[str, object]) -> None:
219
- await self.ws.send_json(message)
220
+ try:
221
+ await self.ws.send_json(message)
222
+ except WebSocketDisconnect as exc:
223
+ raise WebSocketDisconnected from exc
220
224
 
221
225
  async def close(self, code: int, reason: str) -> None:
222
226
  await self.ws.close(code=code, reason=reason)
@@ -7,7 +7,6 @@ from typing import (
7
7
  TYPE_CHECKING,
8
8
  Any,
9
9
  Awaitable,
10
- Callable,
11
10
  Dict,
12
11
  List,
13
12
  Optional,
@@ -15,7 +14,11 @@ from typing import (
15
14
 
16
15
  from graphql import GraphQLError, GraphQLSyntaxError, parse
17
16
 
18
- from strawberry.http.exceptions import NonJsonMessageReceived, NonTextMessageReceived
17
+ from strawberry.http.exceptions import (
18
+ NonJsonMessageReceived,
19
+ NonTextMessageReceived,
20
+ WebSocketDisconnected,
21
+ )
19
22
  from strawberry.subscriptions.protocols.graphql_transport_ws.types import (
20
23
  CompleteMessage,
21
24
  ConnectionAckMessage,
@@ -76,12 +79,17 @@ class BaseGraphQLTransportWSHandler:
76
79
  self.on_request_accepted()
77
80
 
78
81
  try:
79
- async for message in self.websocket.iter_json():
80
- await self.handle_message(message)
81
- except NonTextMessageReceived:
82
- await self.handle_invalid_message("WebSocket message type must be text")
83
- except NonJsonMessageReceived:
84
- await self.handle_invalid_message("WebSocket message must be valid JSON")
82
+ try:
83
+ async for message in self.websocket.iter_json():
84
+ await self.handle_message(message)
85
+ except NonTextMessageReceived:
86
+ await self.handle_invalid_message("WebSocket message type must be text")
87
+ except NonJsonMessageReceived:
88
+ await self.handle_invalid_message(
89
+ "WebSocket message must be valid JSON"
90
+ )
91
+ except WebSocketDisconnected:
92
+ pass
85
93
  finally:
86
94
  await self.shutdown()
87
95
 
@@ -127,50 +135,41 @@ class BaseGraphQLTransportWSHandler:
127
135
  self.task_logger.exception("Exception in worker task", exc_info=error)
128
136
 
129
137
  async def handle_message(self, message: dict) -> None:
130
- handler: Callable
131
- handler_arg: Any
132
138
  try:
133
139
  message_type = message.pop("type")
134
140
 
135
141
  if message_type == ConnectionInitMessage.type:
136
- handler = self.handle_connection_init
137
- handler_arg = ConnectionInitMessage(**message)
142
+ await self.handle_connection_init(ConnectionInitMessage(**message))
138
143
 
139
144
  elif message_type == PingMessage.type:
140
- handler = self.handle_ping
141
- handler_arg = PingMessage(**message)
145
+ await self.handle_ping(PingMessage(**message))
142
146
 
143
147
  elif message_type == PongMessage.type:
144
- handler = self.handle_pong
145
- handler_arg = PongMessage(**message)
148
+ await self.handle_pong(PongMessage(**message))
146
149
 
147
150
  elif message_type == SubscribeMessage.type:
148
- handler = self.handle_subscribe
149
-
150
151
  payload_args = message.pop("payload")
151
-
152
152
  payload = SubscribeMessagePayload(
153
153
  query=payload_args["query"],
154
154
  operationName=payload_args.get("operationName"),
155
155
  variables=payload_args.get("variables"),
156
156
  extensions=payload_args.get("extensions"),
157
157
  )
158
- handler_arg = SubscribeMessage(payload=payload, **message)
158
+ await self.handle_subscribe(
159
+ SubscribeMessage(payload=payload, **message)
160
+ )
159
161
 
160
162
  elif message_type == CompleteMessage.type:
161
- handler = self.handle_complete
162
- handler_arg = CompleteMessage(**message)
163
+ await self.handle_complete(CompleteMessage(**message))
163
164
 
164
165
  else:
165
- handler = self.handle_invalid_message
166
- handler_arg = f"Unknown message type: {message_type}"
166
+ error_message = f"Unknown message type: {message_type}"
167
+ await self.handle_invalid_message(error_message)
167
168
 
168
169
  except (KeyError, TypeError):
169
- handler = self.handle_invalid_message
170
- handler_arg = "Failed to parse message"
171
-
172
- await handler(handler_arg)
173
- await self.reap_completed_tasks()
170
+ await self.handle_invalid_message("Failed to parse message")
171
+ finally:
172
+ await self.reap_completed_tasks()
174
173
 
175
174
  async def handle_connection_init(self, message: ConnectionInitMessage) -> None:
176
175
  if self.connection_timed_out:
@@ -11,7 +11,7 @@ from typing import (
11
11
  cast,
12
12
  )
13
13
 
14
- from strawberry.http.exceptions import NonTextMessageReceived
14
+ from strawberry.http.exceptions import NonTextMessageReceived, WebSocketDisconnected
15
15
  from strawberry.subscriptions.protocols.graphql_ws import (
16
16
  GQL_COMPLETE,
17
17
  GQL_CONNECTION_ACK,
@@ -65,12 +65,17 @@ class BaseGraphQLWSHandler:
65
65
 
66
66
  async def handle(self) -> None:
67
67
  try:
68
- async for message in self.websocket.iter_json(ignore_parsing_errors=True):
69
- await self.handle_message(cast(OperationMessage, message))
70
- except NonTextMessageReceived:
71
- await self.websocket.close(
72
- code=1002, reason="WebSocket message type must be text"
73
- )
68
+ try:
69
+ async for message in self.websocket.iter_json(
70
+ ignore_parsing_errors=True
71
+ ):
72
+ await self.handle_message(cast(OperationMessage, message))
73
+ except NonTextMessageReceived:
74
+ await self.websocket.close(
75
+ code=1002, reason="WebSocket message type must be text"
76
+ )
77
+ except WebSocketDisconnected:
78
+ pass
74
79
  finally:
75
80
  if self.keep_alive_task:
76
81
  self.keep_alive_task.cancel()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: strawberry-graphql
3
- Version: 0.247.0
3
+ Version: 0.247.1
4
4
  Summary: A library for creating GraphQL APIs
5
5
  Home-page: https://strawberry.rocks/
6
6
  License: MIT
@@ -3,9 +3,9 @@ strawberry/__main__.py,sha256=3U77Eu21mJ-LY27RG-JEnpbh6Z63wGOom4i-EoLtUcY,59
3
3
  strawberry/aiohttp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  strawberry/aiohttp/test/__init__.py,sha256=4xxdUZtIISSOwjrcnmox7AvT4WWjowCm5bUuPdQneMg,71
5
5
  strawberry/aiohttp/test/client.py,sha256=xPwOo1V0XbC86LWHiSRTLcGNOa796flz49wzWmdkvSs,1775
6
- strawberry/aiohttp/views.py,sha256=Y7seaVmuz2jLQfgcYOhQLQW5oDEIVrHqZoiqe49VVnI,7636
6
+ strawberry/aiohttp/views.py,sha256=nzZSiCT3ruBHRmPy7P7Ow8tzRtCfSpHq0KR_Eu8U1WY,7765
7
7
  strawberry/annotation.py,sha256=u5rkFs6CDUaiJZMK7jp_VDUWdZZ3HXQEbR2ocruDpxA,13065
8
- strawberry/asgi/__init__.py,sha256=2_dRxUUaXp-tMWB9kebutLFK9BH-hSMP6vwmveZHJHQ,7857
8
+ strawberry/asgi/__init__.py,sha256=cykkfbnNfpJu65DrCn3GPI4QamW1d2ez2fI6WVsEnwE,7993
9
9
  strawberry/asgi/test/__init__.py,sha256=4xxdUZtIISSOwjrcnmox7AvT4WWjowCm5bUuPdQneMg,71
10
10
  strawberry/asgi/test/client.py,sha256=VolupxMna9ktF1lYgV_dUQAIN53DNzVyWTeWTbwsxqE,1448
11
11
  strawberry/chalice/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -134,7 +134,7 @@ strawberry/flask/views.py,sha256=3gd1Xgxg3IT72dz2nrMBK094dMNxTUHciu3oofGOAG4,623
134
134
  strawberry/http/__init__.py,sha256=GSvHUDXl1cHfLnb37PXOAnxfoXhvz0f467P1O8uDatM,1620
135
135
  strawberry/http/async_base_view.py,sha256=n4Kg9sG9awN7EWa0JIQUmMtnyfI6aqRmg3n2IkoQ_F4,15742
136
136
  strawberry/http/base.py,sha256=DFGBb6UhHR1EOmZkLn5V-2IKXzjYasg6yv06PQnm9Ds,2336
137
- strawberry/http/exceptions.py,sha256=6AF0F-Y_CGReeLtZefN4ApJw0cYWfLctvHGWL6NuNTM,297
137
+ strawberry/http/exceptions.py,sha256=9E2dreS1crRoJVUEPuHyx23NcDELDHNzkAOa-rGv-8I,348
138
138
  strawberry/http/ides.py,sha256=njYI2b5R0PnY27ll1ePdIvgPQU3m6Aod_JTBrcZYs0U,638
139
139
  strawberry/http/parse_content_type.py,sha256=sgtcOO_ZOFg7WWWibYyLc4SU58K-SErcW56kQczQmKU,412
140
140
  strawberry/http/sync_base_view.py,sha256=qA9o-Ic4ZcTXiKF02lBsrN7ET6VeXGYWf9m9mjhlfWU,7199
@@ -142,7 +142,7 @@ strawberry/http/temporal_response.py,sha256=QrGYSg7Apu7Mh-X_uPKDZby-UicXw2J_ywxa
142
142
  strawberry/http/types.py,sha256=cAuaiUuvaMI_XhZ2Ey6Ej23WyQKqMGFxzzpVHDjVazY,371
143
143
  strawberry/http/typevars.py,sha256=8hK5PfNPZXb2EhZmqlobYyfwJJcO2Wb96T91MlLEVJs,450
144
144
  strawberry/litestar/__init__.py,sha256=zsXzg-mglCGUVO9iNXLm-yadoDSCK7k-zuyRqyvAh1w,237
145
- strawberry/litestar/controller.py,sha256=vGLfjnTb6AljROkAy4nUdzr08BeDF5dJFrjDO26NBJM,13856
145
+ strawberry/litestar/controller.py,sha256=yA8f59NuC6ZJgpG2p4HoILko3FdWiNx5AWdkQGti_6U,13992
146
146
  strawberry/parent.py,sha256=sXURm0lauSpjUADsmfNGY-Zl7kHs0A67BFcWuWKzRxw,771
147
147
  strawberry/permission.py,sha256=HusiB46yZANdpZM3AdzFVZB6JkCu7dcvoZ3QP2E01jM,7575
148
148
  strawberry/printer/__init__.py,sha256=DmepjmgtkdF5RxK_7yC6qUyRWn56U-9qeZMbkztYB9w,62
@@ -187,10 +187,10 @@ strawberry/static/pathfinder.html,sha256=0DPx9AmJ2C_sJstFXnWOz9k5tVQHeHaK7qdVY4l
187
187
  strawberry/subscriptions/__init__.py,sha256=1VGmiCzFepqRFyCikagkUoHHdoTG3XYlFu9GafoQMws,170
188
188
  strawberry/subscriptions/protocols/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
189
189
  strawberry/subscriptions/protocols/graphql_transport_ws/__init__.py,sha256=wN6dkMu6WiaIZTE19PGoN9xXpIN_RdDE_q7F7ZgjCxk,138
190
- strawberry/subscriptions/protocols/graphql_transport_ws/handlers.py,sha256=WE45AJp3D7LO4tKnFfapQnAK5D1a7Liv3aY5Ga7fvvU,14537
190
+ strawberry/subscriptions/protocols/graphql_transport_ws/handlers.py,sha256=pxP_yeEqXku3_AHh-Ev9BdHBn8iTfwKo4wrTo8RKz8g,14486
191
191
  strawberry/subscriptions/protocols/graphql_transport_ws/types.py,sha256=udYxzGtwjETYvY5f23org0t-aY4cimTjEGFYUR3idaY,2596
192
192
  strawberry/subscriptions/protocols/graphql_ws/__init__.py,sha256=ijn1A1O0Fzv5p9n-jw3T5H7M3oxbN4gbxRaepN7HyJk,553
193
- strawberry/subscriptions/protocols/graphql_ws/handlers.py,sha256=1Cy3GGQfiAhKJNAvGESR1WElzh4g9YsKYnhFuQoxt-0,7582
193
+ strawberry/subscriptions/protocols/graphql_ws/handlers.py,sha256=IabXcES66aBA8aE2h2o73gwdp6iZ5HG9Hm2G5TOTuNc,7739
194
194
  strawberry/subscriptions/protocols/graphql_ws/types.py,sha256=CKm4Hy95p6H9u_-QyWdxipwzNeeDIWtilP3RRp8vjPw,1050
195
195
  strawberry/test/__init__.py,sha256=U3B5Ng7C_H8GpCpfvgZZcfADMw6cor5hm78gS3nDdMI,115
196
196
  strawberry/test/client.py,sha256=Va7J1tIjZ6PxbOqPl57jSp5lNLOZSueHPmrUuUx5sRY,6462
@@ -230,8 +230,8 @@ strawberry/utils/logging.py,sha256=U1cseHGquN09YFhFmRkiphfASKCyK0HUZREImPgVb0c,7
230
230
  strawberry/utils/operation.py,sha256=SSXxN-vMqdHO6W2OZtip-1z7y4_A-eTVFdhDvhKeLCk,1193
231
231
  strawberry/utils/str_converters.py,sha256=KGd7QH90RevaJjH6SQEkiVVsb8KuhJr_wv5AsI7UzQk,897
232
232
  strawberry/utils/typing.py,sha256=3xws5kxSQGsp8BnYyUwClvxXNzZakMAuOPoq1rjHRuk,14252
233
- strawberry_graphql-0.247.0.dist-info/LICENSE,sha256=m-XnIVUKqlG_AWnfi9NReh9JfKhYOB-gJfKE45WM1W8,1072
234
- strawberry_graphql-0.247.0.dist-info/METADATA,sha256=BIXpXvq7MkMvSToInnl-p1uTVQR_SR1YwogjRYOTSFs,7758
235
- strawberry_graphql-0.247.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
236
- strawberry_graphql-0.247.0.dist-info/entry_points.txt,sha256=Nk7-aT3_uEwCgyqtHESV9H6Mc31cK-VAvhnQNTzTb4k,49
237
- strawberry_graphql-0.247.0.dist-info/RECORD,,
233
+ strawberry_graphql-0.247.1.dist-info/LICENSE,sha256=m-XnIVUKqlG_AWnfi9NReh9JfKhYOB-gJfKE45WM1W8,1072
234
+ strawberry_graphql-0.247.1.dist-info/METADATA,sha256=eb7SR0I78_-i_gttEvj0BVWxHZky6TUv6nAlfqgJxWs,7758
235
+ strawberry_graphql-0.247.1.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
236
+ strawberry_graphql-0.247.1.dist-info/entry_points.txt,sha256=Nk7-aT3_uEwCgyqtHESV9H6Mc31cK-VAvhnQNTzTb4k,49
237
+ strawberry_graphql-0.247.1.dist-info/RECORD,,