dataframe-textual 1.2.0__tar.gz → 1.4.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dataframe-textual
3
- Version: 1.2.0
3
+ Version: 1.4.0
4
4
  Summary: Interactive terminal viewer/editor for tabular data
5
5
  Project-URL: Homepage, https://github.com/need47/dataframe-textual
6
6
  Project-URL: Repository, https://github.com/need47/dataframe-textual.git
@@ -29,7 +29,7 @@ Classifier: Topic :: Utilities
29
29
  Classifier: Typing :: Typed
30
30
  Requires-Python: >=3.11
31
31
  Requires-Dist: polars>=1.34.0
32
- Requires-Dist: textual>=6.5.0
32
+ Requires-Dist: textual[syntax]>=6.5.0
33
33
  Provides-Extra: dev
34
34
  Requires-Dist: textual-dev>=1.8.0; extra == 'dev'
35
35
  Provides-Extra: excel
@@ -129,6 +129,13 @@ uv run python main.py pokemon.csv
129
129
  # Read from stdin (auto-detects format; defaults to TSV if not recognized)
130
130
  cat data.tsv | dv
131
131
  dv < data.tsv
132
+
133
+ # Gzipped files are supported
134
+ dv data.csv.gz
135
+ dv large_dataset.tsv.gz
136
+
137
+ # Specify format for gzipped stdin
138
+ zcat data.csv.gz | dv -f csv
132
139
  ```
133
140
 
134
141
  ### Multi-File Usage - Multiple Tabs
@@ -142,6 +149,9 @@ dv file.xlsx
142
149
 
143
150
  # Mix files and stdin (read from stdin, then open file)
144
151
  dv data1.tsv < data2.tsv
152
+
153
+ # Mix regular and gzipped files
154
+ dv data1.csv data2.csv.gz data3.tsv.gz
145
155
  ```
146
156
 
147
157
  When multiple files are opened:
@@ -151,6 +161,67 @@ When multiple files are opened:
151
161
  - Close the current tab with `Ctrl+W`
152
162
  - Each file maintains its own state (edits, sort order, selections, history, etc.)
153
163
 
164
+ ## Command Line Options
165
+
166
+ ```
167
+ usage: dv [-h] [-f {csv,excel,tsv,parquet,json,ndjson}] [-H] [-I] [-L SKIP_LINES] [-K SKIP_ROWS_AFTER_HEADER] [-U NULL [NULL ...]] [files ...]
168
+
169
+ Interactive terminal based viewer/editor for tabular data (e.g., CSV/Excel).
170
+
171
+ positional arguments:
172
+ files Files to view (or read from stdin)
173
+
174
+ options:
175
+ -h, --help show this help message and exit
176
+ -f, --format {csv,excel,tsv,parquet,json,ndjson}
177
+ Specify the format of the input files
178
+ -H, --no-header Specify that input files have no header row
179
+ -I, --no-inferrence Do not infer data types when reading CSV/TSV
180
+ -L, --skip-lines SKIP_LINES
181
+ Skip lines when reading CSV/TSV (default: 0)
182
+ -K, --skip-rows-after-header SKIP_ROWS_AFTER_HEADER
183
+ Skip rows after header when reading CSV/TSV (default: 0)
184
+ -U, --null NULL [NULL ...]
185
+ Values to interpret as null values when reading CSV/TSV
186
+ ```
187
+
188
+ ### CLI Examples
189
+
190
+ ```bash
191
+ # View CSV file without header row
192
+ dv -H data_no_header.csv
193
+
194
+ # Disable type inference for faster loading
195
+ dv -I large_data.csv
196
+
197
+ # Skip first 3 lines of file (e.g., comments, metadata)
198
+ dv -L 3 data_with_comments.csv
199
+
200
+ # Skip 1 row after header (e.g., units row)
201
+ dv -K 1 data_with_units.csv
202
+
203
+ # Treat specific values as null/missing (e.g., 'NA', 'N/A', '-')
204
+ dv -U NA N/A - data.csv
205
+
206
+ # Multiple null values with different formats
207
+ dv -U NULL NA "" "Not Available" messy_data.csv
208
+
209
+ # Complex CSV with comments and units row
210
+ dv -L 3 -K 1 -I messy_scientific_data.csv
211
+
212
+ # Combine all options: skip lines, skip after header, no header, no inference, gzipped
213
+ dv -L 2 -K 1 -H -I complex_data.csv.gz
214
+
215
+ # Process compressed data from stdin with line skipping
216
+ zcat compressed_data.csv.gz | dv -f csv -L 2
217
+
218
+ # CSV with custom null values and no header
219
+ dv -H -U NA "N/A" "-" raw_data.csv
220
+
221
+ # Skip lines, specify null values, and disable type inference
222
+ dv -L 5 -U NA "" data_with_metadata.csv
223
+ ```
224
+
154
225
  ## Keyboard Shortcuts
155
226
 
156
227
  ### App-Level Controls
@@ -161,7 +232,7 @@ When multiple files are opened:
161
232
  |-----|--------|
162
233
  | `Ctrl+O` | Open file in a new tab |
163
234
  | `Ctrl+W` | Close current tab |
164
- | `Ctrl+Shift+S` | Save all open tabs to Excel file |
235
+ | `Ctrl+A` | Save all open tabs to Excel file |
165
236
  | `>` or `b` | Move to next tab |
166
237
  | `<` | Move to previous tab |
167
238
  | `B` | Toggle tab bar visibility |
@@ -171,7 +242,7 @@ When multiple files are opened:
171
242
 
172
243
  | Key | Action |
173
244
  |-----|--------|
174
- | `Ctrl+H` | Toggle help panel |
245
+ | `F1` | Toggle help panel |
175
246
  | `k` | Cycle through themes |
176
247
 
177
248
  ---
@@ -189,6 +260,8 @@ When multiple files are opened:
189
260
  | `Home` / `End` | Jump to first/last column in current row |
190
261
  | `Ctrl + Home` / `Ctrl + End` | Jump to top/bottom in current page |
191
262
  | `PageDown` / `PageUp` | Scroll down/up one page |
263
+ | `Ctrl+F` | Page down |
264
+ | `Ctrl+B` | Page up |
192
265
 
193
266
  #### Viewing & Display
194
267
 
@@ -200,6 +273,7 @@ When multiple files are opened:
200
273
  | `S` | Show statistics for entire dataframe |
201
274
  | `K` | Cycle cursor type: cell → row → column → cell |
202
275
  | `~` | Toggle row labels |
276
+ | `_` (underscore) | Expand column to full width |
203
277
 
204
278
  #### Data Editing
205
279
 
@@ -212,8 +286,6 @@ When multiple files are opened:
212
286
  | `a` | Add empty column after current |
213
287
  | `A` | Add column with name and value/expression |
214
288
  | `-` (minus) | Delete current column |
215
- | `_` (underscore) | Delete current column and all columns after |
216
- | `Ctrl+-` | Delete current column and all columns before |
217
289
  | `x` | Delete current row |
218
290
  | `X` | Delete current row and all rows below |
219
291
  | `Ctrl+X` | Delete current row and all rows above |
@@ -241,12 +313,19 @@ When multiple files are opened:
241
313
  | `v` | View only rows by selected rows and/or matches or cursor value |
242
314
  | `V` | View only rows by expression |
243
315
 
316
+ #### SQL Interface
317
+
318
+ | Key | Action |
319
+ |-----|--------|
320
+ | `l` | Simple SQL interface (select columns & WHERE clause) |
321
+ | `L` | Advanced SQL interface (full SQL queries) |
322
+
244
323
  #### Find & Replace
245
324
 
246
325
  | Key | Action |
247
326
  |-----|--------|
248
- | `f` | Find across all columns with cursor value |
249
- | `Ctrl+F` | Find across all columns with expression |
327
+ | `;` | Find across all columns with cursor value |
328
+ | `:` | Find across all columns with expression |
250
329
  | `r` | Find and replace in current column (interactive or replace all) |
251
330
  | `R` | Find and replace across all columns (interactive or replace all) |
252
331
 
@@ -322,8 +401,8 @@ The application provides multiple search modes for different use cases:
322
401
  **Find Operations** - Find by value/expression:
323
402
  - **`/` - Column Find**: Find cursor value within current column
324
403
  - **`?` - Column Expression Find**: Open dialog to search current column with expression
325
- - **`f` - Global Find**: Find cursor value across all columns
326
- - **`Ctrl+f` - Global Expression Find**: Open dialog to search all columns with expression
404
+ - **`;` - Global Find**: Find cursor value across all columns
405
+ - **`:` - Global Expression Find**: Open dialog to search all columns with expression
327
406
 
328
407
  **Selection & Filtering**:
329
408
  - **`'` - Toggle Row Selection**: Select/deselect current row (marks it for filtering)
@@ -703,7 +782,40 @@ Press `@` to make URLs in the current column clickable:
703
782
  - **Scans** all cells in the current column for URLs starting with `http://` or `https://`
704
783
  - **Applies** link styling to make them clickable and dataframe remains unchanged
705
784
 
706
- ### 19. Clipboard Operations
785
+ ### 19. SQL Interface
786
+
787
+ The SQL interface provides two modes for querying your dataframe:
788
+
789
+ #### Simple SQL Interface (`l`)
790
+ Select specific columns and apply WHERE conditions without writing full SQL:
791
+ - Choose which columns to include in results
792
+ - Specify WHERE clause for filtering
793
+ - Ideal for quick filtering and column selection
794
+
795
+ #### Advanced SQL Interface (`L`)
796
+ Execute complete SQL queries for advanced data manipulation:
797
+ - Write full SQL queries with standard [SQL syntax](https://docs.pola.rs/api/python/stable/reference/sql/index.html)
798
+ - Support for JOINs, GROUP BY, aggregations, and more
799
+ - Access to all SQL capabilities for complex transformations
800
+ - Always use `self` as the table name
801
+
802
+ **Examples:**
803
+ ```sql
804
+ -- Filter and select specific rows and/or columns
805
+ SELECT name, age FROM self WHERE age > 30
806
+
807
+ -- Aggregate with GROUP BY
808
+ SELECT department, COUNT(*) as count, AVG(salary) as avg_salary
809
+ FROM self
810
+ GROUP BY department
811
+
812
+ -- Complex filtering with multiple conditions
813
+ SELECT *
814
+ FROM self
815
+ WHERE (age > 25 AND salary > 50000) OR department = 'Management'
816
+ ```
817
+
818
+ ### 20. Clipboard Operations
707
819
 
708
820
  Copies value to system clipboard with `pbcopy` on macOS and `xclip` on Linux
709
821
 
@@ -722,6 +834,30 @@ dv pokemon.csv
722
834
 
723
835
  # Chain with other command and specify input file format
724
836
  cut -d',' -f1,2,3 pokemon.csv | dv -f csv
837
+
838
+ # Work with gzipped files
839
+ dv large_dataset.csv.gz
840
+
841
+ # CSV file without header row
842
+ dv -H raw_data.csv
843
+
844
+ # Skip type inference for faster loading
845
+ dv -I huge_file.csv
846
+
847
+ # Skip first 5 lines (comments, metadata)
848
+ dv -L 5 data_with_metadata.csv
849
+
850
+ # Skip 1 row after header (units row)
851
+ dv -K 1 data_with_units.csv
852
+
853
+ # Complex CSV with comments and units row
854
+ dv -L 3 -K 1 -I messy_scientific_data.csv
855
+
856
+ # Combine all options: skip lines, skip after header, no header, no inference, gzipped
857
+ dv -L 2 -K 1 -H -I complex_data.csv.gz
858
+
859
+ # Process compressed data from stdin with line skipping
860
+ zcat compressed_data.csv.gz | dv -f csv -L 2
725
861
  ```
726
862
 
727
863
  ### Multi-File/Tab Examples
@@ -730,8 +866,8 @@ cut -d',' -f1,2,3 pokemon.csv | dv -f csv
730
866
  # Open multiple sheets as tabs in a single Excel
731
867
  dv sales.xlsx
732
868
 
733
- # Open multiple files as tabs
734
- dv pokemon.csv titanic.csv
869
+ # Open multiple files as tabs (including gzipped)
870
+ dv pokemon.csv titanic.csv large_data.csv.gz
735
871
 
736
872
  # Start with one file, then open others using Ctrl+O
737
873
  dv initial_data.csv
@@ -90,6 +90,13 @@ uv run python main.py pokemon.csv
90
90
  # Read from stdin (auto-detects format; defaults to TSV if not recognized)
91
91
  cat data.tsv | dv
92
92
  dv < data.tsv
93
+
94
+ # Gzipped files are supported
95
+ dv data.csv.gz
96
+ dv large_dataset.tsv.gz
97
+
98
+ # Specify format for gzipped stdin
99
+ zcat data.csv.gz | dv -f csv
93
100
  ```
94
101
 
95
102
  ### Multi-File Usage - Multiple Tabs
@@ -103,6 +110,9 @@ dv file.xlsx
103
110
 
104
111
  # Mix files and stdin (read from stdin, then open file)
105
112
  dv data1.tsv < data2.tsv
113
+
114
+ # Mix regular and gzipped files
115
+ dv data1.csv data2.csv.gz data3.tsv.gz
106
116
  ```
107
117
 
108
118
  When multiple files are opened:
@@ -112,6 +122,67 @@ When multiple files are opened:
112
122
  - Close the current tab with `Ctrl+W`
113
123
  - Each file maintains its own state (edits, sort order, selections, history, etc.)
114
124
 
125
+ ## Command Line Options
126
+
127
+ ```
128
+ usage: dv [-h] [-f {csv,excel,tsv,parquet,json,ndjson}] [-H] [-I] [-L SKIP_LINES] [-K SKIP_ROWS_AFTER_HEADER] [-U NULL [NULL ...]] [files ...]
129
+
130
+ Interactive terminal based viewer/editor for tabular data (e.g., CSV/Excel).
131
+
132
+ positional arguments:
133
+ files Files to view (or read from stdin)
134
+
135
+ options:
136
+ -h, --help show this help message and exit
137
+ -f, --format {csv,excel,tsv,parquet,json,ndjson}
138
+ Specify the format of the input files
139
+ -H, --no-header Specify that input files have no header row
140
+ -I, --no-inferrence Do not infer data types when reading CSV/TSV
141
+ -L, --skip-lines SKIP_LINES
142
+ Skip lines when reading CSV/TSV (default: 0)
143
+ -K, --skip-rows-after-header SKIP_ROWS_AFTER_HEADER
144
+ Skip rows after header when reading CSV/TSV (default: 0)
145
+ -U, --null NULL [NULL ...]
146
+ Values to interpret as null values when reading CSV/TSV
147
+ ```
148
+
149
+ ### CLI Examples
150
+
151
+ ```bash
152
+ # View CSV file without header row
153
+ dv -H data_no_header.csv
154
+
155
+ # Disable type inference for faster loading
156
+ dv -I large_data.csv
157
+
158
+ # Skip first 3 lines of file (e.g., comments, metadata)
159
+ dv -L 3 data_with_comments.csv
160
+
161
+ # Skip 1 row after header (e.g., units row)
162
+ dv -K 1 data_with_units.csv
163
+
164
+ # Treat specific values as null/missing (e.g., 'NA', 'N/A', '-')
165
+ dv -U NA N/A - data.csv
166
+
167
+ # Multiple null values with different formats
168
+ dv -U NULL NA "" "Not Available" messy_data.csv
169
+
170
+ # Complex CSV with comments and units row
171
+ dv -L 3 -K 1 -I messy_scientific_data.csv
172
+
173
+ # Combine all options: skip lines, skip after header, no header, no inference, gzipped
174
+ dv -L 2 -K 1 -H -I complex_data.csv.gz
175
+
176
+ # Process compressed data from stdin with line skipping
177
+ zcat compressed_data.csv.gz | dv -f csv -L 2
178
+
179
+ # CSV with custom null values and no header
180
+ dv -H -U NA "N/A" "-" raw_data.csv
181
+
182
+ # Skip lines, specify null values, and disable type inference
183
+ dv -L 5 -U NA "" data_with_metadata.csv
184
+ ```
185
+
115
186
  ## Keyboard Shortcuts
116
187
 
117
188
  ### App-Level Controls
@@ -122,7 +193,7 @@ When multiple files are opened:
122
193
  |-----|--------|
123
194
  | `Ctrl+O` | Open file in a new tab |
124
195
  | `Ctrl+W` | Close current tab |
125
- | `Ctrl+Shift+S` | Save all open tabs to Excel file |
196
+ | `Ctrl+A` | Save all open tabs to Excel file |
126
197
  | `>` or `b` | Move to next tab |
127
198
  | `<` | Move to previous tab |
128
199
  | `B` | Toggle tab bar visibility |
@@ -132,7 +203,7 @@ When multiple files are opened:
132
203
 
133
204
  | Key | Action |
134
205
  |-----|--------|
135
- | `Ctrl+H` | Toggle help panel |
206
+ | `F1` | Toggle help panel |
136
207
  | `k` | Cycle through themes |
137
208
 
138
209
  ---
@@ -150,6 +221,8 @@ When multiple files are opened:
150
221
  | `Home` / `End` | Jump to first/last column in current row |
151
222
  | `Ctrl + Home` / `Ctrl + End` | Jump to top/bottom in current page |
152
223
  | `PageDown` / `PageUp` | Scroll down/up one page |
224
+ | `Ctrl+F` | Page down |
225
+ | `Ctrl+B` | Page up |
153
226
 
154
227
  #### Viewing & Display
155
228
 
@@ -161,6 +234,7 @@ When multiple files are opened:
161
234
  | `S` | Show statistics for entire dataframe |
162
235
  | `K` | Cycle cursor type: cell → row → column → cell |
163
236
  | `~` | Toggle row labels |
237
+ | `_` (underscore) | Expand column to full width |
164
238
 
165
239
  #### Data Editing
166
240
 
@@ -173,8 +247,6 @@ When multiple files are opened:
173
247
  | `a` | Add empty column after current |
174
248
  | `A` | Add column with name and value/expression |
175
249
  | `-` (minus) | Delete current column |
176
- | `_` (underscore) | Delete current column and all columns after |
177
- | `Ctrl+-` | Delete current column and all columns before |
178
250
  | `x` | Delete current row |
179
251
  | `X` | Delete current row and all rows below |
180
252
  | `Ctrl+X` | Delete current row and all rows above |
@@ -202,12 +274,19 @@ When multiple files are opened:
202
274
  | `v` | View only rows by selected rows and/or matches or cursor value |
203
275
  | `V` | View only rows by expression |
204
276
 
277
+ #### SQL Interface
278
+
279
+ | Key | Action |
280
+ |-----|--------|
281
+ | `l` | Simple SQL interface (select columns & WHERE clause) |
282
+ | `L` | Advanced SQL interface (full SQL queries) |
283
+
205
284
  #### Find & Replace
206
285
 
207
286
  | Key | Action |
208
287
  |-----|--------|
209
- | `f` | Find across all columns with cursor value |
210
- | `Ctrl+F` | Find across all columns with expression |
288
+ | `;` | Find across all columns with cursor value |
289
+ | `:` | Find across all columns with expression |
211
290
  | `r` | Find and replace in current column (interactive or replace all) |
212
291
  | `R` | Find and replace across all columns (interactive or replace all) |
213
292
 
@@ -283,8 +362,8 @@ The application provides multiple search modes for different use cases:
283
362
  **Find Operations** - Find by value/expression:
284
363
  - **`/` - Column Find**: Find cursor value within current column
285
364
  - **`?` - Column Expression Find**: Open dialog to search current column with expression
286
- - **`f` - Global Find**: Find cursor value across all columns
287
- - **`Ctrl+f` - Global Expression Find**: Open dialog to search all columns with expression
365
+ - **`;` - Global Find**: Find cursor value across all columns
366
+ - **`:` - Global Expression Find**: Open dialog to search all columns with expression
288
367
 
289
368
  **Selection & Filtering**:
290
369
  - **`'` - Toggle Row Selection**: Select/deselect current row (marks it for filtering)
@@ -664,7 +743,40 @@ Press `@` to make URLs in the current column clickable:
664
743
  - **Scans** all cells in the current column for URLs starting with `http://` or `https://`
665
744
  - **Applies** link styling to make them clickable and dataframe remains unchanged
666
745
 
667
- ### 19. Clipboard Operations
746
+ ### 19. SQL Interface
747
+
748
+ The SQL interface provides two modes for querying your dataframe:
749
+
750
+ #### Simple SQL Interface (`l`)
751
+ Select specific columns and apply WHERE conditions without writing full SQL:
752
+ - Choose which columns to include in results
753
+ - Specify WHERE clause for filtering
754
+ - Ideal for quick filtering and column selection
755
+
756
+ #### Advanced SQL Interface (`L`)
757
+ Execute complete SQL queries for advanced data manipulation:
758
+ - Write full SQL queries with standard [SQL syntax](https://docs.pola.rs/api/python/stable/reference/sql/index.html)
759
+ - Support for JOINs, GROUP BY, aggregations, and more
760
+ - Access to all SQL capabilities for complex transformations
761
+ - Always use `self` as the table name
762
+
763
+ **Examples:**
764
+ ```sql
765
+ -- Filter and select specific rows and/or columns
766
+ SELECT name, age FROM self WHERE age > 30
767
+
768
+ -- Aggregate with GROUP BY
769
+ SELECT department, COUNT(*) as count, AVG(salary) as avg_salary
770
+ FROM self
771
+ GROUP BY department
772
+
773
+ -- Complex filtering with multiple conditions
774
+ SELECT *
775
+ FROM self
776
+ WHERE (age > 25 AND salary > 50000) OR department = 'Management'
777
+ ```
778
+
779
+ ### 20. Clipboard Operations
668
780
 
669
781
  Copies value to system clipboard with `pbcopy` on macOS and `xclip` on Linux
670
782
 
@@ -683,6 +795,30 @@ dv pokemon.csv
683
795
 
684
796
  # Chain with other command and specify input file format
685
797
  cut -d',' -f1,2,3 pokemon.csv | dv -f csv
798
+
799
+ # Work with gzipped files
800
+ dv large_dataset.csv.gz
801
+
802
+ # CSV file without header row
803
+ dv -H raw_data.csv
804
+
805
+ # Skip type inference for faster loading
806
+ dv -I huge_file.csv
807
+
808
+ # Skip first 5 lines (comments, metadata)
809
+ dv -L 5 data_with_metadata.csv
810
+
811
+ # Skip 1 row after header (units row)
812
+ dv -K 1 data_with_units.csv
813
+
814
+ # Complex CSV with comments and units row
815
+ dv -L 3 -K 1 -I messy_scientific_data.csv
816
+
817
+ # Combine all options: skip lines, skip after header, no header, no inference, gzipped
818
+ dv -L 2 -K 1 -H -I complex_data.csv.gz
819
+
820
+ # Process compressed data from stdin with line skipping
821
+ zcat compressed_data.csv.gz | dv -f csv -L 2
686
822
  ```
687
823
 
688
824
  ### Multi-File/Tab Examples
@@ -691,8 +827,8 @@ cut -d',' -f1,2,3 pokemon.csv | dv -f csv
691
827
  # Open multiple sheets as tabs in a single Excel
692
828
  dv sales.xlsx
693
829
 
694
- # Open multiple files as tabs
695
- dv pokemon.csv titanic.csv
830
+ # Open multiple files as tabs (including gzipped)
831
+ dv pokemon.csv titanic.csv large_data.csv.gz
696
832
 
697
833
  # Start with one file, then open others using Ctrl+O
698
834
  dv initial_data.csv
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "dataframe-textual"
7
- version = "1.2.0"
7
+ version = "1.4.0"
8
8
  description = "Interactive terminal viewer/editor for tabular data"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -34,7 +34,7 @@ classifiers = [
34
34
  ]
35
35
  dependencies = [
36
36
  "polars>=1.34.0",
37
- "textual>=6.5.0",
37
+ "textual[syntax]>=6.5.0",
38
38
  ]
39
39
 
40
40
  [project.urls]
@@ -69,4 +69,5 @@ dev = [
69
69
  ]
70
70
 
71
71
  [project.scripts]
72
+ dataframe-textual = "dataframe_textual.__main__:main"
72
73
  dv = "dataframe_textual.__main__:main"
@@ -0,0 +1,90 @@
1
+ """Entry point for running DataFrameViewer as a module."""
2
+
3
+ import argparse
4
+ import sys
5
+ from pathlib import Path
6
+
7
+ from .common import SUPPORTED_FORMATS, load_dataframe
8
+ from .data_frame_viewer import DataFrameViewer
9
+
10
+
11
+ def cli() -> argparse.Namespace:
12
+ """Parse command-line arguments.
13
+
14
+ Determines input files or stdin and validates file existence
15
+ """
16
+ parser = argparse.ArgumentParser(
17
+ prog="dv",
18
+ description="Interactive terminal based viewer/editor for tabular data (e.g., CSV/Excel).",
19
+ formatter_class=argparse.RawDescriptionHelpFormatter,
20
+ epilog="Examples:\n"
21
+ " %(prog)s data.csv\n"
22
+ " %(prog)s file1.csv file2.csv file3.csv\n"
23
+ " %(prog)s data.xlsx (opens each sheet in separate tab)\n"
24
+ " cat data.csv | %(prog)s --format csv\n",
25
+ )
26
+ parser.add_argument("files", nargs="*", help="Files to view (or read from stdin)")
27
+ parser.add_argument(
28
+ "-f",
29
+ "--format",
30
+ choices=SUPPORTED_FORMATS,
31
+ help="Specify the format of the input files (csv, excel, tsv etc.)",
32
+ )
33
+ parser.add_argument(
34
+ "-H",
35
+ "--no-header",
36
+ action="store_true",
37
+ help="Specify that input files have no header row when reading CSV/TSV",
38
+ )
39
+ parser.add_argument(
40
+ "-I", "--no-inferrence", action="store_true", help="Do not infer data types when reading CSV/TSV"
41
+ )
42
+ parser.add_argument(
43
+ "-C", "--comment-prefix", nargs="?", const="#", help="Comment lines are skipped when reading CSV/TSV"
44
+ )
45
+ parser.add_argument("-L", "--skip-lines", type=int, default=0, help="Skip lines when reading CSV/TSV")
46
+ parser.add_argument(
47
+ "-K", "--skip-rows-after-header", type=int, default=0, help="Skip rows after header when reading CSV/TSV"
48
+ )
49
+ parser.add_argument("-U", "--null", nargs="+", help="Values to interpret as null values when reading CSV/TSV")
50
+
51
+ args = parser.parse_args()
52
+ if args.files is None:
53
+ args.files = []
54
+
55
+ # Check if reading from stdin (pipe or redirect)
56
+ if not sys.stdin.isatty():
57
+ args.files.append("-")
58
+ else:
59
+ # Validate all files exist
60
+ for filename in args.files:
61
+ if not Path(filename).exists():
62
+ print(f"File not found: {filename}")
63
+ sys.exit(1)
64
+
65
+ if not args.files:
66
+ parser.print_help()
67
+ sys.exit(1)
68
+
69
+ return args
70
+
71
+
72
+ def main() -> None:
73
+ """Run the DataFrame Viewer application."""
74
+ args = cli()
75
+ sources = load_dataframe(
76
+ args.files,
77
+ file_format=args.format,
78
+ has_header=not args.no_header,
79
+ infer_schema=not args.no_inferrence,
80
+ comment_prefix=args.comment_prefix,
81
+ skip_lines=args.skip_lines,
82
+ skip_rows_after_header=args.skip_rows_after_header,
83
+ null_values=args.null,
84
+ )
85
+ app = DataFrameViewer(*sources)
86
+ app.run()
87
+
88
+
89
+ if __name__ == "__main__":
90
+ main()