Spaces:
Running
Running
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
|
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 |
-
|
177 |
-
|
|
|
|
|
|
|
|
|
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(
|
|
|
|
|
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
|
|
|
|
|
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
|
232 |
-
|
|
|
|
|
|
|
|
|
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 |
|