My jupyter extension is breaking ipywidgets

So trame_jupyter_extension>=1,<2 for JupyterLab v3 is breaking any ipywidgets and I have no idea why and how to prevent that.

I have a binder example highlighting what is happening.

My jupyter extension is here and mainly do 3 things:

  1. execute some Python code on each kernel to set environment variables.
  2. create a comm channel on the JS side to proxy any trame communication to each kernel.
  3. serve static (html/js/css) content for any trame app.

Any pointer on how to fix my code to prevent breaking ipywidgets would be great. :wink:

What the binder example should look like

ipywidgets are working for me .

Great how did you install trame_jupyter_extension to make the ipywidgets work?

You both are comparing different types of Jupyter systems. The latter one is JupyterLite. And does trame work there in the JupyterLite one?

1 Like

No, JupyterLite is not yet supported with trame.

No trame is’nt working in the jupyterLite one. ipywidgets are working.
How trame_jupyter_extension is related to ipywidgets?

More broadly: if this “only” works in (I)Python, why not embrace the existing ipywidgets and @jupyter-widgets/jupyterlab-manager bus, which already handles most of this complexity?

With the custom comm messages, one can implement just about any RPC/PubSub/REST-ish pattern. The simple Button example shows the basics of this on the ts and python, but much more advanced things are possible, such as arbitrary binary buffers, as shown by ipywebrtc.

No relationship except that if people start using my extension, it will break any ipywidget usage.

Hence my question on “why my extension is breaking ipywidgets” and what to do to prevent that from happening. Is it on my side or on ipywidgets side ?

Ideally, I would like to not require ipywidgets if not needed, but maybe every jupyter instance out there always has ipywidgets and therefore my wish is moot. :wink:

I will look at your pointer @bollwyvl. If I do that, will the same code works for both jupyter-lab 3 and 4?

both jupyter-lab 3 and 4?

Yes, the chances of a “pure” widget extension working for end users with no funny stuff in Lab 3/4 and Notebook 7 is higher than with things that work at a lower level (build tools, contents models, sessions, kernels, etc), as there were a number of breaking changes between the two major versions. Luckily, as two official Jupyter projects, Don’t Break Widgets is an important part of the JupyterLab/Notebook 7+ release/development cycle, with a good deal of overlap in the knowledge/maintainer base. And yes, even folks that don’t really use widgets, might use things like tqdm, etc.

Further, with “pure” widgets, it’s possible to even to continue to support users o f Notebook 6, in its senescence, with the patterns shown in widget-ts-cookiecutter.

As to the development cycle: a significant “gotcha” is that the versions of jlpm (the white-label yarn shipped with jupyterlab) are incompatible. Still trying to figure out why. Anyhow, one should plan on building on either 3 or 4, and then testing the as-built .whl with both.

Missing from that cookiecutter, perhaps, are some more robust acceptance tests. This is another 3/4 gotcha: the officially supported approach, the nodejs- and playwright-based galata is also incompatible between the two versions of Lab/Notebook (as it doesn’t support Notebook 6 at all). For this reason, for broad acceptance testing in real browsers, I’ve been maintaining the python- and selenium-based robotframework-jupyterlibrary, which i usually install in a separate conda environment (due to firefox and geckodriver), which can then test any number of other environments.

1 Like

While right now I have a branch for jupyter-lab v3 and another one for v4, the code I have is so simple that I don’t necessarily want to complexify it with another dependency.

Right now I’m exploring the ipywidget path and see if that can be an option. So far the documentation is really well done. Just missing a couple of things specific to me. But I’m going to play with the cookie-cutter and look at the webrtc code to fill in the blanks.

Thanks for your feedback and if anyone has any idea on why the current code conflicts with ipywidgets I will still be happy to hear about it.

It is diverging from the original topic, but now that I’m exploring using ipywidgets as base infrastructure for my extension, I’m not sure on how to handle the following:

  1. create a custom tornado handler for serving static content dynamically (kernel writing content but served by tornado)
  2. how do I execute code on a kernel at the kernel’s startup when the JS plugin is enabled?

create a custom tornado handler for serving static content dynamically (kernel writing content but served by tornado)

This requirement would be a poor fit for the widget infrastructure, as widgets live firmly in the kernel part of the architecture, entirely distinct from server_extensions, contents, jupyter_server, and tornado.

This is mostly due the existence of things like kernel_gateway, where there is no guarantee that that kernel is running on the same metal/container as the jupyter_server.

Indeed, there are other backends that implement the Jupyter Server REST API + WebSockets.

One can “fake” contents over the widget bus, however, with the aforementioned custom messages.

All that being said, there are additional examples to crib from the JupyterLab extension template, which shows how one might add a custom REST endpoint.

Thanks for your input, indeed the JupyterLab extension template path is what I’ve used.
And to be clear, it is working for me on binder and SageMaker (as far as I can tell).

But I don’t know why my extension is messing things up with ipywidgets.

I figured out the issue but am unsure how to solve it.

So both ipywidgets and trame-extension expect to createComm on a kernel connection (@jupyterlab/services/lib/kernel/kernel.IKernelConnection).

But the extension that gets initialized first can do it, while the second one will fail with that error

Error: Comms are disabled on this kernel connection

By default, mine was creating its kernel connection first and therefore breaking ipywidgets. If I delay my kernel connection creation, the ipywidgets are working as expected but then my extension is failing by not being able to create a comm later on.

Question: From the JS side from my jupyter-lab extension, is there

  1. a way to know if ipywidgets extension is available?
    • so I don’t try to create a kernel connection myself
  2. if so, can I get my hand on the ipywidgets kernel connection instance (from kernel id)?
    • so I can safely call createComm on it

Bonus question:
In fact, the only thing I need is in JS to be able to call createComm on a kernelConnection for which I already know the kernel id. So any other path as a suggestion is welcome.