ipylab icon indicating copy to clipboard operation
ipylab copied to clipboard

Awaitables

Open fleming79 opened this issue 3 months ago • 5 comments

This PR is a subset of #160

This PR enables asynchronous code execution as follows:

  • Python methods are coroutines (async def)
  • Each request sent to the frontend is assigned a Pending (just like an asyncio.Future). When the frontend replies, the pending is set done and the result is returned.
  • A JSON representation is returned if the result can be converted to JSON.
  • A Connection object is provided if the object returned in the frontend is a disposable (or when the transform is specified as a connection).
  • The connection can be used to:
    • access the methods and properties
    • close the object
    • use the object as a reference in the frontend using 'toObject'
    • conveted to a lumino widget using 'toLuminoWidget'

Demo running all cells at once

Awaiting in each cell ensures the result is available for the next cell. The gif below is 0.5x playback speed.

ezgif-405a2e1b8e1514bb

Menus

This gif demonstrates the usage of menus and restoration when the page is refreshed.

ezgif-4b4a42d822193ae5

Async execution is enabled in notebooks with async-kernel.

Subshells

Requires async-kernel

Leverages on the concept of kernel subshells to provide isolated user_ns and common global_user_ns.

ezgif-36277de683b32f49

resolves #11

Replaces #160

fleming79 avatar Oct 08 '25 10:10 fleming79

Binder :point_left: Try it on Binder (branch fleming79/ipylab/ipylab-awaitable)

github-actions[bot] avatar Oct 08 '25 10:10 github-actions[bot]

@jtpio I've made an attempt at splitting up the the other PR into smaller chunks. Unfortunately, it still remains rather large.

Feel free to make changes as you see fit, particularly with the js code.

Notes:

  • I switched to using uv for building to make it is easier to setup a dev environment on Windows.
  • I don't think the async version will be compatible with Jupyterlite.

fleming79 avatar Oct 08 '25 10:10 fleming79

described_by was added in this commit. It provides a similar interface to the first part of #162 (printing args only).

image

This illustrates how awaitables can be used to add in more functionality.

fleming79 avatar Nov 26 '25 03:11 fleming79

Yeh, the goal over on #162 was to add some more optional features without breaking the public APIs (even though that took a good deal of mangling). The execute(..., handler) is likely even more interesting than describe.

Until there is a proper upstream ipywidgets async (iterable) story, I think having additive, alternate APIs here would be nice, for sure.

bollwyvl avatar Nov 26 '25 17:11 bollwyvl

Yeh, the goal over on #162 was to add some more optional features without breaking the public APIs (even though that took a good deal of mangling). The execute(..., handler) is likely even more interesting than describe.

Until there is a proper upstream ipywidgets async (iterable) story, I think having additive, alternate APIs here would be nice, for sure.

Your comment "Until there is a proper upstream ipywidgets async" made me realize that the patched libraries aren't required for this PR; so I've removed them. At the moment it still requires the kernel to be async-kernel, which was developed specifically to make ipylab work nicely in notebooks.

In this PR:

  • CommandRegistry.execute returns the result of execution in the frontend (or a Connection to an object).
  • The 'described_by' feature (without validation) is configurable on the CommandConnection which gets returned when a command is created.
  • Icons can be included in CommandRegistry.add_command
  • Multiple command registries are supported; a new registry can be created with CommandRegistry(name="my new registry").

fleming79 avatar Nov 26 '25 21:11 fleming79