From cb637c92a77287b21b9dcddcbb84edd3b5aedc62 Mon Sep 17 00:00:00 2001 From: Brianna Major Date: Wed, 19 Jul 2023 18:36:21 -0400 Subject: [PATCH] WIP: set_label_image Try to pull data from client-side rather than pushing from server-side --- itkwidgets/standalone/index.html | 20 ++++++++++++++ itkwidgets/standalone_server.py | 45 ++++++++++++++++++++++++++++++-- itkwidgets/viewer.py | 18 +++++++++++-- 3 files changed, 79 insertions(+), 4 deletions(-) diff --git a/itkwidgets/standalone/index.html b/itkwidgets/standalone/index.html index a8847124..a298a6b3 100644 --- a/itkwidgets/standalone/index.html +++ b/itkwidgets/standalone/index.html @@ -77,6 +77,26 @@ }, viewer: () => viewer }); + await server.registerService({ + name: "setLabelOrImage", + id: "set-label-or-image", + description: "Set the image or label image.", + config: { + visibility: "protected", + require_context: false, + run_in_executor: true, + }, + set_label_image: async () => { + remoteService = await server.getService(`${remoteID}:fetch-zarr-store`); + let labelImage = await remoteService.fetchZarrStore("label_image"); + viewer.setLabelImage(labelImage); + }, + set_image: async () => { + remoteService = await server.getService(`${remoteID}:fetch-zarr-store`); + let image = await remoteService.fetchZarrStore("image"); + viewer.setImage(image); + } + }); remoteService = await server.getService(`${remoteID}:itkwidgets-viewer-ready`); await remoteService.viewerReady(viewer); } diff --git a/itkwidgets/standalone_server.py b/itkwidgets/standalone_server.py index da152c26..e57f469b 100644 --- a/itkwidgets/standalone_server.py +++ b/itkwidgets/standalone_server.py @@ -1,4 +1,5 @@ import argparse +import functools import logging import socket import code @@ -45,6 +46,7 @@ def find_port(port=SERVER_PORT): PORT = find_port() OPTS = None EVENT = threading.Event() +VIEWER = None def standalone_viewer(url): @@ -97,6 +99,16 @@ async def viewer_ready(itk_viewer): EVENT.set() +def set_label_or_image(server, type): + workspace = server.config.workspace + svc = server.get_service(f"{workspace}/itkwidgets-client:set-label-or-image") + getattr(svc, f"set_{type}")() + + +def fetch_zarr_store(store_type): + return getattr(VIEWER, store_type, None) + + def start_viewer(server_url): server = connect_to_server_sync( { @@ -136,6 +148,34 @@ def start_viewer(server_url): } ) + server.register_service( + { + "name": "zarr_store", + "id": "zarr-store", + "description": "", + "config": { + "visibility": "protected", + "require_context": False, + "run_in_executor": True, + }, + "zarr_store": functools.partial(zarr_store, server), + } + ) + + server.register_service( + { + "name": "data_set", + "id": "data-set", + "description": "Save the image data set via REPL session.", + "config": { + "visibility": "protected", + "require_context": False, + "run_in_executor": True, + }, + "set_label_or_image": functools.partial(set_label_or_image, server), + } + ) + workspace = server.config.workspace token = server.generate_token() params = urlencode({"workspace": workspace, "token": token}) @@ -144,6 +184,7 @@ def start_viewer(server_url): def main(): + global VIEWER JWT_SECRET = str(uuid.uuid4()) os.environ["JWT_SECRET"] = JWT_SECRET hypha_server_env = os.environ.copy() @@ -184,14 +225,14 @@ def main(): EVENT.wait() # Wait until viewer is created before launching REPL workspace = server.config.workspace svc = server.get_service(f"{workspace}/itkwidgets-client:itk-vtk-viewer") - viewer = view(itk_viewer=svc.viewer()) + VIEWER = view(itk_viewer=svc.viewer(), server=server) banner = f""" Welcome to the itkwidgets command line tool! Press CTRL+D or run `exit()` to terminate the REPL session. Use the `viewer` object to manipulate the viewer. """ exitmsg = "Exiting REPL. Press CTRL+C to teminate CLI tool." - code.interact(banner=banner, local={"viewer": viewer}, exitmsg=exitmsg) + code.interact(banner=banner, local={"viewer": VIEWER}, exitmsg=exitmsg) def cli_entrypoint(): diff --git a/itkwidgets/viewer.py b/itkwidgets/viewer.py index 6dfbe39f..8bc0a155 100644 --- a/itkwidgets/viewer.py +++ b/itkwidgets/viewer.py @@ -146,6 +146,8 @@ def __init__( api.export(self.viewer_rpc) else: self._itk_viewer = add_data_kwargs.get('itk_viewer', None) + self.server = add_data_kwargs.get('server', None) + self.workspace = self.server.config.workspace @property def loop(self): @@ -208,7 +210,13 @@ def set_image(self, image: Image, name: str = 'Image'): render_type = _detect_render_type(image, 'image') if render_type is RenderType.IMAGE: image = _get_viewer_image(image, label=False) - self.queue_request('setImage', image, name) + if ENVIRONMENT is Env.HYPHA: + self.image = image + svc_name = f'{self.workspace}/itkwidgets-server:data-set' + svc = self.server.get_service(svc_name) + svc.set_label_or_image('image') + else: + self.queue_request('setImage', image, name) elif render_type is RenderType.POINT_SET: image = _get_viewer_point_set(image) self.queue_request('setPointSets', image) @@ -279,7 +287,13 @@ def set_label_image(self, label_image: Image): render_type = _detect_render_type(label_image, 'image') if render_type is RenderType.IMAGE: label_image = _get_viewer_image(label_image, label=True) - self.queue_request('setLabelImage', label_image) + if ENVIRONMENT is Env.HYPHA: + self.label_image = label_image + svc_name = f"{self.workspace}/itkwidgets-server:data-set" + svc = self.server.get_service(svc_name) + svc.set_label_or_image('label_image') + else: + self.queue_request('setLabelImage', label_image) elif render_type is RenderType.POINT_SET: label_image = _get_viewer_point_set(label_image) self.queue_request('setPointSets', label_image)