erys


Nameerys JSON
Version 0.1.1 PyPI version JSON
download
home_pageNone
SummaryTerminal interface for creating, editing, and running Jupyter Notebook
upload_time2025-07-18 03:49:49
maintainerNathnael (Nati) Bekele
docs_urlNone
authorNathnael (Nati) Bekele
requires_python>=3.10
licenseNone
keywords jupyter notebook terminal textual notebook python tui
VCS
bugtrack_url
requirements textual pyperclip jupyter_client pillow
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # ***`Erys`***: Terminal Interface for Jupyter Notebooks.

![Demo](https://raw.githubusercontent.com/natibek/erys/main/data/demo.gif)

**`Erys`** is a tool for opening, creating, editing, running, interacting with, and
saving Jupyter Notebooks in the terminal. It uses [Textual](https://textual.textualize.io/)
for creating the interface and `jupyter_client` for executing code with kernel managers and clients.

---

## Table of Contents
- [Installation](#installation)
- [Using Erys](#using-erys)
- [App Features](#features)
- [Cell Functionalities](#cell-functionalities)
- [Key Bindings](#key-bindings)
- [Coming Features](#coming-features)
- [Contributing](#contributing)
- [License](#license)

---

## Installation:

The best way to install **`Erys`** is using [`uv`](https://github.com/astral-sh/uv):

```bash
$ uv tool install erys
```
will install it as a system wide executable tool.

Similarly, `pipx` can also be used to install **`Erys`** on the system,

```bash
$ pipx install erys
```

---

## Using `Erys`

Calling `$ erys` in the terminal without any arguments launches the application with an empty notebook.
Using the directory tree docked on the left, notebooks can be loaded into the app. File types without
the `.ipynb` extension will not be opened. `backspace` will take you up a directory and `enter` will
go into a directory.

![Directory Tree](https://raw.githubusercontent.com/natibek/erys/main/data/directory-tree.png)

Look at the [Key Bindings](#key-bindings) section to see how to open, save, save as, and close notebooks.

**`Erys`** can also be called with arguments in the command line. These arguments should be paths to jupyter notebook files with the `.ipynb` extension. Any file path that does not have this extension is ignored. The app will
load each valid file paths into an *`erys`* notebook.

> *In the future, validate that the file is actually a notebook.*

When saving a notebook as new, the following screen is opened:

![Save as screen](https://raw.githubusercontent.com/natibek/erys/main/data/save_as_screen.png)

1. The directory that the file is being saved in is stated on the top.
1. The input field can be used to write the file name.
    1. The input field is validated on submission. Any file names that don't have the `.ipynb` extension
    are not accepted.
1. The directory tree can be used to change what directory to the save file in.
1. Selecting a file in the directory tree will update the input field to have the selected file name
and updates the path as well.

Use the up and down arrow keys within a notebook to traverse the cells. Pressing `enter` will focus
on the text area of the cell. `escape` will blur out of the text area and focus on the parent cell.
Cells have more functionality which are stated in the [Cell Key Bindings](#cell-key-bindings) section.

### SSH consideration

If using **`Erys`** over ssh, use X11 forwarding to get the rendered images and html. These two
outputs use the separate windows for rendering.

--- 

## Features:

### Opening Exising Notebooks

**`Erys`** Erys can open various notebook format versions and saves notebooks using format version 4.5.

> Do share problems with loading different notebook formats :)

> NB Format: https://nbformat.readthedocs.io/en/latest/format_description.html

### Creating Notebooks

**`Erys`** can create, edit, and save Jupyter Notebooks.

### Code Execution

**`Erys`** can execute `Python` source code in code cells. The `Python` environment in which the source code
is executed is the one in which the **`Erys`** is created. Also, if `ipykernel` is not found in the
`Python` environment, code cells can not be executed. However, the notebook can still be edited and saved.

Each notebook has its own kernel manager and kernel client. Hence, there is no leaking environment from
notebook to notebook within the application. However, all notebook opened in the same **`Erys`** process 
are in the same `Python` environment.

A running code cell can be interrupted by pressing the interrupt button `□` on the left.

### Rendering 

**`Erys`** handles terminal rendering for:
1. Markdown: Rendered with `Markdown` widget from `Textual`.
1. JSON: Rendered with `Pretty` widget from `Textual` \*.
1. Errors: Rendered with `Static` widget from `Textual` and `rich.Text` \*.
    1. ansi escaped string is converted to markup. (Some background coloring is difficult to read)

> \* When these are rendered as outputs from code execution, focus on them to get the plain text output.
> The plain text output supports copying content.

![Pretty and plain error](https://raw.githubusercontent.com/natibek/erys/main/data/pretty-plain-error.webm)

**`Erys`** parses image/png and text/html outputs from code cell execution and renders them outside of the 
terminal. Press on the `🖼 IMG` and `🖼 HTML` buttons to render them respectively. Images are rendered
using `Pillow` and html is rendered in the default browser using `webbrowser`.

![Notebook with image and html](https://raw.githubusercontent.com/natibek/erys/main/data/img-html-button.png)

![Rendering image and html](https://raw.githubusercontent.com/natibek/erys/main/data/rendering-img.png)

### Syntax Highlighting

**`Erys`** has python and markdown syntax highlighting through textual.

![Python syntax highlighting](https://raw.githubusercontent.com/natibek/erys/main/data/code-syntax-highlighting.png)

--- 

## Cell Functionalities:

The `Markdown` and `Code` cells have useful features:

1. Splitting: A cell will be split with the text up to the cursor's position (not inclusive) kept in the
current cell and the text starting from the cursor's position (inclusive) used to create a new cell.

![Splitting](https://raw.githubusercontent.com/natibek/erys/main/data/splitting.gif)

1. Joining with cell before and after: A cell can be joined with the cell before or after it.

1. Merging: Multiple cells can be merged into one. Select the cells in the order they should appear in the merge
by holding down `ctrl` and selecting with the mouse. The content of first selected cell will appear first in the final merged cell. The resulting
cell wil be of the same type as the first selected cell. The cells selected for merging will be highlighted.

![Merging](https://raw.githubusercontent.com/natibek/erys/main/data/merging.gif)

1. Toggle cell type: The cell types can be swtiched back and forth.

1. Collapsing: Both cell types can be collapsed to take up less space. The `Code` cell's output can also be collapsed.

1. Moving: A cell can be moved up and down the notebook.

![Moving](https://raw.githubusercontent.com/natibek/erys/main/data/move_cell.gif)

1. Copy/Cut Paste: A cell can be copied or cut and pasted. It is pasted after the currently focused cell. 
The new cell will have a different id than the original. Cut can be undone.

1. Deleting: A cell can be deleted. Deletion can be undone.

--- 

## Key Bindings:

**`Erys`** has different sets on key bindings depending on what is in focus.

### App Key Bindings:

|Key Binding|Function|
|:-:|:-:|
|ctrl+n|New Notebook|
|ctrl+k|Close Notebook|
|ctrl+l|Clear Tabs|
|d|Toggle Directory Tree|
|ctrl+q|Quit|

### Notebook Key Bindings:

|Key Binding|Function|
|:-:|:-:|
|a| Add Cell After|
|b| Add Cell Before|
|t| Toggle Cell Type|
|ctrl+d| Delete Cell \*|
|ctrl+u| Undo Delete \*|
|ctrl+up| Move Cell Up|
|ctrl+down| Move Cell Down|
|M| Merge Cells \*\*|
|ctrl+c| Copy Cell|
|ctrl+x| Cut Cell|
|ctrl+v| Paste Cell|
|ctrl+s| Save|
|ctrl+w| Save As|

> \* A maximum of 20 deletes can be undone at a time. The stack keeping track of the deleted cells
> has a maximum size of 20.


### Cell Key Bindings:
|Key Binding|Function|
|:-:|:-:|
|c| Collapse Cell|
|ctrl+pageup| Join with Before|
|ctrl+pagedown| Join with After|

#### Additionally, for code cell

|Key Binding|Function|
|:-:|:-:|
|r| Run|

### Text Area Bindings:
|Key Binding|Function|
|:-:|:-:|
|ctrl+backslash|Split Cell|
|ctrl+r|Run Code Cell \*|

> \* Only for `Code` Cell.
---

## Coming Features
1. Execution time duration for code cell
1. Read config for themes and key bindings?
1. Attaching to user selected kernels
1. Raw cells
1. Saving progress backup
1. Opening from cached backup
1. Ask to save editted files on exit
1. Mime output types rendering
1. Edit other text and code files
1. Validate notebook

--- 

## Contributing

Pull requests and feedback are welcome! Create issues and PRs that can help improve and grow
the project.

--- 

## License

This project is licensed under the Apache-2.0 License. 

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "erys",
    "maintainer": "Nathnael (Nati) Bekele",
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": null,
    "keywords": "jupyter notebook, terminal, textual, notebook, python, tui",
    "author": "Nathnael (Nati) Bekele",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/8e/5b/34b4b4141b0cdd48e83b61d476cba7995b879370047e9c968e8265727ebd/erys-0.1.1.tar.gz",
    "platform": null,
    "description": "# ***`Erys`***: Terminal Interface for Jupyter Notebooks.\n\n![Demo](https://raw.githubusercontent.com/natibek/erys/main/data/demo.gif)\n\n**`Erys`** is a tool for opening, creating, editing, running, interacting with, and\nsaving Jupyter Notebooks in the terminal. It uses [Textual](https://textual.textualize.io/)\nfor creating the interface and `jupyter_client` for executing code with kernel managers and clients.\n\n---\n\n## Table of Contents\n- [Installation](#installation)\n- [Using Erys](#using-erys)\n- [App Features](#features)\n- [Cell Functionalities](#cell-functionalities)\n- [Key Bindings](#key-bindings)\n- [Coming Features](#coming-features)\n- [Contributing](#contributing)\n- [License](#license)\n\n---\n\n## Installation:\n\nThe best way to install **`Erys`** is using [`uv`](https://github.com/astral-sh/uv):\n\n```bash\n$ uv tool install erys\n```\nwill install it as a system wide executable tool.\n\nSimilarly, `pipx` can also be used to install **`Erys`** on the system,\n\n```bash\n$ pipx install erys\n```\n\n---\n\n## Using `Erys`\n\nCalling `$ erys` in the terminal without any arguments launches the application with an empty notebook.\nUsing the directory tree docked on the left, notebooks can be loaded into the app. File types without\nthe `.ipynb` extension will not be opened. `backspace` will take you up a directory and `enter` will\ngo into a directory.\n\n![Directory Tree](https://raw.githubusercontent.com/natibek/erys/main/data/directory-tree.png)\n\nLook at the [Key Bindings](#key-bindings) section to see how to open, save, save as, and close notebooks.\n\n**`Erys`** can also be called with arguments in the command line. These arguments should be paths to jupyter notebook files with the `.ipynb` extension. Any file path that does not have this extension is ignored. The app will\nload each valid file paths into an *`erys`* notebook.\n\n> *In the future, validate that the file is actually a notebook.*\n\nWhen saving a notebook as new, the following screen is opened:\n\n![Save as screen](https://raw.githubusercontent.com/natibek/erys/main/data/save_as_screen.png)\n\n1. The directory that the file is being saved in is stated on the top.\n1. The input field can be used to write the file name.\n    1. The input field is validated on submission. Any file names that don't have the `.ipynb` extension\n    are not accepted.\n1. The directory tree can be used to change what directory to the save file in.\n1. Selecting a file in the directory tree will update the input field to have the selected file name\nand updates the path as well.\n\nUse the up and down arrow keys within a notebook to traverse the cells. Pressing `enter` will focus\non the text area of the cell. `escape` will blur out of the text area and focus on the parent cell.\nCells have more functionality which are stated in the [Cell Key Bindings](#cell-key-bindings) section.\n\n### SSH consideration\n\nIf using **`Erys`** over ssh, use X11 forwarding to get the rendered images and html. These two\noutputs use the separate windows for rendering.\n\n--- \n\n## Features:\n\n### Opening Exising Notebooks\n\n**`Erys`** Erys can open various notebook format versions and saves notebooks using format version 4.5.\n\n> Do share problems with loading different notebook formats :)\n\n> NB Format: https://nbformat.readthedocs.io/en/latest/format_description.html\n\n### Creating Notebooks\n\n**`Erys`** can create, edit, and save Jupyter Notebooks.\n\n### Code Execution\n\n**`Erys`** can execute `Python` source code in code cells. The `Python` environment in which the source code\nis executed is the one in which the **`Erys`** is created. Also, if `ipykernel` is not found in the\n`Python` environment, code cells can not be executed. However, the notebook can still be edited and saved.\n\nEach notebook has its own kernel manager and kernel client. Hence, there is no leaking environment from\nnotebook to notebook within the application. However, all notebook opened in the same **`Erys`** process \nare in the same `Python` environment.\n\nA running code cell can be interrupted by pressing the interrupt button `\u25a1` on the left.\n\n### Rendering \n\n**`Erys`** handles terminal rendering for:\n1. Markdown: Rendered with `Markdown` widget from `Textual`.\n1. JSON: Rendered with `Pretty` widget from `Textual` \\*.\n1. Errors: Rendered with `Static` widget from `Textual` and `rich.Text` \\*.\n    1. ansi escaped string is converted to markup. (Some background coloring is difficult to read)\n\n> \\* When these are rendered as outputs from code execution, focus on them to get the plain text output.\n> The plain text output supports copying content.\n\n![Pretty and plain error](https://raw.githubusercontent.com/natibek/erys/main/data/pretty-plain-error.webm)\n\n**`Erys`** parses image/png and text/html outputs from code cell execution and renders them outside of the \nterminal. Press on the `\ud83d\uddbc IMG` and `\ud83d\uddbc HTML` buttons to render them respectively. Images are rendered\nusing `Pillow` and html is rendered in the default browser using `webbrowser`.\n\n![Notebook with image and html](https://raw.githubusercontent.com/natibek/erys/main/data/img-html-button.png)\n\n![Rendering image and html](https://raw.githubusercontent.com/natibek/erys/main/data/rendering-img.png)\n\n### Syntax Highlighting\n\n**`Erys`** has python and markdown syntax highlighting through textual.\n\n![Python syntax highlighting](https://raw.githubusercontent.com/natibek/erys/main/data/code-syntax-highlighting.png)\n\n--- \n\n## Cell Functionalities:\n\nThe `Markdown` and `Code` cells have useful features:\n\n1. Splitting: A cell will be split with the text up to the cursor's position (not inclusive) kept in the\ncurrent cell and the text starting from the cursor's position (inclusive) used to create a new cell.\n\n![Splitting](https://raw.githubusercontent.com/natibek/erys/main/data/splitting.gif)\n\n1. Joining with cell before and after: A cell can be joined with the cell before or after it.\n\n1. Merging: Multiple cells can be merged into one. Select the cells in the order they should appear in the merge\nby holding down `ctrl` and selecting with the mouse. The content of first selected cell will appear first in the final merged cell. The resulting\ncell wil be of the same type as the first selected cell. The cells selected for merging will be highlighted.\n\n![Merging](https://raw.githubusercontent.com/natibek/erys/main/data/merging.gif)\n\n1. Toggle cell type: The cell types can be swtiched back and forth.\n\n1. Collapsing: Both cell types can be collapsed to take up less space. The `Code` cell's output can also be collapsed.\n\n1. Moving: A cell can be moved up and down the notebook.\n\n![Moving](https://raw.githubusercontent.com/natibek/erys/main/data/move_cell.gif)\n\n1. Copy/Cut Paste: A cell can be copied or cut and pasted. It is pasted after the currently focused cell. \nThe new cell will have a different id than the original. Cut can be undone.\n\n1. Deleting: A cell can be deleted. Deletion can be undone.\n\n--- \n\n## Key Bindings:\n\n**`Erys`** has different sets on key bindings depending on what is in focus.\n\n### App Key Bindings:\n\n|Key Binding|Function|\n|:-:|:-:|\n|ctrl+n|New Notebook|\n|ctrl+k|Close Notebook|\n|ctrl+l|Clear Tabs|\n|d|Toggle Directory Tree|\n|ctrl+q|Quit|\n\n### Notebook Key Bindings:\n\n|Key Binding|Function|\n|:-:|:-:|\n|a| Add Cell After|\n|b| Add Cell Before|\n|t| Toggle Cell Type|\n|ctrl+d| Delete Cell \\*|\n|ctrl+u| Undo Delete \\*|\n|ctrl+up| Move Cell Up|\n|ctrl+down| Move Cell Down|\n|M| Merge Cells \\*\\*|\n|ctrl+c| Copy Cell|\n|ctrl+x| Cut Cell|\n|ctrl+v| Paste Cell|\n|ctrl+s| Save|\n|ctrl+w| Save As|\n\n> \\* A maximum of 20 deletes can be undone at a time. The stack keeping track of the deleted cells\n> has a maximum size of 20.\n\n\n### Cell Key Bindings:\n|Key Binding|Function|\n|:-:|:-:|\n|c| Collapse Cell|\n|ctrl+pageup| Join with Before|\n|ctrl+pagedown| Join with After|\n\n#### Additionally, for code cell\n\n|Key Binding|Function|\n|:-:|:-:|\n|r| Run|\n\n### Text Area Bindings:\n|Key Binding|Function|\n|:-:|:-:|\n|ctrl+backslash|Split Cell|\n|ctrl+r|Run Code Cell \\*|\n\n> \\* Only for `Code` Cell.\n---\n\n## Coming Features\n1. Execution time duration for code cell\n1. Read config for themes and key bindings?\n1. Attaching to user selected kernels\n1. Raw cells\n1. Saving progress backup\n1. Opening from cached backup\n1. Ask to save editted files on exit\n1. Mime output types rendering\n1. Edit other text and code files\n1. Validate notebook\n\n--- \n\n## Contributing\n\nPull requests and feedback are welcome! Create issues and PRs that can help improve and grow\nthe project.\n\n--- \n\n## License\n\nThis project is licensed under the Apache-2.0 License. \n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Terminal interface for creating, editing, and running Jupyter Notebook",
    "version": "0.1.1",
    "project_urls": {
        "Changelog": "https://github.com/natibek/erys/blob/main/CHANGELOG",
        "Homepage": "https://github.com/natibek/erys",
        "Issues": "https://github.com/natibek/erys/issues",
        "Readme": "https://github.com/natibek/erys/blob/main/README.md",
        "Repository": "https://github.com/natibek/erys"
    },
    "split_keywords": [
        "jupyter notebook",
        " terminal",
        " textual",
        " notebook",
        " python",
        " tui"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "244c04118f0ed995a6c4ba30df27bfde960be2b4e976a4dc3b90defa1e2974a5",
                "md5": "6c7c86914589322e43d4f0fddee8cb48",
                "sha256": "1682e393419301c4990ba90e086aad677b328f0c9e6ff7b44081274056332bea"
            },
            "downloads": -1,
            "filename": "erys-0.1.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "6c7c86914589322e43d4f0fddee8cb48",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 32101,
            "upload_time": "2025-07-18T03:49:48",
            "upload_time_iso_8601": "2025-07-18T03:49:48.051585Z",
            "url": "https://files.pythonhosted.org/packages/24/4c/04118f0ed995a6c4ba30df27bfde960be2b4e976a4dc3b90defa1e2974a5/erys-0.1.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "8e5b34b4b4141b0cdd48e83b61d476cba7995b879370047e9c968e8265727ebd",
                "md5": "11e02b98696a0fdd02ee7eb02cc4b39c",
                "sha256": "2abb619f26d2fcc37e16f7a9ef901441eb2958a9ecce35ba421db7d3e475be5f"
            },
            "downloads": -1,
            "filename": "erys-0.1.1.tar.gz",
            "has_sig": false,
            "md5_digest": "11e02b98696a0fdd02ee7eb02cc4b39c",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 27557,
            "upload_time": "2025-07-18T03:49:49",
            "upload_time_iso_8601": "2025-07-18T03:49:49.065536Z",
            "url": "https://files.pythonhosted.org/packages/8e/5b/34b4b4141b0cdd48e83b61d476cba7995b879370047e9c968e8265727ebd/erys-0.1.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-18 03:49:49",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "natibek",
    "github_project": "erys",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [
        {
            "name": "textual",
            "specs": [
                [
                    "~=",
                    "4.0.0"
                ]
            ]
        },
        {
            "name": "pyperclip",
            "specs": [
                [
                    "~=",
                    "1.9.0"
                ]
            ]
        },
        {
            "name": "jupyter_client",
            "specs": [
                [
                    "~=",
                    "8.6.3"
                ]
            ]
        },
        {
            "name": "pillow",
            "specs": [
                [
                    "~=",
                    "11.3.0"
                ]
            ]
        }
    ],
    "lcname": "erys"
}
        
Elapsed time: 0.58551s