Spaces:
Running
Running
Fix some issues. Almost working!
Browse files- server/basic_ops.py +3 -3
- server/main.py +3 -0
- server/ops.py +7 -1
- web/src/LynxKiteFlow.svelte +9 -3
server/basic_ops.py
CHANGED
|
@@ -9,7 +9,7 @@ def import_parquet(*, filename: str):
|
|
| 9 |
return pd.read_parquet(filename)
|
| 10 |
|
| 11 |
@ops.op("Create scale-free graph")
|
| 12 |
-
def create_scale_free_graph(*, nodes: int):
|
| 13 |
'''Creates a scale-free graph with the given number of nodes.'''
|
| 14 |
return nx.scale_free_graph(nodes)
|
| 15 |
|
|
@@ -19,7 +19,7 @@ def compute_pagerank(graph, *, damping: 0.85, iterations: 3):
|
|
| 19 |
|
| 20 |
@ops.op("Visualize graph")
|
| 21 |
def visualize_graph(graph) -> 'graphviz':
|
| 22 |
-
return {
|
| 23 |
'attributes': {
|
| 24 |
'name': 'My Graph'
|
| 25 |
},
|
|
@@ -39,4 +39,4 @@ def visualize_graph(graph) -> 'graphviz':
|
|
| 39 |
'target': 'Eric',
|
| 40 |
}
|
| 41 |
]
|
| 42 |
-
}
|
|
|
|
| 9 |
return pd.read_parquet(filename)
|
| 10 |
|
| 11 |
@ops.op("Create scale-free graph")
|
| 12 |
+
def create_scale_free_graph(*, nodes: int = 10):
|
| 13 |
'''Creates a scale-free graph with the given number of nodes.'''
|
| 14 |
return nx.scale_free_graph(nodes)
|
| 15 |
|
|
|
|
| 19 |
|
| 20 |
@ops.op("Visualize graph")
|
| 21 |
def visualize_graph(graph) -> 'graphviz':
|
| 22 |
+
return {
|
| 23 |
'attributes': {
|
| 24 |
'name': 'My Graph'
|
| 25 |
},
|
|
|
|
| 39 |
'target': 'Eric',
|
| 40 |
}
|
| 41 |
]
|
| 42 |
+
}
|
server/main.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
| 1 |
from typing import Optional
|
| 2 |
import fastapi
|
| 3 |
import pydantic
|
|
|
|
| 4 |
from . import ops
|
| 5 |
from . import basic_ops
|
| 6 |
|
|
@@ -65,9 +66,11 @@ def execute(ws):
|
|
| 65 |
try:
|
| 66 |
output = op(*inputs, **data.params)
|
| 67 |
except Exception as e:
|
|
|
|
| 68 |
data.error = str(e)
|
| 69 |
failed += 1
|
| 70 |
continue
|
|
|
|
| 71 |
outputs[node.id] = output
|
| 72 |
if op.type == 'graphviz':
|
| 73 |
data.graph = output
|
|
|
|
| 1 |
from typing import Optional
|
| 2 |
import fastapi
|
| 3 |
import pydantic
|
| 4 |
+
import traceback
|
| 5 |
from . import ops
|
| 6 |
from . import basic_ops
|
| 7 |
|
|
|
|
| 66 |
try:
|
| 67 |
output = op(*inputs, **data.params)
|
| 68 |
except Exception as e:
|
| 69 |
+
traceback.print_exc()
|
| 70 |
data.error = str(e)
|
| 71 |
failed += 1
|
| 72 |
continue
|
| 73 |
+
data.error = None
|
| 74 |
outputs[node.id] = output
|
| 75 |
if op.type == 'graphviz':
|
| 76 |
data.graph = output
|
server/ops.py
CHANGED
|
@@ -14,7 +14,13 @@ class Op:
|
|
| 14 |
type: str
|
| 15 |
|
| 16 |
def __call__(self, *inputs, **params):
|
| 17 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
res = self.func(*inputs, **params)
|
| 19 |
return res
|
| 20 |
|
|
|
|
| 14 |
type: str
|
| 15 |
|
| 16 |
def __call__(self, *inputs, **params):
|
| 17 |
+
# Convert parameters.
|
| 18 |
+
sig = inspect.signature(self.func)
|
| 19 |
+
for p in params:
|
| 20 |
+
if p in self.params:
|
| 21 |
+
t = sig.parameters[p].annotation
|
| 22 |
+
if t == int:
|
| 23 |
+
params[p] = int(params[p])
|
| 24 |
res = self.func(*inputs, **params)
|
| 25 |
return res
|
| 26 |
|
web/src/LynxKiteFlow.svelte
CHANGED
|
@@ -113,6 +113,12 @@
|
|
| 113 |
|
| 114 |
const graph = derived([nodes, edges], ([nodes, edges]) => ({ nodes, edges }));
|
| 115 |
let backendWorkspace;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 116 |
graph.subscribe(async (g) => {
|
| 117 |
const dragging = g.nodes.find((n) => n.dragging);
|
| 118 |
if (dragging) return;
|
|
@@ -120,7 +126,7 @@
|
|
| 120 |
for (const node of g.nodes) {
|
| 121 |
delete node.computed;
|
| 122 |
}
|
| 123 |
-
const ws =
|
| 124 |
if (ws === backendWorkspace) return;
|
| 125 |
console.log('current vs backend', '\n' + ws, '\n' + backendWorkspace);
|
| 126 |
backendWorkspace = ws;
|
|
@@ -129,10 +135,10 @@
|
|
| 129 |
headers: {
|
| 130 |
'Content-Type': 'application/json',
|
| 131 |
},
|
| 132 |
-
body:
|
| 133 |
});
|
| 134 |
const j = await res.json();
|
| 135 |
-
backendWorkspace =
|
| 136 |
nodes.set(j.nodes);
|
| 137 |
});
|
| 138 |
</script>
|
|
|
|
| 113 |
|
| 114 |
const graph = derived([nodes, edges], ([nodes, edges]) => ({ nodes, edges }));
|
| 115 |
let backendWorkspace;
|
| 116 |
+
// Like JSON.stringify, but with keys sorted.
|
| 117 |
+
function orderedJSON(obj: any) {
|
| 118 |
+
const allKeys = new Set();
|
| 119 |
+
JSON.stringify(obj, (key, value) => (allKeys.add(key), value));
|
| 120 |
+
return JSON.stringify(obj, Array.from(allKeys).sort());
|
| 121 |
+
}
|
| 122 |
graph.subscribe(async (g) => {
|
| 123 |
const dragging = g.nodes.find((n) => n.dragging);
|
| 124 |
if (dragging) return;
|
|
|
|
| 126 |
for (const node of g.nodes) {
|
| 127 |
delete node.computed;
|
| 128 |
}
|
| 129 |
+
const ws = orderedJSON(g);
|
| 130 |
if (ws === backendWorkspace) return;
|
| 131 |
console.log('current vs backend', '\n' + ws, '\n' + backendWorkspace);
|
| 132 |
backendWorkspace = ws;
|
|
|
|
| 135 |
headers: {
|
| 136 |
'Content-Type': 'application/json',
|
| 137 |
},
|
| 138 |
+
body: ws,
|
| 139 |
});
|
| 140 |
const j = await res.json();
|
| 141 |
+
backendWorkspace = orderedJSON(j);
|
| 142 |
nodes.set(j.nodes);
|
| 143 |
});
|
| 144 |
</script>
|