viewinline 0.2.2__tar.gz → 0.2.3__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,3 +1,36 @@
1
+ Metadata-Version: 2.4
2
+ Name: viewinline
3
+ Version: 0.2.3
4
+ Summary: Quick look geospatial viewer for the terminal, with inline image previews
5
+ Project-URL: Homepage, https://github.com/nkeikon/viewinline
6
+ Project-URL: Repository, https://github.com/nkeikon/viewinline
7
+ Project-URL: Issues, https://github.com/nkeikon/viewinline/issues
8
+ Author: Keiko Nomura
9
+ License: Apache-2.0
10
+ License-File: LICENSE
11
+ Requires-Python: >=3.9
12
+ Requires-Dist: geopandas
13
+ Requires-Dist: matplotlib
14
+ Requires-Dist: numpy
15
+ Requires-Dist: pandas
16
+ Requires-Dist: pillow
17
+ Requires-Dist: pyogrio
18
+ Requires-Dist: rasterio
19
+ Provides-Extra: all
20
+ Requires-Dist: duckdb; extra == 'all'
21
+ Requires-Dist: h5py; extra == 'all'
22
+ Requires-Dist: netcdf4; extra == 'all'
23
+ Requires-Dist: pyarrow; extra == 'all'
24
+ Provides-Extra: hdf5
25
+ Requires-Dist: h5py; extra == 'hdf5'
26
+ Provides-Extra: netcdf
27
+ Requires-Dist: netcdf4; extra == 'netcdf'
28
+ Provides-Extra: parquet
29
+ Requires-Dist: pyarrow; extra == 'parquet'
30
+ Provides-Extra: sql
31
+ Requires-Dist: duckdb; extra == 'sql'
32
+ Description-Content-Type: text/markdown
33
+
1
34
  # viewinline
2
35
  [![Downloads](https://static.pepy.tech/badge/viewinline)](https://pepy.tech/project/viewinline)
3
36
  [![PyPI version](https://img.shields.io/pypi/v/viewinline)](https://pypi.org/project/viewinline/)
@@ -17,7 +50,7 @@ Particularly useful on HPC systems and remote servers accessed via SSH. Images r
17
50
 
18
51
  This tool combines the core display logic of `viewtif` and `viewgeom`, but is **non-interactive**: you can't zoom, pan, or switch colormaps on the fly. Instead, you control everything through command-line options (e.g. --display, --color-by, --colormap).
19
52
 
20
- It uses the iTerm2 inline image protocol (OSC 1337) to render previews. In incompatible terminals, the escape codes are silently ignored with no errors or crashes.
53
+ It uses the iTerm2 inline image protocol (OSC 1337) in supported terminals, and falls back to `chafa` in others, which displays real high-res images in terminals like kitty and Ghostty, and colored block-art (ASCII art) previews in Terminal.app, VS Code, and most Linux terminals. Without `chafa` installed, non-iTerm2-family terminals show an info message instead.
21
54
 
22
55
  ## Installation
23
56
  Requires Python 3.9 or later.
@@ -63,18 +96,30 @@ viewinline data.geoparquet --table --where "POP > 100000" --sort POP --desc
63
96
 
64
97
  ## Compatible terminals
65
98
 
66
- The iTerm2 inline image protocol (OSC 1337) is supported by:
99
+ Native (no extra install required): images render via the iTerm2 inline image protocol on:
67
100
 
68
101
  - **iTerm2** (macOS)
69
102
  - **WezTerm** (cross-platform)
70
103
  - **Konsole** (Linux/KDE)
71
104
  - **Rio**, **Contour** (cross-platform)
72
105
 
73
- **Not compatible:** Mac Terminal, GNOME Terminal, Kitty (uses different protocol), Ghostty, Alacritty
106
+ Via `chafa` (recommended for everyone else): install chafa and viewinline works in nearly every terminal:
107
+ - kitty, Ghostty, foot — real high-resolution images via the kitty graphics protocol or sixel
108
+ - Terminal.app, VS Code, GNOME Terminal, Alacritty, Warp, Hyper — colored block-art previews with 24-bit color
109
+
110
+ Install chafa once (it's a system binary, available across all conda/virtualenv environments):
111
+
112
+ ```
113
+ brew install chafa # macOS
114
+ sudo apt install chafa # Debian/Ubuntu
115
+ sudo dnf install chafa # Fedora
116
+ ```
117
+ Without chafa, terminals outside the native list above show an info message instead of an image.
118
+ You can also force the chafa path on any terminal by setting `INLINE_VIEWER_ENGINE=chafa`.
74
119
 
75
120
  **SSH/HPC usage:** Works over SSH when connecting from a compatible terminal. Images render on your local machine, not the remote server. No X11 forwarding or VNC required.
76
121
 
77
- **tmux/screen:** Inline images don't work inside tmux or screen sessions, even with `allow-passthrough on`. Use a plain terminal tab.
122
+ **tmux/screen:** Inline images work inside tmux only when the outer terminal is iTerm2 (or WezTerm/Konsole/Rio/Contour). In tmux with other outer terminals (kitty, Terminal.app, etc.), viewinline displays ASCII art previews instead of full-quality images.
78
123
 
79
124
  **Fallback:** In terminals that do not support inline images, you can fallback to ASCII art by installing [`chafa`](https://hpjansson.org/chafa/) command-line tool. Install `chafa` with your package manager (e.g. `brew install chafa` or `sudo apt install chafa`). You can also force the use of `chafa` by setting the environment variable `INLINE_VIEWER_ENGINE=chafa`.
80
125
 
@@ -137,6 +182,7 @@ The iTerm2 inline image protocol (OSC 1337) is supported by:
137
182
  - `numpy`, `pandas` — data handling
138
183
 
139
184
  **Optional dependencies:**
185
+ - `chafa` — strongly recommended for terminal coverage beyond iTerm2/WezTerm/Konsole/Rio/Contour. System binary, not a Python package. See "Terminal support" above for install instructions.
140
186
  - `duckdb` — required for `--where`, `--sort`, `--sql`, `--limit` with filtering
141
187
  ```bash
142
188
  pip install duckdb
@@ -1,33 +1,3 @@
1
- Metadata-Version: 2.4
2
- Name: viewinline
3
- Version: 0.2.2
4
- Summary: Quick look geospatial viewer for iTerm2 compatible terminals
5
- Project-URL: Homepage, https://github.com/nkeikon/viewinline
6
- Project-URL: Repository, https://github.com/nkeikon/viewinline
7
- Project-URL: Issues, https://github.com/nkeikon/viewinline/issues
8
- Author: Keiko Nomura
9
- License: Apache-2.0
10
- License-File: LICENSE
11
- Requires-Python: >=3.9
12
- Requires-Dist: geopandas
13
- Requires-Dist: matplotlib
14
- Requires-Dist: numpy
15
- Requires-Dist: pandas
16
- Requires-Dist: pillow
17
- Requires-Dist: pyogrio
18
- Requires-Dist: rasterio
19
- Provides-Extra: all
20
- Requires-Dist: duckdb; extra == 'all'
21
- Requires-Dist: h5py; extra == 'all'
22
- Requires-Dist: pyarrow; extra == 'all'
23
- Provides-Extra: hdf5
24
- Requires-Dist: h5py; extra == 'hdf5'
25
- Provides-Extra: parquet
26
- Requires-Dist: pyarrow; extra == 'parquet'
27
- Provides-Extra: sql
28
- Requires-Dist: duckdb; extra == 'sql'
29
- Description-Content-Type: text/markdown
30
-
31
1
  # viewinline
32
2
  [![Downloads](https://static.pepy.tech/badge/viewinline)](https://pepy.tech/project/viewinline)
33
3
  [![PyPI version](https://img.shields.io/pypi/v/viewinline)](https://pypi.org/project/viewinline/)
@@ -47,7 +17,7 @@ Particularly useful on HPC systems and remote servers accessed via SSH. Images r
47
17
 
48
18
  This tool combines the core display logic of `viewtif` and `viewgeom`, but is **non-interactive**: you can't zoom, pan, or switch colormaps on the fly. Instead, you control everything through command-line options (e.g. --display, --color-by, --colormap).
49
19
 
50
- It uses the iTerm2 inline image protocol (OSC 1337) to render previews. In incompatible terminals, the escape codes are silently ignored with no errors or crashes.
20
+ It uses the iTerm2 inline image protocol (OSC 1337) in supported terminals, and falls back to `chafa` in others, which displays real high-res images in terminals like kitty and Ghostty, and colored block-art (ASCII art) previews in Terminal.app, VS Code, and most Linux terminals. Without `chafa` installed, non-iTerm2-family terminals show an info message instead.
51
21
 
52
22
  ## Installation
53
23
  Requires Python 3.9 or later.
@@ -93,18 +63,30 @@ viewinline data.geoparquet --table --where "POP > 100000" --sort POP --desc
93
63
 
94
64
  ## Compatible terminals
95
65
 
96
- The iTerm2 inline image protocol (OSC 1337) is supported by:
66
+ Native (no extra install required): images render via the iTerm2 inline image protocol on:
97
67
 
98
68
  - **iTerm2** (macOS)
99
69
  - **WezTerm** (cross-platform)
100
70
  - **Konsole** (Linux/KDE)
101
71
  - **Rio**, **Contour** (cross-platform)
102
72
 
103
- **Not compatible:** Mac Terminal, GNOME Terminal, Kitty (uses different protocol), Ghostty, Alacritty
73
+ Via `chafa` (recommended for everyone else): install chafa and viewinline works in nearly every terminal:
74
+ - kitty, Ghostty, foot — real high-resolution images via the kitty graphics protocol or sixel
75
+ - Terminal.app, VS Code, GNOME Terminal, Alacritty, Warp, Hyper — colored block-art previews with 24-bit color
76
+
77
+ Install chafa once (it's a system binary, available across all conda/virtualenv environments):
78
+
79
+ ```
80
+ brew install chafa # macOS
81
+ sudo apt install chafa # Debian/Ubuntu
82
+ sudo dnf install chafa # Fedora
83
+ ```
84
+ Without chafa, terminals outside the native list above show an info message instead of an image.
85
+ You can also force the chafa path on any terminal by setting `INLINE_VIEWER_ENGINE=chafa`.
104
86
 
105
87
  **SSH/HPC usage:** Works over SSH when connecting from a compatible terminal. Images render on your local machine, not the remote server. No X11 forwarding or VNC required.
106
88
 
107
- **tmux/screen:** Inline images don't work inside tmux or screen sessions, even with `allow-passthrough on`. Use a plain terminal tab.
89
+ **tmux/screen:** Inline images work inside tmux only when the outer terminal is iTerm2 (or WezTerm/Konsole/Rio/Contour). In tmux with other outer terminals (kitty, Terminal.app, etc.), viewinline displays ASCII art previews instead of full-quality images.
108
90
 
109
91
  **Fallback:** In terminals that do not support inline images, you can fallback to ASCII art by installing [`chafa`](https://hpjansson.org/chafa/) command-line tool. Install `chafa` with your package manager (e.g. `brew install chafa` or `sudo apt install chafa`). You can also force the use of `chafa` by setting the environment variable `INLINE_VIEWER_ENGINE=chafa`.
110
92
 
@@ -167,6 +149,7 @@ The iTerm2 inline image protocol (OSC 1337) is supported by:
167
149
  - `numpy`, `pandas` — data handling
168
150
 
169
151
  **Optional dependencies:**
152
+ - `chafa` — strongly recommended for terminal coverage beyond iTerm2/WezTerm/Konsole/Rio/Contour. System binary, not a Python package. See "Terminal support" above for install instructions.
170
153
  - `duckdb` — required for `--where`, `--sort`, `--sql`, `--limit` with filtering
171
154
  ```bash
172
155
  pip install duckdb
@@ -4,8 +4,8 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "viewinline"
7
- version = "0.2.2"
8
- description = "Quick look geospatial viewer for iTerm2 compatible terminals"
7
+ version = "0.2.3"
8
+ description = "Quick look geospatial viewer for the terminal, with inline image previews"
9
9
  readme = "README.md"
10
10
  license = { text = "Apache-2.0" }
11
11
  authors = [
@@ -22,12 +22,12 @@ dependencies = [
22
22
  "pyogrio",
23
23
  "pandas"
24
24
  ]
25
-
26
25
  [project.optional-dependencies]
27
26
  sql = ["duckdb"]
28
27
  parquet = ["pyarrow"]
29
28
  hdf5 = ["h5py"]
30
- all = ["duckdb", "pyarrow", "h5py"]
29
+ netcdf = ["netCDF4"]
30
+ all = ["duckdb", "pyarrow", "h5py", "netCDF4"]
31
31
 
32
32
  [project.scripts]
33
33
  viewinline = "viewinline.viewinline:main"
@@ -33,7 +33,7 @@ import warnings
33
33
  warnings.filterwarnings("ignore", message="More than one layer found", category=UserWarning)
34
34
  warnings.filterwarnings("ignore", message="Dataset has no geotransform", category=UserWarning)
35
35
 
36
- __version__ = "0.2.2"
36
+ __version__ = "0.2.3"
37
37
 
38
38
  AVAILABLE_COLORMAPS = [
39
39
  "viridis", "inferno", "magma", "plasma",
@@ -41,12 +41,61 @@ AVAILABLE_COLORMAPS = [
41
41
  "Spectral", "cubehelix", "tab10", "turbo"
42
42
  ]
43
43
 
44
+ # Terminals that don't natively support the iTerm2 OSC 1337 inline image
45
+ # protocol. Output for these is routed through chafa instead.
46
+ #
47
+ # Note: presence in this list does NOT mean "no images." Chafa auto-detects
48
+ # the terminal and picks the best output:
49
+ # - kitty (xterm-kitty) → real images via kitty graphics protocol
50
+ # - some others (e.g. foot, Ghostty) → may render real images via sixel
51
+ # or kitty protocol depending on chafa's detection
52
+ # - most others → Unicode block-art preview with 24-bit color
53
+ # (Terminal.app, VS Code, GNOME Terminal, Alacritty, Warp, etc.)
54
+ # Only terminals without chafa installed see no rendering at all.
55
+
44
56
  _TERMINALS_WITHOUT_IMAGES = [
45
- 'unknown', 'cygwin', 'tmux', 'screen',
46
- 'vscode', 'xterm', 'rxvt', 'alacritty', 'foot', 'st', 'kitty',
47
- 'gnome-terminal', 'xfce4-terminal', 'lxterminal', 'terminator',
48
- 'tilix', 'hyper', 'windows terminal', 'putty', 'sakura',
49
- 'terminology', 'eterm', 'guake', 'tilda', 'deepin-terminal',
57
+ # macOS
58
+ 'Apple_Terminal', # $TERM_PROGRAM for Terminal.app
59
+
60
+ # kitty (renders real images via chafa → kitty graphics protocol)
61
+ 'xterm-kitty', # $TERM in kitty
62
+
63
+ # tmux / screen (TERM strings; $TMUX env var also signals tmux)
64
+ 'screen', 'screen-256color',
65
+ 'tmux', 'tmux-256color',
66
+
67
+ # Editors / IDE terminals
68
+ 'vscode', # $TERM_PROGRAM in VS Code integrated terminal
69
+
70
+ # Cross-platform terminals known not to support OSC 1337
71
+ 'alacritty',
72
+ 'foot', # supports sixel → chafa renders real images
73
+ 'ghostty', 'xterm-ghostty',
74
+ 'WarpTerminal', # $TERM_PROGRAM in Warp
75
+ 'Hyper', # $TERM_PROGRAM in Hyper
76
+
77
+ # Generic / legacy
78
+ 'unknown',
79
+ 'cygwin',
80
+ 'rxvt', 'rxvt-unicode', 'rxvt-unicode-256color',
81
+ 'st-256color', # suckless st
82
+
83
+ # Linux desktop terminals (most are VTE-based, no OSC 1337)
84
+ 'gnome-terminal',
85
+ 'xfce4-terminal',
86
+ 'lxterminal',
87
+ 'terminator',
88
+ 'tilix',
89
+ 'sakura',
90
+ 'terminology',
91
+ 'guake',
92
+ 'tilda',
93
+ 'deepin-terminal',
94
+ 'eterm',
95
+
96
+ # Windows
97
+ 'putty',
98
+ 'Windows Terminal',
50
99
  ]
51
100
 
52
101
  def detect_terminal() -> dict[str, str]:
@@ -136,40 +185,57 @@ def show_inline_image(image_array: np.ndarray, display_scale = None, is_vector:
136
185
  if _TERMINAL_SUPPORTS_IMAGES:
137
186
  sys.stdout.write(f"\033]1337;File=inline=1;width={width_pct}%:{encoded}\a\n")
138
187
  else:
188
+ # if is_chafa_available():
189
+ # chafa_output = subprocess.check_output(
190
+ # ["chafa", "-"],
191
+ # input=image_bytes
192
+ # ).decode()
193
+
194
+ # sys.stdout.write(f"\n{chafa_output}\a\n")
139
195
  if is_chafa_available():
196
+ # Inside tmux, force chafa to use block-art symbols instead of
197
+ # graphics protocols. Tmux mangles kitty graphics and sixel
198
+ # protocols, producing dot-character garbage on screen. Block-art
199
+ # passes through tmux reliably on every outer terminal.
200
+ chafa_args = ["chafa", "-"]
201
+ if os.environ.get("TMUX"):
202
+ chafa_args = ["chafa", "-f", "symbols", "-"]
140
203
  chafa_output = subprocess.check_output(
141
- ["chafa", "-"],
204
+ chafa_args,
142
205
  input=image_bytes
143
206
  ).decode()
144
207
 
145
208
  sys.stdout.write(f"\n{chafa_output}\a\n")
209
+
146
210
  else:
147
211
  sys.stdout.write(f"[INFO] Use supported terminal or install 'chafa' for ascii art fallback. Detected: {_TERMINAL_INFO}\n")
148
212
 
149
213
  sys.stdout.flush()
150
214
 
151
-
152
- def show_image_auto(img: np.ndarray, display_scale = None, is_vector: bool = False) -> None:
153
- """Attempt inline image display. No fallbacks, no detection.
215
+ def show_image_auto(img: np.ndarray, display_scale=None, is_vector: bool = False) -> None:
216
+ """Render an image inline, with chafa fallback for non-iTerm2 terminals.
154
217
 
155
- Just sends the iTerm2 inline image escape sequence. If the terminal supports it,
156
- great. If not, the escape codes are ignored and nothing happens.
218
+ Cascade:
219
+ 1. If terminal supports OSC 1337 emit iTerm2 inline image sequence.
220
+ 2. Else if chafa is installed → pipe through chafa (which auto-detects
221
+ and emits the terminal's native graphics protocol or block-art).
222
+ 3. Else → print an info message suggesting chafa installation.
157
223
 
224
+ The branching happens inside show_inline_image(); this wrapper handles
225
+ status messaging and exception safety.
158
226
  """
159
- if os.environ.get("TMUX"):
160
- print("[WARN] Inside tmux — inline images won't display even with allow-passthrough on (known iTerm2/tmux issue). Use a plain terminal tab.")
161
- return
162
-
163
227
  try:
164
228
  show_inline_image(img, display_scale, is_vector)
165
- print("[VIEW] Image sent — visible in compatible terminals")
229
+ if _TERMINAL_SUPPORTS_IMAGES:
230
+ print("[VIEW] Image rendered")
231
+ elif is_chafa_available():
232
+ print("[VIEW] Rendered via chafa")
233
+ # If neither path applies, show_inline_image already printed the info message
166
234
  except Exception as e:
167
- # If image encoding fails, print error but don't crash
168
- print(f"[ERROR] Failed to encode image: {e}")
235
+ print(f"[ERROR] Failed to render image: {e}")
169
236
  import traceback
170
237
  traceback.print_exc()
171
238
 
172
-
173
239
  def resize_to_terminal(img: np.ndarray) -> tuple[np.ndarray, float]:
174
240
  """Resize image to fit terminal window (approx 8x16 pixel cells)."""
175
241
  cols, rows = shutil.get_terminal_size((100, 40))
@@ -593,6 +659,7 @@ def render_raster(paths: list[str], args) -> None:
593
659
  # Handle NetCDF/HDF with subdatasets
594
660
  if path.lower().endswith(('.nc', '.hdf', '.hdf5', '.h5')):
595
661
  try:
662
+
596
663
  with rasterio.open(path) as src:
597
664
  subdatasets = src.subdatasets
598
665
 
File without changes
File without changes