helius-python 0.2.0__tar.gz → 0.3.0__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.
Files changed (40) hide show
  1. {helius_python-0.2.0 → helius_python-0.3.0}/AGENTS.md +3 -85
  2. {helius_python-0.2.0 → helius_python-0.3.0}/CONTRIBUTING.md +1 -0
  3. {helius_python-0.2.0 → helius_python-0.3.0}/PKG-INFO +82 -5
  4. {helius_python-0.2.0 → helius_python-0.3.0}/README.md +80 -4
  5. helius_python-0.3.0/TODO.md +3 -0
  6. {helius_python-0.2.0 → helius_python-0.3.0}/pyproject.toml +5 -1
  7. {helius_python-0.2.0 → helius_python-0.3.0}/requirements.txt +1 -0
  8. helius_python-0.3.0/src/helius/admin/admin.py +95 -0
  9. helius_python-0.3.0/src/helius/laserstream/websockets.py +398 -0
  10. helius_python-0.3.0/src/helius/rpc/__init__.py +3 -0
  11. helius_python-0.3.0/src/helius/rpc/json_rpc_request.py +52 -0
  12. helius_python-0.3.0/src/helius/solana_rpc/__init__.py +5 -0
  13. helius_python-0.2.0/src/helius/solana_rpc.py → helius_python-0.3.0/src/helius/solana_rpc/client.py +74 -112
  14. {helius_python-0.2.0/src/helius → helius_python-0.3.0/src/helius/solana_rpc}/models.py +7 -0
  15. helius_python-0.3.0/tests/unit/admin/test_admin.py +73 -0
  16. helius_python-0.3.0/tests/unit/lasterstream/test_websockets.py +871 -0
  17. helius_python-0.3.0/tests/unit/rpc/test_json_rpc_request.py +50 -0
  18. helius_python-0.2.0/tests/unit/test_helius_client.py → helius_python-0.3.0/tests/unit/solana_rpc/test_client.py +3 -2
  19. {helius_python-0.2.0/tests/unit → helius_python-0.3.0/tests/unit/solana_rpc}/test_models.py +30 -2
  20. helius_python-0.2.0/tests/unit/test_rpc_request.py +0 -48
  21. {helius_python-0.2.0 → helius_python-0.3.0}/.editorconfig +0 -0
  22. {helius_python-0.2.0 → helius_python-0.3.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  23. {helius_python-0.2.0 → helius_python-0.3.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  24. {helius_python-0.2.0 → helius_python-0.3.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  25. {helius_python-0.2.0 → helius_python-0.3.0}/.github/workflows/python-package.yml +0 -0
  26. {helius_python-0.2.0 → helius_python-0.3.0}/.github/workflows/python-publish.yml +0 -0
  27. {helius_python-0.2.0 → helius_python-0.3.0}/.gitignore +0 -0
  28. {helius_python-0.2.0 → helius_python-0.3.0}/CLAUDE.md +0 -0
  29. {helius_python-0.2.0 → helius_python-0.3.0}/LICENSE +0 -0
  30. {helius_python-0.2.0 → helius_python-0.3.0}/examples/block_explorer.py +0 -0
  31. {helius_python-0.2.0 → helius_python-0.3.0}/examples/devnet_airdrop.py +0 -0
  32. {helius_python-0.2.0 → helius_python-0.3.0}/examples/network_status.py +0 -0
  33. {helius_python-0.2.0 → helius_python-0.3.0}/examples/priority_fees.py +0 -0
  34. {helius_python-0.2.0 → helius_python-0.3.0}/examples/stake_overview.py +0 -0
  35. {helius_python-0.2.0 → helius_python-0.3.0}/examples/token_inspector.py +0 -0
  36. {helius_python-0.2.0 → helius_python-0.3.0}/examples/transaction_inspector.py +0 -0
  37. {helius_python-0.2.0 → helius_python-0.3.0}/examples/wallet_tracker.py +0 -0
  38. {helius_python-0.2.0 → helius_python-0.3.0}/src/helius/__init__.py +0 -0
  39. {helius_python-0.2.0 → helius_python-0.3.0}/tests/fixtures/account.json +0 -0
  40. {helius_python-0.2.0 → helius_python-0.3.0}/tests/fixtures/supply.json +0 -0
@@ -1,84 +1,3 @@
1
- When implementing a function for a RPC method in the SolanaRpcClient class, read the docs for the specific RPC method. For example, for the get_supply function (getSupply RPC method) you should read https://www.helius.dev/docs/rpc/guides/getsupply and https://www.helius.dev/docs/api-reference/rpc/http/getsupply.
2
-
3
- # API Reference
4
-
5
- The API reference is generated from **Google-style docstrings** on every public symbol in `src/helius/`. Whenever you add or modify a public method, model, or class, you MUST write or update its docstring following the rules below. The README's "Supported methods" table is a quick index only — the docstring is the source of truth.
6
-
7
- ## Where docstrings live
8
-
9
- - **Client methods** (`SolanaRpcClient.get_*`, `is_*`, `request_*`, etc.) — every public method gets a docstring. Private methods (`_send`, dunders) do not need one.
10
- - **Models** (`src/helius/models.py`) — every public model class gets a docstring describing what it represents. Individual fields don't need per-field docstrings if their names and types are self-explanatory; only document fields where the meaning, units, or nullability isn't obvious from the type alone.
11
- - **Builders / helpers** (`RpcRequest`) — class docstring describing purpose, plus one-line docstrings on each public method.
12
-
13
- ## Client method docstring format
14
-
15
- Use Google-style sections. Order matters; omit any section that doesn't apply.
16
-
17
- ```python
18
- def method_name(self, ...) -> ReturnType:
19
- """One-line summary in the imperative mood, ending with a period.
20
-
21
- Optional longer description: a paragraph or two on what the method does,
22
- when to use it, and any non-obvious behavior. Keep this short — link to
23
- the upstream Helius docs rather than restating them.
24
-
25
- Args:
26
- param_one: Description of the first parameter, including units
27
- (lamports vs. SOL, slot vs. block height) when relevant. Mention
28
- the upstream JSON field name only if it differs in a non-obvious
29
- way from the snake_case Python name.
30
- param_two: Description. Note constraints like "must be base-58
31
- encoded" or "max 500_000 slots from `start_slot`".
32
- commitment: Optional commitment level. Defaults to the node's default
33
- when omitted.
34
-
35
- Returns:
36
- Describe the return shape. For tuples, describe each element in
37
- order. For models, name the model and what it represents. For
38
- primitives, name the unit (e.g. "Balance in lamports.").
39
-
40
- Raises:
41
- ValueError: When the arguments violate the documented constraints
42
- (e.g. mutually exclusive params, mismatched pairs).
43
-
44
- Note:
45
- Only available on Devnet and Testnet, not Mainnet Beta.
46
-
47
- See Also:
48
- - Helius guide: https://www.helius.dev/docs/rpc/guides/<method>
49
- - Helius API reference: https://www.helius.dev/docs/api-reference/rpc/http/<method>
50
- """
51
- ```
52
-
53
- Rules:
54
-
55
- - **Summary line** is one sentence, imperative mood, ≤ 88 chars, ends with a period. Example: `"Return the SOL balance of an account in lamports."`
56
- - **`Args:`** documents every parameter, even `commitment` and `min_context_slot`. One entry per param. Don't re-state the type — basedpyright already shows it.
57
- - **`Returns:`** is mandatory unless the method returns `None`.
58
- - **`Raises:`** is required if the method calls `raise` directly. Don't document exceptions that bubble up from `httpx` — those are covered by the library-wide error-handling docs.
59
- - **`Note:`** for network restrictions, version requirements, pagination limits, deprecation warnings, etc. One section per concern.
60
- - **`See Also:`** ALWAYS includes the Helius guide and API reference URLs for the underlying RPC method. This is the contract for an RPC wrapper — the docstring tells you what we do, the upstream docs tell you what the network does.
61
- - Keep prose tight. The docstring should be readable in `help(client.method)` without scrolling forever.
62
-
63
- ## Model docstring format
64
-
65
- ```python
66
- class Supply(BaseModel):
67
- """Total, circulating, and non-circulating SOL supply, in lamports.
68
-
69
- Returned as the `value` field of `getSupply`. All amounts are in
70
- lamports (1 SOL = 1_000_000_000 lamports).
71
-
72
- See Also:
73
- - Helius API reference: https://www.helius.dev/docs/api-reference/rpc/http/getsupply
74
- """
75
- ...
76
- ```
77
-
78
- Rules:
79
-
80
- - One-line summary + optional paragraph + `See Also:` linking the upstream docs that define the shape.
81
- - If a field has surprising semantics (e.g. `ui_amount` can be `None` when the mint has too many decimals, `non_circulating_accounts` is only populated when not excluded), document it inline with `Field(..., description="...")` or in the class docstring.
82
1
 
83
2
  ## Conventions
84
3
 
@@ -98,11 +17,10 @@ Rules:
98
17
 
99
18
  ## Checklist for adding a new client method
100
19
 
101
- 1. Read both Helius doc URLs for the RPC method (see the top of this file).
20
+ 1. Read the docs. The user should provide the relevant URLs. If they don't, ask them to do so.
102
21
  2. Implement the method, following the **Implementation conventions** above — in particular, return `(context, value)` if the upstream response is wrapped.
103
- 3. Add a docstring with `Args`, `Returns`, `Raises` (if any), `Note` (if any), and `See Also` with both Helius URLs.
104
- 4. Add the method to the "Supported methods" table in `README.md`.
105
- 5. Add tests per the Testing section.
22
+ 3. Add the method to the "Supported methods" table in `README.md`.
23
+ 4. Add tests per the Testing section.
106
24
 
107
25
  # Testing
108
26
 
@@ -44,6 +44,7 @@ easiest to most involved:
44
44
  - **Improve docs and examples.** Clearer docstrings, better README snippets,
45
45
  more realistic examples.
46
46
  - **Create an example or refine an existing one.** Examples make it easier for developers to get started.
47
+ - **Improve test coverage** Write a missing test or improve an existing one.
47
48
 
48
49
  If you're not sure where to start, browse the
49
50
  [open issues](https://github.com/markosnarinian/helius-python/issues).
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: helius-python
3
- Version: 0.2.0
3
+ Version: 0.3.0
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
@@ -13,6 +13,7 @@ Requires-Python: >=3.10
13
13
  Requires-Dist: httpx
14
14
  Requires-Dist: pydantic
15
15
  Requires-Dist: python-dotenv
16
+ Requires-Dist: websockets
16
17
  Provides-Extra: dev
17
18
  Requires-Dist: pytest; extra == 'dev'
18
19
  Requires-Dist: respx; extra == 'dev'
@@ -137,11 +138,16 @@ wraps it.
137
138
  Webhooks API, Mint API, token metadata, address lookups, and beyond.
138
139
  **(in progress)**
139
140
  - 🚧 **Platform features** — streaming, websockets, and any new
140
- capability Helius adds to its API. **(in progress)**
141
+ capability Helius adds to its API. The full WebSocket subscription
142
+ surface (`accountSubscribe`, `transactionSubscribe`, `logsSubscribe`,
143
+ `programSubscribe`, and the rest) is **supported today**; other
144
+ platform features are **in progress**.
141
145
 
142
- > **Current status:** only the standard Solana JSON-RPC surface is
143
- > implemented today. Support for Helius RPC extensions, REST endpoints,
144
- > and platform features is actively being worked on.
146
+ > **Current status:** the standard Solana JSON-RPC surface, the
147
+ > WebSocket subscription surface, and the Admin (account management)
148
+ > usage endpoint are implemented today. Support for Helius RPC
149
+ > extensions and the remaining REST endpoints is actively being worked
150
+ > on.
145
151
 
146
152
  ## Goals
147
153
 
@@ -152,6 +158,11 @@ wraps it.
152
158
  4. **Zero magic** — thin, predictable wrappers that map directly to the
153
159
  documented Helius API.
154
160
 
161
+ ## Installation via PyPI
162
+ ```bash
163
+ pip install helius-python
164
+ ```
165
+
155
166
  ## Authentication
156
167
 
157
168
  Pass your Helius API key explicitly:
@@ -312,6 +323,72 @@ continuously.
312
323
  | `requestAirdrop` | `request_airdrop(...)` | [guide](https://www.helius.dev/docs/rpc/guides/requestairdrop), [reference](https://www.helius.dev/docs/api-reference/rpc/http/requestairdrop) |
313
324
  | `sendTransaction` | `send_transaction(...)` | [guide](https://www.helius.dev/docs/rpc/guides/sendtransaction), [reference](https://www.helius.dev/docs/api-reference/rpc/http/sendtransaction) |
314
325
 
326
+ ## WebSocket subscriptions
327
+
328
+ `WebSocketClient` wraps the Solana/Helius WebSocket subscription surface.
329
+ It connects over `wss://` on construction, exposes one `*_subscribe` /
330
+ `*_unsubscribe` pair per subscription type, and parses incoming
331
+ notifications into typed pydantic models.
332
+
333
+ ```python
334
+ from helius.laserstream.websockets import WebSocketClient
335
+
336
+ with WebSocketClient(api_key="YOUR_HELIUS_API_KEY") as ws:
337
+ subscription = ws.account_subscribe(
338
+ pubkey="So11111111111111111111111111111111111111112",
339
+ commitment="confirmed",
340
+ )
341
+
342
+ for context, notification, sub in ws.listen():
343
+ print(notification) # typed AccountNotification
344
+
345
+ ws.account_unsubscribe(subscription)
346
+ ```
347
+
348
+ Like `SolanaRpcClient`, it supports the context-manager protocol and a
349
+ manual `close()`. The constructor defaults to
350
+ `wss://mainnet.helius-rpc.com` and reads `HELIUS_API_KEY` from the
351
+ environment or `.env` when `api_key` is omitted; an optional `proxy` is
352
+ also accepted.
353
+
354
+ Each `*_subscribe` call returns the integer subscription id. Use
355
+ `receive()` to read a single notification or `listen()` to iterate over
356
+ them; both yield a `(context, notification, subscription)` tuple where
357
+ `notification` is the model below.
358
+
359
+ | Subscribe method | Unsubscribe method | Notification model | Helius docs |
360
+ | ------------------------------- | --------------------------------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
361
+ | `account_subscribe(...)` | `account_unsubscribe(...)` | `AccountNotification` | [reference](https://www.helius.dev/docs/api-reference/rpc/websocket/accountsubscribe) |
362
+ | `block_subscribe(...)` | `block_unsubscribe(...)` | `BlockNotification` | [reference](https://www.helius.dev/docs/api-reference/rpc/websocket/blocksubscribe) |
363
+ | `logs_subscribe(...)` | `logs_unsubscribe(...)` | `LogsNotification` | [reference](https://www.helius.dev/docs/api-reference/rpc/websocket/logssubscribe) |
364
+ | `program_subscribe(...)` | `program_unsubscribe(...)` | `ProgramNotification` | [reference](https://www.helius.dev/docs/api-reference/rpc/websocket/programsubscribe) |
365
+ | `root_subscribe()` | `root_unsubscribe(...)` | `RootNotification` | [reference](https://www.helius.dev/docs/api-reference/rpc/websocket/rootsubscribe) |
366
+ | `signature_subscribe(...)` | `signature_unsubscribe(...)` | `SignatureNotification` | [reference](https://www.helius.dev/docs/api-reference/rpc/websocket/signaturesubscribe) |
367
+ | `slot_subscribe()` | `slot_unsubscribe(...)` | `SlotNotification` | [reference](https://www.helius.dev/docs/api-reference/rpc/websocket/slotsubscribe) |
368
+ | `slots_updates_subscribe()` | `slots_updates_unsubscribe(...)` | `SlotsUpdatesNotification` | [reference](https://www.helius.dev/docs/api-reference/rpc/websocket/slotsupdatessubscribe) |
369
+ | `vote_subscribe()` | `vote_unsubscribe(...)` | `VoteNotification` | [reference](https://www.helius.dev/docs/api-reference/rpc/websocket/votesubscribe) |
370
+ | `transaction_subscribe(...)` | `transaction_unsubscribe(...)` | `TransactionNotification` | [reference](https://www.helius.dev/docs/api-reference/rpc/websocket/slotunsubscribe) |
371
+
372
+ ## Admin API
373
+
374
+ `AccountManagementClient` wraps the Helius admin API. Today it exposes
375
+ project credit usage via `get_project_usage(...)`, which returns a typed
376
+ `ProjectUsage` model.
377
+
378
+ ```python
379
+ from helius.admin.admin import AccountManagementClient
380
+
381
+ with AccountManagementClient(api_key="YOUR_HELIUS_API_KEY") as admin:
382
+ usage = admin.get_project_usage(project_id="YOUR_PROJECT_ID")
383
+ print(usage.credits_remaining, usage.usage.rpc)
384
+ ```
385
+
386
+ The `project_id` can be passed per call or set once on the constructor;
387
+ if neither is provided, `get_project_usage` raises `ValueError`. The
388
+ client defaults to `https://admin-api.helius.xyz` and, like the others,
389
+ supports the context-manager protocol, a manual `close()`, and reads
390
+ `HELIUS_API_KEY` from the environment or `.env`.
391
+
315
392
  ## License
316
393
 
317
394
  [MIT](LICENSE)
@@ -117,11 +117,16 @@ wraps it.
117
117
  Webhooks API, Mint API, token metadata, address lookups, and beyond.
118
118
  **(in progress)**
119
119
  - 🚧 **Platform features** — streaming, websockets, and any new
120
- capability Helius adds to its API. **(in progress)**
120
+ capability Helius adds to its API. The full WebSocket subscription
121
+ surface (`accountSubscribe`, `transactionSubscribe`, `logsSubscribe`,
122
+ `programSubscribe`, and the rest) is **supported today**; other
123
+ platform features are **in progress**.
121
124
 
122
- > **Current status:** only the standard Solana JSON-RPC surface is
123
- > implemented today. Support for Helius RPC extensions, REST endpoints,
124
- > and platform features is actively being worked on.
125
+ > **Current status:** the standard Solana JSON-RPC surface, the
126
+ > WebSocket subscription surface, and the Admin (account management)
127
+ > usage endpoint are implemented today. Support for Helius RPC
128
+ > extensions and the remaining REST endpoints is actively being worked
129
+ > on.
125
130
 
126
131
  ## Goals
127
132
 
@@ -132,6 +137,11 @@ wraps it.
132
137
  4. **Zero magic** — thin, predictable wrappers that map directly to the
133
138
  documented Helius API.
134
139
 
140
+ ## Installation via PyPI
141
+ ```bash
142
+ pip install helius-python
143
+ ```
144
+
135
145
  ## Authentication
136
146
 
137
147
  Pass your Helius API key explicitly:
@@ -292,6 +302,72 @@ continuously.
292
302
  | `requestAirdrop` | `request_airdrop(...)` | [guide](https://www.helius.dev/docs/rpc/guides/requestairdrop), [reference](https://www.helius.dev/docs/api-reference/rpc/http/requestairdrop) |
293
303
  | `sendTransaction` | `send_transaction(...)` | [guide](https://www.helius.dev/docs/rpc/guides/sendtransaction), [reference](https://www.helius.dev/docs/api-reference/rpc/http/sendtransaction) |
294
304
 
305
+ ## WebSocket subscriptions
306
+
307
+ `WebSocketClient` wraps the Solana/Helius WebSocket subscription surface.
308
+ It connects over `wss://` on construction, exposes one `*_subscribe` /
309
+ `*_unsubscribe` pair per subscription type, and parses incoming
310
+ notifications into typed pydantic models.
311
+
312
+ ```python
313
+ from helius.laserstream.websockets import WebSocketClient
314
+
315
+ with WebSocketClient(api_key="YOUR_HELIUS_API_KEY") as ws:
316
+ subscription = ws.account_subscribe(
317
+ pubkey="So11111111111111111111111111111111111111112",
318
+ commitment="confirmed",
319
+ )
320
+
321
+ for context, notification, sub in ws.listen():
322
+ print(notification) # typed AccountNotification
323
+
324
+ ws.account_unsubscribe(subscription)
325
+ ```
326
+
327
+ Like `SolanaRpcClient`, it supports the context-manager protocol and a
328
+ manual `close()`. The constructor defaults to
329
+ `wss://mainnet.helius-rpc.com` and reads `HELIUS_API_KEY` from the
330
+ environment or `.env` when `api_key` is omitted; an optional `proxy` is
331
+ also accepted.
332
+
333
+ Each `*_subscribe` call returns the integer subscription id. Use
334
+ `receive()` to read a single notification or `listen()` to iterate over
335
+ them; both yield a `(context, notification, subscription)` tuple where
336
+ `notification` is the model below.
337
+
338
+ | Subscribe method | Unsubscribe method | Notification model | Helius docs |
339
+ | ------------------------------- | --------------------------------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
340
+ | `account_subscribe(...)` | `account_unsubscribe(...)` | `AccountNotification` | [reference](https://www.helius.dev/docs/api-reference/rpc/websocket/accountsubscribe) |
341
+ | `block_subscribe(...)` | `block_unsubscribe(...)` | `BlockNotification` | [reference](https://www.helius.dev/docs/api-reference/rpc/websocket/blocksubscribe) |
342
+ | `logs_subscribe(...)` | `logs_unsubscribe(...)` | `LogsNotification` | [reference](https://www.helius.dev/docs/api-reference/rpc/websocket/logssubscribe) |
343
+ | `program_subscribe(...)` | `program_unsubscribe(...)` | `ProgramNotification` | [reference](https://www.helius.dev/docs/api-reference/rpc/websocket/programsubscribe) |
344
+ | `root_subscribe()` | `root_unsubscribe(...)` | `RootNotification` | [reference](https://www.helius.dev/docs/api-reference/rpc/websocket/rootsubscribe) |
345
+ | `signature_subscribe(...)` | `signature_unsubscribe(...)` | `SignatureNotification` | [reference](https://www.helius.dev/docs/api-reference/rpc/websocket/signaturesubscribe) |
346
+ | `slot_subscribe()` | `slot_unsubscribe(...)` | `SlotNotification` | [reference](https://www.helius.dev/docs/api-reference/rpc/websocket/slotsubscribe) |
347
+ | `slots_updates_subscribe()` | `slots_updates_unsubscribe(...)` | `SlotsUpdatesNotification` | [reference](https://www.helius.dev/docs/api-reference/rpc/websocket/slotsupdatessubscribe) |
348
+ | `vote_subscribe()` | `vote_unsubscribe(...)` | `VoteNotification` | [reference](https://www.helius.dev/docs/api-reference/rpc/websocket/votesubscribe) |
349
+ | `transaction_subscribe(...)` | `transaction_unsubscribe(...)` | `TransactionNotification` | [reference](https://www.helius.dev/docs/api-reference/rpc/websocket/slotunsubscribe) |
350
+
351
+ ## Admin API
352
+
353
+ `AccountManagementClient` wraps the Helius admin API. Today it exposes
354
+ project credit usage via `get_project_usage(...)`, which returns a typed
355
+ `ProjectUsage` model.
356
+
357
+ ```python
358
+ from helius.admin.admin import AccountManagementClient
359
+
360
+ with AccountManagementClient(api_key="YOUR_HELIUS_API_KEY") as admin:
361
+ usage = admin.get_project_usage(project_id="YOUR_PROJECT_ID")
362
+ print(usage.credits_remaining, usage.usage.rpc)
363
+ ```
364
+
365
+ The `project_id` can be passed per call or set once on the constructor;
366
+ if neither is provided, `get_project_usage` raises `ValueError`. The
367
+ client defaults to `https://admin-api.helius.xyz` and, like the others,
368
+ supports the context-manager protocol, a manual `close()`, and reads
369
+ `HELIUS_API_KEY` from the environment or `.env`.
370
+
295
371
  ## License
296
372
 
297
373
  [MIT](LICENSE)
@@ -0,0 +1,3 @@
1
+ - Mangling __
2
+ - WebSocket subscription manager
3
+ - Use typeddicts where useful
@@ -10,7 +10,7 @@ build-backend = "hatchling.build"
10
10
 
11
11
  [project]
12
12
  name = "helius-python"
13
- version = "0.2.0"
13
+ version = "0.3.0"
14
14
  authors = [
15
15
  { name="Markos Narinian", email="manarinian@gmail.com" },
16
16
  ]
@@ -21,6 +21,7 @@ dependencies = [
21
21
  "httpx",
22
22
  "pydantic",
23
23
  "python-dotenv",
24
+ "websockets",
24
25
  ]
25
26
  classifiers = [
26
27
  "Programming Language :: Python :: 3",
@@ -41,3 +42,6 @@ dev = [
41
42
 
42
43
  [tool.hatch.build.targets.wheel]
43
44
  packages = ["src/helius"]
45
+
46
+ [tool.pytest.ini_options]
47
+ pythonpath = ["src"]
@@ -3,3 +3,4 @@ pydantic
3
3
  python-dotenv
4
4
  respx
5
5
  pytest
6
+ websockets
@@ -0,0 +1,95 @@
1
+ from os import environ
2
+
3
+ import httpx
4
+ from dotenv import dotenv_values
5
+ from pydantic import AliasGenerator, BaseModel, ConfigDict
6
+ from pydantic.alias_generators import to_camel
7
+
8
+
9
+ class BillingCycle(BaseModel):
10
+ start: str
11
+ end: str
12
+
13
+
14
+ class SubscriptionDetails(BaseModel):
15
+ model_config = ConfigDict(alias_generator=AliasGenerator(validation_alias=to_camel))
16
+
17
+ billing_cycle: BillingCycle
18
+ credits_limit: float
19
+ plan: str
20
+
21
+
22
+ class Usage(BaseModel):
23
+ model_config = ConfigDict(alias_generator=AliasGenerator(validation_alias=to_camel))
24
+
25
+ api: int
26
+ archival: int
27
+ das: int
28
+ grpc: int
29
+ grpc_geyser: int
30
+ photon: int
31
+ rpc: int
32
+ stream: int
33
+ webhook: int
34
+ websocket: int
35
+
36
+
37
+ class ProjectUsage(BaseModel):
38
+ model_config = ConfigDict(alias_generator=AliasGenerator(validation_alias=to_camel))
39
+
40
+ credits_remaining: float
41
+ credits_used: float
42
+ prepaid_credits_remaining: float
43
+ prepaid_credits_used: float
44
+ subscription_details: SubscriptionDetails
45
+ usage: Usage
46
+
47
+
48
+ class AccountManagementClient:
49
+ def __init__(
50
+ self,
51
+ *,
52
+ base_url: str = "https://admin-api.helius.xyz/v0/admin/projects/{id}/usage",
53
+ api_key: str | None = None,
54
+ project_id: str | None = None,
55
+ headers: dict[str, str] | None = None,
56
+ proxy: str | None = None,
57
+ ) -> None:
58
+ base_url = base_url
59
+ api_key = (
60
+ api_key
61
+ or environ.get("HELIUS_API_KEY")
62
+ or dotenv_values().get("HELIUS_API_KEY")
63
+ or None
64
+ )
65
+ self.project_id = project_id
66
+ client_options: dict = {
67
+ "base_url": base_url,
68
+ "headers": headers,
69
+ "proxy": proxy,
70
+ }
71
+ if api_key is not None:
72
+ client_options.update({"params": {"api-key": api_key}})
73
+ self._client = httpx.Client(**client_options)
74
+
75
+ def __enter__(self):
76
+ return self
77
+
78
+ def __exit__(self, exc_type, exc_value, traceback):
79
+ self.close()
80
+
81
+ def __del__(self):
82
+ self.close()
83
+
84
+ def close(self) -> None:
85
+ self._client.close()
86
+
87
+ def get_project_usage(self, project_id: str | None = None) -> ProjectUsage:
88
+ project_id = project_id or self.project_id or None
89
+ if project_id is None:
90
+ raise ValueError("No project ID provided.")
91
+ response = self._client.request(
92
+ method="GET", url="/", params={"id": project_id}
93
+ )
94
+ response.raise_for_status()
95
+ return ProjectUsage.model_validate(response.json())