Is it possible to setup napari as a microservice that can recieve data and update on the viewer?

Using the qt_gui context manager opens a GUI and blocks, and I’m not sure how I could update the data using something like a publisher-subscriber pattern from another python process. Any leads on this is appreciated.

Like most gui programs, napari runs in an event loop. So you need to hook into that loop by connect (subscribing) to one of the many events that are emitted (published) while using napari. I suggest starting with the documentation on the event loop in napari, and then let us know if you have specific questions (for instance, it would be helpful to what you want to happen, and in response to what event).

Also, note that if you like to debug/troubleshoot things in an interactive session, you don’t have to use the gui_qt context manager (that’s just a convenience and one of many ways to start the Qt event loop that napari requires). In IPython for instance, you can use the %gui qt magic, or start ipython with ipython --gui qt from the command line. Then you don’t need the context manager:

$ ipython --gui qt
Python 3.8.3 | packaged by conda-forge | (default, Jun  1 2020, 17:21:09) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.16.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]:  import napari

In [2]: v = napari.Viewer()  # no gui_qt necessary

In [3]: # you can keep interacting with it...
1 Like

if you want to listen to another process… one possibility is to set up a worker that listens for events/messages from the other process using thread_worker, and then have that worker yield data or whatever when it comes it, then connect the yielded event on the worker to whatever you want to happen…

totally untested quasi-code:

from napari.qt.threading import thread_worker
from multiprocessing.connection import Connection 

def my_callback(message):
    # ... whatever you want to do with the message
 
@thread_worker(connect={"yielded": my_callback})
def listener(handle):
    conn = Connection(handle)
    while True:
        message = conn.recv()
        yield message
        if some_exit_condition:
            break

worker = listener(connection_handle)  # start listening
2 Likes