question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Create MagicUI based UI using on a JSON or similiar

See original GitHub issue

Hi,

imagine you have a JSON file, that is used to define the input elements for an UI (example below). What would be the best approach to get started to create a magicgui-based interface using this as an input? or in other words, is there an example etc., where can I get an idea how to “dynamically” create an UI based on a JSON or dict etc?

The idea is to (maybe) create a Napari plugin that can run our APEER modules, which come with such an Input UI specification. In our ZEN software and on www.apeer.com we already use such specs to create the UI dynamically and I wonder if this would work using magicgui (inside Napari) as well?

We already a commandline-based APEER module executor, which is completely docker-based and can in principle run on Windows on Linux.

Any ideas are appreciated?

{
    "spec": {
        "inputs": {
            "input_image": {
                "type:file": {}
            },
            "red": {
                "type:number": {
                    "lower_inclusive": 0.0,
                    "upper_inclusive": 1.0
                }
            },
            "green": {
                "type:number": {
                    "lower_inclusive": 0.0,
                    "upper_inclusive": 1.0
                }
            },
            "blue": {
                "type:number": {
                    "lower_inclusive": 0.0,
                    "upper_inclusive": 1.0
                }
            }
        },
        "outputs": {
            "tinted_image": {
                "type:file": {}
            }
        }
    },
    "ui": {
        "inputs": {
            "red": {
                "index": 51,
                "label": "Red channel",
                "widget:slider": {
                    "step": 0.1
                }
            },
            "green": {
                "index": 52,
                "label": "Green channel",
                "widget:slider": {
                    "step": 0.1
                }
            },
            "blue": {
                "index": 53,
                "label": "Blue channel",
                "widget:slider": {
                    "step": 0.1
                }
            }
        },
        "outputs": {}
    }
}

This renders in our SW like this:

image

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:7 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
tlambert03commented, May 7, 2021

in the first take APEER modules take files as an input and produce files as an output as well. So maybe we can “workaround” subprocesses in the beginning … 😃

ok, that does simplify things to start with! so, a basic first implementation might look something like this:

  1. manually start up an apeer docker server (assuming there’s something like a server?)
  2. in another process, start up napari.
  3. in your napari widget, you’d have some interactive element (such as that generated by magicgui) that would either ping your server notifying it of some workflow, or, I guess, drop a file into a folder that the server is watching?
  4. apeer does its business
  5. then you need something back in napari to get notified when a result is ready. This could be something like folder “watcher” running in another thread (something like watchdog, or we can roll our own type thing). And then that watcher needs to emit an event “file ready” that is connected to some callback in your widget that reads the file and adds it to the viewer.

there’s obviously a lot of important details left out there 😂 but that’s what a basic two-process file-based communication scheme could start out as

1reaction
tlambert03commented, May 7, 2021

yep, all makes sense. would be an awesome use case. I haven’t looked into apeer or the module system, but provided that you can get that JSON string in your first post, it would be feasible to generate a UI for it (some more thoughts on that below). As for napari–>docker APEER–>napari, that also seems feasible, but of course, much more involved than the GUI generation… so let’s leave that discussion for a future date 😃

If you want to get started playing with this now, the challenge is in converting the schema from your ui json to python types that magicgui can recognize. So basically, you need to convert this:

{
            "red": {
                "type:number": {
                    "lower_inclusive": 0.0,
                    "upper_inclusive": 1.0
                }
            },

            "red": {
                "index": 51,
                "label": "Red channel",
                "widget:slider": {
                    "step": 0.1
                }
            }
}

into this:

from magicgui import widgets

red_slider = widgets.FloatSlider(min=0, max=1, step=0.1, label='Red Channel')

or, probably more useful in this case is the magicgui.widgets.create_widget factory function:

red_slider = widgets.create_widget(
    annotation=float,
    widget_type='FloatSlider',
    label='Red Channel',
    options={'min': 0, 'max': 1, 'step': 0.1}
)

to get things playing nicely in napari, you can use a type of napari.types.ImageData for your input_image field (which, once the widget is in a napari viewer, will render as a dropdown menu showing the available image layers).

from napari.types import ImageData

image_dropdown = create_widget(annotation=ImageData, label = 'Input Image')

you can then combine these subwidgets into a container:

container = widgets.Container(widgets=[red_slider, image_dropdown, ...])

# and add that to napari:

viewer.window.add_dock_widget(container)

This doesn’t cover what events happen when the user interacts with your GUI… but it’s a start. See https://napari.org/guides/stable/magicgui.html for more details on napari-specific types that you can use in magicgui (like ImageData), and see the magicgui widget overview and associated docs for more details on the fields accepted by magicgui.

But again: all of this should be eventually done automatically for you!

Read more comments on GitHub >

github_iconTop Results From Across the Web

One code to rule them all: Android Server Driven UI
Welcome to Server Driven User Interface. JSON tree of data for a Server Driven UI app calling “/home” end-point. Note in this last...
Read more >
Building a declarative user interface app using JSON and ...
In this episode we build an app that loads its user interface from remote JSON, adding in actions to show web pages, alerts,...
Read more >
Extending UI with HTML, Javascript and CSS | Evaluation Guide
At OutSystems, we want to shield our developers from the complexities of HTML, CSS and Javascript as much as possible. We do this...
Read more >
Ways to Render UI dynamically from JSON response. - Reddit
I am planning to render the components dynamically on UI like text area, checkboxes, dropdown from the JSON response received from the ...
Read more >
How to :: Kafka Magic Tool
Publish Messages using Schemas. Kafka Magic allows you to publish JSON or Avro serialized messages to a Kafka topic via User Interface or...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found