David Brochart

@davidbrochart

Jupyter in the terminal

davidbrochart

Hello World!

logo.png

As I was wondering how to start this post, the template was suggesting a first heading named "Hello World!", and I figured that it is actually kind of appropriate :)

jpterm is a JupyterLab-like environment running in the terminal. Although it is still very early stage, I think it has a lot of potential. Not that it's the only solution out there (there was nbterm and euporie), but I think what sets jpterm apart is that it builds on the shoulders of giants, one of which is Textual.

The terminal is the new browser

As its original author said, with Textual the terminal is going to eat some of the browser's lunch. This TUI (text-based user interface) framework is indeed setting the bar quite high, allowing things that were never seen before in terms of interactions, reactivity and performance. A number of widgets have already been developed, some of them are so beautifully animated that it's hard to believe the terminal could do that. All of this can be styled using CSS, a technology that comes from the browser.

image.png

The Select Textual widget

While JavaScript is the language of the browser, Python is the language in which Textual is implemented, and so it's now possible to create beautiful applications in the terminal using a sane language :) What this also means is that while the browser needs a server, this is not mandatory for a Textual application. The backend and frontend parts don't have to be two different things anymore, they can be part of the same program. This allows to simplify the API and it makes it easier to build applications.

But it doesn't mean Textual's use case is limited to local programs that are closed to the outside world, on the contrary. Python has extensive third-party libraries for web access (httpx, FastAPI, to name a few), so a Textual application can be a client to an external server, or a server for external clients. With textual-web, you can even deploy your application very easily by running it locally and making it accessible through a browser at a public URL.

JupyterLab vs jpterm

The comparison is unfair, because JupyterLab is such a great and popular project! But under the hood it's "just" an application written in TypeScript that happens to run in the browser. It's also a framework of its own, with its plugin system and a custom GUI system called lumino. In this regard, it is comparable to Qt which is targeted at the desktop. A lot of people who are not very familiar with the JavaScript ecosystem (including myself) find it difficult to contribute to.

On the other hand, jpterm is written in Python and is hopefully more approachable. It is designed similarly to JupyterLab, where everything is a plugin. For instance, jpterm comes with a file browser by default, but you can provide your own, as long as it complies with a defined API. You can also extend jpterm by installing new plugins. For instance, jpterm is currently able to open images (yes!), text files, Markdown files, and Notebooks, but you could provide your own editor or viewer for other types of file. One I'm thinking about would show a JSON file as a tree.

The plugin system is also what enables jpterm to run either locally on your machine, or remotely through a Jupyter server. Switching between these two modes actually swaps two services, the ones providing the contents (which allow accessing the filesystem and loading/saving files) and the ones providing the kernels (which allow executing a notebook). A version of these services works locally, and another version hits a server, but their API is identical.

When jpterm runs remotely through a Jupyter server, it behaves just as another client that the server cannot differentiate from a regular JupyterLab client running in the browser. Even better, when collaborative editing is enabled, you can work on the same document at the same time from jpterm and from JupyterLab, and see each other's modifications live!

image.png

JupyterLab and jpterm working collaboratively

JupyterLite vs jpterm

JupyterLite is a WASM-based distribution of JupyterLab where everything runs in the browser, so no Jupyter server is needed (it's just static assets served by any server). That makes deployment much easier, much cheaper, and much more scalable because it runs on your machine, in your browser.

If you think about it, jpterm also runs on your machine, at least in local mode. So everything that makes JupyterLite attractive also applies to jpterm. With textual-web, you can even deploy your application and make it publicly available. It also doesn't suffer from the same limitations as WASM, since you can install and run any package on your machine.

In a way, the terminal really resets all our expectations. Thanks to Textual, it is now closer to the browser. But unlike the browser, it can freely access your system's resources. Not limited by JavaScript or WASM technologies, it can run as if it were directly on bare-metal, because it is! And deployment doesn't mean running a complex application in your browser, but just sending character updates over the wire so that they can be displayed on the other side.

What's next?

There is still a lot of polishing to be done in jpterm, but the proof-of-concept has proven successful. I am confident that it has an architecture that can be built upon. One area of interest would be to improve plotting features in notebooks, since they are often used for scientific work. The textual-plotext goes in that direction, so it seems to be a good solution.

textual-plotext-example.png

Plotting using plotext in Textual

In general, jpterm will benefit a lot from the Textual ecosystem. For instance, tooi is a Textual-based Mastodon client. I can imagine turning it into a jpterm plugin that would show a timeline where people would publish notebooks, similarly to what Observable does. Clicking on a post would fetch the notebook and open it in jpterm, ready to be executed. This would effectively be a social network for notebooks :)

image.png

Textual-based Mastodon client (tooi)

Since I am also a core developer of Jupyter, I see jpterm as a platform for experimenting new ideas that can land in official Jupyter projects later. One of them was the implementation of server-side notebook execution and state recovery, including widgets. The idea proved successful and quite easy to implement in jpterm.

I am excited about the future of jpterm. I don't see it as a "downgraded" version of JupyterLab, but as a novel project that can bring innovation to the Jupyter ecosystem. If you are interested, please go ahead and try it, report bugs, request new features, or contribute!