oxarchive 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.
@@ -0,0 +1,387 @@
1
+ Metadata-Version: 2.4
2
+ Name: oxarchive
3
+ Version: 0.3.0
4
+ Summary: Official Python SDK for 0xarchive - Hyperliquid Historical Data API
5
+ Project-URL: Homepage, https://0xarchive.io
6
+ Project-URL: Documentation, https://0xarchive.io/docs/sdks
7
+ Project-URL: Repository, https://github.com/0xarchiveIO/sdk-python
8
+ Project-URL: Issues, https://github.com/0xarchiveIO/sdk-python/issues
9
+ Author-email: 0xarchive <support@0xarchive.io>
10
+ License-Expression: MIT
11
+ Keywords: 0xarchive,api,historical-data,hyperliquid,orderbook,sdk,trading
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Classifier: Typing :: Typed
23
+ Requires-Python: >=3.9
24
+ Requires-Dist: httpx>=0.25.0
25
+ Requires-Dist: pydantic>=2.0.0
26
+ Provides-Extra: all
27
+ Requires-Dist: websockets>=12.0; extra == 'all'
28
+ Provides-Extra: dev
29
+ Requires-Dist: mypy>=1.9.0; extra == 'dev'
30
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
31
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
32
+ Requires-Dist: ruff>=0.4.0; extra == 'dev'
33
+ Provides-Extra: websocket
34
+ Requires-Dist: websockets>=12.0; extra == 'websocket'
35
+ Description-Content-Type: text/markdown
36
+
37
+ # oxarchive
38
+
39
+ Official Python SDK for [0xarchive](https://0xarchive.io) - Hyperliquid Historical Data API.
40
+
41
+ ## Installation
42
+
43
+ ```bash
44
+ pip install oxarchive
45
+ ```
46
+
47
+ ## Quick Start
48
+
49
+ ```python
50
+ from oxarchive import Client
51
+
52
+ client = Client(api_key="ox_your_api_key")
53
+
54
+ # Get current order book
55
+ orderbook = client.orderbook.get("BTC")
56
+ print(f"BTC mid price: {orderbook.mid_price}")
57
+
58
+ # Get historical order book snapshots
59
+ history = client.orderbook.history(
60
+ "ETH",
61
+ start="2024-01-01",
62
+ end="2024-01-02",
63
+ limit=100
64
+ )
65
+ ```
66
+
67
+ ## Async Support
68
+
69
+ All methods have async versions prefixed with `a`:
70
+
71
+ ```python
72
+ import asyncio
73
+ from oxarchive import Client
74
+
75
+ async def main():
76
+ client = Client(api_key="ox_your_api_key")
77
+
78
+ # Async get
79
+ orderbook = await client.orderbook.aget("BTC")
80
+ print(f"BTC mid price: {orderbook.mid_price}")
81
+
82
+ # Don't forget to close the client
83
+ await client.aclose()
84
+
85
+ asyncio.run(main())
86
+ ```
87
+
88
+ Or use as async context manager:
89
+
90
+ ```python
91
+ async with Client(api_key="ox_your_api_key") as client:
92
+ orderbook = await client.orderbook.aget("BTC")
93
+ ```
94
+
95
+ ## Configuration
96
+
97
+ ```python
98
+ client = Client(
99
+ api_key="ox_your_api_key", # Required
100
+ base_url="https://api.0xarchive.io", # Optional
101
+ timeout=30.0, # Optional, request timeout in seconds
102
+ )
103
+ ```
104
+
105
+ ## API Reference
106
+
107
+ ### Order Book
108
+
109
+ ```python
110
+ # Get current order book
111
+ orderbook = client.orderbook.get("BTC")
112
+
113
+ # Get order book at specific timestamp
114
+ historical = client.orderbook.get("BTC", timestamp=1704067200000)
115
+
116
+ # Get with limited depth
117
+ shallow = client.orderbook.get("BTC", depth=10)
118
+
119
+ # Get historical snapshots
120
+ history = client.orderbook.history(
121
+ "BTC",
122
+ start="2024-01-01",
123
+ end="2024-01-02",
124
+ limit=1000
125
+ )
126
+ ```
127
+
128
+ ### Trades
129
+
130
+ ```python
131
+ # Get recent trades
132
+ recent = client.trades.recent("BTC", limit=100)
133
+
134
+ # Get trade history
135
+ trades = client.trades.list(
136
+ "ETH",
137
+ start="2024-01-01",
138
+ end="2024-01-02",
139
+ side="buy" # Optional: filter by side
140
+ )
141
+ ```
142
+
143
+ ### Instruments
144
+
145
+ ```python
146
+ # List all instruments
147
+ instruments = client.instruments.list()
148
+
149
+ # Get specific instrument
150
+ btc = client.instruments.get("BTC")
151
+ ```
152
+
153
+ ### Funding Rates
154
+
155
+ ```python
156
+ # Get current funding rate
157
+ current = client.funding.current("BTC")
158
+
159
+ # Get funding rate history
160
+ history = client.funding.history(
161
+ "ETH",
162
+ start="2024-01-01",
163
+ end="2024-01-07"
164
+ )
165
+ ```
166
+
167
+ ### Open Interest
168
+
169
+ ```python
170
+ # Get current open interest
171
+ current = client.open_interest.current("BTC")
172
+
173
+ # Get open interest history
174
+ history = client.open_interest.history(
175
+ "ETH",
176
+ start="2024-01-01",
177
+ end="2024-01-07"
178
+ )
179
+ ```
180
+
181
+ ## Timestamp Formats
182
+
183
+ The SDK accepts timestamps in multiple formats:
184
+
185
+ ```python
186
+ from datetime import datetime
187
+
188
+ # Unix milliseconds
189
+ client.orderbook.get("BTC", timestamp=1704067200000)
190
+
191
+ # ISO string
192
+ client.orderbook.history("BTC", start="2024-01-01", end="2024-01-02")
193
+
194
+ # datetime object
195
+ client.orderbook.history("BTC", start=datetime(2024, 1, 1), end=datetime(2024, 1, 2))
196
+ ```
197
+
198
+ ## WebSocket Streaming
199
+
200
+ For real-time data, install with WebSocket support:
201
+
202
+ ```bash
203
+ pip install oxarchive[websocket]
204
+ ```
205
+
206
+ ### Basic Usage
207
+
208
+ ```python
209
+ import asyncio
210
+ from oxarchive import OxArchiveWs, WsOptions
211
+
212
+ async def main():
213
+ ws = OxArchiveWs(WsOptions(api_key="ox_your_api_key"))
214
+
215
+ # Set up handlers
216
+ ws.on_open(lambda: print("Connected"))
217
+ ws.on_close(lambda code, reason: print(f"Disconnected: {code}"))
218
+ ws.on_error(lambda e: print(f"Error: {e}"))
219
+
220
+ # Connect
221
+ await ws.connect()
222
+
223
+ # Subscribe to channels
224
+ ws.subscribe_orderbook("BTC")
225
+ ws.subscribe_orderbook("ETH")
226
+ ws.subscribe_trades("BTC")
227
+ ws.subscribe_all_tickers()
228
+
229
+ # Handle orderbook updates
230
+ ws.on_orderbook(lambda coin, data: print(f"{coin}: {data.mid_price}"))
231
+
232
+ # Handle trade updates
233
+ ws.on_trades(lambda coin, trades: print(f"{coin}: {len(trades)} trades"))
234
+
235
+ # Keep running
236
+ await asyncio.sleep(60)
237
+
238
+ # Disconnect
239
+ await ws.disconnect()
240
+
241
+ asyncio.run(main())
242
+ ```
243
+
244
+ ### Historical Replay (like Tardis.dev)
245
+
246
+ Replay historical data with timing preserved:
247
+
248
+ ```python
249
+ import asyncio
250
+ import time
251
+ from oxarchive import OxArchiveWs, WsOptions
252
+
253
+ async def main():
254
+ ws = OxArchiveWs(WsOptions(api_key="ox_..."))
255
+
256
+ # Handle replay data
257
+ ws.on_historical_data(lambda coin, ts, data:
258
+ print(f"{ts}: {data['mid_price']}")
259
+ )
260
+
261
+ ws.on_replay_start(lambda ch, coin, start, end, speed:
262
+ print(f"Starting replay from {start} to {end} at {speed}x")
263
+ )
264
+
265
+ ws.on_replay_complete(lambda ch, coin, sent:
266
+ print(f"Replay complete: {sent} records")
267
+ )
268
+
269
+ await ws.connect()
270
+
271
+ # Start replay at 10x speed
272
+ await ws.replay(
273
+ "orderbook", "BTC",
274
+ start=int(time.time() * 1000) - 86400000, # 24 hours ago
275
+ speed=10
276
+ )
277
+
278
+ # Control playback
279
+ await ws.replay_pause()
280
+ await ws.replay_resume()
281
+ await ws.replay_seek(1704067200000) # Jump to timestamp
282
+ await ws.replay_stop()
283
+
284
+ asyncio.run(main())
285
+ ```
286
+
287
+ ### Bulk Streaming (like Databento)
288
+
289
+ Fast bulk download for data pipelines:
290
+
291
+ ```python
292
+ import asyncio
293
+ import time
294
+ from oxarchive import OxArchiveWs, WsOptions
295
+
296
+ async def main():
297
+ ws = OxArchiveWs(WsOptions(api_key="ox_..."))
298
+ all_data = []
299
+
300
+ # Handle batched data
301
+ ws.on_batch(lambda coin, records:
302
+ all_data.extend([r.data for r in records])
303
+ )
304
+
305
+ ws.on_stream_progress(lambda snapshots_sent:
306
+ print(f"Sent: {snapshots_sent} snapshots")
307
+ )
308
+
309
+ ws.on_stream_complete(lambda ch, coin, sent:
310
+ print(f"Downloaded {sent} records")
311
+ )
312
+
313
+ await ws.connect()
314
+
315
+ # Start bulk stream
316
+ await ws.stream(
317
+ "orderbook", "ETH",
318
+ start=int(time.time() * 1000) - 3600000, # 1 hour ago
319
+ end=int(time.time() * 1000),
320
+ batch_size=1000
321
+ )
322
+
323
+ # Stop stream if needed
324
+ await ws.stream_stop()
325
+
326
+ asyncio.run(main())
327
+ ```
328
+
329
+ ### Configuration
330
+
331
+ ```python
332
+ ws = OxArchiveWs(WsOptions(
333
+ api_key="ox_your_api_key",
334
+ ws_url="wss://api.0xarchive.io/ws", # Optional
335
+ auto_reconnect=True, # Auto-reconnect on disconnect
336
+ reconnect_delay=1.0, # Initial reconnect delay (seconds)
337
+ max_reconnect_attempts=10, # Max reconnect attempts
338
+ ping_interval=30.0, # Keep-alive ping interval (seconds)
339
+ ))
340
+ ```
341
+
342
+ ### Available Channels
343
+
344
+ | Channel | Description | Requires Coin |
345
+ |---------|-------------|---------------|
346
+ | `orderbook` | L2 order book updates | Yes |
347
+ | `trades` | Trade/fill updates | Yes |
348
+ | `ticker` | Price and 24h volume | Yes |
349
+ | `all_tickers` | All market tickers | No |
350
+
351
+ ## Error Handling
352
+
353
+ ```python
354
+ from oxarchive import Client, OxArchiveError
355
+
356
+ client = Client(api_key="ox_your_api_key")
357
+
358
+ try:
359
+ orderbook = client.orderbook.get("INVALID")
360
+ except OxArchiveError as e:
361
+ print(f"API Error: {e.message}")
362
+ print(f"Status Code: {e.code}")
363
+ print(f"Request ID: {e.request_id}")
364
+ ```
365
+
366
+ ## Type Hints
367
+
368
+ Full type hint support with Pydantic models:
369
+
370
+ ```python
371
+ from oxarchive import Client, OrderBook, Trade
372
+
373
+ client = Client(api_key="ox_your_api_key")
374
+
375
+ orderbook: OrderBook = client.orderbook.get("BTC")
376
+ trades: list[Trade] = client.trades.recent("BTC")
377
+ ```
378
+
379
+ ## Requirements
380
+
381
+ - Python 3.9+
382
+ - httpx
383
+ - pydantic
384
+
385
+ ## License
386
+
387
+ MIT
@@ -0,0 +1,351 @@
1
+ # oxarchive
2
+
3
+ Official Python SDK for [0xarchive](https://0xarchive.io) - Hyperliquid Historical Data API.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install oxarchive
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```python
14
+ from oxarchive import Client
15
+
16
+ client = Client(api_key="ox_your_api_key")
17
+
18
+ # Get current order book
19
+ orderbook = client.orderbook.get("BTC")
20
+ print(f"BTC mid price: {orderbook.mid_price}")
21
+
22
+ # Get historical order book snapshots
23
+ history = client.orderbook.history(
24
+ "ETH",
25
+ start="2024-01-01",
26
+ end="2024-01-02",
27
+ limit=100
28
+ )
29
+ ```
30
+
31
+ ## Async Support
32
+
33
+ All methods have async versions prefixed with `a`:
34
+
35
+ ```python
36
+ import asyncio
37
+ from oxarchive import Client
38
+
39
+ async def main():
40
+ client = Client(api_key="ox_your_api_key")
41
+
42
+ # Async get
43
+ orderbook = await client.orderbook.aget("BTC")
44
+ print(f"BTC mid price: {orderbook.mid_price}")
45
+
46
+ # Don't forget to close the client
47
+ await client.aclose()
48
+
49
+ asyncio.run(main())
50
+ ```
51
+
52
+ Or use as async context manager:
53
+
54
+ ```python
55
+ async with Client(api_key="ox_your_api_key") as client:
56
+ orderbook = await client.orderbook.aget("BTC")
57
+ ```
58
+
59
+ ## Configuration
60
+
61
+ ```python
62
+ client = Client(
63
+ api_key="ox_your_api_key", # Required
64
+ base_url="https://api.0xarchive.io", # Optional
65
+ timeout=30.0, # Optional, request timeout in seconds
66
+ )
67
+ ```
68
+
69
+ ## API Reference
70
+
71
+ ### Order Book
72
+
73
+ ```python
74
+ # Get current order book
75
+ orderbook = client.orderbook.get("BTC")
76
+
77
+ # Get order book at specific timestamp
78
+ historical = client.orderbook.get("BTC", timestamp=1704067200000)
79
+
80
+ # Get with limited depth
81
+ shallow = client.orderbook.get("BTC", depth=10)
82
+
83
+ # Get historical snapshots
84
+ history = client.orderbook.history(
85
+ "BTC",
86
+ start="2024-01-01",
87
+ end="2024-01-02",
88
+ limit=1000
89
+ )
90
+ ```
91
+
92
+ ### Trades
93
+
94
+ ```python
95
+ # Get recent trades
96
+ recent = client.trades.recent("BTC", limit=100)
97
+
98
+ # Get trade history
99
+ trades = client.trades.list(
100
+ "ETH",
101
+ start="2024-01-01",
102
+ end="2024-01-02",
103
+ side="buy" # Optional: filter by side
104
+ )
105
+ ```
106
+
107
+ ### Instruments
108
+
109
+ ```python
110
+ # List all instruments
111
+ instruments = client.instruments.list()
112
+
113
+ # Get specific instrument
114
+ btc = client.instruments.get("BTC")
115
+ ```
116
+
117
+ ### Funding Rates
118
+
119
+ ```python
120
+ # Get current funding rate
121
+ current = client.funding.current("BTC")
122
+
123
+ # Get funding rate history
124
+ history = client.funding.history(
125
+ "ETH",
126
+ start="2024-01-01",
127
+ end="2024-01-07"
128
+ )
129
+ ```
130
+
131
+ ### Open Interest
132
+
133
+ ```python
134
+ # Get current open interest
135
+ current = client.open_interest.current("BTC")
136
+
137
+ # Get open interest history
138
+ history = client.open_interest.history(
139
+ "ETH",
140
+ start="2024-01-01",
141
+ end="2024-01-07"
142
+ )
143
+ ```
144
+
145
+ ## Timestamp Formats
146
+
147
+ The SDK accepts timestamps in multiple formats:
148
+
149
+ ```python
150
+ from datetime import datetime
151
+
152
+ # Unix milliseconds
153
+ client.orderbook.get("BTC", timestamp=1704067200000)
154
+
155
+ # ISO string
156
+ client.orderbook.history("BTC", start="2024-01-01", end="2024-01-02")
157
+
158
+ # datetime object
159
+ client.orderbook.history("BTC", start=datetime(2024, 1, 1), end=datetime(2024, 1, 2))
160
+ ```
161
+
162
+ ## WebSocket Streaming
163
+
164
+ For real-time data, install with WebSocket support:
165
+
166
+ ```bash
167
+ pip install oxarchive[websocket]
168
+ ```
169
+
170
+ ### Basic Usage
171
+
172
+ ```python
173
+ import asyncio
174
+ from oxarchive import OxArchiveWs, WsOptions
175
+
176
+ async def main():
177
+ ws = OxArchiveWs(WsOptions(api_key="ox_your_api_key"))
178
+
179
+ # Set up handlers
180
+ ws.on_open(lambda: print("Connected"))
181
+ ws.on_close(lambda code, reason: print(f"Disconnected: {code}"))
182
+ ws.on_error(lambda e: print(f"Error: {e}"))
183
+
184
+ # Connect
185
+ await ws.connect()
186
+
187
+ # Subscribe to channels
188
+ ws.subscribe_orderbook("BTC")
189
+ ws.subscribe_orderbook("ETH")
190
+ ws.subscribe_trades("BTC")
191
+ ws.subscribe_all_tickers()
192
+
193
+ # Handle orderbook updates
194
+ ws.on_orderbook(lambda coin, data: print(f"{coin}: {data.mid_price}"))
195
+
196
+ # Handle trade updates
197
+ ws.on_trades(lambda coin, trades: print(f"{coin}: {len(trades)} trades"))
198
+
199
+ # Keep running
200
+ await asyncio.sleep(60)
201
+
202
+ # Disconnect
203
+ await ws.disconnect()
204
+
205
+ asyncio.run(main())
206
+ ```
207
+
208
+ ### Historical Replay (like Tardis.dev)
209
+
210
+ Replay historical data with timing preserved:
211
+
212
+ ```python
213
+ import asyncio
214
+ import time
215
+ from oxarchive import OxArchiveWs, WsOptions
216
+
217
+ async def main():
218
+ ws = OxArchiveWs(WsOptions(api_key="ox_..."))
219
+
220
+ # Handle replay data
221
+ ws.on_historical_data(lambda coin, ts, data:
222
+ print(f"{ts}: {data['mid_price']}")
223
+ )
224
+
225
+ ws.on_replay_start(lambda ch, coin, start, end, speed:
226
+ print(f"Starting replay from {start} to {end} at {speed}x")
227
+ )
228
+
229
+ ws.on_replay_complete(lambda ch, coin, sent:
230
+ print(f"Replay complete: {sent} records")
231
+ )
232
+
233
+ await ws.connect()
234
+
235
+ # Start replay at 10x speed
236
+ await ws.replay(
237
+ "orderbook", "BTC",
238
+ start=int(time.time() * 1000) - 86400000, # 24 hours ago
239
+ speed=10
240
+ )
241
+
242
+ # Control playback
243
+ await ws.replay_pause()
244
+ await ws.replay_resume()
245
+ await ws.replay_seek(1704067200000) # Jump to timestamp
246
+ await ws.replay_stop()
247
+
248
+ asyncio.run(main())
249
+ ```
250
+
251
+ ### Bulk Streaming (like Databento)
252
+
253
+ Fast bulk download for data pipelines:
254
+
255
+ ```python
256
+ import asyncio
257
+ import time
258
+ from oxarchive import OxArchiveWs, WsOptions
259
+
260
+ async def main():
261
+ ws = OxArchiveWs(WsOptions(api_key="ox_..."))
262
+ all_data = []
263
+
264
+ # Handle batched data
265
+ ws.on_batch(lambda coin, records:
266
+ all_data.extend([r.data for r in records])
267
+ )
268
+
269
+ ws.on_stream_progress(lambda snapshots_sent:
270
+ print(f"Sent: {snapshots_sent} snapshots")
271
+ )
272
+
273
+ ws.on_stream_complete(lambda ch, coin, sent:
274
+ print(f"Downloaded {sent} records")
275
+ )
276
+
277
+ await ws.connect()
278
+
279
+ # Start bulk stream
280
+ await ws.stream(
281
+ "orderbook", "ETH",
282
+ start=int(time.time() * 1000) - 3600000, # 1 hour ago
283
+ end=int(time.time() * 1000),
284
+ batch_size=1000
285
+ )
286
+
287
+ # Stop stream if needed
288
+ await ws.stream_stop()
289
+
290
+ asyncio.run(main())
291
+ ```
292
+
293
+ ### Configuration
294
+
295
+ ```python
296
+ ws = OxArchiveWs(WsOptions(
297
+ api_key="ox_your_api_key",
298
+ ws_url="wss://api.0xarchive.io/ws", # Optional
299
+ auto_reconnect=True, # Auto-reconnect on disconnect
300
+ reconnect_delay=1.0, # Initial reconnect delay (seconds)
301
+ max_reconnect_attempts=10, # Max reconnect attempts
302
+ ping_interval=30.0, # Keep-alive ping interval (seconds)
303
+ ))
304
+ ```
305
+
306
+ ### Available Channels
307
+
308
+ | Channel | Description | Requires Coin |
309
+ |---------|-------------|---------------|
310
+ | `orderbook` | L2 order book updates | Yes |
311
+ | `trades` | Trade/fill updates | Yes |
312
+ | `ticker` | Price and 24h volume | Yes |
313
+ | `all_tickers` | All market tickers | No |
314
+
315
+ ## Error Handling
316
+
317
+ ```python
318
+ from oxarchive import Client, OxArchiveError
319
+
320
+ client = Client(api_key="ox_your_api_key")
321
+
322
+ try:
323
+ orderbook = client.orderbook.get("INVALID")
324
+ except OxArchiveError as e:
325
+ print(f"API Error: {e.message}")
326
+ print(f"Status Code: {e.code}")
327
+ print(f"Request ID: {e.request_id}")
328
+ ```
329
+
330
+ ## Type Hints
331
+
332
+ Full type hint support with Pydantic models:
333
+
334
+ ```python
335
+ from oxarchive import Client, OrderBook, Trade
336
+
337
+ client = Client(api_key="ox_your_api_key")
338
+
339
+ orderbook: OrderBook = client.orderbook.get("BTC")
340
+ trades: list[Trade] = client.trades.recent("BTC")
341
+ ```
342
+
343
+ ## Requirements
344
+
345
+ - Python 3.9+
346
+ - httpx
347
+ - pydantic
348
+
349
+ ## License
350
+
351
+ MIT