helius-python 0.5.0__tar.gz → 0.5.2__tar.gz
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.
- {helius_python-0.5.0 → helius_python-0.5.2}/PKG-INFO +1 -1
- {helius_python-0.5.0 → helius_python-0.5.2}/pyproject.toml +1 -1
- {helius_python-0.5.0 → helius_python-0.5.2}/src/helius/laserstream/websockets.py +33 -22
- {helius_python-0.5.0 → helius_python-0.5.2}/test_examples.py +83 -22
- {helius_python-0.5.0 → helius_python-0.5.2}/tests/unit/lasterstream/test_websockets.py +70 -5
- {helius_python-0.5.0 → helius_python-0.5.2}/.editorconfig +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/.github/workflows/python-package.yml +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/.github/workflows/python-publish.yml +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/.gitignore +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/AGENTS.md +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/CLAUDE.md +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/CONTRIBUTING.md +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/LICENSE +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/README.md +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/TODO.md +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/examples/laserstream/websocket_logs.py +0 -0
- {helius_python-0.5.0/examples/solana_rpc → helius_python-0.5.2/examples/rpc}/address_transactions.py +0 -0
- {helius_python-0.5.0/examples/solana_rpc → helius_python-0.5.2/examples/rpc}/address_transfers.py +0 -0
- {helius_python-0.5.0/examples/solana_rpc → helius_python-0.5.2/examples/rpc}/block_explorer.py +0 -0
- {helius_python-0.5.0/examples/solana_rpc → helius_python-0.5.2/examples/rpc}/devnet_airdrop.py +0 -0
- {helius_python-0.5.0/examples/solana_rpc → helius_python-0.5.2/examples/rpc}/network_status.py +0 -0
- {helius_python-0.5.0/examples/solana_rpc → helius_python-0.5.2/examples/rpc}/priority_fees.py +0 -0
- {helius_python-0.5.0/examples/solana_rpc → helius_python-0.5.2/examples/rpc}/stake_overview.py +0 -0
- {helius_python-0.5.0/examples/solana_rpc → helius_python-0.5.2/examples/rpc}/token_inspector.py +0 -0
- {helius_python-0.5.0/examples/solana_rpc → helius_python-0.5.2/examples/rpc}/transaction_inspector.py +0 -0
- {helius_python-0.5.0/examples/solana_rpc → helius_python-0.5.2/examples/rpc}/wallet_tracker.py +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/examples/webhooks/webhook_crud.py +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/examples/webhooks/webhook_receiver.py +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/requirements.txt +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/src/helius/__init__.py +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/src/helius/admin/__init__.py +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/src/helius/admin/admin.py +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/src/helius/rpc/__init__.py +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/src/helius/rpc/client.py +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/src/helius/rpc/models.py +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/src/helius/utils/__init__.py +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/src/helius/utils/json_rpc_request.py +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/src/helius/webhooks/__init__.py +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/src/helius/webhooks/webhooks.py +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/tests/fixtures/account.json +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/tests/fixtures/supply.json +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/tests/unit/admin/test_admin.py +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/tests/unit/solana_rpc/test_client.py +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/tests/unit/solana_rpc/test_models.py +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/tests/unit/utils/test_json_rpc_request.py +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/tests/unit/webhooks/test_webhook.py +0 -0
- {helius_python-0.5.0 → helius_python-0.5.2}/tests/unit/webhooks/test_webhooks_api_client.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: helius-python
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.2
|
|
4
4
|
Summary: Typed Python client for the Helius API
|
|
5
5
|
Project-URL: Homepage, https://github.com/markosnarinian/helius-python
|
|
6
6
|
Project-URL: Issues, https://github.com/markosnarinian/helius-python/issues
|
|
@@ -132,6 +132,10 @@ class WebSocketClient:
|
|
|
132
132
|
base_url="wss://mainnet.helius-rpc.com",
|
|
133
133
|
api_key: str | None = None,
|
|
134
134
|
proxy: str | None = None,
|
|
135
|
+
open_timeout: float | None = 10,
|
|
136
|
+
ping_interval: float | None = 20,
|
|
137
|
+
ping_timeout: float | None = 20,
|
|
138
|
+
close_timeout: float | None = 10,
|
|
135
139
|
):
|
|
136
140
|
|
|
137
141
|
base_url = base_url
|
|
@@ -144,7 +148,14 @@ class WebSocketClient:
|
|
|
144
148
|
if not api_key:
|
|
145
149
|
raise ValueError("No API key provided.")
|
|
146
150
|
uri = httpx.URL(base_url).copy_with(path="/", params={"api-key": api_key})
|
|
147
|
-
self._websocket = connect(
|
|
151
|
+
self._websocket = connect(
|
|
152
|
+
str(uri),
|
|
153
|
+
proxy=proxy,
|
|
154
|
+
open_timeout=open_timeout,
|
|
155
|
+
ping_interval=ping_interval,
|
|
156
|
+
ping_timeout=ping_timeout,
|
|
157
|
+
close_timeout=close_timeout,
|
|
158
|
+
)
|
|
148
159
|
|
|
149
160
|
def close(self):
|
|
150
161
|
self._websocket.close()
|
|
@@ -163,6 +174,27 @@ class WebSocketClient:
|
|
|
163
174
|
response = self._websocket.recv()
|
|
164
175
|
return json.loads(response)
|
|
165
176
|
|
|
177
|
+
def receive(self) -> tuple[dict | None, Notification, int]:
|
|
178
|
+
response = json.loads(self._websocket.recv())
|
|
179
|
+
model = self.MODELS[response["method"]]
|
|
180
|
+
result = response["params"]["result"]
|
|
181
|
+
subscription = response["params"]["subscription"]
|
|
182
|
+
if isinstance(result, dict):
|
|
183
|
+
context = result.get("context")
|
|
184
|
+
value = result.get("value")
|
|
185
|
+
else:
|
|
186
|
+
context, value = None, None
|
|
187
|
+
if value is not None:
|
|
188
|
+
notification = model.model_validate(value)
|
|
189
|
+
else:
|
|
190
|
+
notification = model.model_validate(result)
|
|
191
|
+
return context, notification, subscription
|
|
192
|
+
|
|
193
|
+
def listen(self):
|
|
194
|
+
while True:
|
|
195
|
+
context, notification, subscription = self.receive()
|
|
196
|
+
yield context, notification, subscription
|
|
197
|
+
|
|
166
198
|
def _unsubscribe(self, subscription_type, subscription) -> bool:
|
|
167
199
|
request = (
|
|
168
200
|
JsonRpcRequest(method=f"{subscription_type}Unsubscribe")
|
|
@@ -376,24 +408,3 @@ class WebSocketClient:
|
|
|
376
408
|
|
|
377
409
|
def vote_unsubscribe(self, subscription) -> bool:
|
|
378
410
|
return self._unsubscribe("vote", subscription)
|
|
379
|
-
|
|
380
|
-
def receive(self) -> tuple[dict | None, Notification, int]:
|
|
381
|
-
response = json.loads(self._websocket.recv())
|
|
382
|
-
model = self.MODELS[response["method"]]
|
|
383
|
-
result = response["params"]["result"]
|
|
384
|
-
subscription = response["params"]["subscription"]
|
|
385
|
-
if isinstance(result, dict):
|
|
386
|
-
context = result.get("context")
|
|
387
|
-
value = result.get("value")
|
|
388
|
-
else:
|
|
389
|
-
context, value = None, None
|
|
390
|
-
if value is not None:
|
|
391
|
-
notification = model.model_validate(value)
|
|
392
|
-
else:
|
|
393
|
-
notification = model.model_validate(result)
|
|
394
|
-
return context, notification, subscription
|
|
395
|
-
|
|
396
|
-
def listen(self):
|
|
397
|
-
while True:
|
|
398
|
-
context, notification, subscription = self.receive()
|
|
399
|
-
yield context, notification, subscription
|
|
@@ -9,13 +9,15 @@ Usage:
|
|
|
9
9
|
.venv/bin/python test_examples.py
|
|
10
10
|
|
|
11
11
|
The runner expects `HELIUS_API_KEY` to be available in the environment or in
|
|
12
|
-
`.env`, matching the examples themselves.
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
`.env`, matching the examples themselves. Missing/unauthorized API key failures
|
|
13
|
+
are reported as "auth" instead of as example runtime bugs. Some Helius endpoints
|
|
14
|
+
are plan-gated or network-gated; other failures in that class are reported as
|
|
15
|
+
"external".
|
|
15
16
|
"""
|
|
16
17
|
|
|
17
18
|
from __future__ import annotations
|
|
18
19
|
|
|
20
|
+
import argparse
|
|
19
21
|
import os
|
|
20
22
|
import subprocess
|
|
21
23
|
import sys
|
|
@@ -28,6 +30,7 @@ USE_COLOR = "NO_COLOR" not in os.environ
|
|
|
28
30
|
|
|
29
31
|
GREEN = "\033[32m"
|
|
30
32
|
YELLOW = "\033[33m"
|
|
33
|
+
ORANGE = "\033[38;5;208m"
|
|
31
34
|
RED = "\033[31m"
|
|
32
35
|
BOLD = "\033[1m"
|
|
33
36
|
RESET = "\033[0m"
|
|
@@ -37,6 +40,16 @@ SMALL_MINT = "J5iyNuTa6zqqA62Xe4h1VBvcBW5CTSNNva3QPh8DU5RV"
|
|
|
37
40
|
KNOWN_SIGNATURE = "eqRntqi1tjXv1zEGBM5btQGWoxWc73XXGDJXjxLE65Atj6T6qzNnJf5LyTbUoGXHS9TzeAnQniAre48SjcJft9f"
|
|
38
41
|
DEVNET_ADDRESS = "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU"
|
|
39
42
|
|
|
43
|
+
AUTH_FAILURE_MARKERS = (
|
|
44
|
+
"No API key provided.",
|
|
45
|
+
"HTTP 401",
|
|
46
|
+
"401 Unauthorized",
|
|
47
|
+
"HTTP 403",
|
|
48
|
+
"403 Forbidden",
|
|
49
|
+
"Unauthorized",
|
|
50
|
+
"Forbidden",
|
|
51
|
+
)
|
|
52
|
+
|
|
40
53
|
|
|
41
54
|
@dataclass(frozen=True)
|
|
42
55
|
class ExampleTest:
|
|
@@ -118,8 +131,6 @@ TESTS = [
|
|
|
118
131
|
timeout=45,
|
|
119
132
|
external_failure_markers=(
|
|
120
133
|
"TimeoutError: timed out",
|
|
121
|
-
"403 Forbidden",
|
|
122
|
-
"HTTP 403",
|
|
123
134
|
),
|
|
124
135
|
),
|
|
125
136
|
ExampleTest(
|
|
@@ -141,6 +152,41 @@ def color(text: str, ansi_color: str) -> str:
|
|
|
141
152
|
return f"{ansi_color}{text}{RESET}"
|
|
142
153
|
|
|
143
154
|
|
|
155
|
+
def parse_args() -> argparse.Namespace:
|
|
156
|
+
parser = argparse.ArgumentParser(description=__doc__)
|
|
157
|
+
parser.add_argument(
|
|
158
|
+
"-v",
|
|
159
|
+
action="count",
|
|
160
|
+
default=0,
|
|
161
|
+
dest="verbose_count",
|
|
162
|
+
help="increase verbosity; use -v for level 1 or -vv for level 2",
|
|
163
|
+
)
|
|
164
|
+
parser.add_argument(
|
|
165
|
+
"--verbose",
|
|
166
|
+
type=int,
|
|
167
|
+
choices=(0, 1, 2),
|
|
168
|
+
default=None,
|
|
169
|
+
help=(
|
|
170
|
+
"0: only results and failure names; "
|
|
171
|
+
"1: include script output for non-passing tests; "
|
|
172
|
+
"2: include script output for all tests"
|
|
173
|
+
),
|
|
174
|
+
)
|
|
175
|
+
args = parser.parse_args()
|
|
176
|
+
args.verbose = (
|
|
177
|
+
args.verbose if args.verbose is not None else min(args.verbose_count, 2)
|
|
178
|
+
)
|
|
179
|
+
return args
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def output_preview(output: str) -> str:
|
|
183
|
+
lines = output.strip().splitlines()
|
|
184
|
+
preview = "\n".join(lines[:30])
|
|
185
|
+
if len(lines) > 30:
|
|
186
|
+
preview += f"\n... ({len(lines) - 30} more lines)"
|
|
187
|
+
return preview
|
|
188
|
+
|
|
189
|
+
|
|
144
190
|
def run_example(test: ExampleTest) -> tuple[str, str]:
|
|
145
191
|
env = os.environ.copy()
|
|
146
192
|
env["PYTHONPATH"] = (
|
|
@@ -167,47 +213,60 @@ def run_example(test: ExampleTest) -> tuple[str, str]:
|
|
|
167
213
|
output = result.stdout + result.stderr
|
|
168
214
|
if result.returncode == 0:
|
|
169
215
|
return "passed", output
|
|
216
|
+
if any(marker in output for marker in AUTH_FAILURE_MARKERS):
|
|
217
|
+
return "auth", output
|
|
170
218
|
if any(marker in output for marker in test.external_failure_markers):
|
|
171
219
|
return "external", output
|
|
172
220
|
return "failed", output
|
|
173
221
|
|
|
174
222
|
|
|
175
223
|
def main() -> int:
|
|
224
|
+
args = parse_args()
|
|
176
225
|
passed: list[str] = []
|
|
226
|
+
auth: list[str] = []
|
|
177
227
|
external: list[str] = []
|
|
178
228
|
failed: list[tuple[str, str]] = []
|
|
179
229
|
|
|
180
230
|
for test in TESTS:
|
|
181
|
-
print(f"\n=== {test.name} ===", flush=True)
|
|
182
231
|
status, output = run_example(test)
|
|
183
232
|
if status == "passed":
|
|
184
233
|
passed.append(test.name)
|
|
185
|
-
|
|
234
|
+
result = color("PASS", GREEN + BOLD)
|
|
235
|
+
elif status == "auth":
|
|
236
|
+
auth.append(test.name)
|
|
237
|
+
result = (
|
|
238
|
+
color("AUTH", ORANGE + BOLD)
|
|
239
|
+
+ " - missing API key or endpoint is not authorized for this key"
|
|
240
|
+
)
|
|
186
241
|
elif status == "external":
|
|
187
242
|
external.append(test.name)
|
|
188
|
-
|
|
189
|
-
color(
|
|
190
|
-
|
|
191
|
-
YELLOW + BOLD,
|
|
192
|
-
)
|
|
193
|
-
+ ": endpoint, plan, or network prevented a live success"
|
|
243
|
+
result = (
|
|
244
|
+
color("EXTERNAL", YELLOW + BOLD)
|
|
245
|
+
+ " - endpoint, plan, or network prevented a live success"
|
|
194
246
|
)
|
|
195
247
|
else:
|
|
196
248
|
failed.append((test.name, output))
|
|
197
|
-
|
|
249
|
+
result = color("FAIL", RED + BOLD)
|
|
198
250
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
251
|
+
print(f"{result}: {test.name}", flush=True)
|
|
252
|
+
|
|
253
|
+
should_print_output = output.strip() and (
|
|
254
|
+
args.verbose == 2 or (args.verbose == 1 and status != "passed")
|
|
255
|
+
)
|
|
256
|
+
if should_print_output:
|
|
257
|
+
print(output_preview(output))
|
|
205
258
|
|
|
206
259
|
print("\n=== Summary ===")
|
|
207
260
|
print(f"{color('Passed', GREEN)} : {len(passed)}")
|
|
261
|
+
print(f"{color('Auth', ORANGE)} : {len(auth)}")
|
|
208
262
|
print(f"{color('External', YELLOW)} : {len(external)}")
|
|
209
263
|
print(f"{color('Failed', RED)} : {len(failed)}")
|
|
210
264
|
|
|
265
|
+
if auth:
|
|
266
|
+
print("\nAuth failures:")
|
|
267
|
+
for name in auth:
|
|
268
|
+
print(f" - {name}")
|
|
269
|
+
|
|
211
270
|
if external:
|
|
212
271
|
print("\nExternal failures:")
|
|
213
272
|
for name in external:
|
|
@@ -216,8 +275,10 @@ def main() -> int:
|
|
|
216
275
|
if failed:
|
|
217
276
|
print("\nUnexpected failures:")
|
|
218
277
|
for name, output in failed:
|
|
219
|
-
print(f"
|
|
220
|
-
|
|
278
|
+
print(f" - {name}")
|
|
279
|
+
if args.verbose >= 1:
|
|
280
|
+
print(f"\n--- {name} ---")
|
|
281
|
+
print(output.strip())
|
|
221
282
|
return 1
|
|
222
283
|
|
|
223
284
|
return 0
|
|
@@ -64,9 +64,20 @@ def fake_ws(monkeypatch):
|
|
|
64
64
|
"""Patch `connect` so `WebSocketClient.__init__` returns a FakeWebSocket."""
|
|
65
65
|
fake = FakeWebSocket()
|
|
66
66
|
|
|
67
|
-
def fake_connect(
|
|
67
|
+
def fake_connect(
|
|
68
|
+
uri,
|
|
69
|
+
proxy=None,
|
|
70
|
+
open_timeout=None,
|
|
71
|
+
ping_interval=None,
|
|
72
|
+
ping_timeout=None,
|
|
73
|
+
close_timeout=None,
|
|
74
|
+
):
|
|
68
75
|
fake.uri = uri
|
|
69
76
|
fake.proxy = proxy
|
|
77
|
+
fake.open_timeout = open_timeout
|
|
78
|
+
fake.ping_interval = ping_interval
|
|
79
|
+
fake.ping_timeout = ping_timeout
|
|
80
|
+
fake.close_timeout = close_timeout
|
|
70
81
|
return fake
|
|
71
82
|
|
|
72
83
|
monkeypatch.setattr(ws_module, "connect", fake_connect)
|
|
@@ -283,13 +294,29 @@ def test_init_picks_up_api_key_from_env(monkeypatch):
|
|
|
283
294
|
monkeypatch.setenv("HELIUS_API_KEY", "from-env")
|
|
284
295
|
monkeypatch.setattr(ws_module, "dotenv_values", lambda: {})
|
|
285
296
|
|
|
286
|
-
def fake_connect(
|
|
297
|
+
def fake_connect(
|
|
298
|
+
uri,
|
|
299
|
+
proxy=None,
|
|
300
|
+
open_timeout=None,
|
|
301
|
+
ping_interval=None,
|
|
302
|
+
ping_timeout=None,
|
|
303
|
+
close_timeout=None,
|
|
304
|
+
):
|
|
287
305
|
fake.uri = uri
|
|
306
|
+
fake.proxy = proxy
|
|
307
|
+
fake.open_timeout = open_timeout
|
|
308
|
+
fake.ping_interval = ping_interval
|
|
309
|
+
fake.ping_timeout = ping_timeout
|
|
310
|
+
fake.close_timeout = close_timeout
|
|
288
311
|
return fake
|
|
289
312
|
|
|
290
313
|
monkeypatch.setattr(ws_module, "connect", fake_connect)
|
|
291
314
|
client = WebSocketClient()
|
|
292
315
|
assert "api-key=from-env" in fake.uri
|
|
316
|
+
assert fake.open_timeout == 10
|
|
317
|
+
assert fake.ping_interval == 20
|
|
318
|
+
assert fake.ping_timeout == 20
|
|
319
|
+
assert fake.close_timeout == 10
|
|
293
320
|
assert client._websocket is fake
|
|
294
321
|
|
|
295
322
|
|
|
@@ -297,29 +324,67 @@ def test_init_builds_uri_with_api_key_and_passes_proxy(monkeypatch):
|
|
|
297
324
|
fake = FakeWebSocket()
|
|
298
325
|
captured = {}
|
|
299
326
|
|
|
300
|
-
def fake_connect(
|
|
327
|
+
def fake_connect(
|
|
328
|
+
uri,
|
|
329
|
+
proxy=None,
|
|
330
|
+
open_timeout=None,
|
|
331
|
+
ping_interval=None,
|
|
332
|
+
ping_timeout=None,
|
|
333
|
+
close_timeout=None,
|
|
334
|
+
):
|
|
301
335
|
captured["uri"] = uri
|
|
302
336
|
captured["proxy"] = proxy
|
|
337
|
+
captured["open_timeout"] = open_timeout
|
|
338
|
+
captured["ping_interval"] = ping_interval
|
|
339
|
+
captured["ping_timeout"] = ping_timeout
|
|
340
|
+
captured["close_timeout"] = close_timeout
|
|
303
341
|
return fake
|
|
304
342
|
|
|
305
343
|
monkeypatch.setattr(ws_module, "connect", fake_connect)
|
|
306
|
-
WebSocketClient(
|
|
344
|
+
WebSocketClient(
|
|
345
|
+
api_key="test",
|
|
346
|
+
proxy="http://proxy:8080",
|
|
347
|
+
open_timeout=1,
|
|
348
|
+
ping_interval=2,
|
|
349
|
+
ping_timeout=3,
|
|
350
|
+
close_timeout=4,
|
|
351
|
+
)
|
|
307
352
|
assert "api-key=test" in captured["uri"]
|
|
308
353
|
assert captured["uri"].startswith("wss://mainnet.helius-rpc.com")
|
|
309
354
|
assert captured["proxy"] == "http://proxy:8080"
|
|
355
|
+
assert captured["open_timeout"] == 1
|
|
356
|
+
assert captured["ping_interval"] == 2
|
|
357
|
+
assert captured["ping_timeout"] == 3
|
|
358
|
+
assert captured["close_timeout"] == 4
|
|
310
359
|
|
|
311
360
|
|
|
312
361
|
def test_init_uses_custom_base_url(monkeypatch):
|
|
313
362
|
fake = FakeWebSocket()
|
|
314
363
|
captured = {}
|
|
315
364
|
|
|
316
|
-
def fake_connect(
|
|
365
|
+
def fake_connect(
|
|
366
|
+
uri,
|
|
367
|
+
proxy=None,
|
|
368
|
+
open_timeout=None,
|
|
369
|
+
ping_interval=None,
|
|
370
|
+
ping_timeout=None,
|
|
371
|
+
close_timeout=None,
|
|
372
|
+
):
|
|
317
373
|
captured["uri"] = uri
|
|
374
|
+
captured["proxy"] = proxy
|
|
375
|
+
captured["open_timeout"] = open_timeout
|
|
376
|
+
captured["ping_interval"] = ping_interval
|
|
377
|
+
captured["ping_timeout"] = ping_timeout
|
|
378
|
+
captured["close_timeout"] = close_timeout
|
|
318
379
|
return fake
|
|
319
380
|
|
|
320
381
|
monkeypatch.setattr(ws_module, "connect", fake_connect)
|
|
321
382
|
WebSocketClient(api_key="test", base_url="wss://devnet.helius-rpc.com")
|
|
322
383
|
assert captured["uri"].startswith("wss://devnet.helius-rpc.com")
|
|
384
|
+
assert captured["open_timeout"] == 10
|
|
385
|
+
assert captured["ping_interval"] == 20
|
|
386
|
+
assert captured["ping_timeout"] == 20
|
|
387
|
+
assert captured["close_timeout"] == 10
|
|
323
388
|
|
|
324
389
|
|
|
325
390
|
def test_close_delegates_to_websocket(client, fake_ws):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{helius_python-0.5.0/examples/solana_rpc → helius_python-0.5.2/examples/rpc}/address_transactions.py
RENAMED
|
File without changes
|
{helius_python-0.5.0/examples/solana_rpc → helius_python-0.5.2/examples/rpc}/address_transfers.py
RENAMED
|
File without changes
|
{helius_python-0.5.0/examples/solana_rpc → helius_python-0.5.2/examples/rpc}/block_explorer.py
RENAMED
|
File without changes
|
{helius_python-0.5.0/examples/solana_rpc → helius_python-0.5.2/examples/rpc}/devnet_airdrop.py
RENAMED
|
File without changes
|
{helius_python-0.5.0/examples/solana_rpc → helius_python-0.5.2/examples/rpc}/network_status.py
RENAMED
|
File without changes
|
{helius_python-0.5.0/examples/solana_rpc → helius_python-0.5.2/examples/rpc}/priority_fees.py
RENAMED
|
File without changes
|
{helius_python-0.5.0/examples/solana_rpc → helius_python-0.5.2/examples/rpc}/stake_overview.py
RENAMED
|
File without changes
|
{helius_python-0.5.0/examples/solana_rpc → helius_python-0.5.2/examples/rpc}/token_inspector.py
RENAMED
|
File without changes
|
|
File without changes
|
{helius_python-0.5.0/examples/solana_rpc → helius_python-0.5.2/examples/rpc}/wallet_tracker.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|