Skip to content

Commit

Permalink
Make ypywidgets optional
Browse files Browse the repository at this point in the history
  • Loading branch information
davidbrochart committed Dec 18, 2023
1 parent 190a70e commit 74009c8
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 53 deletions.
4 changes: 2 additions & 2 deletions plugins/kernels/fps_kernels/kernel_driver/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ async def _handle_iopub(self, msg_id: str, ycell: Map) -> None:
ycell["execution_state"] = "idle"

async def _handle_comms(self) -> None:
if self.yjs is None:
if self.yjs is None or self.yjs.widgets is None: # type: ignore
return

while True:
Expand Down Expand Up @@ -247,7 +247,7 @@ async def _handle_outputs(self, outputs: Array, msg: Dict[str, Any]):
if "application/vnd.jupyter.ywidget-view+json" in content["data"]:
# this is a collaborative widget
model_id = content["data"]["application/vnd.jupyter.ywidget-view+json"]["model_id"]
if self.yjs is not None:
if self.yjs is not None and self.yjs.widgets is not None: # type: ignore
if model_id in self.yjs.widgets.widgets: # type: ignore
doc = self.yjs.widgets.widgets[model_id]["model"].ydoc # type: ignore
path = f"ywidget:{doc.guid}"
Expand Down
5 changes: 4 additions & 1 deletion plugins/yjs/fps_yjs/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ def __init__(
super().__init__(app=app, auth=auth)
self.contents = contents
self.room_manager = RoomManager(contents)
self.widgets = Widgets()
if Widgets is None:
self.widgets = None
else:
self.widgets = Widgets() # type: ignore

async def collaboration_room_websocket(
self,
Expand Down
112 changes: 62 additions & 50 deletions plugins/yjs/fps_yjs/ywidgets/widgets.py
Original file line number Diff line number Diff line change
@@ -1,52 +1,64 @@
from typing import Any

import pkg_resources
from pycrdt import TransactionEvent
from ypywidgets.utils import ( # type: ignore
YMessageType,
YSyncMessageType,
create_update_message,
process_sync_message,
sync,
)


class Widgets:
def __init__(self):
self.ydocs = {
ep.name: ep.load() for ep in pkg_resources.iter_entry_points(group="ypywidgets")
}
self.widgets = {}

def comm_open(self, msg, comm) -> None:
target_name = msg["content"]["target_name"]
if target_name != "ywidget":
return

name = msg["metadata"]["ymodel_name"]
comm_id = msg["content"]["comm_id"]
self.comm = comm
model = self.ydocs[f"{name}Model"]()
self.widgets[comm_id] = {"model": model, "comm": comm}
msg = sync(model.ydoc)
comm.send(**msg)

def comm_msg(self, msg) -> None:
comm_id = msg["content"]["comm_id"]
message = bytes(msg["buffers"][0])
if message[0] == YMessageType.SYNC:
ydoc = self.widgets[comm_id]["model"].ydoc
reply = process_sync_message(
message[1:],
ydoc,
)
if reply:
self.widgets[comm_id]["comm"].send(buffers=[reply])
if message[1] == YSyncMessageType.SYNC_STEP2:
ydoc.observe(self._send)

def _send(self, event: TransactionEvent):
update = event.update # type: ignore
message = create_update_message(update)
try:
self.comm.send(buffers=[message])
except Exception:
pass

try:
from ypywidgets.utils import ( # type: ignore
YMessageType,
YSyncMessageType,
create_update_message,
process_sync_message,
sync,
)
ypywidgets_installed = True
except ImportError:
ypywidgets_installed = False


Widgets: Any

if ypywidgets_installed:
class Widgets:
def __init__(self):
self.ydocs = {
ep.name: ep.load() for ep in pkg_resources.iter_entry_points(group="ypywidgets")
}
self.widgets = {}

def comm_open(self, msg, comm) -> None:
target_name = msg["content"]["target_name"]
if target_name != "ywidget":
return

name = msg["metadata"]["ymodel_name"]
comm_id = msg["content"]["comm_id"]
self.comm = comm
model = self.ydocs[f"{name}Model"]()
self.widgets[comm_id] = {"model": model, "comm": comm}
msg = sync(model.ydoc)
comm.send(**msg)

def comm_msg(self, msg) -> None:
comm_id = msg["content"]["comm_id"]
message = bytes(msg["buffers"][0])
if message[0] == YMessageType.SYNC:
ydoc = self.widgets[comm_id]["model"].ydoc
reply = process_sync_message(
message[1:],
ydoc,
)
if reply:
self.widgets[comm_id]["comm"].send(buffers=[reply])
if message[1] == YSyncMessageType.SYNC_STEP2:
ydoc.observe(self._send)

def _send(self, event: TransactionEvent):
update = event.update # type: ignore
message = create_update_message(update)
try:
self.comm.send(buffers=[message])
except Exception:
pass
else:
Widgets = None

0 comments on commit 74009c8

Please sign in to comment.