strawberry-graphql 0.250.0__py3-none-any.whl → 0.251.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.
@@ -87,7 +87,10 @@ class AioHTTPRequestAdapter(AsyncHTTPRequestAdapter):
87
87
 
88
88
 
89
89
  class AioHTTPWebSocketAdapter(AsyncWebSocketAdapter):
90
- def __init__(self, request: web.Request, ws: web.WebSocketResponse) -> None:
90
+ def __init__(
91
+ self, view: AsyncBaseHTTPView, request: web.Request, ws: web.WebSocketResponse
92
+ ) -> None:
93
+ super().__init__(view)
91
94
  self.request = request
92
95
  self.ws = ws
93
96
 
@@ -107,7 +110,7 @@ class AioHTTPWebSocketAdapter(AsyncWebSocketAdapter):
107
110
 
108
111
  async def send_json(self, message: Mapping[str, object]) -> None:
109
112
  try:
110
- await self.ws.send_json(message)
113
+ await self.ws.send_str(self.view.encode_json(message))
111
114
  except RuntimeError as exc:
112
115
  raise WebSocketDisconnected from exc
113
116
 
@@ -87,7 +87,10 @@ class ASGIRequestAdapter(AsyncHTTPRequestAdapter):
87
87
 
88
88
 
89
89
  class ASGIWebSocketAdapter(AsyncWebSocketAdapter):
90
- def __init__(self, request: WebSocket, response: WebSocket) -> None:
90
+ def __init__(
91
+ self, view: AsyncBaseHTTPView, request: WebSocket, response: WebSocket
92
+ ) -> None:
93
+ super().__init__(view)
91
94
  self.ws = response
92
95
 
93
96
  async def iter_json(
@@ -107,7 +110,7 @@ class ASGIWebSocketAdapter(AsyncWebSocketAdapter):
107
110
 
108
111
  async def send_json(self, message: Mapping[str, object]) -> None:
109
112
  try:
110
- await self.ws.send_json(message)
113
+ await self.ws.send_text(self.view.encode_json(message))
111
114
  except WebSocketDisconnect as exc:
112
115
  raise WebSocketDisconnected from exc
113
116
 
@@ -28,7 +28,13 @@ if TYPE_CHECKING:
28
28
 
29
29
 
30
30
  class ChannelsWebSocketAdapter(AsyncWebSocketAdapter):
31
- def __init__(self, request: GraphQLWSConsumer, response: GraphQLWSConsumer) -> None:
31
+ def __init__(
32
+ self,
33
+ view: AsyncBaseHTTPView,
34
+ request: GraphQLWSConsumer,
35
+ response: GraphQLWSConsumer,
36
+ ) -> None:
37
+ super().__init__(view)
32
38
  self.ws_consumer = response
33
39
 
34
40
  async def iter_json(
@@ -50,7 +56,7 @@ class ChannelsWebSocketAdapter(AsyncWebSocketAdapter):
50
56
  raise NonJsonMessageReceived()
51
57
 
52
58
  async def send_json(self, message: Mapping[str, object]) -> None:
53
- serialized_message = json.dumps(message)
59
+ serialized_message = self.view.encode_json(message)
54
60
  await self.ws_consumer.send(serialized_message)
55
61
 
56
62
  async def close(self, code: int, reason: str) -> None:
@@ -201,8 +201,8 @@ class BaseView:
201
201
  },
202
202
  )
203
203
 
204
- def encode_json(self, response_data: GraphQLHTTPResponse) -> str:
205
- return json.dumps(response_data, cls=DjangoJSONEncoder)
204
+ def encode_json(self, data: object) -> str:
205
+ return json.dumps(data, cls=DjangoJSONEncoder)
206
206
 
207
207
 
208
208
  class GraphQLView(
@@ -80,6 +80,9 @@ class AsyncHTTPRequestAdapter(abc.ABC):
80
80
 
81
81
 
82
82
  class AsyncWebSocketAdapter(abc.ABC):
83
+ def __init__(self, view: "AsyncBaseHTTPView") -> None:
84
+ self.view = view
85
+
83
86
  @abc.abstractmethod
84
87
  def iter_json(
85
88
  self, *, ignore_parsing_errors: bool = False
@@ -113,7 +116,8 @@ class AsyncBaseHTTPView(
113
116
  connection_init_wait_timeout: timedelta = timedelta(minutes=1)
114
117
  request_adapter_class: Callable[[Request], AsyncHTTPRequestAdapter]
115
118
  websocket_adapter_class: Callable[
116
- [WebSocketRequest, WebSocketResponse], AsyncWebSocketAdapter
119
+ ["AsyncBaseHTTPView", WebSocketRequest, WebSocketResponse],
120
+ AsyncWebSocketAdapter,
117
121
  ]
118
122
  graphql_transport_ws_handler_class = BaseGraphQLTransportWSHandler
119
123
  graphql_ws_handler_class = BaseGraphQLWSHandler
@@ -265,7 +269,7 @@ class AsyncBaseHTTPView(
265
269
  websocket_response = await self.create_websocket_response(
266
270
  request, websocket_subprotocol
267
271
  )
268
- websocket = self.websocket_adapter_class(request, websocket_response)
272
+ websocket = self.websocket_adapter_class(self, request, websocket_response)
269
273
 
270
274
  context = (
271
275
  await self.get_context(request, response=websocket_response)
strawberry/http/base.py CHANGED
@@ -2,7 +2,6 @@ import json
2
2
  from typing import Any, Dict, Generic, List, Mapping, Optional, Union
3
3
  from typing_extensions import Protocol
4
4
 
5
- from strawberry.http import GraphQLHTTPResponse
6
5
  from strawberry.http.ides import GraphQL_IDE, get_graphql_ide_html
7
6
  from strawberry.http.types import HTTPMethod, QueryParams
8
7
 
@@ -44,8 +43,8 @@ class BaseView(Generic[Request]):
44
43
  except json.JSONDecodeError as e:
45
44
  raise HTTPException(400, "Unable to parse request body as JSON") from e
46
45
 
47
- def encode_json(self, response_data: GraphQLHTTPResponse) -> str:
48
- return json.dumps(response_data)
46
+ def encode_json(self, data: object) -> str:
47
+ return json.dumps(data)
49
48
 
50
49
  def parse_query_params(self, params: QueryParams) -> Dict[str, Any]:
51
50
  params = dict(params)
@@ -194,7 +194,10 @@ class LitestarRequestAdapter(AsyncHTTPRequestAdapter):
194
194
 
195
195
 
196
196
  class LitestarWebSocketAdapter(AsyncWebSocketAdapter):
197
- def __init__(self, request: WebSocket, response: WebSocket) -> None:
197
+ def __init__(
198
+ self, view: AsyncBaseHTTPView, request: WebSocket, response: WebSocket
199
+ ) -> None:
200
+ super().__init__(view)
198
201
  self.ws = response
199
202
 
200
203
  async def iter_json(
@@ -218,7 +221,7 @@ class LitestarWebSocketAdapter(AsyncWebSocketAdapter):
218
221
 
219
222
  async def send_json(self, message: Mapping[str, object]) -> None:
220
223
  try:
221
- await self.ws.send_json(message)
224
+ await self.ws.send_data(data=self.view.encode_json(message))
222
225
  except WebSocketDisconnect as exc:
223
226
  raise WebSocketDisconnected from exc
224
227
 
@@ -12,14 +12,9 @@ from typing import (
12
12
 
13
13
  from strawberry.http.exceptions import NonTextMessageReceived, WebSocketDisconnected
14
14
  from strawberry.subscriptions.protocols.graphql_ws.types import (
15
- CompleteMessage,
16
- ConnectionAckMessage,
17
- ConnectionErrorMessage,
18
15
  ConnectionInitMessage,
19
- ConnectionKeepAliveMessage,
20
16
  ConnectionTerminateMessage,
21
17
  DataMessage,
22
- ErrorMessage,
23
18
  OperationMessage,
24
19
  StartMessage,
25
20
  StopMessage,
@@ -93,15 +88,13 @@ class BaseGraphQLWSHandler:
93
88
  async def handle_connection_init(self, message: ConnectionInitMessage) -> None:
94
89
  payload = message.get("payload")
95
90
  if payload is not None and not isinstance(payload, dict):
96
- error_message: ConnectionErrorMessage = {"type": "connection_error"}
97
- await self.websocket.send_json(error_message)
91
+ await self.send_message({"type": "connection_error"})
98
92
  await self.websocket.close(code=1000, reason="")
99
93
  return
100
94
 
101
95
  self.connection_params = payload
102
96
 
103
- connection_ack_message: ConnectionAckMessage = {"type": "connection_ack"}
104
- await self.websocket.send_json(connection_ack_message)
97
+ await self.send_message({"type": "connection_ack"})
105
98
 
106
99
  if self.keep_alive:
107
100
  keep_alive_handler = self.handle_keep_alive()
@@ -139,8 +132,7 @@ class BaseGraphQLWSHandler:
139
132
  async def handle_keep_alive(self) -> None:
140
133
  assert self.keep_alive_interval
141
134
  while True:
142
- data: ConnectionKeepAliveMessage = {"type": "ka"}
143
- await self.websocket.send_json(data)
135
+ await self.send_message({"type": "ka"})
144
136
  await asyncio.sleep(self.keep_alive_interval)
145
137
 
146
138
  async def handle_async_results(
@@ -160,26 +152,22 @@ class BaseGraphQLWSHandler:
160
152
  )
161
153
  if isinstance(agen_or_err, PreExecutionError):
162
154
  assert agen_or_err.errors
163
- error_payload = agen_or_err.errors[0].formatted
164
- error_message: ErrorMessage = {
165
- "type": "error",
166
- "id": operation_id,
167
- "payload": error_payload,
168
- }
169
- await self.websocket.send_json(error_message)
155
+ await self.send_message(
156
+ {
157
+ "type": "error",
158
+ "id": operation_id,
159
+ "payload": agen_or_err.errors[0].formatted,
160
+ }
161
+ )
170
162
  else:
171
163
  self.subscriptions[operation_id] = agen_or_err
172
164
 
173
165
  async for result in agen_or_err:
174
- await self.send_data(result, operation_id)
166
+ await self.send_data_message(result, operation_id)
175
167
 
176
- await self.websocket.send_json(
177
- CompleteMessage({"type": "complete", "id": operation_id})
178
- )
168
+ await self.send_message({"type": "complete", "id": operation_id})
179
169
  except asyncio.CancelledError:
180
- await self.websocket.send_json(
181
- CompleteMessage({"type": "complete", "id": operation_id})
182
- )
170
+ await self.send_message({"type": "complete", "id": operation_id})
183
171
 
184
172
  async def cleanup_operation(self, operation_id: str) -> None:
185
173
  if operation_id in self.subscriptions:
@@ -192,7 +180,7 @@ class BaseGraphQLWSHandler:
192
180
  await self.tasks[operation_id]
193
181
  del self.tasks[operation_id]
194
182
 
195
- async def send_data(
183
+ async def send_data_message(
196
184
  self, execution_result: ExecutionResult, operation_id: str
197
185
  ) -> None:
198
186
  data_message: DataMessage = {
@@ -209,7 +197,10 @@ class BaseGraphQLWSHandler:
209
197
  if execution_result.extensions:
210
198
  data_message["payload"]["extensions"] = execution_result.extensions
211
199
 
212
- await self.websocket.send_json(data_message)
200
+ await self.send_message(data_message)
201
+
202
+ async def send_message(self, message: OperationMessage) -> None:
203
+ await self.websocket.send_json(message)
213
204
 
214
205
 
215
206
  __all__ = ["BaseGraphQLWSHandler"]
@@ -78,6 +78,7 @@ OperationMessage = Union[
78
78
  DataMessage,
79
79
  ErrorMessage,
80
80
  CompleteMessage,
81
+ ConnectionKeepAliveMessage,
81
82
  ]
82
83
 
83
84
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: strawberry-graphql
3
- Version: 0.250.0
3
+ Version: 0.251.0
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=nzZSiCT3ruBHRmPy7P7Ow8tzRtCfSpHq0KR_Eu8U1WY,7765
6
+ strawberry/aiohttp/views.py,sha256=-D1SWYgXbF9UUpt3BnvzSOTrqAZOSQrPQmP_H4736IQ,7857
7
7
  strawberry/annotation.py,sha256=u5rkFs6CDUaiJZMK7jp_VDUWdZZ3HXQEbR2ocruDpxA,13065
8
- strawberry/asgi/__init__.py,sha256=cykkfbnNfpJu65DrCn3GPI4QamW1d2ez2fI6WVsEnwE,7993
8
+ strawberry/asgi/__init__.py,sha256=49JPYO-DRXpFqxRYBYhqvoFA2GbIjXBM-nBvrOI88O8,8086
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
@@ -14,7 +14,7 @@ strawberry/channels/__init__.py,sha256=-9ENTIu1AILbqffJ663qH6AwpZgLrJx_kaokS7RrC
14
14
  strawberry/channels/handlers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
15
  strawberry/channels/handlers/base.py,sha256=KV4KA0eF5NRtikV9m4ssoPI5pmCZvDuRkfoTxwh42qI,7853
16
16
  strawberry/channels/handlers/http_handler.py,sha256=fnQcPwdUz2CboVlnI3s1urQ_ZnZyNZvRx7SM_xPLLEA,11577
17
- strawberry/channels/handlers/ws_handler.py,sha256=k9xax8S1g0tfEFSe76UOHkheHqIrnYjEioYlLm4UPLo,6052
17
+ strawberry/channels/handlers/ws_handler.py,sha256=YvrbaYtF6arDSGFYE3TMWddmHjdkTtHHzVRh7Y3uS3M,6158
18
18
  strawberry/channels/router.py,sha256=DKIbl4zuRBhfvViUVpyu0Rf_WRT41E6uZC-Yic9Ltvo,2024
19
19
  strawberry/channels/testing.py,sha256=0q7XQi3uOa-WbqXTkZKWwsLH2B8IHfP3JAXF-b-1qM4,6490
20
20
  strawberry/cli/__init__.py,sha256=byS5VrEiTJatAH6YS4V1Kd4SOwMRAQO2M1oJdIddivg,585
@@ -49,7 +49,7 @@ strawberry/django/apps.py,sha256=ZWw3Mzv1Cgy0T9xT8Jr2_dkCTZjT5WQABb34iqnu5pc,135
49
49
  strawberry/django/context.py,sha256=XL85jDGAVnb2pwgm5uRUvIXwlGia3i-8ZVfKihf0T24,655
50
50
  strawberry/django/test/__init__.py,sha256=4xxdUZtIISSOwjrcnmox7AvT4WWjowCm5bUuPdQneMg,71
51
51
  strawberry/django/test/client.py,sha256=6dorWECd0wdn8fu3dabE-dfGK3uza58mGrdJ-xPct-w,626
52
- strawberry/django/views.py,sha256=b0DgNAKqKlM0CTOipDLUPm9liS_02wLJaZuxIaIR1Xk,9573
52
+ strawberry/django/views.py,sha256=jPb_J6-bXd_xb478Cv0nR5eLtRZN8CgvxlopkhckgJQ,9542
53
53
  strawberry/exceptions/__init__.py,sha256=-yYcgv3cxEyDSxWyFId9j-yy2pNnXQC4lIpk7bHr8fs,6257
54
54
  strawberry/exceptions/conflicting_arguments.py,sha256=68f6kMSXdjuEjZkoe8o2I9PSIjwTS1kXsSGaQBPk_hI,1587
55
55
  strawberry/exceptions/duplicated_type_name.py,sha256=-FG5qG_Mvkd7ROdOxCB9bijf8QR6Olryf07mbAFC0-U,2210
@@ -131,8 +131,8 @@ strawberry/file_uploads/utils.py,sha256=2zsXg3QsKgGLD7of2dW-vgQn_Naf7I3Men9PhEAF
131
131
  strawberry/flask/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
132
132
  strawberry/flask/views.py,sha256=3gd1Xgxg3IT72dz2nrMBK094dMNxTUHciu3oofGOAG4,6235
133
133
  strawberry/http/__init__.py,sha256=GSvHUDXl1cHfLnb37PXOAnxfoXhvz0f467P1O8uDatM,1620
134
- strawberry/http/async_base_view.py,sha256=n4Kg9sG9awN7EWa0JIQUmMtnyfI6aqRmg3n2IkoQ_F4,15742
135
- strawberry/http/base.py,sha256=DFGBb6UhHR1EOmZkLn5V-2IKXzjYasg6yv06PQnm9Ds,2336
134
+ strawberry/http/async_base_view.py,sha256=K9NAOd9pw2D-7bAAgU_o59mjIb5XlL0Ojrrm9ylhASY,15863
135
+ strawberry/http/base.py,sha256=tEG39pgz4StQ_Xwk1CfOu0wxu9cb53zMfHhc4jaXHSM,2257
136
136
  strawberry/http/exceptions.py,sha256=9E2dreS1crRoJVUEPuHyx23NcDELDHNzkAOa-rGv-8I,348
137
137
  strawberry/http/ides.py,sha256=njYI2b5R0PnY27ll1ePdIvgPQU3m6Aod_JTBrcZYs0U,638
138
138
  strawberry/http/parse_content_type.py,sha256=sgtcOO_ZOFg7WWWibYyLc4SU58K-SErcW56kQczQmKU,412
@@ -141,7 +141,7 @@ strawberry/http/temporal_response.py,sha256=QrGYSg7Apu7Mh-X_uPKDZby-UicXw2J_ywxa
141
141
  strawberry/http/types.py,sha256=cAuaiUuvaMI_XhZ2Ey6Ej23WyQKqMGFxzzpVHDjVazY,371
142
142
  strawberry/http/typevars.py,sha256=8hK5PfNPZXb2EhZmqlobYyfwJJcO2Wb96T91MlLEVJs,450
143
143
  strawberry/litestar/__init__.py,sha256=zsXzg-mglCGUVO9iNXLm-yadoDSCK7k-zuyRqyvAh1w,237
144
- strawberry/litestar/controller.py,sha256=yA8f59NuC6ZJgpG2p4HoILko3FdWiNx5AWdkQGti_6U,13992
144
+ strawberry/litestar/controller.py,sha256=IsIZoRiuaoDfoioye6lifys4_9xX8sRjOV_7gM_x6x4,14090
145
145
  strawberry/parent.py,sha256=sXURm0lauSpjUADsmfNGY-Zl7kHs0A67BFcWuWKzRxw,771
146
146
  strawberry/permission.py,sha256=rCJLK21cRNDQ6N9eSqcEiIUZiuCvF3FVOK3onXGai9E,7543
147
147
  strawberry/printer/__init__.py,sha256=DmepjmgtkdF5RxK_7yC6qUyRWn56U-9qeZMbkztYB9w,62
@@ -189,8 +189,8 @@ strawberry/subscriptions/protocols/graphql_transport_ws/__init__.py,sha256=wN6dk
189
189
  strawberry/subscriptions/protocols/graphql_transport_ws/handlers.py,sha256=R9QCGHJ_lf0gmNf_wzt4Ow-HFA5ulFsGUiNo_K3CHkI,14104
190
190
  strawberry/subscriptions/protocols/graphql_transport_ws/types.py,sha256=AtKPEyFuNIKgnIIBD-MC4kAYFQ6uhXeq3xyRF6Dh-hg,2181
191
191
  strawberry/subscriptions/protocols/graphql_ws/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
192
- strawberry/subscriptions/protocols/graphql_ws/handlers.py,sha256=oM0o85zC24LpBjtVq8VakKx2hBGL0kb3Q9yl0GyFLS8,7614
193
- strawberry/subscriptions/protocols/graphql_ws/types.py,sha256=diZ36w56Nb_YmgfWXe6uXGiQOKmWIVjNEkcM-PkjaSs,1939
192
+ strawberry/subscriptions/protocols/graphql_ws/handlers.py,sha256=BmUh_IRJRW7xKCvZD7ewJK0rT8iERzkff53FaJJGRlk,7224
193
+ strawberry/subscriptions/protocols/graphql_ws/types.py,sha256=WvCZVhxFRkojvOFKiDuXPtighsEJkQU-I9y4Vgo5c4w,1971
194
194
  strawberry/test/__init__.py,sha256=U3B5Ng7C_H8GpCpfvgZZcfADMw6cor5hm78gS3nDdMI,115
195
195
  strawberry/test/client.py,sha256=Va7J1tIjZ6PxbOqPl57jSp5lNLOZSueHPmrUuUx5sRY,6462
196
196
  strawberry/tools/__init__.py,sha256=pdGpZx8wpq03VfUZJyF9JtYxZhGqzzxCiipsalWxJX4,127
@@ -229,8 +229,8 @@ strawberry/utils/logging.py,sha256=U1cseHGquN09YFhFmRkiphfASKCyK0HUZREImPgVb0c,7
229
229
  strawberry/utils/operation.py,sha256=SSXxN-vMqdHO6W2OZtip-1z7y4_A-eTVFdhDvhKeLCk,1193
230
230
  strawberry/utils/str_converters.py,sha256=KGd7QH90RevaJjH6SQEkiVVsb8KuhJr_wv5AsI7UzQk,897
231
231
  strawberry/utils/typing.py,sha256=G6k2wWD1TDQ9WFk-Togekj_hTVFqHV-g7Phf2Wu41ms,14380
232
- strawberry_graphql-0.250.0.dist-info/LICENSE,sha256=m-XnIVUKqlG_AWnfi9NReh9JfKhYOB-gJfKE45WM1W8,1072
233
- strawberry_graphql-0.250.0.dist-info/METADATA,sha256=4VaLyKu8LPZoMQwYXdWBxpVCoVtEM5JVKH6bST7gY3U,7758
234
- strawberry_graphql-0.250.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
235
- strawberry_graphql-0.250.0.dist-info/entry_points.txt,sha256=Nk7-aT3_uEwCgyqtHESV9H6Mc31cK-VAvhnQNTzTb4k,49
236
- strawberry_graphql-0.250.0.dist-info/RECORD,,
232
+ strawberry_graphql-0.251.0.dist-info/LICENSE,sha256=m-XnIVUKqlG_AWnfi9NReh9JfKhYOB-gJfKE45WM1W8,1072
233
+ strawberry_graphql-0.251.0.dist-info/METADATA,sha256=zGnSUBu5qpT4aH6iRSSagrmXlvJ4EhUOAIbQvZqSm_Q,7758
234
+ strawberry_graphql-0.251.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
235
+ strawberry_graphql-0.251.0.dist-info/entry_points.txt,sha256=Nk7-aT3_uEwCgyqtHESV9H6Mc31cK-VAvhnQNTzTb4k,49
236
+ strawberry_graphql-0.251.0.dist-info/RECORD,,