ENB: Re-designing Leo's IPython bridge

136 views
Skip to first unread message

Edward K. Ream

unread,
Oct 18, 2024, 9:42:14 AM10/18/24
to leo-editor
This Engineering Notebook post rethinks what Leo's IPython bridge (in leoIPython.py) must be.

Leo's IPython bridge has likely not worked for years. Imo, the bridge has never been much more than a toy. As a result, I feel free to re-imagine everything about Leo's relationship to IPython.

Goals and requirements

I'll retire leoIPython.py unless Leo can become an easy-to-use IPython notebook.

- Leo and IPython must run without blocking each other.
- IPython must have access to c, g and p.

Managing event loops

As an experiment, I tried running this Leonine script:

import IPython
IPython.embed()


As expected, this script starts IPython in the console window from which Leo launched. And IPython does have access to c, g and p!

In [1]: c
Out[1]: Commander 1439643722256: 'c:/Repos/leo-editor/leo/core/leoPy.leo'
In [2]: g
Out[2]: <module 'leo.core.leoGlobals' from 'C:\\Repos\\leo-editor\\leo\\core\\leoGlobals.py'>
In [3]: p
Out[3]: <pos 1439662055744 childIndex: 6 lvl: 0 key: 1439726600784:6 embed>


Alas, Leo hangs until IPython quits. So more work is needed :-)

Managing namespaces

A new Leo command, execute-ipython-script, should execute p.b in a namespace that includes all names known to the running IPython instance.

Similarly, IPython must have access to c, g and p without using embed.

Packaging

Leo's present --ipython command-line arg starts Leo in a ipython console window. I would like to retire this arg: it's clumsy and adds nothing essential.

Instead, a new Leo command, say launch-ipython, would:

- Exit with a warning if importing ipython fails.
- Launch (once) IPython in the console from which Leo was launched.

Summary

Leo's IPython bridge is little more than a toy. Worse, leoIPython.py has not worked for years. I shall retire leoIPython.py unless Leo can become a straightforward, easy-to-use IPython notebook. This notebook must:

- block neither IPython nor Leo.
- give IPython access to c, g and p.
- have an execute-ipython-script command.

It remains an open question whether these goals are attainable. I have hopes: IPython's API (fully accessible from Leo) has many features relating to embedding IPython into applications.

All comments and questions are welcome.

Edward

P.S. Running Leo from Leo's bridge is not the answer. We could avoid clashing event loops by embedding Leo's bridge (in leoBridge.leo) into IPython. But giving IPython access to Leo via Leo's bridge would add almost nothing to IPython!

EKR

Thomas Passin

unread,
Oct 18, 2024, 11:00:31 AM10/18/24
to leo-editor
I think that a good approach would be to come up with several use-cases or scenarios of how someone would actually use a hybrid Leo-IPython system.  It's no different that the case of Jupyter or sage.  I stopped supporting Jupyter notebooks in VR3 for the reason that I couldn't come up with one, at least one that wouldn't take a huge amount of work.

In the case of Jupyter notebooks, it's obvious that the input and output blocks could become Leo nodes, and Leo would bring a superior way to work with, view, and and handle those nodes. There are two things that stand in the way: 1) code in each Jupyter input node has access to the variables computed by earlier nodes, and 2) the inline display of graphics.  There is also trickiness that about recomputing when the code changes. I can live with the graphics by viewing the notebook with VR3, and I have made fairly extensive notebook-style outlines including code-generated graphics that way. Passing variables from one node to the next would require a serious rethink of how VR3 operates.

Since Jupyter is in some sense an elaborate extension of IPython similar points should apply.  I don't know about Sage but it too probably fits into that kind of picture.

IPython clients communicate with a server process, isn't that right? I know it's that way with Jupyter.  I don't know why there couldn't be a Leo client, but it wouldn't be VR3 (and there is no reason why it should be).  Again, the most important starting point is to think through how a Leo client would work from the user's point of view. Once that is understood, we can come to grips with how to make it work.  Trying to make something work before understanding a way or ways to make use of IPython support isn't likely to lead to helpful results, in my view.

Viktor Ransmayr

unread,
Oct 19, 2024, 11:05:26 AM10/19/24
to leo-editor
Hello Edward & Thomas,

Looking forward how this re-design will evolve.

tbp1...@gmail.com schrieb am Freitag, 18. Oktober 2024 um 17:00:31 UTC+2:
I think that a good approach would be to come up with several use-cases or scenarios of how someone would actually use a hybrid Leo-IPython system.  It's no different that the case of Jupyter or sage.  I stopped supporting Jupyter notebooks in VR3 for the reason that I couldn't come up with one, at least one that wouldn't take a huge amount of work.

In the case of Jupyter notebooks, it's obvious that the input and output blocks could become Leo nodes, and Leo would bring a superior way to work with, view, and and handle those nodes. There are two things that stand in the way: 1) code in each Jupyter input node has access to the variables computed by earlier nodes, and 2) the inline display of graphics.  There is also trickiness that about recomputing when the code changes. I can live with the graphics by viewing the notebook with VR3, and I have made fairly extensive notebook-style outlines including code-generated graphics that way. Passing variables from one node to the next would require a serious rethink of how VR3 operates.

Since Jupyter is in some sense an elaborate extension of IPython similar points should apply.  I don't know about Sage but it too probably fits into that kind of picture.

IPython clients communicate with a server process, isn't that right? I know it's that way with Jupyter.  I don't know why there couldn't be a Leo client, but it wouldn't be VR3 (and there is no reason why it should be). 
 
I have checked the Jupyter documentation - and - have found the following links, which I believe will answer the question & help in the design process:
Again, the most important starting point is to think through how a Leo client would work from the user's point of view. Once that is understood, we can come to grips with how to make it work.  Trying to make something work before understanding a way or ways to make use of IPython support isn't likely to lead to helpful results, in my view.

With kind regards,

Viktor
 

Edward K. Ream

unread,
Oct 19, 2024, 11:11:32 AM10/19/24
to leo-e...@googlegroups.com
On Fri, Oct 18, 2024 at 10:00 AM Thomas Passin <tbp1...@gmail.com> wrote:

I think that a good approach would be to come up with several use-cases or scenarios of how someone would actually use a hybrid Leo-IPython system.

Thanks for this excellent analysis. I was just going to create an ENB on this topic. I agree: plausible use cases must come first. See below for further discussion.

My only firm conclusion: it's time to retire leoIPython.py. The present code doesn't work and IPython's server has been deprecated and will be retired in a future release.

It's no different that the case of Jupyter or sage.  I stopped supporting Jupyter notebooks in VR3 for the reason that I couldn't come up with one, at least one that wouldn't take a huge amount of work.

I agree. Otoh, I would be willing to live with some scheme that uses IPython to display graphics results.

In the case of Jupyter notebooks, it's obvious that the input and output blocks could become Leo nodes, and Leo would bring a superior way to work with, view, and handle those nodes.

That's the idea.

There are two things that stand in the way: 1) code in each Jupyter input node has access to the variables computed by earlier nodes, and 2) the inline display of graphics. 

There may be other issues standing in the way :-)

There is also trickiness that about recomputing when the code changes. I can live with the graphics by viewing the notebook with VR3, and I have made fairly extensive notebook-style outlines including code-generated graphics that way. Passing variables from one node to the next would require a serious rethink of how VR3 operates.

I think of VR/VR3 support as optional. I'm having a devil of a time wrapping my head around all the possibilities as it is.

Since Jupyter is in some sense an elaborate extension of IPython similar points should apply.  I don't know about Sage but it too probably fits into that kind of picture.

Last night I realized that a client/server architecture might be essential. Jupyter provides such an architecture, but is way heavy.

Embedding a server into IPython (customized to Leo, when IPython starts) is possible. Such an architecture would be similar to LeoInteg's architecture. Leo would be a client of that server.

IPython clients communicate with a server process, isn't that right?

I'm not sure. Anyway, the existing IPython server has been deprecated.

I know it's that way with Jupyter.  I don't know why there couldn't be a Leo client

Yes, Leo could be a client, but the Jupyter server is obsessed (as it must be) with security. A local, bespoke, server would be much easier to create and use.

Again, the most important starting point is to think through how a Leo client would work from the user's point of view. Once that is understood, we can come to grips with how to make it work.  Trying to make something work before understanding a way or ways to make use of IPython support isn't likely to lead to helpful results, in my view.

I agree completely, and it has taken days of exploration to come around to the Aha!

Previously, I assumed that Leo's IPython bridge was something more than a toy, so I didn't look for use cases!

Summary

Many thanks for your analysis. Finding a plausible use case for using Leo in the SageMath, IPython or Jupyter worlds will drive all my explorations.

Otoh, this is a speculative, open-ended project. The only goal is vague: finding some way to incorporate IPython's many powers into Leo. I'm spending a lot of time googling and noodling.

Edward

My only firm conclusion: it's time to retire leoIPython.py.

Edward

Edward K. Ream

unread,
Oct 19, 2024, 11:12:11 AM10/19/24
to leo-e...@googlegroups.com
On Sat, Oct 19, 2024 at 10:05 AM Viktor Ransmayr <viktor....@gmail.com> wrote:
Hello Edward & Thomas,

Looking forward how this re-design will evolve.

Thanks. So am I!

Edward

HaveF HaveF

unread,
Oct 20, 2024, 12:21:06 AM10/20/24
to leo-editor
Honestly, it would be great if Leo was used to organize jupyter, but I think this problem is too complicated. Maintainability may also become a big problem in the future.
I usually synchronize the source code and ipynb through https://github.com/mwouts/jupytext, and then use Leo to organize the source code.
Of course, my whole process seems to be a little troublesome, but in general, the complexity is low, and if there is a problem, it can be easily found.


Edward K. Ream

unread,
Oct 20, 2024, 4:06:11 AM10/20/24
to leo-e...@googlegroups.com
On Sat, Oct 19, 2024 at 11:21 PM HaveF HaveF <iamap...@gmail.com> wrote:

Honestly, it would be great if Leo was used to organize jupyter, but I think this problem is too complicated.
Maintainability may also become a big problem in the future.

I agree. Your remarks here came at the perfect time. I thought of them often while writing my latest post.

I usually synchronize the source code and ipynb through https://github.com/mwouts/jupytext, and then use Leo to organize the source code.

Thanks for the link! jupytext supports the conclusion that IPython needs no help from Leo.
 
Of course, my whole process seems to be a little troublesome, but in general, the complexity is low, and if there is a problem, it can be easily found.

It was a mistake to think that Leo gains from working closely with IPython.

Thanks for helping us all abandon this mistaken idea!

Edward

George Zipperlen

unread,
Oct 21, 2024, 12:49:27 AM10/21/24
to leo-editor
There are two issue that I have with iPython / Jupyter notebooks where Leo can be of immense help:

The notebooks are giant JSON blobs, which makes version control painful,  I have ad-hoc scripts to break these blobs into an outer skeleton file, and individual files for each cell and to merge them back.  This is the kind of thing that Leo handles easily with a node tree.

Jupyter itself is a horrible code editor -- I end up using whatever else is available -- textedit, xed, pico, emacs, vi, or, ... leo!

The thing I like about Jupyter, more than plain iPython notebooks, is that it runs multiple languages -- Julia, R, and Python with seamless  integration of input/output and workspace variables between input and output cells.  The graphics support in output cells is outstanding. Other languages like bash, yaml, and elixir are also supported -- either natively, or through plugins.  In my world there is no single-language solution, and both code and data need version control.

Summary: I support Leo / JuPyteR integration, whether it is hosted by Jupyter or by Leo.

On Friday, October 18, 2024 at 9:42:14 AM UTC-4 Edward K. Ream wrote:

George Zipperlen

unread,
Oct 21, 2024, 1:04:12 AM10/21/24
to leo-editor
On Monday, October 21, 2024 at 12:49:27 AM UTC-4 George Zipperlen wrote:

The thing I like about Jupyter, more than plain iPython notebooks, is that it runs multiple languages -- Julia, R, and Python with seamless  integration of input/output and workspace variables between input and output cells.  The graphics support in output cells is outstanding. Other languages like bash, yaml, and elixir are also supported -- either natively, or through plugins.  In my world there is no single-language solution, and both code and data need version control.

How could I forget to mention documentation cells!  Markdown and LaTeX...

Thomas Passin

unread,
Oct 21, 2024, 8:39:27 AM10/21/24
to leo-editor
How do you see using Leo with jupyter files?  Jupytext has shown one way to get to a more textual representation.  How would you deal with generated output, especially graphics?  Would you want to run code from within Leo? How do you want to deal with magics?  Or do you want just to do strictly textual work without doing any code generation or graphics presentation? Would you need to retain any generated results or would you expect to rerun everything the next time the files go back to Jupyter?  Or maybe you envision the Jupyter server doing all those things while you are in Leo.  I'm sure you would want to preserve the structure that Leo applies but the server won't know about that.

The way Leo works with RsT documents, using the rst3 command and then running Sphinx is strictly one way. Leo never gets back the Sphinx output and does further work on it. Do you envision working that way? I.e., make changes in Leo, have the Jupyter server run whatever it needs to, view the results in Jupyter, and repeat as needed.  No round-trips between Leo and Jupyter. That might actually be the best way to work.

Edward K. Ream

unread,
Oct 21, 2024, 8:54:45 AM10/21/24
to leo-e...@googlegroups.com
On Sun, Oct 20, 2024 at 11:49 PM George Zipperlen <george.z...@gmail.com> wrote:

There are two issue that I have with iPython / Jupyter notebooks where Leo can be of immense help:

The notebooks are giant JSON blobs...
...
Jupyter itself is a horrible code editor...
...
In my world there is no single-language solution, and both code and data need version control.

Summary: I support Leo / JuPyteR integration, whether it is hosted by Jupyter or by Leo.

Many thanks, George, for this request. You've given me a juicy new project!

There are at least two ways forward. None requires heroic solutions such as running Leo within Jupyter or vice versa.

1: Make Jupyter a client of Leo's existing server

leoserver.py would be enhanced to provide Jupyter-specific requests. Maybe something like 'convert-ipynb-to-outline'. Details are fuzzy :-) However, there's probably a simpler way:

2: Enhance Leo's existing support for detecting changed external files

Leo will already detect changes to any external file given by "@file" or "@clean" nodes. So Leo should detect changes in .ipynb files, provided they occur in Leo's outline.

With jupytext as an inspiration, Leo might pair .ipynb with corresponding outline nodes:

- Update the paired outline node when the corresponding .ipynb file changes.
- Write the paired .ipynb file when the corresponding outline node changes.

The details of pairing .ipynb files with outline nodes are fuzzy. But surely this pairing is possible.

I assume that Jupyter can update .ipynb files when they change externally.

Maintaining outline structure

Pairing .ipynb files with "@clean" nodes will preserve outline structure auto-magically. This approach should suffice when sharing files because there is no way to change outline structure within Jupyter Notebooks!

This issue may need a rethink if Jupyter becomes a client of Leo's server. For example, Leo could embed alternate sentinel comments into the text of the .ipynb. We definitely do not want to inject Leo's existing sentinels!

Summary

The simplest way forward would be to pair "@clean" nodes with corresponding .ipynb nodes:

- Update outline nodes when their paired .ipynb files change.
- Write .ipynb files when their paired outline nodes change.

The details of pairing are unclear, but prototyping this approach should take only a few hours.

I'll investigate making Jupyter a client of leoserver only as a last resort.

Edward

Thomas Passin

unread,
Oct 21, 2024, 9:09:53 AM10/21/24
to leo-editor
On Monday, October 21, 2024 at 8:54:45 AM UTC-4 Edward K. Ream wrote:
I'll investigate making Jupyter a client of leoserver only as a last resort.

I think it should be the other way around - Leo would act as a client of a Jupyter server.  Most of the real work happens in the server anyway, doesn't it?  Code execution, graphics insertion, and so on. But a pairing scheme might be better.

HaveF HaveF

unread,
Oct 21, 2024, 9:44:35 AM10/21/24
to leo-e...@googlegroups.com

With jupytext as an inspiration, Leo might pair .ipynb with corresponding outline nodes:

- Update the paired outline node when the corresponding .ipynb file changes.
- Write the paired .ipynb file when the corresponding outline node changes.

The details of pairing .ipynb files with outline nodes are fuzzy. But surely this pairing is possible.

I assume that Jupyter can update .ipynb files when they change externally.
 
 It would be great if this works. I wouldn't have to use jupytext as a bridge. 

Also, as far as I know, jupyter is not able to detect external updates, and can only be updated using `reload notebook from disk` in the File menu.

You can edit the .py version of the paired notebook, and get the edits back in Jupyter by selecting reload notebook from disk. The outputs will be reloaded from the .ipynb file, if it exists. The .ipynb version will be updated or recreated the next time you save the notebook in Jupyter. 

Thomas Passin

unread,
Oct 21, 2024, 9:52:37 AM10/21/24
to leo-editor
More and more I am thinking that we should give up the idea of round-tripping between Leo and Jupyter.  What you have written goes in that direction.  Leo would be the primary authoring tool. From time to time a user can reload in Jupyter and see if the results are what was intended.  That's how it works with Sphinx documents and I've been happy with it.

I think most sharing of Jupyter notebooks takes place using an HTML file which is read in a browser. I'm not sure how it's generated, but maybe an actual Jupyter client session wouldn't even be required.

Edward K. Ream

unread,
Oct 21, 2024, 10:05:41 AM10/21/24
to leo-e...@googlegroups.com
On Mon, Oct 21, 2024 at 8:09 AM Thomas Passin <tbp1...@gmail.com> wrote:
On Monday, October 21, 2024 at 8:54:45 AM UTC-4 Edward K. Ream wrote:
I'll investigate making Jupyter a client of leoserver only as a last resort.

I think it should be the other way around.

I don't think so. Leo knows how to provide the necessary services.

But this question is moot for now.

Edward

Edward K. Ream

unread,
Oct 21, 2024, 10:14:57 AM10/21/24
to leo-e...@googlegroups.com
On Mon, Oct 21, 2024 at 8:44 AM HaveF HaveF wrote:

>> With jupytext as an inspiration, Leo might pair .ipynb with corresponding outline nodes:
>  It would be great if this works. I wouldn't have to use jupytext as a bridge.

It should work:
- Jupyter will know nothing about Leo.
- This is a text-only scheme.

It should be possible to borrow/steal code from jupytext. Studying jupytext is next.

> Also, as far as I know, jupyter is not able to detect external updates, and can only be updated using `reload notebook from disk` in the File menu.

Hard to believe, but a script, say ~/.jupyter/jupyter_init.py, should be able to detect changes.

I've recently created and played with jupyter_init.py. I don't see big obstacles. We'll see.

Edward

Edward K. Ream

unread,
Oct 21, 2024, 10:16:42 AM10/21/24
to leo-e...@googlegroups.com
On Mon, Oct 21, 2024 at 8:52 AM Thomas Passin <tbp1...@gmail.com> wrote:

> More and more I am thinking that we should give up the idea of round-tripping between Leo and Jupyter.

Two days ago I would have agreed with you :-) But jupytext may change our minds. We'll see.

Edward

Edward K. Ream

unread,
Oct 21, 2024, 10:47:05 AM10/21/24
to leo-e...@googlegroups.com
On Mon, Oct 21, 2024 at 9:14 AM Edward K. Ream wrote:
On Mon, Oct 21, 2024 at 8:44 AM HaveF HaveF wrote:

> HaveF: Also, as far as I know, jupyter is not able to detect external updates, and can only be updated using `reload notebook from disk` in the File menu.

> EKR: Hard to believe...

From the jupytext FAQ:

"Closing the notebook in Jupyter while you refactor it in another editor will help you avoid the message Untitled.ipynb has changed on disk."

So it looks like Jupyter can detect changed files.

Edward

Edward K. Ream

unread,
Oct 21, 2024, 10:55:28 AM10/21/24
to leo-e...@googlegroups.com
On Mon, Oct 21, 2024 at 9:46 AM Edward K. Ream <edre...@gmail.com> wrote:
On Mon, Oct 21, 2024 at 9:14 AM Edward K. Ream wrote:
On Mon, Oct 21, 2024 at 8:44 AM HaveF HaveF wrote:

> HaveF: Also, as far as I know, jupyter is not able to detect external updates, and can only be updated using `reload notebook from disk` in the File menu.

> EKR: Hard to believe...

From the jupytext FAQ:

Otoh, googling "jupyter detect changed file" yields multiple confusing, conflicting, results. So the jury is still out.

Edward

Edward K. Ream

unread,
Oct 21, 2024, 11:31:37 AM10/21/24
to leo-editor
On Monday, October 21, 2024 at 9:16:42 AM UTC-5 Edward K. Ream wrote:
On Mon, Oct 21, 2024 at 8:52 AM Thomas Passin wrote:

> TBP: More and more I am thinking that we should give up the idea of round-tripping between Leo and Jupyter.
> EKR: Two days ago I would have agreed with you :-) But jupytext may change our minds.

I've just created #4117 for this project. It's schedule for Leo 6.8.3: It's way too late for Leo 6.8.2.

Edward

HaveF HaveF

unread,
Oct 25, 2024, 10:18:26 PM10/25/24
to leo-editor
On Monday, October 21, 2024 at 12:49:27 PM UTC+8 george.z...@gmail.com wrote:
There are two issue that I have with iPython / Jupyter notebooks where Leo can be of immense help:

Hi, George!

Thanks to Edward's genius ideas, we can use Leo's powerful outline function with Jupyter so quickly. If you are interested, you can check out this demonstration video, that is my use case. Ah, I really love this feature!


Reply all
Reply to author
Forward
0 new messages