SlicerCAT as web service

Hi,

I’m thinking about making a web service based on SlicerCAT.

That means SlicerCAT should be run as a backend and the frontend should control what is rendered in SlicerCAT and all the VTK interaction (same as we do it in Slicer like zooming, rotating etc using mouse or hotkeys).

Frontend should be implemented in browser. Maybe I could try using streamlit for that.

I’ve tested Slicer Web Server. I think it is possible to add sliders, checkboxes and other GUI staff to control the scene.
But I don’t know whether it is possible to keep VTK interactivity.

Maybe somebody has any suggestions?

Yes, the WebServer module is designed to support that architecture.

Since both Slicer and the web application are asynchronous you need to pay some attention to make sure, for example, that you don’t make too many requests from the web side before the Slicer side has processed the previous requests.

1 Like

Thank you for the hint!

Yes that is what I’m afraid of.

Let suppose on the front end we have VTK interactor (don’t yet how to implement it) i.e we can rotate the 3D view for example.
For each small movement we will have a request I guess. May this be a problem of sending too much requests or rotating/zooming work fast enough in Slicer so there should not be such problem?

I don’t have a worked out example, but it should be possible to manage things so that new requests are compacted so the request rate is in sync with the response rate. Such a system would need to be adaptive so that you get fast response on a local connection but gracefully degrade on remote connections.

Maybe you can try a simple scenario and let us know what your experience it.

1 Like

RIght. I should try a simple scenario first.

It seems that vtkWeb is most suited for me as I would like to use client-server architecture for remote view without transferring the whole mesh to the client (it may be pretty big).

Were there any attempts to use Slicer 3D views as remote view with custom GUI on the client side (probably with vtkWeb)?

I haven’t tried that particular technical combination. It would be great if you could try some experiments and let us know how it goes.

1 Like

I just made small experiments based on example.

To adjust a server I use Slicer Jupyter.
In this example we will remotely render 3D scene.

Define a server subclass:

r"""
    This module is a VTK Web server application.
    The following command line illustrates how to use it::

        $ vtkpython .../vtk_server.py

    Any VTK Web executable script comes with a set of standard arguments that
    can be overriden if need be::
        --host localhost
             Interface on which the HTTP server will listen.

        --port 8080
             Port number on which the HTTP server will listen.

        --content /path-to-web-content/
             Directory that you want to serve as static web content.
             By default, this variable is empty which means that we rely on another server
             to deliver the static content and the current process only focuses on the
             WebSocket connectivity of clients.

        --authKey wslink-secret
             Secret key that should be provided by the client to allow it to make any
             WebSocket communication. The client will assume if none is given that the
             server expects "wslink-secret" as the secret key.
"""

# import to process args
import sys
import os

import slicer

# import vtk modules.
import vtk
from vtk.web import protocols
from vtk.web import wslink as vtk_wslink
from wslink import server

# =============================================================================
# Create custom ServerProtocol class to handle clients requests
# =============================================================================


class _MyWebServer(vtk_wslink.ServerProtocol):

    # Application configuration
    view = None
    authKey = "wslink-secret"

    def initialize(self):
        global renderer, renderWindow, renderWindowInteractor, cone, mapper, actor

        # Bring used components
        self.registerVtkWebProtocol(protocols.vtkWebMouseHandler())
        self.registerVtkWebProtocol(protocols.vtkWebViewPort())
        self.registerVtkWebProtocol(protocols.vtkWebPublishImageDelivery(decode=False))
        self.registerVtkWebProtocol(protocols.vtkWebViewPortGeometryDelivery())

        # Update authentication key to use
        self.updateSecret(_MyWebServer.authKey)

        # tell the C++ web app to use no encoding.
        # ParaViewWebPublishImageDelivery must be set to decode=False to match.
        self.getApplication().SetImageEncoding(0)

        # Create default pipeline (Only once for all the session)
        if not _MyWebServer.view:
            # VTK Web application specific
            view = slicer.app.layoutManager().threeDWidget(0).threeDView()
            # Capture RGBA image
            renderWindow = view.renderWindow()
            _MyWebServer.view = renderWindow
            self.getApplication().GetObjectIdMap().SetActiveObject("VIEW", renderWindow)

start server:

from wslink import websocket as wsl
from wslink import backends

import argparse
from dataclasses import dataclass


parser = argparse.ArgumentParser(
        description="VTK/Web Slicer 3D web-application")
# Add default arguments
server.add_arguments(parser)

# Extract arguments
args = parser.parse_args()
args.port = 1234

print(args)

server.start_webserver(options=args, protocol=_MyWebServer)

Go to this page or full screen and you should be able to see 3D view in web browser and be able to interact:

Looks pretty promising but after some time of intercation (using different mouse keys) the rendering becomes very very slow. So further investigations needed.

1 Like