Skip to content

Commit

Permalink
bugfix: Add missing inputs and outputs in REST API JSON payload (#312)
Browse files Browse the repository at this point in the history
* Fix logic for fixing missing inputs and outputs

* Fix logic for fixing missing inputs and outputs

* update test ground truth
  • Loading branch information
sameeul authored Jan 8, 2025
1 parent ce3a1af commit 20f0865
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 40 deletions.
1 change: 0 additions & 1 deletion src/sophios/api/http/restapi.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from pathlib import Path
import argparse
import copy
import uuid
import yaml


Expand Down
72 changes: 35 additions & 37 deletions src/sophios/api/utils/converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -327,45 +327,43 @@ def update_payload_missing_inputs_outputs(wfb_data: Json) -> Json:
nodes = wfb_data_copy["state"]["nodes"]
plugins = wfb_data_copy["plugins"]

# hashmap of node id to nodes for fast node lookup
nodes_dict = {node['id']: node for node in nodes}
if plugins != []:
plugin_config_map: dict[str, dict] = {}
plugin_output_map: dict[str, list] = {}
for plugin in plugins:
pid: str = plugin.get("pid", "")
if pid == "":
continue
plugin_config_map[pid] = get_node_config(plugin)
plugin_output_map[pid] = plugin.get("outputs", [])

# add missing outputs
for node in nodes:
base_name = node["name"].replace(" ", "").lower() + "_" + str(node["id"])
if "outputs" not in node["settings"]:
node["settings"]["outputs"] = {}
node_outputs = node["settings"]["outputs"]
plugin_outputs: list = plugin_output_map.get(node["pluginId"], [])
for output in plugin_outputs:
if output["type"] == "path" and output["name"] not in node_outputs:
node_outputs[output["name"]] = base_name + "-" + output["name"]

# hashmap of node id to nodes for fast node lookup
nodes_dict = {node['id']: node for node in nodes}
# use the look up logic similar to WFB to connect inputs and outputs
for link in links:
src_node = nodes_dict[link['sourceId']]
tgt_node = nodes_dict[link['targetId']]

# hashmap of plugins id to nodes for fast plugin lookup
plugins_dict = {plugin['pid']: plugin for plugin in plugins}

# find links corresponding to the node
for link in links:

# link ids
target_id: int = link["targetId"]
source_id: int = link["sourceId"]

target_node = nodes_dict[target_id]
source_node = nodes_dict[source_id]

# plugins corresponding to the nodes
target_plugin = plugins_dict[target_node["pluginId"]]
source_plugin = plugins_dict[source_node["pluginId"]]

def is_inlet(binding: Json) -> bool:
"""Check if a wfb input is an inlet (directory)"""

return (
binding['type'] in ['directory', 'file', 'path', 'collection', 'csvCollection'] or
binding['name'].lower() == 'inpdir' or
binding['name'].lower().endswith('path') or
binding['name'].lower().endswith('dir')
)

# filter inputs by to only be inlets (directories)
input_directories = [binding for binding in target_plugin["inputs"] if is_inlet(binding)]
output_directories = [binding for binding in source_plugin["outputs"] if is_inlet(binding)]

missing_input_key = input_directories[link["inletIndex"]]["name"]
missing_output_key = output_directories[link["outletIndex"]]["name"]
src_node_ui_config = plugin_config_map.get(src_node['pluginId'], None)
tgt_node_ui_config = plugin_config_map.get(tgt_node['pluginId'], None)

# add the missing input value to the node if needed
target_node["settings"]["inputs"][missing_input_key] = source_node["settings"]["outputs"][missing_output_key]
if src_node_ui_config and tgt_node_ui_config:
inlet_index = link['inletIndex']
outlet_index = link['outletIndex']
src_node_out_arg = src_node_ui_config['outputs'][outlet_index]["name"]
tgt_node_in_arg = tgt_node_ui_config['inputs'][inlet_index]["name"]
tgt_node["settings"]["inputs"][tgt_node_in_arg] = src_node["settings"]["outputs"][src_node_out_arg]

if validate_schema_and_object(SCHEMA, wfb_data_copy):
print('Updated object is valid against input object schema')
Expand Down
4 changes: 2 additions & 2 deletions tests/data/wfb_data/multi_node/multi_node_wfb_truth.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@
"width": 250,
"settings": {
"inputs": {
"stitchPath": "omeconverter_2-outDir",
"imgPath": "montage_4-outDir"
"stitchPath": "montage_4-outDir",
"imgPath": "omeconverter_2-outDir"
},
"outputs": {
"outDir": "imageassembler_5-outDir"
Expand Down

0 comments on commit 20f0865

Please sign in to comment.