Institutional-grade Python SDK for the Viper Execution trading API on Hyperliquid.
Project description
Viper Execution Python SDK
Institutional-grade Python client for the Viper Execution trading API on Hyperliquid.
Status: SDK
0.1.3(beta). Ships the resilient WebSocket client and the resync REST-fetch mapping. The full typed REST client lands in a subsequent release. The SDK version is independent of the API version — this is SDK 0.x against API v1.
Install
pip install viper-execution
Requires Python ≥ 3.10.
Quickstart
import os
import asyncio
from viper import ViperWSClient
async def main():
# from_env() reads VIPER_API_KEY / VIPER_API_SECRET / VIPER_HANDLE /
# VIPER_WALLET. Pass anything explicitly to override the environment.
wallet = os.environ["VIPER_WALLET"].lower()
client = ViperWSClient.from_env(
on_event=lambda f: print(f["channel"], f.get("event")),
)
await client.start()
await client.subscribe("account.state", wallet)
await asyncio.sleep(30)
await client.close()
asyncio.run(main())
Using credentials
ViperWSClient takes credentials two ways, both first-class — pick whichever fits how your process gets its secrets.
From the environment (quickest, and production-correct). from_env() reads VIPER_API_KEY, VIPER_API_SECRET, VIPER_HANDLE, and VIPER_WALLET. This is also the right pattern for deployment: containers, CI, and secret managers all inject secrets as env vars, so the same code runs unchanged from laptop to production. Anything passed explicitly overrides the environment:
client = ViperWSClient.from_env(handle="override-handle")
Explicitly (your own secret store). If your keys live in Vault, AWS Secrets Manager, an HSM, or a config file, fetch them in your code and pass them to the constructor directly — from_env() is never required:
api_key_id, api_secret = my_secret_store.get("viper") # however you fetch them
client = ViperWSClient(
api_key_id=api_key_id,
api_secret=api_secret,
handle="your-handle",
wallet="0x...",
on_event=lambda f: print(f["channel"], f.get("event")),
)
Runnable examples
Examples ship inside the package — no extra downloads. List the catalog and run one by name or number:
viper-examples # list the catalog
viper-examples stream-account-state # run by name
viper-examples 01 # ...or by number
Set the env vars the examples read — bash/zsh:
export VIPER_API_KEY=vk_...
export VIPER_API_SECRET=vs_...
export VIPER_HANDLE=your-handle # optional
export VIPER_WALLET=0x... # the wallet to stream
…or PowerShell:
$env:VIPER_API_KEY = "vk_..."
$env:VIPER_API_SECRET = "vs_..."
$env:VIPER_HANDLE = "your-handle" # optional
$env:VIPER_WALLET = "0x..." # the wallet to stream
The source for each example lives in
src/viper/examples/.
What the WebSocket client handles for you
The /v1/ws stream has a number of behaviors a naive client gets wrong. ViperWSClient handles them as a built-in contract:
- Liveness — transport ping/pong plus a data-staleness watchdog; silent half-open connections are detected and reconnected.
- Reconnect with resume — on drop, it reconnects with exponential backoff and resubscribes every scope carrying its
last_seqcursor, so you resume exactly where you left off (replay from the per-scope ring buffer). - Resync recovery — when the server can't satisfy a cursor (
buffer_overflow/last_seq_ahead_of_server/scope_not_found), it REST-fetches authoritative current state and resubscribes fresh. - Multi-wallet attribution — every data frame is routed by
data.wallet, so one socket can carry many wallets without cross-attribution. (Control markers such ashydratedcarry nodata.wallet; route those byscope_id.) - Slow hydration —
account.statehydration is server-slow (~5s; it gathers balance + HIP-3 collateral across all dexes, then bursts frames). The client does not mistake that for a dead stream, and neither should your application logic. - Terminal conditions — credential revocation (close
4013), a handshake auth rejection (HTTP401/403— revoked/invalid key or insufficient scope), or an exhausted reconnect budget all stop the loop permanently viaon_terminalrather than reconnect-hammering.
Callbacks
| Callback | Fires on |
|---|---|
on_event(frame) |
Every classified data frame (the main path) |
on_meta(frame) |
_meta frames: welcome + upstream connectivity events |
on_terminal(code) |
Terminal stop. code is the WS close code (4013 = credentials revoked), the handshake HTTP status (401/403), or -1 (reconnect budget exhausted) |
on_command_result(frame) |
Subscribe acks / command errors (no correlation id) |
on_raw(frame) |
Optional advanced tap: every frame pre-classification (audit/metrics) |
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file viper_execution-0.1.3.tar.gz.
File metadata
- Download URL: viper_execution-0.1.3.tar.gz
- Upload date:
- Size: 15.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a4dd421eb9842346d265bb304d0373ca05c707a264ed86468ced448b229c6fe6
|
|
| MD5 |
e0e74b7e4e0ccca83b28f0644e88f4e5
|
|
| BLAKE2b-256 |
4cd517f61a1d9ee19971bb4655a2be7ad1e2d0de0c38a17d97df925f2366d789
|
Provenance
The following attestation bundles were made for viper_execution-0.1.3.tar.gz:
Publisher:
release.yml on viperexecution/viper-sdk-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
viper_execution-0.1.3.tar.gz -
Subject digest:
a4dd421eb9842346d265bb304d0373ca05c707a264ed86468ced448b229c6fe6 - Sigstore transparency entry: 1928734819
- Sigstore integration time:
-
Permalink:
viperexecution/viper-sdk-python@a91f01e285cb0b9c6814b74fdb925fc7114cfa21 -
Branch / Tag:
refs/tags/v0.1.3 - Owner: https://github.com/viperexecution
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@a91f01e285cb0b9c6814b74fdb925fc7114cfa21 -
Trigger Event:
push
-
Statement type:
File details
Details for the file viper_execution-0.1.3-py3-none-any.whl.
File metadata
- Download URL: viper_execution-0.1.3-py3-none-any.whl
- Upload date:
- Size: 18.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ac158dccdb2f93b5549606482f46fe6205d01618d864a4b5e3f85a513ee6cff7
|
|
| MD5 |
fcf5a3b968ff020fc377cfeb71ee5c80
|
|
| BLAKE2b-256 |
3eeb54197ac07ce245716730b7942c9c07499b659f6911c32e97dfcc62df266a
|
Provenance
The following attestation bundles were made for viper_execution-0.1.3-py3-none-any.whl:
Publisher:
release.yml on viperexecution/viper-sdk-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
viper_execution-0.1.3-py3-none-any.whl -
Subject digest:
ac158dccdb2f93b5549606482f46fe6205d01618d864a4b5e3f85a513ee6cff7 - Sigstore transparency entry: 1928735021
- Sigstore integration time:
-
Permalink:
viperexecution/viper-sdk-python@a91f01e285cb0b9c6814b74fdb925fc7114cfa21 -
Branch / Tag:
refs/tags/v0.1.3 - Owner: https://github.com/viperexecution
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@a91f01e285cb0b9c6814b74fdb925fc7114cfa21 -
Trigger Event:
push
-
Statement type: