nbcat 0.9.3__py3-none-any.whl → 0.9.5__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 CHANGED
@@ -1 +1 @@
1
- __version__ = "0.9.3"
1
+ __version__ = "0.9.5"
nbcat/enums.py CHANGED
@@ -14,3 +14,10 @@ class OutputType(str, Enum):
14
14
  EXECUTE_RESULT = "execute_result"
15
15
  ERROR = "error"
16
16
  PYOUT = "pyout"
17
+
18
+
19
+ class OutputCellType(str, Enum):
20
+ PLAIN = "plain"
21
+ HTML = "html"
22
+ IMAGE = "image"
23
+ JSON = "json"
nbcat/main.py CHANGED
@@ -1,6 +1,7 @@
1
1
  import argparse
2
2
  import sys
3
3
  from pathlib import Path
4
+ from typing import Union
4
5
 
5
6
  import argcomplete
6
7
  import requests
@@ -10,12 +11,13 @@ from rich import box
10
11
  from rich.console import Console, RenderableType
11
12
  from rich.markdown import Markdown
12
13
  from rich.panel import Panel
14
+ from rich.pretty import Pretty
13
15
  from rich.syntax import Syntax
14
16
  from rich.table import Table
15
17
  from rich.text import Text
16
18
 
17
19
  from . import __version__
18
- from .enums import CellType
20
+ from .enums import CellType, OutputCellType
19
21
  from .exceptions import (
20
22
  InvalidNotebookFormatError,
21
23
  NotebookNotFoundError,
@@ -66,7 +68,7 @@ def read_notebook(fp: str, debug: bool = False) -> Notebook:
66
68
  raise InvalidNotebookFormatError(f"Invalid notebook: {e}")
67
69
 
68
70
 
69
- def render_cell(cell: Cell) -> list[tuple[str | None, RenderableType]]:
71
+ def render_cell(cell: Cell) -> list[tuple[Union[str, None], RenderableType]]:
70
72
  """
71
73
  Render the content of a notebook cell for display.
72
74
 
@@ -91,18 +93,28 @@ def render_cell(cell: Cell) -> list[tuple[str | None, RenderableType]]:
91
93
  def _render_raw(input: str) -> Text:
92
94
  return Text(input)
93
95
 
96
+ def _render_image(input: str) -> None:
97
+ return None
98
+
99
+ def _render_json(input: str) -> Pretty:
100
+ return Pretty(input)
101
+
94
102
  RENDERERS = {
95
103
  CellType.MARKDOWN: _render_markdown,
96
104
  CellType.CODE: _render_code,
97
105
  CellType.RAW: _render_raw,
98
106
  CellType.HEADING: _render_markdown,
107
+ OutputCellType.PLAIN: _render_raw,
108
+ OutputCellType.HTML: _render_markdown,
109
+ OutputCellType.IMAGE: _render_image,
110
+ OutputCellType.JSON: _render_json,
99
111
  }
100
112
 
101
- rows: list[tuple[str | None, RenderableType]] = []
113
+ rows: list[tuple[Union[str, None], RenderableType]] = []
102
114
  renderer = RENDERERS.get(cell.cell_type)
103
115
  source = renderer(cell.input) if renderer else None
104
116
  if source:
105
- label = f"[green][{cell.execution_count}][/]:" if cell.execution_count else None
117
+ label = f"[green][{cell.execution_count}][/]" if cell.execution_count else None
106
118
  rows.append(
107
119
  (
108
120
  label,
@@ -112,13 +124,16 @@ def render_cell(cell: Cell) -> list[tuple[str | None, RenderableType]]:
112
124
 
113
125
  for o in cell.outputs:
114
126
  if o.output:
115
- label = f"[blue][{o.execution_count}][/]:" if o.execution_count else None
116
- rows.append(
117
- (
118
- label,
119
- o.output,
127
+ renderer = RENDERERS.get(o.output.output_type)
128
+ output = renderer(o.output.text) if renderer else None
129
+ if output:
130
+ label = f"[blue][{o.execution_count}][/]" if o.execution_count else None
131
+ rows.append(
132
+ (
133
+ label,
134
+ output,
135
+ )
120
136
  )
121
- )
122
137
  return rows
123
138
 
124
139
 
nbcat/schemas.py CHANGED
@@ -1,25 +1,29 @@
1
- from typing import Any
1
+ from typing import Any, Union
2
2
 
3
3
  from pydantic import BaseModel, computed_field, model_validator
4
4
 
5
- from .enums import CellType, OutputType
5
+ from .enums import CellType, OutputCellType, OutputType
6
6
  from .exceptions import InvalidNotebookFormatError
7
7
 
8
8
 
9
9
  class BaseOutput(BaseModel):
10
10
  output_type: OutputType
11
- execution_count: int | None = None
11
+ execution_count: Union[int, None] = None
12
+
13
+
14
+ class CellOutput(BaseModel):
15
+ output_type: OutputCellType
16
+ text: str
12
17
 
13
18
 
14
19
  class StreamOutput(BaseOutput):
15
- text: list[str] | str
20
+ text: Union[list[str], str]
16
21
 
17
22
  @computed_field
18
23
  @property
19
- def output(self) -> str:
20
- if isinstance(self.text, list):
21
- return "".join(self.text)
22
- return self.text
24
+ def output(self) -> CellOutput:
25
+ text = "".join(self.text) if isinstance(self.text, list) else self.text
26
+ return CellOutput(output_type=OutputCellType.PLAIN, text=text)
23
27
 
24
28
 
25
29
  class DisplayDataOutput(BaseOutput):
@@ -27,9 +31,18 @@ class DisplayDataOutput(BaseOutput):
27
31
 
28
32
  @computed_field
29
33
  @property
30
- def output(self) -> str:
31
- # TODO: add support for rich display outputs
32
- return ""
34
+ def output(self) -> Union[CellOutput, None]:
35
+ data_type_map = {
36
+ "text/html": OutputCellType.HTML,
37
+ "text/png": OutputCellType.IMAGE,
38
+ "text/plain": OutputCellType.PLAIN,
39
+ "application/vnd.raw.v1+json": OutputCellType.JSON,
40
+ }
41
+ for data_type, output_type in data_type_map.items():
42
+ data = self.data.get(data_type)
43
+ if data:
44
+ text = "".join(data) if isinstance(data, list) else str(data)
45
+ return CellOutput(output_type=output_type, text=text)
33
46
 
34
47
 
35
48
  class ErrorOutput(BaseOutput):
@@ -39,8 +52,8 @@ class ErrorOutput(BaseOutput):
39
52
 
40
53
  @computed_field
41
54
  @property
42
- def output(self) -> str:
43
- return "\n".join(self.traceback)
55
+ def output(self) -> CellOutput:
56
+ return CellOutput(output_type=OutputCellType.PLAIN, text="\n".join(self.traceback))
44
57
 
45
58
 
46
59
  class PyoutDataOutput(BaseOutput):
@@ -48,16 +61,16 @@ class PyoutDataOutput(BaseOutput):
48
61
 
49
62
  @computed_field
50
63
  @property
51
- def output(self) -> str:
52
- return "\n".join(self.text)
64
+ def output(self) -> CellOutput:
65
+ return CellOutput(output_type=OutputCellType.PLAIN, text="\n".join(self.text))
53
66
 
54
67
 
55
68
  class Cell(BaseModel):
56
69
  cell_type: CellType
57
- source: list[str] | str
58
- level: int | None = None
59
- execution_count: int | None = None
60
- outputs: list[StreamOutput | DisplayDataOutput | ErrorOutput | PyoutDataOutput] = []
70
+ source: Union[list[str], str]
71
+ level: Union[int, None] = None
72
+ execution_count: Union[int, None] = None
73
+ outputs: list[Union[StreamOutput, DisplayDataOutput, ErrorOutput, PyoutDataOutput]] = []
61
74
 
62
75
  @model_validator(mode="before")
63
76
  @classmethod
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nbcat
3
- Version: 0.9.3
3
+ Version: 0.9.5
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,7 +28,7 @@ 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.10
31
+ Requires-Python: >=3.9
32
32
  Requires-Dist: argcomplete
33
33
  Requires-Dist: pydantic
34
34
  Requires-Dist: requests
@@ -43,15 +43,25 @@ Description-Content-Type: text/markdown
43
43
 
44
44
  # 📦 nbcat
45
45
 
46
- `nbcat` lets you preview Jupyter notebooks directly in your terminal. Think of it as `cat`, but for `.ipynb` files.
46
+ `nbcat` let you preview Jupyter notebooks directly in your terminal. Think of it as `cat`, but for `.ipynb` files.
47
47
 
48
- ## 🚀 Features
48
+ ## Features
49
49
 
50
- - Fast and lightweight with minimal external dependencies
50
+ - Very fast and lightweight with minimal dependencies
51
51
  - Preview remote notebooks without downloading them
52
- - Supports for all Jupyter notebook versions - including legacy formats
52
+ - Supports for all Jupyter notebook versions, including old legacy formats
53
53
 
54
- ## 📦 Installation
54
+ ## Motivation
55
+
56
+ The idea of previewing notebooks in a terminal is not new - there have been many previous attempts to achieve it.
57
+ However, most are either slow and overengineered with a ton of half-working features, or they're outdated and incompatible with modern Python.
58
+
59
+ I was looking for a simple tool that let me quickly render Jupyter notebooks without switching context from my terminal window or installing a ton of dependencies.
60
+
61
+ Please note, that `nbcat` doesn't aim to replace JupyterLab. If you need a full-featured terminal experience, I recommend checking out [euporie](https://euporie.readthedocs.io/) instead.
62
+
63
+
64
+ ## Installation
55
65
 
56
66
  From the command line using pip:
57
67
 
@@ -59,7 +69,7 @@ From the command line using pip:
59
69
  pip install nbcat
60
70
  ```
61
71
 
62
- ## 🛠️ Quickstart
72
+ ## Quickstart
63
73
 
64
74
  ```bash
65
75
  $ nbcat notebook.ipynb
@@ -91,15 +101,15 @@ Check code quality:
91
101
  make format lint
92
102
  ```
93
103
 
94
- ## 🙌 Contributing
104
+ ## Contributing
95
105
 
96
106
  Contributions are welcome! Please open an issue or [pull request](https://github.com/akopdev/nbcat/pulls).
97
107
 
98
- ## 📄 License
108
+ ## License
99
109
 
100
110
  Distributed under the MIT License. See [`LICENSE`](./LICENSE) for more information.
101
111
 
102
- ## 🔗 Useful Links
112
+ ## Useful Links
103
113
 
104
114
  - 📘 Documentation: _coming soon_
105
115
  - 🐛 Issues: [GitHub Issues](https://github.com/akopdev/nbcat/issues)
@@ -0,0 +1,11 @@
1
+ nbcat/__init__.py,sha256=ORAtCCI2THBDcdzIbh6oBsoshDvkkmXUWpmO4Q5McAk,22
2
+ nbcat/enums.py,sha256=Fn8PIcLl_uY4nQIs1EUvmKTwfhNUIZgmhRFiCSJk9wk,411
3
+ nbcat/exceptions.py,sha256=Ho7LQz9K70VtIMDNtAwuAtGmb-lFKxGxSj7MN3-EpDA,321
4
+ nbcat/main.py,sha256=H2gQgJYzf00DLOVp8v6yKbcKW3ZL3O9jb65VZEM7IZ0,5809
5
+ nbcat/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ nbcat/schemas.py,sha256=fjSbdXa4pHKRV1Z-vUESkYZywkojanCvSu8s7rc9Xkw,3134
7
+ nbcat-0.9.5.dist-info/METADATA,sha256=6X7lT_xc9vkN1HI6pCbxE9cIK7dqeIB6NJQ1ATuLJlU,3970
8
+ nbcat-0.9.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
9
+ nbcat-0.9.5.dist-info/entry_points.txt,sha256=io_GRDsecAkYuCZALsjyea3VBq91VCoSznqlZEAJshY,42
10
+ nbcat-0.9.5.dist-info/licenses/LICENSE,sha256=7GjUnahXdd5opdvlpJdb1BisLbiXt2iOFhzIUduhdkE,1072
11
+ nbcat-0.9.5.dist-info/RECORD,,
@@ -1,11 +0,0 @@
1
- nbcat/__init__.py,sha256=xKd3pzbczuMsdB08eLAOqZDUd_q1IRxwZ_ccAFL4c4A,22
2
- nbcat/enums.py,sha256=ZsuOwYLF0D4PVwSkS74LwoXY0y0DkeBToLBWnmiS97Y,300
3
- nbcat/exceptions.py,sha256=Ho7LQz9K70VtIMDNtAwuAtGmb-lFKxGxSj7MN3-EpDA,321
4
- nbcat/main.py,sha256=X1UbLxXF9Y9V4Z8vE_pUz5cG22zx2oBMMlvpJVWITD0,5236
5
- nbcat/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- nbcat/schemas.py,sha256=IK1l2a4UcP6Ivh8xRBzV5BIQTbeES1b1cCH-6goEq8Q,2366
7
- nbcat-0.9.3.dist-info/METADATA,sha256=IQV8OPxQ0sQFu1BdLK9g6z5-nSv4j36rUhaMJYv0FQ0,3376
8
- nbcat-0.9.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
9
- nbcat-0.9.3.dist-info/entry_points.txt,sha256=io_GRDsecAkYuCZALsjyea3VBq91VCoSznqlZEAJshY,42
10
- nbcat-0.9.3.dist-info/licenses/LICENSE,sha256=7GjUnahXdd5opdvlpJdb1BisLbiXt2iOFhzIUduhdkE,1072
11
- nbcat-0.9.3.dist-info/RECORD,,
File without changes