defistream 1.0.6__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.
@@ -0,0 +1,438 @@
1
+ Metadata-Version: 2.4
2
+ Name: defistream
3
+ Version: 1.0.6
4
+ Summary: Python client for the DeFiStream API
5
+ Project-URL: Homepage, https://defistream.dev
6
+ Project-URL: Documentation, https://docs.defistream.dev
7
+ Project-URL: Repository, https://github.com/Eren-Nevin/DeFiStream_PythonClient
8
+ Author-email: DeFiStream <support@defistream.dev>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: api,blockchain,crypto,defi,ethereum,web3
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
+ Classifier: Typing :: Typed
22
+ Requires-Python: >=3.9
23
+ Requires-Dist: httpx>=0.25.0
24
+ Requires-Dist: pandas>=2.0.0
25
+ Requires-Dist: pyarrow>=14.0.0
26
+ Requires-Dist: pydantic>=2.0.0
27
+ Provides-Extra: dev
28
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
29
+ Requires-Dist: pytest>=7.0.0; extra == 'dev'
30
+ Requires-Dist: python-dotenv>=1.0.0; extra == 'dev'
31
+ Provides-Extra: polars
32
+ Requires-Dist: polars>=0.20.0; extra == 'polars'
33
+ Description-Content-Type: text/markdown
34
+
35
+ # DeFiStream Python Client
36
+
37
+ Official Python client for the [DeFiStream API](https://defistream.dev).
38
+
39
+ ## Getting an API Key
40
+
41
+ To use the DeFiStream API, you need to sign up for an account at [defistream.dev](https://defistream.dev) to obtain your API key.
42
+
43
+ ## Installation
44
+
45
+ ```bash
46
+ pip install defistream
47
+ ```
48
+
49
+ This includes pandas and pyarrow by default for DataFrame support.
50
+
51
+ With polars support (in addition to pandas):
52
+ ```bash
53
+ pip install defistream[polars]
54
+ ```
55
+
56
+ ## Quick Start
57
+
58
+ ```python
59
+ from defistream import DeFiStream
60
+
61
+ # Initialize client (reads DEFISTREAM_API_KEY from environment if not provided)
62
+ client = DeFiStream()
63
+
64
+ # Or with explicit API key
65
+ client = DeFiStream(api_key="dsk_your_api_key")
66
+
67
+ # Query ERC20 transfers using builder pattern
68
+ df = (
69
+ client.erc20.transfers("USDT")
70
+ .network("ETH")
71
+ .block_range(21000000, 21010000)
72
+ .as_df()
73
+ )
74
+
75
+ print(df.head())
76
+ ```
77
+
78
+ ## Features
79
+
80
+ - **Builder pattern**: Fluent query API with chainable methods
81
+ - **Type-safe**: Full type hints and Pydantic models
82
+ - **Multiple formats**: DataFrame (pandas/polars), CSV, Parquet, JSON
83
+ - **Async support**: Native async/await with `AsyncDeFiStream`
84
+ - **All protocols**: ERC20, AAVE, Uniswap, Lido, Stader, Threshold, Native tokens
85
+
86
+ ## Supported Protocols
87
+
88
+ | Protocol | Events |
89
+ |----------|--------|
90
+ | ERC20 | `transfers` |
91
+ | Native Token | `transfers` |
92
+ | AAVE V3 | `deposits`, `withdrawals`, `borrows`, `repays`, `flashloans`, `liquidations` |
93
+ | Uniswap V3 | `swaps`, `deposits`, `withdrawals`, `collects` |
94
+ | Lido | `deposits`, `withdrawal_requests`, `withdrawals_claimed`, `l2_deposits`, `l2_withdrawal_requests` |
95
+ | Stader | `deposits`, `withdrawal_requests`, `withdrawals` |
96
+ | Threshold | `deposit_requests`, `deposits`, `withdrawal_requests`, `withdrawals` |
97
+
98
+ ## Usage Examples
99
+
100
+ ### Builder Pattern
101
+
102
+ The client uses a fluent builder pattern. The query is only executed when you call a terminal method like `as_df()`, `as_file()`, or `as_dict()`.
103
+
104
+ ```python
105
+ from defistream import DeFiStream
106
+
107
+ client = DeFiStream()
108
+
109
+ # Build query step by step
110
+ query = client.erc20.transfers("USDT")
111
+ query = query.network("ETH")
112
+ query = query.block_range(21000000, 21010000)
113
+ query = query.min_amount(1000)
114
+
115
+ # Execute and get DataFrame
116
+ df = query.as_df()
117
+
118
+ # Or chain everything
119
+ df = (
120
+ client.erc20.transfers("USDT")
121
+ .network("ETH")
122
+ .block_range(21000000, 21010000)
123
+ .min_amount(1000)
124
+ .as_df()
125
+ )
126
+ ```
127
+
128
+ ### ERC20 Transfers
129
+
130
+ ```python
131
+ # Get USDT transfers over 10,000 USDT
132
+ df = (
133
+ client.erc20.transfers("USDT")
134
+ .network("ETH")
135
+ .block_range(21000000, 21010000)
136
+ .min_amount(10000)
137
+ .as_df()
138
+ )
139
+
140
+ # Filter by sender
141
+ df = (
142
+ client.erc20.transfers("USDT")
143
+ .network("ETH")
144
+ .block_range(21000000, 21010000)
145
+ .sender("0x28c6c06298d514db089934071355e5743bf21d60")
146
+ .as_df()
147
+ )
148
+ ```
149
+
150
+ ### AAVE Events
151
+
152
+ ```python
153
+ # Get deposits
154
+ df = (
155
+ client.aave.deposits()
156
+ .network("ETH")
157
+ .block_range(21000000, 21010000)
158
+ .as_df()
159
+ )
160
+
161
+ # Use a specific market type on ETH (Core, Prime, or EtherFi)
162
+ df = (
163
+ client.aave.deposits()
164
+ .network("ETH")
165
+ .block_range(21000000, 21010000)
166
+ .eth_market_type("Prime")
167
+ .as_df()
168
+ )
169
+ ```
170
+
171
+ ### Uniswap Swaps
172
+
173
+ ```python
174
+ # Get swaps for WETH/USDC pool with 0.05% fee tier
175
+ df = (
176
+ client.uniswap.swaps("WETH", "USDC", 500)
177
+ .network("ETH")
178
+ .block_range(21000000, 21010000)
179
+ .as_df()
180
+ )
181
+
182
+ # Or build with chain methods
183
+ df = (
184
+ client.uniswap.swaps()
185
+ .symbol0("WETH")
186
+ .symbol1("USDC")
187
+ .fee(500)
188
+ .network("ETH")
189
+ .block_range(21000000, 21010000)
190
+ .as_df()
191
+ )
192
+ ```
193
+
194
+ ### Native Token Transfers
195
+
196
+ ```python
197
+ # Get ETH transfers >= 1 ETH
198
+ df = (
199
+ client.native_token.transfers()
200
+ .network("ETH")
201
+ .block_range(21000000, 21010000)
202
+ .min_amount(1.0)
203
+ .as_df()
204
+ )
205
+ ```
206
+
207
+ ### Verbose Mode
208
+
209
+ By default, responses omit metadata fields to reduce payload size. Use `.verbose()` to include all fields:
210
+
211
+ ```python
212
+ # Default: compact response (no tx_hash, tx_id, log_index, network, name)
213
+ df = (
214
+ client.erc20.transfers("USDT")
215
+ .network("ETH")
216
+ .block_range(21000000, 21010000)
217
+ .as_df()
218
+ )
219
+
220
+ # Verbose: includes all metadata fields
221
+ df = (
222
+ client.erc20.transfers("USDT")
223
+ .network("ETH")
224
+ .block_range(21000000, 21010000)
225
+ .verbose()
226
+ .as_df()
227
+ )
228
+ ```
229
+
230
+ ### Return as DataFrame
231
+
232
+ ```python
233
+ # As pandas DataFrame (default)
234
+ df = (
235
+ client.erc20.transfers("USDT")
236
+ .network("ETH")
237
+ .block_range(21000000, 21010000)
238
+ .as_df()
239
+ )
240
+
241
+ # As polars DataFrame
242
+ df = (
243
+ client.erc20.transfers("USDT")
244
+ .network("ETH")
245
+ .block_range(21000000, 21010000)
246
+ .as_df("polars")
247
+ )
248
+ ```
249
+
250
+ ### Save to File
251
+
252
+ Format is automatically determined by file extension:
253
+
254
+ ```python
255
+ # Save as Parquet (recommended for large datasets)
256
+ (
257
+ client.erc20.transfers("USDT")
258
+ .network("ETH")
259
+ .block_range(21000000, 21100000)
260
+ .as_file("transfers.parquet")
261
+ )
262
+
263
+ # Save as CSV
264
+ (
265
+ client.erc20.transfers("USDT")
266
+ .network("ETH")
267
+ .block_range(21000000, 21100000)
268
+ .as_file("transfers.csv")
269
+ )
270
+
271
+ # Save as JSON
272
+ (
273
+ client.erc20.transfers("USDT")
274
+ .network("ETH")
275
+ .block_range(21000000, 21010000)
276
+ .as_file("transfers.json")
277
+ )
278
+ ```
279
+
280
+ ### Return as Dictionary (JSON)
281
+
282
+ For small queries, you can get results as a list of dictionaries:
283
+
284
+ ```python
285
+ transfers = (
286
+ client.erc20.transfers("USDT")
287
+ .network("ETH")
288
+ .block_range(21000000, 21010000)
289
+ .as_dict()
290
+ )
291
+
292
+ for transfer in transfers:
293
+ print(f"{transfer['sender']} -> {transfer['receiver']}: {transfer['amount']}")
294
+ ```
295
+
296
+ > **Note:** `as_dict()` and `as_file("*.json")` use JSON format which has a **10,000 block limit**. For larger block ranges, use `as_df()` or `as_file()` with `.parquet` or `.csv` extensions, which support up to 1,000,000 blocks.
297
+
298
+ ### Async Usage
299
+
300
+ ```python
301
+ import asyncio
302
+ from defistream import AsyncDeFiStream
303
+
304
+ async def main():
305
+ async with AsyncDeFiStream() as client:
306
+ df = await (
307
+ client.erc20.transfers("USDT")
308
+ .network("ETH")
309
+ .block_range(21000000, 21010000)
310
+ .as_df()
311
+ )
312
+ print(f"Found {len(df)} transfers")
313
+
314
+ asyncio.run(main())
315
+ ```
316
+
317
+ ## Configuration
318
+
319
+ ### Environment Variables
320
+
321
+ ```bash
322
+ export DEFISTREAM_API_KEY=dsk_your_api_key
323
+ export DEFISTREAM_BASE_URL=https://api.defistream.dev/v1 # optional
324
+ ```
325
+
326
+ ```python
327
+ from defistream import DeFiStream
328
+
329
+ # API key from environment
330
+ client = DeFiStream()
331
+
332
+ # Or explicit
333
+ client = DeFiStream(api_key="dsk_...", base_url="https://api.defistream.dev/v1")
334
+ ```
335
+
336
+ ### Timeout and Retries
337
+
338
+ ```python
339
+ client = DeFiStream(
340
+ api_key="dsk_...",
341
+ timeout=60.0, # seconds
342
+ max_retries=3
343
+ )
344
+ ```
345
+
346
+ ## Error Handling
347
+
348
+ ```python
349
+ from defistream import DeFiStream
350
+ from defistream.exceptions import (
351
+ DeFiStreamError,
352
+ AuthenticationError,
353
+ QuotaExceededError,
354
+ RateLimitError,
355
+ ValidationError
356
+ )
357
+
358
+ client = DeFiStream()
359
+
360
+ try:
361
+ df = (
362
+ client.erc20.transfers("USDT")
363
+ .network("ETH")
364
+ .block_range(21000000, 21010000)
365
+ .as_df()
366
+ )
367
+ except AuthenticationError:
368
+ print("Invalid API key")
369
+ except QuotaExceededError as e:
370
+ print(f"Quota exceeded. Remaining: {e.remaining}")
371
+ except RateLimitError as e:
372
+ print(f"Rate limited. Retry after: {e.retry_after}s")
373
+ except ValidationError as e:
374
+ print(f"Invalid request: {e.message}")
375
+ except DeFiStreamError as e:
376
+ print(f"API error: {e}")
377
+ ```
378
+
379
+ ## Response Headers
380
+
381
+ Access rate limit and quota information:
382
+
383
+ ```python
384
+ df = (
385
+ client.erc20.transfers("USDT")
386
+ .network("ETH")
387
+ .block_range(21000000, 21010000)
388
+ .as_df()
389
+ )
390
+
391
+ # Access response metadata
392
+ print(f"Rate limit: {client.last_response.rate_limit}")
393
+ print(f"Remaining quota: {client.last_response.quota_remaining}")
394
+ print(f"Request cost: {client.last_response.request_cost}")
395
+ ```
396
+
397
+ ## Builder Methods Reference
398
+
399
+ ### Common Methods (all protocols)
400
+
401
+ | Method | Description |
402
+ |--------|-------------|
403
+ | `.network(net)` | Set network (ETH, ARB, BASE, OP, POLYGON, etc.) |
404
+ | `.start_block(n)` | Set starting block number |
405
+ | `.end_block(n)` | Set ending block number |
406
+ | `.block_range(start, end)` | Set both start and end blocks |
407
+ | `.start_time(ts)` | Set starting time (ISO format or Unix timestamp) |
408
+ | `.end_time(ts)` | Set ending time (ISO format or Unix timestamp) |
409
+ | `.time_range(start, end)` | Set both start and end times |
410
+ | `.verbose()` | Include all metadata fields |
411
+
412
+ ### Protocol-Specific Parameters
413
+
414
+ | Method | Protocols | Description |
415
+ |--------|-----------|-------------|
416
+ | `.token(symbol)` | ERC20 | Token symbol (USDT, USDC) or contract address (required) |
417
+ | `.sender(addr)` | ERC20, Native | Filter by sender address |
418
+ | `.receiver(addr)` | ERC20, Native | Filter by receiver address |
419
+ | `.min_amount(amt)` | ERC20, Native | Minimum transfer amount |
420
+ | `.max_amount(amt)` | ERC20, Native | Maximum transfer amount |
421
+ | `.eth_market_type(type)` | AAVE | Market type for ETH: 'Core', 'Prime', 'EtherFi' |
422
+ | `.symbol0(sym)` | Uniswap | First token symbol (required) |
423
+ | `.symbol1(sym)` | Uniswap | Second token symbol (required) |
424
+ | `.fee(tier)` | Uniswap | Fee tier: 100, 500, 3000, 10000 (required) |
425
+
426
+ ### Terminal Methods
427
+
428
+ | Method | Description |
429
+ |--------|-------------|
430
+ | `.as_df()` | Execute and return pandas DataFrame |
431
+ | `.as_df("polars")` | Execute and return polars DataFrame |
432
+ | `.as_file(path)` | Execute and save to file (format from extension) |
433
+ | `.as_file(path, format="csv")` | Execute and save with explicit format |
434
+ | `.as_dict()` | Execute and return list of dicts (JSON, 10K block limit) |
435
+
436
+ ## License
437
+
438
+ MIT License
@@ -0,0 +1,11 @@
1
+ defistream/__init__.py,sha256=duUlI1d-H7mP16D6dd0zbCslu45ARItE_pwQ5N7o05M,1089
2
+ defistream/client.py,sha256=Ku8ouDbM6Mx4lVmqvBwNvNt-h2FkvqauPMSjKyPkjU4,12717
3
+ defistream/exceptions.py,sha256=_GxZQ18_YvXFtmNHeddWV8fHPIllHgFeP7fP0CmHF1k,1492
4
+ defistream/models.py,sha256=Zw3DHAISxB6pivKybNzyHXR5IcRwvTZl23DHbjfyKwM,622
5
+ defistream/protocols.py,sha256=5_bYd46lDy-mK6LZ8sTGW0Z2IVH4g0cQ5rBbbOXsw0U,15368
6
+ defistream/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ defistream/query.py,sha256=sNn_0OzNDlsp4N74Grumsb08R5OFPPoppPok3vh8Y6Q,16775
8
+ defistream-1.0.6.dist-info/METADATA,sha256=2VBBk9BJNGQiGOyya3YCTB23rFTbes0UjNhma-4R4ig,10877
9
+ defistream-1.0.6.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
10
+ defistream-1.0.6.dist-info/licenses/LICENSE,sha256=72DWAof8dMePfFQmfaswClW5d-sE6k7p-7VpuSKLmU4,1067
11
+ defistream-1.0.6.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.28.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 DeFiStream
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.