cloudcat 0.4.0__tar.gz → 0.6.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.
- {cloudcat-0.4.0 → cloudcat-0.6.0}/PKG-INFO +103 -18
- {cloudcat-0.4.0 → cloudcat-0.6.0}/README.md +93 -17
- {cloudcat-0.4.0 → cloudcat-0.6.0}/cloudcat/__init__.py +1 -1
- {cloudcat-0.4.0 → cloudcat-0.6.0}/cloudcat/cli.py +324 -95
- {cloudcat-0.4.0 → cloudcat-0.6.0}/cloudcat/compression.py +8 -3
- cloudcat-0.6.0/cloudcat/data/SKILL.md +117 -0
- cloudcat-0.6.0/cloudcat/filtering.py +225 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/cloudcat/formatters.py +3 -1
- {cloudcat-0.4.0 → cloudcat-0.6.0}/cloudcat/readers/avro.py +70 -14
- {cloudcat-0.4.0 → cloudcat-0.6.0}/cloudcat/readers/csv.py +42 -2
- {cloudcat-0.4.0 → cloudcat-0.6.0}/cloudcat/readers/json.py +131 -43
- {cloudcat-0.4.0 → cloudcat-0.6.0}/cloudcat/readers/orc.py +54 -11
- cloudcat-0.6.0/cloudcat/readers/parquet.py +380 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/cloudcat/readers/text.py +85 -2
- {cloudcat-0.4.0 → cloudcat-0.6.0}/cloudcat/storage/base.py +66 -19
- cloudcat-0.6.0/cloudcat/storage/local.py +58 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/cloudcat/streaming/filesystems.py +5 -1
- {cloudcat-0.4.0 → cloudcat-0.6.0}/cloudcat/streaming/stats.py +7 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/cloudcat/streaming/tracking.py +2 -1
- cloudcat-0.6.0/cloudcat/tables/__init__.py +123 -0
- cloudcat-0.6.0/cloudcat/tables/delta.py +121 -0
- cloudcat-0.6.0/cloudcat/tables/iceberg.py +148 -0
- cloudcat-0.6.0/cloudcat/tables/pushdown.py +102 -0
- cloudcat-0.6.0/cloudcat/user_config.py +107 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/cloudcat.egg-info/PKG-INFO +103 -18
- {cloudcat-0.4.0 → cloudcat-0.6.0}/cloudcat.egg-info/SOURCES.txt +12 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/cloudcat.egg-info/requires.txt +14 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/pyproject.toml +17 -2
- cloudcat-0.6.0/tests/test_bugfix_round2.py +246 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/tests/test_cli.py +6 -6
- {cloudcat-0.4.0 → cloudcat-0.6.0}/tests/test_cli_features.py +16 -2
- cloudcat-0.6.0/tests/test_config_stats_completion.py +110 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/tests/test_regressions.py +11 -3
- cloudcat-0.6.0/tests/test_skill_install.py +70 -0
- cloudcat-0.6.0/tests/test_tables.py +204 -0
- cloudcat-0.6.0/tests/test_v05_features.py +256 -0
- cloudcat-0.4.0/cloudcat/filtering.py +0 -129
- cloudcat-0.4.0/cloudcat/readers/parquet.py +0 -280
- {cloudcat-0.4.0 → cloudcat-0.6.0}/LICENSE +0 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/cloudcat/config.py +0 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/cloudcat/progress.py +0 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/cloudcat/readers/__init__.py +0 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/cloudcat/storage/__init__.py +0 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/cloudcat/storage/azure.py +0 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/cloudcat/storage/gcs.py +0 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/cloudcat/storage/s3.py +0 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/cloudcat/streaming/__init__.py +0 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/cloudcat.egg-info/dependency_links.txt +0 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/cloudcat.egg-info/entry_points.txt +0 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/cloudcat.egg-info/top_level.txt +0 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/setup.cfg +0 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/tests/test_compression.py +0 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/tests/test_config.py +0 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/tests/test_data_reading.py +0 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/tests/test_file_filtering.py +0 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/tests/test_filtering.py +0 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/tests/test_format_detection.py +0 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/tests/test_integration.py +0 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/tests/test_output_formatting.py +0 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/tests/test_path_parsing.py +0 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/tests/test_read_data_streaming.py +0 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/tests/test_readers_roundtrip.py +0 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/tests/test_storage_listing.py +0 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/tests/test_streaming_stats.py +0 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/tests/test_tracking.py +0 -0
- {cloudcat-0.4.0 → cloudcat-0.6.0}/tests/test_visual_output.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cloudcat
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.0
|
|
4
4
|
Summary: Preview and analyze data files in Google Cloud Storage, AWS S3, and Azure Data Lake Storage Gen2 from your terminal
|
|
5
5
|
Author: Jonathan Sudhakar
|
|
6
6
|
License: MIT
|
|
@@ -38,6 +38,7 @@ Requires-Dist: boto3>=1.18.0
|
|
|
38
38
|
Requires-Dist: azure-storage-file-datalake>=12.0.0
|
|
39
39
|
Requires-Dist: azure-storage-blob>=12.0.0
|
|
40
40
|
Requires-Dist: azure-identity>=1.0.0
|
|
41
|
+
Requires-Dist: tomli>=1.1.0; python_version < "3.11"
|
|
41
42
|
Provides-Extra: parquet
|
|
42
43
|
Requires-Dist: pyarrow>=5.0.0; extra == "parquet"
|
|
43
44
|
Provides-Extra: avro
|
|
@@ -54,6 +55,13 @@ Provides-Extra: compression
|
|
|
54
55
|
Requires-Dist: zstandard>=0.15.0; extra == "compression"
|
|
55
56
|
Requires-Dist: lz4>=3.0.0; extra == "compression"
|
|
56
57
|
Requires-Dist: python-snappy>=0.6.0; extra == "compression"
|
|
58
|
+
Provides-Extra: delta
|
|
59
|
+
Requires-Dist: deltalake>=1.0.0; extra == "delta"
|
|
60
|
+
Provides-Extra: iceberg
|
|
61
|
+
Requires-Dist: pyiceberg[pyarrow]>=0.9.0; extra == "iceberg"
|
|
62
|
+
Provides-Extra: tables
|
|
63
|
+
Requires-Dist: deltalake>=1.0.0; extra == "tables"
|
|
64
|
+
Requires-Dist: pyiceberg[pyarrow]>=0.9.0; extra == "tables"
|
|
57
65
|
Provides-Extra: all
|
|
58
66
|
Requires-Dist: pyarrow>=5.0.0; extra == "all"
|
|
59
67
|
Requires-Dist: fastavro>=1.4.0; extra == "all"
|
|
@@ -63,6 +71,7 @@ Requires-Dist: python-snappy>=0.6.0; extra == "all"
|
|
|
63
71
|
Provides-Extra: test
|
|
64
72
|
Requires-Dist: pytest>=6.0.0; extra == "test"
|
|
65
73
|
Requires-Dist: pytest-mock>=3.6.0; extra == "test"
|
|
74
|
+
Requires-Dist: pyiceberg[sql-sqlite]>=0.9.0; extra == "test"
|
|
66
75
|
Provides-Extra: dev
|
|
67
76
|
Requires-Dist: pytest>=6.0.0; extra == "dev"
|
|
68
77
|
Requires-Dist: pytest-mock>=3.6.0; extra == "dev"
|
|
@@ -156,6 +165,9 @@ pip install 'cloudcat[orc]'
|
|
|
156
165
|
|
|
157
166
|
# With compression support (zstd, lz4, snappy)
|
|
158
167
|
pip install 'cloudcat[compression]'
|
|
168
|
+
|
|
169
|
+
# With lakehouse table support (Delta Lake / Apache Iceberg)
|
|
170
|
+
pip install 'cloudcat[tables]'
|
|
159
171
|
```
|
|
160
172
|
|
|
161
173
|
> **Note:** If using zsh (default on macOS), quotes around extras are required to prevent shell interpretation of brackets.
|
|
@@ -169,14 +181,17 @@ pip install --upgrade 'cloudcat[all]'
|
|
|
169
181
|
### Requirements
|
|
170
182
|
|
|
171
183
|
- **Homebrew**: macOS (Apple Silicon only). Intel Mac users should use pip.
|
|
172
|
-
- **pip**: Python 3.
|
|
184
|
+
- **pip**: Python 3.9+ (all platforms)
|
|
173
185
|
- Cloud provider credentials configured (see [Authentication](#authentication))
|
|
174
186
|
|
|
175
187
|
## Quick Start
|
|
176
188
|
|
|
177
189
|
```bash
|
|
178
|
-
# Preview a CSV file from GCS
|
|
179
|
-
cloudcat
|
|
190
|
+
# Preview a CSV file from GCS (PATH is positional; -p/--path also works)
|
|
191
|
+
cloudcat gcs://my-bucket/data.csv
|
|
192
|
+
|
|
193
|
+
# Preview a local file — no cloud credentials needed
|
|
194
|
+
cloudcat ./data.parquet
|
|
180
195
|
|
|
181
196
|
# Preview a Parquet file from S3
|
|
182
197
|
cloudcat -p s3://my-bucket/analytics/events.parquet
|
|
@@ -196,11 +211,14 @@ cloudcat -p abfss://logs@account.dfs.core.windows.net/app.log -i text
|
|
|
196
211
|
# Read from a Spark output directory
|
|
197
212
|
cloudcat -p s3://my-bucket/spark-output/ -i parquet
|
|
198
213
|
|
|
214
|
+
# Read a Delta Lake or Iceberg table (auto-detected, current snapshot only)
|
|
215
|
+
cloudcat s3://lake/orders_delta/ -w "status=refunded" -n 10
|
|
216
|
+
|
|
199
217
|
# Read compressed files (auto-detected)
|
|
200
218
|
cloudcat -p gcs://my-bucket/data.csv.gz
|
|
201
219
|
|
|
202
|
-
# Filter rows with WHERE
|
|
203
|
-
cloudcat
|
|
220
|
+
# Filter rows with WHERE (streams; stops at -n matches; AND/OR supported)
|
|
221
|
+
cloudcat s3://bucket/users.parquet --where "status=active AND age>30"
|
|
204
222
|
|
|
205
223
|
# Skip first 100 rows (pagination)
|
|
206
224
|
cloudcat -p gcs://bucket/data.csv --offset 100 -n 10
|
|
@@ -215,6 +233,7 @@ cloudcat -p gcs://bucket/data.csv --offset 100 -n 10
|
|
|
215
233
|
| Google Cloud Storage | `gcs://` or `gs://` | ✅ Supported |
|
|
216
234
|
| Amazon S3 | `s3://` | ✅ Supported |
|
|
217
235
|
| Azure Data Lake Gen2 | `abfss://` | ✅ Supported |
|
|
236
|
+
| Local files | `file://` or a plain path | ✅ Supported (no credentials needed) |
|
|
218
237
|
|
|
219
238
|
### File Format Support
|
|
220
239
|
|
|
@@ -228,6 +247,8 @@ cloudcat -p gcs://bucket/data.csv --offset 100 -n 10
|
|
|
228
247
|
| ORC | ✅ | Hive, Hadoop ecosystem |
|
|
229
248
|
| Text | ✅ | Log files, plain text |
|
|
230
249
|
| TSV | Via `--delimiter` | Tab-separated data |
|
|
250
|
+
| Delta Lake | ✅ table dirs | Lakehouse tables (`cloudcat[delta]`) |
|
|
251
|
+
| Apache Iceberg | ✅ table dirs | Lakehouse tables (`cloudcat[iceberg]`) |
|
|
231
252
|
|
|
232
253
|
### Streaming Efficiency
|
|
233
254
|
|
|
@@ -237,8 +258,8 @@ CloudCat uses intelligent streaming to minimize data transfer and egress costs:
|
|
|
237
258
|
|--------|-------------|---------|-------------------|----------------|
|
|
238
259
|
| Parquet | None/Internal | ✅ | ✅ Range requests | ✅ |
|
|
239
260
|
| Parquet | External (.gz) | ❌ | ❌ | ❌ |
|
|
240
|
-
| ORC | None/Internal |
|
|
241
|
-
| ORC | External (.gz) | ❌ |
|
|
261
|
+
| ORC | None/Internal | ✅ Stripe-by-stripe | ✅ | ✅ |
|
|
262
|
+
| ORC | External (.gz) | ❌ | ✅ | ✅ |
|
|
242
263
|
| CSV | None | ✅ | ❌ | ✅ |
|
|
243
264
|
| CSV | gzip/zstd/lz4/bz2 | ✅ | ❌ | ✅ |
|
|
244
265
|
| CSV | snappy | ❌ | ❌ | ❌ |
|
|
@@ -267,7 +288,7 @@ CloudCat automatically detects and decompresses files based on extension (e.g.,
|
|
|
267
288
|
|
|
268
289
|
| Format | Flag | Description |
|
|
269
290
|
|--------|------|-------------|
|
|
270
|
-
| Table | `-o table` |
|
|
291
|
+
| Table | `-o table` | Rounded table with bold headers and type-aware coloring (default) |
|
|
271
292
|
| JSON | `-o json` | Standard JSON Lines output |
|
|
272
293
|
| Pretty JSON | `-o jsonp` | Syntax-highlighted, indented JSON |
|
|
273
294
|
| CSV | `-o csv` | Comma-separated values |
|
|
@@ -324,8 +345,8 @@ cloudcat -p gcs://bucket/events.jsonl
|
|
|
324
345
|
### Filtering and Pagination
|
|
325
346
|
|
|
326
347
|
```bash
|
|
327
|
-
# Filter rows with WHERE
|
|
328
|
-
cloudcat
|
|
348
|
+
# Filter rows with WHERE (streams; stops at -n matches; AND/OR supported)
|
|
349
|
+
cloudcat s3://bucket/users.parquet --where "status=active AND age>30"
|
|
329
350
|
cloudcat -p gcs://bucket/events.json --where "age>30"
|
|
330
351
|
cloudcat -p s3://bucket/logs.csv --where "level=ERROR"
|
|
331
352
|
|
|
@@ -474,7 +495,9 @@ cloudcat -p s3://api-dumps/response.json -o csv > data.csv
|
|
|
474
495
|
Usage: cloudcat [OPTIONS]
|
|
475
496
|
|
|
476
497
|
Options:
|
|
477
|
-
|
|
498
|
+
PATH Positional path: gs://, gcs://, s3://, abfss://,
|
|
499
|
+
file:// URL, or a plain local path
|
|
500
|
+
(-p/--path remains as a compatible alias)
|
|
478
501
|
Format: gcs://bucket/path, s3://bucket/path,
|
|
479
502
|
or abfss://container@account.dfs.core.windows.net/path
|
|
480
503
|
|
|
@@ -483,7 +506,8 @@ Options:
|
|
|
483
506
|
|
|
484
507
|
-O, --output-file PATH Write rendered data to a file instead of stdout
|
|
485
508
|
|
|
486
|
-
-i, --input-format TEXT Input format: csv, json, parquet, avro, orc,
|
|
509
|
+
-i, --input-format TEXT Input format: csv, json, parquet, avro, orc,
|
|
510
|
+
text, delta, iceberg
|
|
487
511
|
[default: auto-detect from extension]
|
|
488
512
|
|
|
489
513
|
-c, --columns TEXT Comma-separated list of columns to display
|
|
@@ -495,10 +519,12 @@ Options:
|
|
|
495
519
|
--offset INTEGER Skip first N rows
|
|
496
520
|
[default: 0]
|
|
497
521
|
|
|
498
|
-
-w, --where TEXT Filter rows with SQL-like conditions
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
522
|
+
-w, --where TEXT Filter rows with SQL-like conditions; combine
|
|
523
|
+
with AND/OR. Streams the file and stops at
|
|
524
|
+
--num-rows matches; Parquet skips row groups
|
|
525
|
+
via column statistics.
|
|
526
|
+
Examples: "status=active", "age>30 AND age<65",
|
|
527
|
+
"level=ERROR or level=FATAL"
|
|
502
528
|
|
|
503
529
|
-s, --schema TEXT Schema display: show, dont_show, schema_only
|
|
504
530
|
[default: show]
|
|
@@ -523,6 +549,13 @@ Options:
|
|
|
523
549
|
|
|
524
550
|
--credentials TEXT Path to GCP service account JSON file
|
|
525
551
|
|
|
552
|
+
--stats Show per-column statistics (nulls, distinct,
|
|
553
|
+
min/max) over the retrieved rows
|
|
554
|
+
|
|
555
|
+
--config-profile TEXT Named profile from ~/.config/cloudcat/config.toml
|
|
556
|
+
|
|
557
|
+
--completion [bash|zsh|fish] Print the shell completion script and exit
|
|
558
|
+
|
|
526
559
|
--az-access-key TEXT Azure storage account access key
|
|
527
560
|
|
|
528
561
|
-y, --yes Skip confirmation prompts (for scripting)
|
|
@@ -699,6 +732,50 @@ pip install -e ".[all]"
|
|
|
699
732
|
pytest
|
|
700
733
|
```
|
|
701
734
|
|
|
735
|
+
## Use with AI Agents
|
|
736
|
+
|
|
737
|
+
CloudCat is optimized for AI coding agents: **stdout carries only data**
|
|
738
|
+
(diagnostics go to stderr, color auto-disables when piped), `-o json` emits
|
|
739
|
+
parseable NDJSON, `-y` makes every command non-interactive, filtering streams
|
|
740
|
+
with Parquet row-group pushdown, and local files need no credentials.
|
|
741
|
+
|
|
742
|
+
The repo ships an [Agent Skill](https://agentskills.io) at
|
|
743
|
+
[`skills/cloudcat/SKILL.md`](skills/cloudcat/SKILL.md) — a compact reference
|
|
744
|
+
that teaches agents the optimal scanning recipes (schema discovery, filtered
|
|
745
|
+
sampling, metadata-fast counts, column profiling) with zero trial-and-error.
|
|
746
|
+
|
|
747
|
+
Install the skill (pick one):
|
|
748
|
+
|
|
749
|
+
```bash
|
|
750
|
+
# 1. Built-in installer — the skill ships inside the package (works offline)
|
|
751
|
+
cloudcat --install-skill claude # Claude Code, all projects (~/.claude/skills)
|
|
752
|
+
cloudcat --install-skill claude-project # Claude Code, this project (./.claude/skills)
|
|
753
|
+
cloudcat --install-skill codex # OpenAI Codex CLI (~/.codex/skills)
|
|
754
|
+
cloudcat --install-skill print # stdout — pipe into any other agent's instructions
|
|
755
|
+
|
|
756
|
+
# 2. Claude Code plugin marketplace
|
|
757
|
+
/plugin marketplace add jonathansudhakar1/cloudcat
|
|
758
|
+
/plugin install cloudcat@cloudcat
|
|
759
|
+
|
|
760
|
+
# 3. Or fetch it directly (no cloudcat install needed)
|
|
761
|
+
curl -fsSL --create-dirs -o ~/.claude/skills/cloudcat/SKILL.md \
|
|
762
|
+
https://raw.githubusercontent.com/jonathansudhakar1/cloudcat/main/skills/cloudcat/SKILL.md
|
|
763
|
+
```
|
|
764
|
+
|
|
765
|
+
The recipes agents learn:
|
|
766
|
+
|
|
767
|
+
```bash
|
|
768
|
+
cloudcat s3://bucket/events/ -s schema_only -y # structure, no data read
|
|
769
|
+
cloudcat s3://bucket/events/ --count -s schema_only -y # exact rows (Parquet/ORC: metadata-only)
|
|
770
|
+
cloudcat s3://bucket/events/ -w "type=purchase AND amount>250" \
|
|
771
|
+
-n 5 -o json -s dont_show -y # filtered NDJSON sample
|
|
772
|
+
cloudcat s3://bucket/events/ --stats -n 0 -s dont_show -y # nulls/distinct/min/max per column
|
|
773
|
+
```
|
|
774
|
+
|
|
775
|
+
Works with any agent framework that can run shell commands and load the
|
|
776
|
+
SKILL.md (or plain markdown) as instructions. See the
|
|
777
|
+
[AI Agents docs](https://cloudcatcli.com/#agents) for details.
|
|
778
|
+
|
|
702
779
|
## Roadmap
|
|
703
780
|
|
|
704
781
|
- [x] Azure Blob Storage support
|
|
@@ -709,8 +786,16 @@ pytest
|
|
|
709
786
|
- [x] Compression support (gzip, zstd, lz4, snappy, bz2)
|
|
710
787
|
- [x] Row offset/pagination (`--offset`)
|
|
711
788
|
- [x] Output to file with `--output-file`
|
|
789
|
+
- [x] Compound WHERE conditions (`AND`/`OR`)
|
|
790
|
+
- [x] Streaming WHERE with Parquet row-group pushdown
|
|
791
|
+
- [x] Local file support (`file://` or plain paths)
|
|
792
|
+
- [x] Configuration file with named profiles
|
|
793
|
+
- [x] Column statistics (`--stats`)
|
|
794
|
+
- [x] Shell completion (bash/zsh/fish)
|
|
795
|
+
- [x] Delta Lake support (current snapshot; `cloudcat[delta]`)
|
|
796
|
+
- [x] Apache Iceberg support (current snapshot, catalog-less; `cloudcat[iceberg]`)
|
|
712
797
|
- [ ] Interactive mode with pagination
|
|
713
|
-
- [ ]
|
|
798
|
+
- [ ] Table time travel (`--at-version` / `--at-snapshot`)
|
|
714
799
|
|
|
715
800
|
## Related Projects
|
|
716
801
|
|
|
@@ -83,6 +83,9 @@ pip install 'cloudcat[orc]'
|
|
|
83
83
|
|
|
84
84
|
# With compression support (zstd, lz4, snappy)
|
|
85
85
|
pip install 'cloudcat[compression]'
|
|
86
|
+
|
|
87
|
+
# With lakehouse table support (Delta Lake / Apache Iceberg)
|
|
88
|
+
pip install 'cloudcat[tables]'
|
|
86
89
|
```
|
|
87
90
|
|
|
88
91
|
> **Note:** If using zsh (default on macOS), quotes around extras are required to prevent shell interpretation of brackets.
|
|
@@ -96,14 +99,17 @@ pip install --upgrade 'cloudcat[all]'
|
|
|
96
99
|
### Requirements
|
|
97
100
|
|
|
98
101
|
- **Homebrew**: macOS (Apple Silicon only). Intel Mac users should use pip.
|
|
99
|
-
- **pip**: Python 3.
|
|
102
|
+
- **pip**: Python 3.9+ (all platforms)
|
|
100
103
|
- Cloud provider credentials configured (see [Authentication](#authentication))
|
|
101
104
|
|
|
102
105
|
## Quick Start
|
|
103
106
|
|
|
104
107
|
```bash
|
|
105
|
-
# Preview a CSV file from GCS
|
|
106
|
-
cloudcat
|
|
108
|
+
# Preview a CSV file from GCS (PATH is positional; -p/--path also works)
|
|
109
|
+
cloudcat gcs://my-bucket/data.csv
|
|
110
|
+
|
|
111
|
+
# Preview a local file — no cloud credentials needed
|
|
112
|
+
cloudcat ./data.parquet
|
|
107
113
|
|
|
108
114
|
# Preview a Parquet file from S3
|
|
109
115
|
cloudcat -p s3://my-bucket/analytics/events.parquet
|
|
@@ -123,11 +129,14 @@ cloudcat -p abfss://logs@account.dfs.core.windows.net/app.log -i text
|
|
|
123
129
|
# Read from a Spark output directory
|
|
124
130
|
cloudcat -p s3://my-bucket/spark-output/ -i parquet
|
|
125
131
|
|
|
132
|
+
# Read a Delta Lake or Iceberg table (auto-detected, current snapshot only)
|
|
133
|
+
cloudcat s3://lake/orders_delta/ -w "status=refunded" -n 10
|
|
134
|
+
|
|
126
135
|
# Read compressed files (auto-detected)
|
|
127
136
|
cloudcat -p gcs://my-bucket/data.csv.gz
|
|
128
137
|
|
|
129
|
-
# Filter rows with WHERE
|
|
130
|
-
cloudcat
|
|
138
|
+
# Filter rows with WHERE (streams; stops at -n matches; AND/OR supported)
|
|
139
|
+
cloudcat s3://bucket/users.parquet --where "status=active AND age>30"
|
|
131
140
|
|
|
132
141
|
# Skip first 100 rows (pagination)
|
|
133
142
|
cloudcat -p gcs://bucket/data.csv --offset 100 -n 10
|
|
@@ -142,6 +151,7 @@ cloudcat -p gcs://bucket/data.csv --offset 100 -n 10
|
|
|
142
151
|
| Google Cloud Storage | `gcs://` or `gs://` | ✅ Supported |
|
|
143
152
|
| Amazon S3 | `s3://` | ✅ Supported |
|
|
144
153
|
| Azure Data Lake Gen2 | `abfss://` | ✅ Supported |
|
|
154
|
+
| Local files | `file://` or a plain path | ✅ Supported (no credentials needed) |
|
|
145
155
|
|
|
146
156
|
### File Format Support
|
|
147
157
|
|
|
@@ -155,6 +165,8 @@ cloudcat -p gcs://bucket/data.csv --offset 100 -n 10
|
|
|
155
165
|
| ORC | ✅ | Hive, Hadoop ecosystem |
|
|
156
166
|
| Text | ✅ | Log files, plain text |
|
|
157
167
|
| TSV | Via `--delimiter` | Tab-separated data |
|
|
168
|
+
| Delta Lake | ✅ table dirs | Lakehouse tables (`cloudcat[delta]`) |
|
|
169
|
+
| Apache Iceberg | ✅ table dirs | Lakehouse tables (`cloudcat[iceberg]`) |
|
|
158
170
|
|
|
159
171
|
### Streaming Efficiency
|
|
160
172
|
|
|
@@ -164,8 +176,8 @@ CloudCat uses intelligent streaming to minimize data transfer and egress costs:
|
|
|
164
176
|
|--------|-------------|---------|-------------------|----------------|
|
|
165
177
|
| Parquet | None/Internal | ✅ | ✅ Range requests | ✅ |
|
|
166
178
|
| Parquet | External (.gz) | ❌ | ❌ | ❌ |
|
|
167
|
-
| ORC | None/Internal |
|
|
168
|
-
| ORC | External (.gz) | ❌ |
|
|
179
|
+
| ORC | None/Internal | ✅ Stripe-by-stripe | ✅ | ✅ |
|
|
180
|
+
| ORC | External (.gz) | ❌ | ✅ | ✅ |
|
|
169
181
|
| CSV | None | ✅ | ❌ | ✅ |
|
|
170
182
|
| CSV | gzip/zstd/lz4/bz2 | ✅ | ❌ | ✅ |
|
|
171
183
|
| CSV | snappy | ❌ | ❌ | ❌ |
|
|
@@ -194,7 +206,7 @@ CloudCat automatically detects and decompresses files based on extension (e.g.,
|
|
|
194
206
|
|
|
195
207
|
| Format | Flag | Description |
|
|
196
208
|
|--------|------|-------------|
|
|
197
|
-
| Table | `-o table` |
|
|
209
|
+
| Table | `-o table` | Rounded table with bold headers and type-aware coloring (default) |
|
|
198
210
|
| JSON | `-o json` | Standard JSON Lines output |
|
|
199
211
|
| Pretty JSON | `-o jsonp` | Syntax-highlighted, indented JSON |
|
|
200
212
|
| CSV | `-o csv` | Comma-separated values |
|
|
@@ -251,8 +263,8 @@ cloudcat -p gcs://bucket/events.jsonl
|
|
|
251
263
|
### Filtering and Pagination
|
|
252
264
|
|
|
253
265
|
```bash
|
|
254
|
-
# Filter rows with WHERE
|
|
255
|
-
cloudcat
|
|
266
|
+
# Filter rows with WHERE (streams; stops at -n matches; AND/OR supported)
|
|
267
|
+
cloudcat s3://bucket/users.parquet --where "status=active AND age>30"
|
|
256
268
|
cloudcat -p gcs://bucket/events.json --where "age>30"
|
|
257
269
|
cloudcat -p s3://bucket/logs.csv --where "level=ERROR"
|
|
258
270
|
|
|
@@ -401,7 +413,9 @@ cloudcat -p s3://api-dumps/response.json -o csv > data.csv
|
|
|
401
413
|
Usage: cloudcat [OPTIONS]
|
|
402
414
|
|
|
403
415
|
Options:
|
|
404
|
-
|
|
416
|
+
PATH Positional path: gs://, gcs://, s3://, abfss://,
|
|
417
|
+
file:// URL, or a plain local path
|
|
418
|
+
(-p/--path remains as a compatible alias)
|
|
405
419
|
Format: gcs://bucket/path, s3://bucket/path,
|
|
406
420
|
or abfss://container@account.dfs.core.windows.net/path
|
|
407
421
|
|
|
@@ -410,7 +424,8 @@ Options:
|
|
|
410
424
|
|
|
411
425
|
-O, --output-file PATH Write rendered data to a file instead of stdout
|
|
412
426
|
|
|
413
|
-
-i, --input-format TEXT Input format: csv, json, parquet, avro, orc,
|
|
427
|
+
-i, --input-format TEXT Input format: csv, json, parquet, avro, orc,
|
|
428
|
+
text, delta, iceberg
|
|
414
429
|
[default: auto-detect from extension]
|
|
415
430
|
|
|
416
431
|
-c, --columns TEXT Comma-separated list of columns to display
|
|
@@ -422,10 +437,12 @@ Options:
|
|
|
422
437
|
--offset INTEGER Skip first N rows
|
|
423
438
|
[default: 0]
|
|
424
439
|
|
|
425
|
-
-w, --where TEXT Filter rows with SQL-like conditions
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
440
|
+
-w, --where TEXT Filter rows with SQL-like conditions; combine
|
|
441
|
+
with AND/OR. Streams the file and stops at
|
|
442
|
+
--num-rows matches; Parquet skips row groups
|
|
443
|
+
via column statistics.
|
|
444
|
+
Examples: "status=active", "age>30 AND age<65",
|
|
445
|
+
"level=ERROR or level=FATAL"
|
|
429
446
|
|
|
430
447
|
-s, --schema TEXT Schema display: show, dont_show, schema_only
|
|
431
448
|
[default: show]
|
|
@@ -450,6 +467,13 @@ Options:
|
|
|
450
467
|
|
|
451
468
|
--credentials TEXT Path to GCP service account JSON file
|
|
452
469
|
|
|
470
|
+
--stats Show per-column statistics (nulls, distinct,
|
|
471
|
+
min/max) over the retrieved rows
|
|
472
|
+
|
|
473
|
+
--config-profile TEXT Named profile from ~/.config/cloudcat/config.toml
|
|
474
|
+
|
|
475
|
+
--completion [bash|zsh|fish] Print the shell completion script and exit
|
|
476
|
+
|
|
453
477
|
--az-access-key TEXT Azure storage account access key
|
|
454
478
|
|
|
455
479
|
-y, --yes Skip confirmation prompts (for scripting)
|
|
@@ -626,6 +650,50 @@ pip install -e ".[all]"
|
|
|
626
650
|
pytest
|
|
627
651
|
```
|
|
628
652
|
|
|
653
|
+
## Use with AI Agents
|
|
654
|
+
|
|
655
|
+
CloudCat is optimized for AI coding agents: **stdout carries only data**
|
|
656
|
+
(diagnostics go to stderr, color auto-disables when piped), `-o json` emits
|
|
657
|
+
parseable NDJSON, `-y` makes every command non-interactive, filtering streams
|
|
658
|
+
with Parquet row-group pushdown, and local files need no credentials.
|
|
659
|
+
|
|
660
|
+
The repo ships an [Agent Skill](https://agentskills.io) at
|
|
661
|
+
[`skills/cloudcat/SKILL.md`](skills/cloudcat/SKILL.md) — a compact reference
|
|
662
|
+
that teaches agents the optimal scanning recipes (schema discovery, filtered
|
|
663
|
+
sampling, metadata-fast counts, column profiling) with zero trial-and-error.
|
|
664
|
+
|
|
665
|
+
Install the skill (pick one):
|
|
666
|
+
|
|
667
|
+
```bash
|
|
668
|
+
# 1. Built-in installer — the skill ships inside the package (works offline)
|
|
669
|
+
cloudcat --install-skill claude # Claude Code, all projects (~/.claude/skills)
|
|
670
|
+
cloudcat --install-skill claude-project # Claude Code, this project (./.claude/skills)
|
|
671
|
+
cloudcat --install-skill codex # OpenAI Codex CLI (~/.codex/skills)
|
|
672
|
+
cloudcat --install-skill print # stdout — pipe into any other agent's instructions
|
|
673
|
+
|
|
674
|
+
# 2. Claude Code plugin marketplace
|
|
675
|
+
/plugin marketplace add jonathansudhakar1/cloudcat
|
|
676
|
+
/plugin install cloudcat@cloudcat
|
|
677
|
+
|
|
678
|
+
# 3. Or fetch it directly (no cloudcat install needed)
|
|
679
|
+
curl -fsSL --create-dirs -o ~/.claude/skills/cloudcat/SKILL.md \
|
|
680
|
+
https://raw.githubusercontent.com/jonathansudhakar1/cloudcat/main/skills/cloudcat/SKILL.md
|
|
681
|
+
```
|
|
682
|
+
|
|
683
|
+
The recipes agents learn:
|
|
684
|
+
|
|
685
|
+
```bash
|
|
686
|
+
cloudcat s3://bucket/events/ -s schema_only -y # structure, no data read
|
|
687
|
+
cloudcat s3://bucket/events/ --count -s schema_only -y # exact rows (Parquet/ORC: metadata-only)
|
|
688
|
+
cloudcat s3://bucket/events/ -w "type=purchase AND amount>250" \
|
|
689
|
+
-n 5 -o json -s dont_show -y # filtered NDJSON sample
|
|
690
|
+
cloudcat s3://bucket/events/ --stats -n 0 -s dont_show -y # nulls/distinct/min/max per column
|
|
691
|
+
```
|
|
692
|
+
|
|
693
|
+
Works with any agent framework that can run shell commands and load the
|
|
694
|
+
SKILL.md (or plain markdown) as instructions. See the
|
|
695
|
+
[AI Agents docs](https://cloudcatcli.com/#agents) for details.
|
|
696
|
+
|
|
629
697
|
## Roadmap
|
|
630
698
|
|
|
631
699
|
- [x] Azure Blob Storage support
|
|
@@ -636,8 +704,16 @@ pytest
|
|
|
636
704
|
- [x] Compression support (gzip, zstd, lz4, snappy, bz2)
|
|
637
705
|
- [x] Row offset/pagination (`--offset`)
|
|
638
706
|
- [x] Output to file with `--output-file`
|
|
707
|
+
- [x] Compound WHERE conditions (`AND`/`OR`)
|
|
708
|
+
- [x] Streaming WHERE with Parquet row-group pushdown
|
|
709
|
+
- [x] Local file support (`file://` or plain paths)
|
|
710
|
+
- [x] Configuration file with named profiles
|
|
711
|
+
- [x] Column statistics (`--stats`)
|
|
712
|
+
- [x] Shell completion (bash/zsh/fish)
|
|
713
|
+
- [x] Delta Lake support (current snapshot; `cloudcat[delta]`)
|
|
714
|
+
- [x] Apache Iceberg support (current snapshot, catalog-less; `cloudcat[iceberg]`)
|
|
639
715
|
- [ ] Interactive mode with pagination
|
|
640
|
-
- [ ]
|
|
716
|
+
- [ ] Table time travel (`--at-version` / `--at-snapshot`)
|
|
641
717
|
|
|
642
718
|
## Related Projects
|
|
643
719
|
|