nbcat 0.13.2__py3-none-any.whl → 1.0.0__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.
- nbcat/__init__.py +1 -1
- nbcat/image.py +18 -23
- nbcat/main.py +5 -3
- nbcat/markdown.py +2 -5
- {nbcat-0.13.2.dist-info → nbcat-1.0.0.dist-info}/METADATA +35 -11
- nbcat-1.0.0.dist-info/RECORD +14 -0
- nbcat-0.13.2.dist-info/RECORD +0 -14
- {nbcat-0.13.2.dist-info → nbcat-1.0.0.dist-info}/WHEEL +0 -0
- {nbcat-0.13.2.dist-info → nbcat-1.0.0.dist-info}/entry_points.txt +0 -0
- {nbcat-0.13.2.dist-info → nbcat-1.0.0.dist-info}/licenses/LICENSE +0 -0
nbcat/__init__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "0.
|
1
|
+
__version__ = "1.0.0"
|
nbcat/image.py
CHANGED
@@ -1,31 +1,26 @@
|
|
1
|
-
import base64
|
2
1
|
import shutil
|
3
2
|
from io import BytesIO
|
4
|
-
from platform import system
|
5
3
|
|
6
4
|
from PIL import Image as PilImage
|
7
|
-
from
|
8
|
-
from
|
9
|
-
from
|
5
|
+
from textual_image.renderable import Image
|
6
|
+
from textual_image.renderable.halfcell import Image as HalfcellImage
|
7
|
+
from textual_image.renderable.sixel import Image as SixelImage
|
8
|
+
from textual_image.renderable.tgp import Image as TGPImage
|
9
|
+
from textual_image.renderable.unicode import Image as UnicodeImage
|
10
10
|
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
self.image = PilImage.open(img)
|
16
|
-
self.method = method if system() != "Windows" else "ascii"
|
12
|
+
def render_image(image_content: bytes) -> TGPImage | SixelImage | HalfcellImage | UnicodeImage:
|
13
|
+
"""
|
14
|
+
Render an image from raw byte content and adjusts it to fit the terminal width.
|
17
15
|
|
18
|
-
|
19
|
-
|
20
|
-
renderer.load_image(self.image)
|
21
|
-
width = shutil.get_terminal_size()[0] - 1
|
22
|
-
if self.method == "sixel":
|
23
|
-
width = width * 6
|
16
|
+
Args:
|
17
|
+
image_content (bytes): The raw byte content of the image.
|
24
18
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
19
|
+
Returns
|
20
|
+
-------
|
21
|
+
TGPImage | SixelImage | HalfcellImage | UnicodeImage: A terminal-compatible image
|
22
|
+
object adjusted to the current terminal width.
|
23
|
+
"""
|
24
|
+
image = PilImage.open(BytesIO(image_content))
|
25
|
+
width = min(image.size[0], shutil.get_terminal_size()[0])
|
26
|
+
return Image(image, width=width, height="auto")
|
nbcat/main.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import argparse
|
2
|
+
import base64
|
2
3
|
import sys
|
3
4
|
from pathlib import Path
|
4
5
|
|
@@ -14,6 +15,8 @@ from rich.pretty import Pretty
|
|
14
15
|
from rich.syntax import Syntax
|
15
16
|
from rich.text import Text
|
16
17
|
|
18
|
+
from nbcat.image import render_image
|
19
|
+
|
17
20
|
from . import __version__
|
18
21
|
from .enums import CellType, OutputCellType
|
19
22
|
from .exceptions import (
|
@@ -21,7 +24,6 @@ from .exceptions import (
|
|
21
24
|
NotebookNotFoundError,
|
22
25
|
UnsupportedNotebookTypeError,
|
23
26
|
)
|
24
|
-
from .image import Image
|
25
27
|
from .markdown import Markdown
|
26
28
|
from .pager import Pager
|
27
29
|
from .schemas import Cell, Notebook
|
@@ -94,8 +96,8 @@ def render_cell(cell: Cell) -> RenderableType:
|
|
94
96
|
def _render_raw(input: str) -> Text:
|
95
97
|
return Text(input)
|
96
98
|
|
97
|
-
def _render_image(input: str) ->
|
98
|
-
return
|
99
|
+
def _render_image(input: str) -> RenderableType:
|
100
|
+
return render_image(base64.b64decode(input.replace("\n", "")))
|
99
101
|
|
100
102
|
def _render_json(input: str) -> Pretty:
|
101
103
|
return Pretty(input)
|
nbcat/markdown.py
CHANGED
@@ -10,7 +10,6 @@
|
|
10
10
|
|
11
11
|
from __future__ import annotations
|
12
12
|
|
13
|
-
import base64
|
14
13
|
from pathlib import Path
|
15
14
|
from typing import ClassVar
|
16
15
|
|
@@ -19,7 +18,7 @@ from rich import markdown as md
|
|
19
18
|
from rich.console import Console, ConsoleOptions, RenderResult
|
20
19
|
from rich.text import Text
|
21
20
|
|
22
|
-
from .image import
|
21
|
+
from .image import render_image
|
23
22
|
|
24
23
|
|
25
24
|
class Heading(md.Heading):
|
@@ -53,9 +52,7 @@ class ImageItem(md.ImageItem):
|
|
53
52
|
except requests.RequestException:
|
54
53
|
return super().__rich_console__(console, options)
|
55
54
|
if image_content:
|
56
|
-
|
57
|
-
image = base64.b64encode(image_content).decode("utf-8")
|
58
|
-
return Image(image).__rich_console__(console, options)
|
55
|
+
return render_image(image_content).__rich_console__(console, options)
|
59
56
|
return super().__rich_console__(console, options)
|
60
57
|
|
61
58
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: nbcat
|
3
|
-
Version: 0.
|
3
|
+
Version: 1.0.0
|
4
4
|
Summary: cat for jupyter notebooks
|
5
5
|
Project-URL: Homepage, https://github.com/akopdev/nbcat
|
6
6
|
Project-URL: Repository, https://github.com/akopdev/nbcat
|
@@ -28,14 +28,14 @@ License: MIT License
|
|
28
28
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
29
29
|
SOFTWARE.
|
30
30
|
License-File: LICENSE
|
31
|
-
Requires-Python: >=3.
|
31
|
+
Requires-Python: >=3.10
|
32
32
|
Requires-Dist: argcomplete
|
33
33
|
Requires-Dist: markdownify
|
34
34
|
Requires-Dist: pydantic
|
35
35
|
Requires-Dist: requests
|
36
36
|
Requires-Dist: rich
|
37
37
|
Requires-Dist: textual
|
38
|
-
Requires-Dist:
|
38
|
+
Requires-Dist: textual-image[textual]
|
39
39
|
Provides-Extra: dev
|
40
40
|
Requires-Dist: pytest; extra == 'dev'
|
41
41
|
Requires-Dist: pytest-cov; extra == 'dev'
|
@@ -44,9 +44,9 @@ Requires-Dist: pytest-responses; extra == 'dev'
|
|
44
44
|
Requires-Dist: ruff; extra == 'dev'
|
45
45
|
Description-Content-Type: text/markdown
|
46
46
|
|
47
|
-
|
47
|
+
<h1 align="center">nbcat: Jupyter notebooks viewer</h1>
|
48
48
|
|
49
|
-
|
49
|
+
[nbcat](https://github.com/akopdev/nbcat) let you preview Jupyter notebooks directly in your terminal. Think of it as `cat`, but for `.ipynb` files.
|
50
50
|
|
51
51
|
<p align="center">
|
52
52
|
<a href="docs/screenshot.png" target="blank"><img src="docs/screenshot.png" width="400" /></a>
|
@@ -58,7 +58,7 @@ Description-Content-Type: text/markdown
|
|
58
58
|
- Very fast and lightweight with minimal dependencies.
|
59
59
|
- Preview remote notebooks without downloading them.
|
60
60
|
- Enable paginated view mode with keyboard navigation (similar to `less`).
|
61
|
-
- Supports image rendering
|
61
|
+
- Supports image rendering in high resolution
|
62
62
|
- Supports for all Jupyter notebook versions, including old legacy formats.
|
63
63
|
|
64
64
|
## Motivation
|
@@ -74,12 +74,12 @@ Please note, that `nbcat` doesn't aim to replace JupyterLab. If you need a full-
|
|
74
74
|
## Installation
|
75
75
|
|
76
76
|
```bash
|
77
|
-
# Install from PyPI
|
78
|
-
pip install nbcat
|
77
|
+
# Install from PyPI (recommended)
|
78
|
+
$ pip install nbcat
|
79
79
|
|
80
80
|
# Install via Homebrew
|
81
|
-
brew tab akopdev/formulas/nbcat
|
82
|
-
brew install nbcat
|
81
|
+
$ brew tab akopdev/formulas/nbcat
|
82
|
+
$ brew install nbcat
|
83
83
|
```
|
84
84
|
|
85
85
|
## Quickstart
|
@@ -93,13 +93,37 @@ You can pass URLs as well.
|
|
93
93
|
```bash
|
94
94
|
$ nbcat https://raw.githubusercontent.com/akopdev/nbcat/refs/heads/main/tests/assets/test4.ipynb
|
95
95
|
```
|
96
|
+
In most cases system `less` will render images in low resolution. Consider using an internal pager instead:
|
96
97
|
|
97
|
-
|
98
|
+
```bash
|
99
|
+
$ nbcat notebook.ipynb --page
|
100
|
+
```
|
101
|
+
## Integrations
|
102
|
+
|
103
|
+
`nbcat` is designed to integrate seamlessly with other tools. Here are a few examples of how easily it can be done.
|
104
|
+
|
105
|
+
### FZF (Fuzzy finder)
|
106
|
+
|
107
|
+
List all `.ipynb` files and use `nbcat` to preview them:
|
98
108
|
|
99
109
|
```bash
|
100
110
|
find . -type f -name "*.ipynb" | fzf --preview 'nbcat {}'
|
101
111
|
```
|
102
112
|
|
113
|
+
### Ranger
|
114
|
+
To enable previews in Ranger, add the `ipynb` extension to the `handle_extension` function in `~/.config/ranger/scope.sh`:
|
115
|
+
|
116
|
+
```bash
|
117
|
+
...
|
118
|
+
|
119
|
+
handle_extension() {
|
120
|
+
case "${FILE_EXTENSION_LOWER}" in
|
121
|
+
ipynb)
|
122
|
+
nbcat "${FILE_PATH}" && exit 5
|
123
|
+
exit 1;;
|
124
|
+
...
|
125
|
+
```
|
126
|
+
|
103
127
|
## Testing & Development
|
104
128
|
|
105
129
|
Run the tests:
|
@@ -0,0 +1,14 @@
|
|
1
|
+
nbcat/__init__.py,sha256=J-j-u0itpEFT6irdmWmixQqYMadNl1X91TxUmoiLHMI,22
|
2
|
+
nbcat/enums.py,sha256=Fn8PIcLl_uY4nQIs1EUvmKTwfhNUIZgmhRFiCSJk9wk,411
|
3
|
+
nbcat/exceptions.py,sha256=Ho7LQz9K70VtIMDNtAwuAtGmb-lFKxGxSj7MN3-EpDA,321
|
4
|
+
nbcat/image.py,sha256=DSTdYpsVtsQTZj_TU9BZ0vrOmxqOoYfJoJsZ6EonIlM,982
|
5
|
+
nbcat/main.py,sha256=8Vf-Cph_D35XT17HKvW8XfKmEosR1FVZIKHCtJj2JNw,6806
|
6
|
+
nbcat/markdown.py,sha256=Onw9FsiW_OXAHBBg4Culf22RA4iM0cttGPyQvSzRD3g,2902
|
7
|
+
nbcat/pager.py,sha256=Yu0XIh5MvhvT-cmULYVxo6s2Ufjf2CQ-NDS5fcMQ-IM,3184
|
8
|
+
nbcat/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
9
|
+
nbcat/schemas.py,sha256=a7GoKgPTHgun199-J-sZq-ahkdQwvyRaCdQVg1gC798,3135
|
10
|
+
nbcat-1.0.0.dist-info/METADATA,sha256=TzEH94VbwxQLYfVnDXPWhjtHQn61DoClnc5zOJiIhoU,5122
|
11
|
+
nbcat-1.0.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
12
|
+
nbcat-1.0.0.dist-info/entry_points.txt,sha256=io_GRDsecAkYuCZALsjyea3VBq91VCoSznqlZEAJshY,42
|
13
|
+
nbcat-1.0.0.dist-info/licenses/LICENSE,sha256=7GjUnahXdd5opdvlpJdb1BisLbiXt2iOFhzIUduhdkE,1072
|
14
|
+
nbcat-1.0.0.dist-info/RECORD,,
|
nbcat-0.13.2.dist-info/RECORD
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
nbcat/__init__.py,sha256=blu6md2c3Nnj5gDBi8U36sYO3k8HcND8s7UoQBjfn3g,23
|
2
|
-
nbcat/enums.py,sha256=Fn8PIcLl_uY4nQIs1EUvmKTwfhNUIZgmhRFiCSJk9wk,411
|
3
|
-
nbcat/exceptions.py,sha256=Ho7LQz9K70VtIMDNtAwuAtGmb-lFKxGxSj7MN3-EpDA,321
|
4
|
-
nbcat/image.py,sha256=hGZZK5mtij7ckWAvQwzim3thqGC92pLW5ZU5CYbRv_Q,995
|
5
|
-
nbcat/main.py,sha256=pTOt0Kt7WJqf7H--JmXtvBgFJG-bBu6WsBG4KFl9wAE,6727
|
6
|
-
nbcat/markdown.py,sha256=fbYBy36rR0SKqvNI6Yj75Xv2snwFRmhbCJIC1wCX2Hg,3055
|
7
|
-
nbcat/pager.py,sha256=Yu0XIh5MvhvT-cmULYVxo6s2Ufjf2CQ-NDS5fcMQ-IM,3184
|
8
|
-
nbcat/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
9
|
-
nbcat/schemas.py,sha256=a7GoKgPTHgun199-J-sZq-ahkdQwvyRaCdQVg1gC798,3135
|
10
|
-
nbcat-0.13.2.dist-info/METADATA,sha256=iL2pq6twnuHVdLDx3jcJizgz4eXjMLmDVsbzLLyaHvA,4443
|
11
|
-
nbcat-0.13.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
12
|
-
nbcat-0.13.2.dist-info/entry_points.txt,sha256=io_GRDsecAkYuCZALsjyea3VBq91VCoSznqlZEAJshY,42
|
13
|
-
nbcat-0.13.2.dist-info/licenses/LICENSE,sha256=7GjUnahXdd5opdvlpJdb1BisLbiXt2iOFhzIUduhdkE,1072
|
14
|
-
nbcat-0.13.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|