darabos commited on
Commit
86e898a
·
1 Parent(s): 97c9ed9

Support for multiple outputs in a dict.

Browse files
lynxkite-app/web/src/workspace/nodes/LynxKiteNode.tsx CHANGED
@@ -42,10 +42,12 @@ function getHandles(inputs: any[], outputs: any[]) {
42
  e.index = counts[e.position];
43
  counts[e.position]++;
44
  }
 
 
 
 
45
  for (const e of handles) {
46
  e.offsetPercentage = (100 * (e.index + 1)) / (counts[e.position] + 1);
47
- const simpleHorizontal = counts.top === 0 && counts.bottom === 0 && handles.length <= 2;
48
- const simpleVertical = counts.left === 0 && counts.right === 0 && handles.length <= 2;
49
  e.showLabel = !simpleHorizontal && !simpleVertical;
50
  }
51
  return handles;
 
42
  e.index = counts[e.position];
43
  counts[e.position]++;
44
  }
45
+ const simpleHorizontal =
46
+ counts.top === 0 && counts.bottom === 0 && counts.left <= 1 && counts.right <= 1;
47
+ const simpleVertical =
48
+ counts.left === 0 && counts.right === 0 && counts.top <= 1 && counts.bottom <= 1;
49
  for (const e of handles) {
50
  e.offsetPercentage = (100 * (e.index + 1)) / (counts[e.position] + 1);
 
 
51
  e.showLabel = !simpleHorizontal && !simpleVertical;
52
  }
53
  return handles;
lynxkite-graph-analytics/src/lynxkite_graph_analytics/core.py CHANGED
@@ -161,11 +161,15 @@ def disambiguate_edges(ws: workspace.Workspace):
161
  seen.add((edge.target, edge.targetHandle))
162
 
163
 
 
 
 
 
164
  @ops.register_executor(ENV)
165
  async def execute(ws: workspace.Workspace):
166
- catalog: dict[str, ops.Op] = ops.CATALOGS[ws.env]
167
  disambiguate_edges(ws)
168
- outputs = {}
169
  nodes = {node.id: node for node in ws.nodes}
170
  todo = set(nodes.keys())
171
  progress = True
@@ -173,8 +177,12 @@ async def execute(ws: workspace.Workspace):
173
  progress = False
174
  for id in list(todo):
175
  node = nodes[id]
176
- input_nodes = [edge.source for edge in ws.edges if edge.target == id]
177
- if all(input in outputs for input in input_nodes):
 
 
 
 
178
  # All inputs for this node are ready, we can compute the output.
179
  todo.remove(id)
180
  progress = True
@@ -187,7 +195,9 @@ async def await_if_needed(obj):
187
  return obj
188
 
189
 
190
- async def _execute_node(node, ws, catalog, outputs):
 
 
191
  params = {**node.data.params}
192
  op = catalog.get(node.data.title)
193
  if not op:
@@ -196,7 +206,9 @@ async def _execute_node(node, ws, catalog, outputs):
196
  node.publish_started()
197
  # TODO: Handle multi-inputs.
198
  input_map = {
199
- edge.targetHandle: outputs[edge.source] for edge in ws.edges if edge.target == node.id
 
 
200
  }
201
  # Convert inputs types to match operation signature.
202
  try:
@@ -228,8 +240,12 @@ async def _execute_node(node, ws, catalog, outputs):
228
  traceback.print_exc()
229
  result = ops.Result(error=str(e))
230
  result.input_metadata = [_get_metadata(i) for i in inputs]
231
- if result.output is not None:
232
- outputs[node.id] = result.output
 
 
 
 
233
  node.publish_result(result)
234
 
235
 
 
161
  seen.add((edge.target, edge.targetHandle))
162
 
163
 
164
+ # Outputs are tracked by node ID and output ID.
165
+ Outputs = dict[(str, str), typing.Any]
166
+
167
+
168
  @ops.register_executor(ENV)
169
  async def execute(ws: workspace.Workspace):
170
+ catalog = ops.CATALOGS[ws.env]
171
  disambiguate_edges(ws)
172
+ outputs: Outputs = {}
173
  nodes = {node.id: node for node in ws.nodes}
174
  todo = set(nodes.keys())
175
  progress = True
 
177
  progress = False
178
  for id in list(todo):
179
  node = nodes[id]
180
+ inputs_done = [
181
+ (edge.source, edge.sourceHandle) in outputs
182
+ for edge in ws.edges
183
+ if edge.target == id
184
+ ]
185
+ if all(inputs_done):
186
  # All inputs for this node are ready, we can compute the output.
187
  todo.remove(id)
188
  progress = True
 
195
  return obj
196
 
197
 
198
+ async def _execute_node(
199
+ node: workspace.WorkspaceNode, ws: workspace.Workspace, catalog: ops.Catalog, outputs: Outputs
200
+ ):
201
  params = {**node.data.params}
202
  op = catalog.get(node.data.title)
203
  if not op:
 
206
  node.publish_started()
207
  # TODO: Handle multi-inputs.
208
  input_map = {
209
+ edge.targetHandle: outputs[edge.source, edge.sourceHandle]
210
+ for edge in ws.edges
211
+ if edge.target == node.id
212
  }
213
  # Convert inputs types to match operation signature.
214
  try:
 
240
  traceback.print_exc()
241
  result = ops.Result(error=str(e))
242
  result.input_metadata = [_get_metadata(i) for i in inputs]
243
+ if isinstance(result.output, dict):
244
+ for k, v in result.output.items():
245
+ outputs[node.id, k] = v
246
+ elif result.output is not None:
247
+ [k] = op.outputs
248
+ outputs[node.id, k.name] = result.output
249
  node.publish_result(result)
250
 
251