defistream 1.0.0__tar.gz → 1.0.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.
- {defistream-1.0.0 → defistream-1.0.2}/PKG-INFO +98 -149
- {defistream-1.0.0 → defistream-1.0.2}/README.md +97 -148
- {defistream-1.0.0 → defistream-1.0.2}/pyproject.toml +1 -1
- defistream-1.0.2/sample_usage.py +23 -0
- {defistream-1.0.0 → defistream-1.0.2}/src/defistream/__init__.py +10 -13
- {defistream-1.0.0 → defistream-1.0.2}/src/defistream/protocols.py +150 -65
- {defistream-1.0.0 → defistream-1.0.2}/src/defistream/query.py +43 -71
- {defistream-1.0.0 → defistream-1.0.2}/tests/test_client.py +79 -29
- defistream-1.0.0/sample_usage.py +0 -11
- {defistream-1.0.0 → defistream-1.0.2}/.gitignore +0 -0
- {defistream-1.0.0 → defistream-1.0.2}/LICENSE +0 -0
- {defistream-1.0.0 → defistream-1.0.2}/src/defistream/client.py +0 -0
- {defistream-1.0.0 → defistream-1.0.2}/src/defistream/exceptions.py +0 -0
- {defistream-1.0.0 → defistream-1.0.2}/src/defistream/models.py +0 -0
- {defistream-1.0.0 → defistream-1.0.2}/src/defistream/py.typed +0 -0
- {defistream-1.0.0 → defistream-1.0.2}/tests/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: defistream
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.2
|
|
4
4
|
Summary: Python client for the DeFiStream API
|
|
5
5
|
Project-URL: Homepage, https://defistream.dev
|
|
6
6
|
Project-URL: Documentation, https://docs.defistream.dev
|
|
@@ -34,7 +34,11 @@ Description-Content-Type: text/markdown
|
|
|
34
34
|
|
|
35
35
|
# DeFiStream Python Client
|
|
36
36
|
|
|
37
|
-
Official Python client for the [DeFiStream API](https://defistream.dev)
|
|
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.
|
|
38
42
|
|
|
39
43
|
## Installation
|
|
40
44
|
|
|
@@ -61,44 +65,41 @@ client = DeFiStream()
|
|
|
61
65
|
client = DeFiStream(api_key="dsk_your_api_key")
|
|
62
66
|
|
|
63
67
|
# Query ERC20 transfers using builder pattern
|
|
64
|
-
|
|
68
|
+
df = (
|
|
65
69
|
client.erc20.transfers("USDT")
|
|
66
70
|
.network("ETH")
|
|
67
|
-
.
|
|
68
|
-
.
|
|
69
|
-
.as_dict()
|
|
71
|
+
.block_range(21000000, 21010000)
|
|
72
|
+
.as_df()
|
|
70
73
|
)
|
|
71
74
|
|
|
72
|
-
|
|
73
|
-
print(f"{transfer['sender']} -> {transfer['receiver']}: {transfer['amount']}")
|
|
75
|
+
print(df.head())
|
|
74
76
|
```
|
|
75
77
|
|
|
76
78
|
## Features
|
|
77
79
|
|
|
78
80
|
- **Builder pattern**: Fluent query API with chainable methods
|
|
79
81
|
- **Type-safe**: Full type hints and Pydantic models
|
|
80
|
-
- **Multiple formats**:
|
|
82
|
+
- **Multiple formats**: DataFrame (pandas/polars), CSV, Parquet, JSON
|
|
81
83
|
- **Async support**: Native async/await with `AsyncDeFiStream`
|
|
82
|
-
- **All protocols**: AAVE, Uniswap, Lido,
|
|
83
|
-
- **Verbose mode**: Include all metadata fields (tx_hash, tx_id, log_index, network, name)
|
|
84
|
+
- **All protocols**: ERC20, AAVE, Uniswap, Lido, Stader, Threshold, Native tokens
|
|
84
85
|
|
|
85
86
|
## Supported Protocols
|
|
86
87
|
|
|
87
88
|
| Protocol | Events |
|
|
88
89
|
|----------|--------|
|
|
89
|
-
| ERC20 | `transfers
|
|
90
|
+
| ERC20 | `transfers` |
|
|
90
91
|
| Native Token | `transfers` |
|
|
91
|
-
| AAVE V3 | `deposits`, `withdrawals`, `borrows`, `repays`, `liquidations` |
|
|
92
|
-
| Uniswap V3 | `swaps`, `
|
|
93
|
-
| Lido | `deposits`, `
|
|
94
|
-
| Stader | `deposits`, `withdrawals` |
|
|
95
|
-
| Threshold | `
|
|
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` |
|
|
96
97
|
|
|
97
98
|
## Usage Examples
|
|
98
99
|
|
|
99
100
|
### Builder Pattern
|
|
100
101
|
|
|
101
|
-
The client uses a fluent builder pattern. The query is only executed when you call a terminal method like `
|
|
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()`.
|
|
102
103
|
|
|
103
104
|
```python
|
|
104
105
|
from defistream import DeFiStream
|
|
@@ -108,21 +109,19 @@ client = DeFiStream()
|
|
|
108
109
|
# Build query step by step
|
|
109
110
|
query = client.erc20.transfers("USDT")
|
|
110
111
|
query = query.network("ETH")
|
|
111
|
-
query = query.
|
|
112
|
-
query = query.end_block(24100000)
|
|
112
|
+
query = query.block_range(21000000, 21010000)
|
|
113
113
|
query = query.min_amount(1000)
|
|
114
114
|
|
|
115
|
-
# Execute and get
|
|
116
|
-
|
|
115
|
+
# Execute and get DataFrame
|
|
116
|
+
df = query.as_df()
|
|
117
117
|
|
|
118
118
|
# Or chain everything
|
|
119
|
-
|
|
119
|
+
df = (
|
|
120
120
|
client.erc20.transfers("USDT")
|
|
121
121
|
.network("ETH")
|
|
122
|
-
.
|
|
123
|
-
.end_block(24100000)
|
|
122
|
+
.block_range(21000000, 21010000)
|
|
124
123
|
.min_amount(1000)
|
|
125
|
-
.
|
|
124
|
+
.as_df()
|
|
126
125
|
)
|
|
127
126
|
```
|
|
128
127
|
|
|
@@ -130,35 +129,21 @@ transfers = (
|
|
|
130
129
|
|
|
131
130
|
```python
|
|
132
131
|
# Get USDT transfers over 10,000 USDT
|
|
133
|
-
|
|
132
|
+
df = (
|
|
134
133
|
client.erc20.transfers("USDT")
|
|
135
134
|
.network("ETH")
|
|
136
|
-
.
|
|
137
|
-
.end_block(24100000)
|
|
135
|
+
.block_range(21000000, 21010000)
|
|
138
136
|
.min_amount(10000)
|
|
139
|
-
.
|
|
137
|
+
.as_df()
|
|
140
138
|
)
|
|
141
139
|
|
|
142
140
|
# Filter by sender
|
|
143
|
-
|
|
141
|
+
df = (
|
|
144
142
|
client.erc20.transfers("USDT")
|
|
145
143
|
.network("ETH")
|
|
146
|
-
.
|
|
147
|
-
.end_block(24100000)
|
|
144
|
+
.block_range(21000000, 21010000)
|
|
148
145
|
.sender("0x28c6c06298d514db089934071355e5743bf21d60")
|
|
149
|
-
.
|
|
150
|
-
)
|
|
151
|
-
|
|
152
|
-
# Or use aliases: from_address/to_address
|
|
153
|
-
transfers = (
|
|
154
|
-
client.erc20.transfers()
|
|
155
|
-
.network("ETH")
|
|
156
|
-
.start_block(24000000)
|
|
157
|
-
.end_block(24100000)
|
|
158
|
-
.token("USDC")
|
|
159
|
-
.from_address("0x...")
|
|
160
|
-
.to_address("0x...")
|
|
161
|
-
.as_dict()
|
|
146
|
+
.as_df()
|
|
162
147
|
)
|
|
163
148
|
```
|
|
164
149
|
|
|
@@ -166,22 +151,20 @@ transfers = (
|
|
|
166
151
|
|
|
167
152
|
```python
|
|
168
153
|
# Get deposits
|
|
169
|
-
|
|
154
|
+
df = (
|
|
170
155
|
client.aave.deposits()
|
|
171
156
|
.network("ETH")
|
|
172
|
-
.
|
|
173
|
-
.
|
|
174
|
-
.as_dict()
|
|
157
|
+
.block_range(21000000, 21010000)
|
|
158
|
+
.as_df()
|
|
175
159
|
)
|
|
176
160
|
|
|
177
|
-
#
|
|
178
|
-
|
|
179
|
-
client.aave.
|
|
161
|
+
# Use a specific market type on ETH (Core, Prime, or EtherFi)
|
|
162
|
+
df = (
|
|
163
|
+
client.aave.deposits()
|
|
180
164
|
.network("ETH")
|
|
181
|
-
.
|
|
182
|
-
.
|
|
183
|
-
.
|
|
184
|
-
.as_dict()
|
|
165
|
+
.block_range(21000000, 21010000)
|
|
166
|
+
.eth_market_type("Prime")
|
|
167
|
+
.as_df()
|
|
185
168
|
)
|
|
186
169
|
```
|
|
187
170
|
|
|
@@ -189,24 +172,22 @@ liquidations = (
|
|
|
189
172
|
|
|
190
173
|
```python
|
|
191
174
|
# Get swaps for WETH/USDC pool with 0.05% fee tier
|
|
192
|
-
|
|
175
|
+
df = (
|
|
193
176
|
client.uniswap.swaps("WETH", "USDC", 500)
|
|
194
177
|
.network("ETH")
|
|
195
|
-
.
|
|
196
|
-
.
|
|
197
|
-
.as_dict()
|
|
178
|
+
.block_range(21000000, 21010000)
|
|
179
|
+
.as_df()
|
|
198
180
|
)
|
|
199
181
|
|
|
200
182
|
# Or build with chain methods
|
|
201
|
-
|
|
183
|
+
df = (
|
|
202
184
|
client.uniswap.swaps()
|
|
203
185
|
.symbol0("WETH")
|
|
204
186
|
.symbol1("USDC")
|
|
205
187
|
.fee(500)
|
|
206
188
|
.network("ETH")
|
|
207
|
-
.
|
|
208
|
-
.
|
|
209
|
-
.as_dict()
|
|
189
|
+
.block_range(21000000, 21010000)
|
|
190
|
+
.as_df()
|
|
210
191
|
)
|
|
211
192
|
```
|
|
212
193
|
|
|
@@ -214,13 +195,12 @@ swaps = (
|
|
|
214
195
|
|
|
215
196
|
```python
|
|
216
197
|
# Get ETH transfers >= 1 ETH
|
|
217
|
-
|
|
198
|
+
df = (
|
|
218
199
|
client.native_token.transfers()
|
|
219
200
|
.network("ETH")
|
|
220
|
-
.
|
|
221
|
-
.end_block(24100000)
|
|
201
|
+
.block_range(21000000, 21010000)
|
|
222
202
|
.min_amount(1.0)
|
|
223
|
-
.
|
|
203
|
+
.as_df()
|
|
224
204
|
)
|
|
225
205
|
```
|
|
226
206
|
|
|
@@ -230,25 +210,21 @@ By default, responses omit metadata fields to reduce payload size. Use `.verbose
|
|
|
230
210
|
|
|
231
211
|
```python
|
|
232
212
|
# Default: compact response (no tx_hash, tx_id, log_index, network, name)
|
|
233
|
-
|
|
213
|
+
df = (
|
|
234
214
|
client.erc20.transfers("USDT")
|
|
235
215
|
.network("ETH")
|
|
236
|
-
.
|
|
237
|
-
.
|
|
238
|
-
.as_dict()
|
|
216
|
+
.block_range(21000000, 21010000)
|
|
217
|
+
.as_df()
|
|
239
218
|
)
|
|
240
|
-
# Returns: [{"block_number": 24000050, "sender": "0x...", "receiver": "0x...", "amount": 1000.0, ...}]
|
|
241
219
|
|
|
242
220
|
# Verbose: includes all metadata fields
|
|
243
|
-
|
|
221
|
+
df = (
|
|
244
222
|
client.erc20.transfers("USDT")
|
|
245
223
|
.network("ETH")
|
|
246
|
-
.
|
|
247
|
-
.end_block(24100000)
|
|
224
|
+
.block_range(21000000, 21010000)
|
|
248
225
|
.verbose()
|
|
249
|
-
.
|
|
226
|
+
.as_df()
|
|
250
227
|
)
|
|
251
|
-
# Returns: [{"name": "TransferEvent", "network": "ETH", "tx_id": "0x...", "tx_hash": "0x...", "log_index": 5, "block_number": 24000050, ...}]
|
|
252
228
|
```
|
|
253
229
|
|
|
254
230
|
### Return as DataFrame
|
|
@@ -258,8 +234,7 @@ transfers = (
|
|
|
258
234
|
df = (
|
|
259
235
|
client.erc20.transfers("USDT")
|
|
260
236
|
.network("ETH")
|
|
261
|
-
.
|
|
262
|
-
.end_block(24100000)
|
|
237
|
+
.block_range(21000000, 21010000)
|
|
263
238
|
.as_df()
|
|
264
239
|
)
|
|
265
240
|
|
|
@@ -267,8 +242,7 @@ df = (
|
|
|
267
242
|
df = (
|
|
268
243
|
client.erc20.transfers("USDT")
|
|
269
244
|
.network("ETH")
|
|
270
|
-
.
|
|
271
|
-
.end_block(24100000)
|
|
245
|
+
.block_range(21000000, 21010000)
|
|
272
246
|
.as_df("polars")
|
|
273
247
|
)
|
|
274
248
|
```
|
|
@@ -278,43 +252,49 @@ df = (
|
|
|
278
252
|
Format is automatically determined by file extension:
|
|
279
253
|
|
|
280
254
|
```python
|
|
281
|
-
# Save as
|
|
255
|
+
# Save as Parquet (recommended for large datasets)
|
|
282
256
|
(
|
|
283
257
|
client.erc20.transfers("USDT")
|
|
284
258
|
.network("ETH")
|
|
285
|
-
.
|
|
286
|
-
.
|
|
287
|
-
.as_file("transfers.csv")
|
|
259
|
+
.block_range(21000000, 21100000)
|
|
260
|
+
.as_file("transfers.parquet")
|
|
288
261
|
)
|
|
289
262
|
|
|
290
|
-
# Save as
|
|
263
|
+
# Save as CSV
|
|
291
264
|
(
|
|
292
265
|
client.erc20.transfers("USDT")
|
|
293
266
|
.network("ETH")
|
|
294
|
-
.
|
|
295
|
-
.
|
|
296
|
-
.as_file("transfers.parquet")
|
|
267
|
+
.block_range(21000000, 21100000)
|
|
268
|
+
.as_file("transfers.csv")
|
|
297
269
|
)
|
|
298
270
|
|
|
299
271
|
# Save as JSON
|
|
300
272
|
(
|
|
301
273
|
client.erc20.transfers("USDT")
|
|
302
274
|
.network("ETH")
|
|
303
|
-
.
|
|
304
|
-
.end_block(24100000)
|
|
275
|
+
.block_range(21000000, 21010000)
|
|
305
276
|
.as_file("transfers.json")
|
|
306
277
|
)
|
|
278
|
+
```
|
|
307
279
|
|
|
308
|
-
|
|
309
|
-
|
|
280
|
+
### Return as Dictionary (JSON)
|
|
281
|
+
|
|
282
|
+
For small queries, you can get results as a list of dictionaries:
|
|
283
|
+
|
|
284
|
+
```python
|
|
285
|
+
transfers = (
|
|
310
286
|
client.erc20.transfers("USDT")
|
|
311
287
|
.network("ETH")
|
|
312
|
-
.
|
|
313
|
-
.
|
|
314
|
-
.as_file("transfers", format="csv")
|
|
288
|
+
.block_range(21000000, 21010000)
|
|
289
|
+
.as_dict()
|
|
315
290
|
)
|
|
291
|
+
|
|
292
|
+
for transfer in transfers:
|
|
293
|
+
print(f"{transfer['sender']} -> {transfer['receiver']}: {transfer['amount']}")
|
|
316
294
|
```
|
|
317
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
|
+
|
|
318
298
|
### Async Usage
|
|
319
299
|
|
|
320
300
|
```python
|
|
@@ -323,41 +303,17 @@ from defistream import AsyncDeFiStream
|
|
|
323
303
|
|
|
324
304
|
async def main():
|
|
325
305
|
async with AsyncDeFiStream() as client:
|
|
326
|
-
|
|
306
|
+
df = await (
|
|
327
307
|
client.erc20.transfers("USDT")
|
|
328
308
|
.network("ETH")
|
|
329
|
-
.
|
|
330
|
-
.
|
|
331
|
-
.as_dict()
|
|
309
|
+
.block_range(21000000, 21010000)
|
|
310
|
+
.as_df()
|
|
332
311
|
)
|
|
333
|
-
print(f"Found {len(
|
|
312
|
+
print(f"Found {len(df)} transfers")
|
|
334
313
|
|
|
335
314
|
asyncio.run(main())
|
|
336
315
|
```
|
|
337
316
|
|
|
338
|
-
### Multiple Networks in Parallel
|
|
339
|
-
|
|
340
|
-
```python
|
|
341
|
-
import asyncio
|
|
342
|
-
from defistream import AsyncDeFiStream
|
|
343
|
-
|
|
344
|
-
async def fetch_all_networks():
|
|
345
|
-
async with AsyncDeFiStream() as client:
|
|
346
|
-
networks = ["ETH", "ARB", "BASE", "OP"]
|
|
347
|
-
tasks = [
|
|
348
|
-
client.erc20.transfers("USDC")
|
|
349
|
-
.network(net)
|
|
350
|
-
.start_block(24000000)
|
|
351
|
-
.end_block(24100000)
|
|
352
|
-
.as_dict()
|
|
353
|
-
for net in networks
|
|
354
|
-
]
|
|
355
|
-
results = await asyncio.gather(*tasks)
|
|
356
|
-
return dict(zip(networks, results))
|
|
357
|
-
|
|
358
|
-
all_transfers = asyncio.run(fetch_all_networks())
|
|
359
|
-
```
|
|
360
|
-
|
|
361
317
|
## Configuration
|
|
362
318
|
|
|
363
319
|
### Environment Variables
|
|
@@ -402,12 +358,11 @@ from defistream.exceptions import (
|
|
|
402
358
|
client = DeFiStream()
|
|
403
359
|
|
|
404
360
|
try:
|
|
405
|
-
|
|
361
|
+
df = (
|
|
406
362
|
client.erc20.transfers("USDT")
|
|
407
363
|
.network("ETH")
|
|
408
|
-
.
|
|
409
|
-
.
|
|
410
|
-
.as_dict()
|
|
364
|
+
.block_range(21000000, 21010000)
|
|
365
|
+
.as_df()
|
|
411
366
|
)
|
|
412
367
|
except AuthenticationError:
|
|
413
368
|
print("Invalid API key")
|
|
@@ -426,12 +381,11 @@ except DeFiStreamError as e:
|
|
|
426
381
|
Access rate limit and quota information:
|
|
427
382
|
|
|
428
383
|
```python
|
|
429
|
-
|
|
384
|
+
df = (
|
|
430
385
|
client.erc20.transfers("USDT")
|
|
431
386
|
.network("ETH")
|
|
432
|
-
.
|
|
433
|
-
.
|
|
434
|
-
.as_dict()
|
|
387
|
+
.block_range(21000000, 21010000)
|
|
388
|
+
.as_df()
|
|
435
389
|
)
|
|
436
390
|
|
|
437
391
|
# Access response metadata
|
|
@@ -446,7 +400,7 @@ print(f"Request cost: {client.last_response.request_cost}")
|
|
|
446
400
|
|
|
447
401
|
| Method | Description |
|
|
448
402
|
|--------|-------------|
|
|
449
|
-
| `.network(net)` | Set network (ETH, ARB, BASE, OP, etc.) |
|
|
403
|
+
| `.network(net)` | Set network (ETH, ARB, BASE, OP, POLYGON, etc.) |
|
|
450
404
|
| `.start_block(n)` | Set starting block number |
|
|
451
405
|
| `.end_block(n)` | Set ending block number |
|
|
452
406
|
| `.block_range(start, end)` | Set both start and end blocks |
|
|
@@ -455,35 +409,30 @@ print(f"Request cost: {client.last_response.request_cost}")
|
|
|
455
409
|
| `.time_range(start, end)` | Set both start and end times |
|
|
456
410
|
| `.verbose()` | Include all metadata fields |
|
|
457
411
|
|
|
458
|
-
###
|
|
412
|
+
### Protocol-Specific Parameters
|
|
459
413
|
|
|
460
414
|
| Method | Protocols | Description |
|
|
461
415
|
|--------|-----------|-------------|
|
|
416
|
+
| `.token(symbol)` | ERC20 | Token symbol (USDT, USDC) or contract address |
|
|
417
|
+
| `.decimals(n)` | ERC20 | Token decimals when using custom address (default: 18) |
|
|
462
418
|
| `.sender(addr)` | ERC20, Native | Filter by sender address |
|
|
463
419
|
| `.receiver(addr)` | ERC20, Native | Filter by receiver address |
|
|
464
|
-
| `.from_address(addr)` | ERC20, Native | Alias for sender |
|
|
465
|
-
| `.to_address(addr)` | ERC20, Native | Alias for receiver |
|
|
466
420
|
| `.min_amount(amt)` | ERC20, Native | Minimum transfer amount |
|
|
467
|
-
| `.
|
|
468
|
-
| `.
|
|
469
|
-
| `.
|
|
470
|
-
| `.
|
|
471
|
-
| `.
|
|
472
|
-
| `.liquidator(addr)` | AAVE Liquidations | Filter by liquidator |
|
|
473
|
-
| `.symbol0(sym)` | Uniswap | First token symbol |
|
|
474
|
-
| `.symbol1(sym)` | Uniswap | Second token symbol |
|
|
475
|
-
| `.fee(tier)` | Uniswap | Fee tier (100, 500, 3000, 10000) |
|
|
476
|
-
| `.pool(addr)` | Uniswap | Pool address |
|
|
421
|
+
| `.max_amount(amt)` | ERC20, Native | Maximum transfer amount |
|
|
422
|
+
| `.eth_market_type(type)` | AAVE | Market type for ETH: 'Core', 'Prime', 'EtherFi' |
|
|
423
|
+
| `.symbol0(sym)` | Uniswap | First token symbol (required) |
|
|
424
|
+
| `.symbol1(sym)` | Uniswap | Second token symbol (required) |
|
|
425
|
+
| `.fee(tier)` | Uniswap | Fee tier: 100, 500, 3000, 10000 (required) |
|
|
477
426
|
|
|
478
427
|
### Terminal Methods
|
|
479
428
|
|
|
480
429
|
| Method | Description |
|
|
481
430
|
|--------|-------------|
|
|
482
|
-
| `.as_dict()` | Execute and return list of dicts (JSON) |
|
|
483
431
|
| `.as_df()` | Execute and return pandas DataFrame |
|
|
484
432
|
| `.as_df("polars")` | Execute and return polars DataFrame |
|
|
485
433
|
| `.as_file(path)` | Execute and save to file (format from extension) |
|
|
486
434
|
| `.as_file(path, format="csv")` | Execute and save with explicit format |
|
|
435
|
+
| `.as_dict()` | Execute and return list of dicts (JSON, 10K block limit) |
|
|
487
436
|
|
|
488
437
|
## License
|
|
489
438
|
|