strawberry-graphql 0.247.0__py3-none-any.whl → 0.247.2__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:
@@ -246,41 +245,42 @@ class BaseGraphQLTransportWSHandler:
246
245
  elif hasattr(self.context, "connection_params"):
247
246
  self.context.connection_params = self.connection_params
248
247
 
248
+ operation = Operation(
249
+ self,
250
+ message.id,
251
+ operation_type,
252
+ message.payload.query,
253
+ message.payload.variables,
254
+ message.payload.operationName,
255
+ )
256
+
257
+ operation.task = asyncio.create_task(self.run_operation(operation))
258
+ self.operations[message.id] = operation
259
+
260
+ async def run_operation(self, operation: Operation) -> None:
261
+ """The operation task's top level method. Cleans-up and de-registers the operation once it is done."""
262
+ # TODO: Handle errors in this method using self.handle_task_exception()
263
+
249
264
  result_source: Awaitable[ExecutionResult] | Awaitable[SubscriptionResult]
250
265
 
251
266
  # Get an AsyncGenerator yielding the results
252
- if operation_type == OperationType.SUBSCRIPTION:
267
+ if operation.operation_type == OperationType.SUBSCRIPTION:
253
268
  result_source = self.schema.subscribe(
254
- query=message.payload.query,
255
- variable_values=message.payload.variables,
256
- operation_name=message.payload.operationName,
269
+ query=operation.query,
270
+ variable_values=operation.variables,
271
+ operation_name=operation.operation_name,
257
272
  context_value=self.context,
258
273
  root_value=self.root_value,
259
274
  )
260
275
  else:
261
276
  result_source = self.schema.execute(
262
- query=message.payload.query,
263
- variable_values=message.payload.variables,
277
+ query=operation.query,
278
+ variable_values=operation.variables,
264
279
  context_value=self.context,
265
280
  root_value=self.root_value,
266
- operation_name=message.payload.operationName,
281
+ operation_name=operation.operation_name,
267
282
  )
268
283
 
269
- operation = Operation(self, message.id, operation_type)
270
-
271
- # Create task to handle this subscription, reserve the operation ID
272
- operation.task = asyncio.create_task(
273
- self.operation_task(result_source, operation)
274
- )
275
- self.operations[message.id] = operation
276
-
277
- async def operation_task(
278
- self,
279
- result_source: Awaitable[ExecutionResult] | Awaitable[SubscriptionResult],
280
- operation: Operation,
281
- ) -> None:
282
- """The operation task's top level method. Cleans-up and de-registers the operation once it is done."""
283
- # TODO: Handle errors in this method using self.handle_task_exception()
284
284
  try:
285
285
  first_res_or_agen = await result_source
286
286
  # that's an immediate error we should end the operation
@@ -341,17 +341,32 @@ class BaseGraphQLTransportWSHandler:
341
341
  class Operation:
342
342
  """A class encapsulating a single operation with its id. Helps enforce protocol state transition."""
343
343
 
344
- __slots__ = ["handler", "id", "operation_type", "completed", "task"]
344
+ __slots__ = [
345
+ "handler",
346
+ "id",
347
+ "operation_type",
348
+ "query",
349
+ "variables",
350
+ "operation_name",
351
+ "completed",
352
+ "task",
353
+ ]
345
354
 
346
355
  def __init__(
347
356
  self,
348
357
  handler: BaseGraphQLTransportWSHandler,
349
358
  id: str,
350
359
  operation_type: OperationType,
360
+ query: str,
361
+ variables: Optional[Dict[str, Any]],
362
+ operation_name: Optional[str],
351
363
  ) -> None:
352
364
  self.handler = handler
353
365
  self.id = id
354
366
  self.operation_type = operation_type
367
+ self.query = query
368
+ self.variables = variables
369
+ self.operation_name = operation_name
355
370
  self.completed = False
356
371
  self.task: Optional[asyncio.Task] = None
357
372
 
@@ -5,13 +5,12 @@ from contextlib import suppress
5
5
  from typing import (
6
6
  TYPE_CHECKING,
7
7
  AsyncGenerator,
8
- Awaitable,
9
8
  Dict,
10
9
  Optional,
11
10
  cast,
12
11
  )
13
12
 
14
- from strawberry.http.exceptions import NonTextMessageReceived
13
+ from strawberry.http.exceptions import NonTextMessageReceived, WebSocketDisconnected
15
14
  from strawberry.subscriptions.protocols.graphql_ws import (
16
15
  GQL_COMPLETE,
17
16
  GQL_CONNECTION_ACK,
@@ -37,7 +36,6 @@ from strawberry.utils.debug import pretty_print_graphql_operation
37
36
  if TYPE_CHECKING:
38
37
  from strawberry.http.async_base_view import AsyncWebSocketAdapter
39
38
  from strawberry.schema import BaseSchema
40
- from strawberry.schema.subscribe import SubscriptionResult
41
39
 
42
40
 
43
41
  class BaseGraphQLWSHandler:
@@ -65,12 +63,17 @@ class BaseGraphQLWSHandler:
65
63
 
66
64
  async def handle(self) -> None:
67
65
  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
- )
66
+ try:
67
+ async for message in self.websocket.iter_json(
68
+ ignore_parsing_errors=True
69
+ ):
70
+ await self.handle_message(cast(OperationMessage, message))
71
+ except NonTextMessageReceived:
72
+ await self.websocket.close(
73
+ code=1002, reason="WebSocket message type must be text"
74
+ )
75
+ except WebSocketDisconnected:
76
+ pass
74
77
  finally:
75
78
  if self.keep_alive_task:
76
79
  self.keep_alive_task.cancel()
@@ -131,15 +134,9 @@ class BaseGraphQLWSHandler:
131
134
  if self.debug:
132
135
  pretty_print_graphql_operation(operation_name, query, variables)
133
136
 
134
- result_source = self.schema.subscribe(
135
- query=query,
136
- variable_values=variables,
137
- operation_name=operation_name,
138
- context_value=self.context,
139
- root_value=self.root_value,
137
+ result_handler = self.handle_async_results(
138
+ operation_id, query, operation_name, variables
140
139
  )
141
-
142
- result_handler = self.handle_async_results(result_source, operation_id)
143
140
  self.tasks[operation_id] = asyncio.create_task(result_handler)
144
141
 
145
142
  async def handle_stop(self, message: OperationMessage) -> None:
@@ -155,11 +152,19 @@ class BaseGraphQLWSHandler:
155
152
 
156
153
  async def handle_async_results(
157
154
  self,
158
- result_source: Awaitable[SubscriptionResult],
159
155
  operation_id: str,
156
+ query: str,
157
+ operation_name: Optional[str],
158
+ variables: Optional[Dict[str, object]],
160
159
  ) -> None:
161
160
  try:
162
- agen_or_err = await result_source
161
+ agen_or_err = await self.schema.subscribe(
162
+ query=query,
163
+ variable_values=variables,
164
+ operation_name=operation_name,
165
+ context_value=self.context,
166
+ root_value=self.root_value,
167
+ )
163
168
  if isinstance(agen_or_err, PreExecutionError):
164
169
  assert agen_or_err.errors
165
170
  error_payload = agen_or_err.errors[0].formatted
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: strawberry-graphql
3
- Version: 0.247.0
3
+ Version: 0.247.2
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=_h-xNf_ZRtjn8PGbxZk3u9qTR-NNNCevdgaFF0uXciw,14728
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=tQmQjoA-x4yXLHbjmq7r7fFnNPluIcc7EiYgQSFbiZ0,7740
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.2.dist-info/LICENSE,sha256=m-XnIVUKqlG_AWnfi9NReh9JfKhYOB-gJfKE45WM1W8,1072
234
+ strawberry_graphql-0.247.2.dist-info/METADATA,sha256=UNSXeMuxxVcoA8hC-8-CP-I7jeo-4R8Syg8W-kIA-ZE,7758
235
+ strawberry_graphql-0.247.2.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
236
+ strawberry_graphql-0.247.2.dist-info/entry_points.txt,sha256=Nk7-aT3_uEwCgyqtHESV9H6Mc31cK-VAvhnQNTzTb4k,49
237
+ strawberry_graphql-0.247.2.dist-info/RECORD,,