Skip to content

Commit 2a2d958

Browse files
authored
Replace cryptic edges notation with elk inspired edges (#52)
* Replace cryptic edges notation with elk inspired edges The eclipse library provides a standard [JSON format for graphs](https://eclipse.dev/elk/documentation/tooldevelopers/graphdatastructure/jsonformat.html). So there is no need to invent a new JSON representation. * fix readme * fix jobflow
1 parent dba1fb4 commit 2a2d958

File tree

11 files changed

+175
-175
lines changed

11 files changed

+175
-175
lines changed

README.md

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,23 +43,23 @@ JSON file:
4343
"5": 2
4444
},
4545
"edges": [
46-
{"tn": 0, "th": "x", "sn": 1, "sh": "x"},
47-
{"tn": 1, "th": "x", "sn": 4, "sh": null},
48-
{"tn": 1, "th": "y", "sn": 5, "sh": null},
49-
{"tn": 0, "th": "y", "sn": 2, "sh": "y"},
50-
{"tn": 2, "th": "x", "sn": 4, "sh": null},
51-
{"tn": 2, "th": "y", "sn": 5, "sh": null},
52-
{"tn": 0, "th": "z", "sn": 3, "sh": "z"},
53-
{"tn": 3, "th": "x", "sn": 4, "sh": null},
54-
{"tn": 3, "th": "y", "sn": 5, "sh": null}
46+
{"target": 0, "targetPort": "x", "source": 1, "sourcePort": "x"},
47+
{"target": 1, "targetPort": "x", "source": 4, "sourcePort": null},
48+
{"target": 1, "targetPort": "y", "source": 5, "sourcePort": null},
49+
{"target": 0, "targetPort": "y", "source": 2, "sourcePort": "y"},
50+
{"target": 2, "targetPort": "x", "source": 4, "sourcePort": null},
51+
{"target": 2, "targetPort": "y", "source": 5, "sourcePort": null},
52+
{"target": 0, "targetPort": "z", "source": 3, "sourcePort": "z"},
53+
{"target": 3, "targetPort": "x", "source": 4, "sourcePort": null},
54+
{"target": 3, "targetPort": "y", "source": 5, "sourcePort": null}
5555
]
5656
}
5757
```
5858
The abbreviations in the definition of the edges are:
59-
* `tn` - target node
60-
* `th` - target handle - for a node with multiple input parameters the target handle specifies which input parameter to use.
61-
* `sn` - source node
62-
* `sh` - source handle - for a node with multiple output parameters the source handle specifies which output parameter to use.
59+
* `target` - target node
60+
* `targetPort` - target port - for a node with multiple input parameters the target port specifies which input parameter to use.
61+
* `source` - source node
62+
* `sourcePort` - source port - for a node with multiple output parameters the source port specifies which output parameter to use.
6363

6464
As the workflow does not require any additional resources, as it is only using built-in functionality of the Python standard
6565
library.

book/simple.md

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,23 +28,23 @@ JSON file:
2828
"5": 2
2929
},
3030
"edges": [
31-
{"tn": 0, "th": "x", "sn": 1, "sh": "x"},
32-
{"tn": 1, "th": "x", "sn": 4, "sh": null},
33-
{"tn": 1, "th": "y", "sn": 5, "sh": null},
34-
{"tn": 0, "th": "y", "sn": 2, "sh": "y"},
35-
{"tn": 2, "th": "x", "sn": 4, "sh": null},
36-
{"tn": 2, "th": "y", "sn": 5, "sh": null},
37-
{"tn": 0, "th": "z", "sn": 3, "sh": "z"},
38-
{"tn": 3, "th": "x", "sn": 4, "sh": null},
39-
{"tn": 3, "th": "y", "sn": 5, "sh": null}
31+
{"target": 0, "targetPort": "x", "source": 1, "sourcePort": "x"},
32+
{"target": 1, "targetPort": "x", "source": 4, "sourcePort": null},
33+
{"target": 1, "targetPort": "y", "source": 5, "sourcePort": null},
34+
{"target": 0, "targetPort": "y", "source": 2, "sourcePort": "y"},
35+
{"target": 2, "targetPort": "x", "source": 4, "sourcePort": null},
36+
{"target": 2, "targetPort": "y", "source": 5, "sourcePort": null},
37+
{"target": 0, "targetPort": "z", "source": 3, "sourcePort": "z"},
38+
{"target": 3, "targetPort": "x", "source": 4, "sourcePort": null},
39+
{"target": 3, "targetPort": "y", "source": 5, "sourcePort": null}
4040
]
4141
}
4242
```
4343
The abbreviations in the definition of the edges are:
44-
* `tn` - target node
45-
* `th` - target handle - for a node with multiple input parameters the target handle specifies which input parameter to use.
46-
* `sn` - source node
47-
* `sh` - source handle - for a node with multiple output parameters the source handle specifies which output parameter to use.
44+
* `target` - target node
45+
* `targetPort` - target port - for a node with multiple input parameters the target port specifies which input parameter to use.
46+
* `source` - source node
47+
* `sourcePort` - source port - for a node with multiple output parameters the source port specifies which output parameter to use.
4848

4949
As the workflow does not require any additional resources, as it is only using built-in functionality of the Python standard
5050
library.

python_workflow_definition/src/python_workflow_definition/aiida.py

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -31,32 +31,32 @@ def load_workflow_json(file_name):
3131

3232
# add links
3333
for link in data["edges"]:
34-
to_task = task_name_mapping[str(link["tn"])]
34+
to_task = task_name_mapping[str(link["target"])]
3535
# if the input is not exit, it means we pass the data into to the kwargs
3636
# in this case, we add the input socket
37-
if link["th"] not in to_task.inputs:
38-
to_socket = to_task.add_input( "workgraph.any", name=link["th"])
37+
if link["targetPort"] not in to_task.inputs:
38+
to_socket = to_task.add_input( "workgraph.any", name=link["targetPort"])
3939
else:
40-
to_socket = to_task.inputs[link["th"]]
41-
from_task = task_name_mapping[str(link["sn"])]
40+
to_socket = to_task.inputs[link["targetPort"]]
41+
from_task = task_name_mapping[str(link["source"])]
4242
if isinstance(from_task, orm.Data):
4343
to_socket.value = from_task
4444
else:
4545
try:
46-
if link["sh"] is None:
47-
link["sh"] = "result"
46+
if link["sourcePort"] is None:
47+
link["sourcePort"] = "result"
4848
# because we are not define the outputs explicitly during the pythonjob creation
4949
# we add it here, and assume the output exit
50-
if link["sh"] not in from_task.outputs:
51-
# if str(link["sh"]) not in from_task.outputs:
50+
if link["sourcePort"] not in from_task.outputs:
51+
# if str(link["sourcePort"]) not in from_task.outputs:
5252
from_socket = from_task.add_output(
5353
"workgraph.any",
54-
name=link["sh"],
55-
# name=str(link["sh"]),
54+
name=link["sourcePort"],
55+
# name=str(link["sourcePort"]),
5656
metadata={"is_function_output": True},
5757
)
5858
else:
59-
from_socket = from_task.outputs[link["sh"]]
59+
from_socket = from_task.outputs[link["sourcePort"]]
6060

6161
wg.add_link(from_socket, to_socket)
6262
except Exception as e:
@@ -84,10 +84,10 @@ def write_workflow_json(wg, file_name):
8484
# if the from socket is the default result, we set it to None
8585
if link_data["from_socket"] == "result":
8686
link_data["from_socket"] = None
87-
link_data["tn"] = node_name_mapping[link_data.pop("to_node")]
88-
link_data["th"] = link_data.pop("to_socket")
89-
link_data["sn"] = node_name_mapping[link_data.pop("from_node")]
90-
link_data["sh"] = link_data.pop("from_socket")
87+
link_data["target"] = node_name_mapping[link_data.pop("to_node")]
88+
link_data["targetPort"] = link_data.pop("to_socket")
89+
link_data["source"] = node_name_mapping[link_data.pop("from_node")]
90+
link_data["sourcePort"] = link_data.pop("from_socket")
9191
data["edges"].append(link_data)
9292

9393
for node in wg.tasks:
@@ -112,10 +112,10 @@ def write_workflow_json(wg, file_name):
112112
else:
113113
input_node_name = data_node_name_mapping[input.value.uuid]
114114
data["edges"].append({
115-
"tn": node_name_mapping[node.name],
116-
"th": input._name,
117-
"sn": input_node_name,
118-
"sh": None
115+
"target": node_name_mapping[node.name],
116+
"targetPort": input._name,
117+
"source": input_node_name,
118+
"sourcePort": None
119119
})
120120
with open(file_name, "w") as f:
121121
# json.dump({"nodes": data[], "edges": edges_new_lst}, f)

python_workflow_definition/src/python_workflow_definition/executorlib.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ def get_item(obj, key):
1212

1313

1414
def _get_value(result_dict, nodes_new_dict, link_dict, exe):
15-
source, source_handle = link_dict["sn"], link_dict["sh"]
15+
source, source_handle = link_dict["source"], link_dict["sourcePort"]
1616
if source in result_dict.keys():
1717
result = result_dict[source]
1818
elif source in nodes_new_dict.keys():

python_workflow_definition/src/python_workflow_definition/jobflow.py

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -26,27 +26,27 @@ def _get_nodes_dict(function_dict):
2626

2727
def _get_edge_from_dict(target, key, value_dict, nodes_mapping_dict):
2828
if len(value_dict['attributes']) == 1:
29-
return {'tn': target, 'th': key, "sn": nodes_mapping_dict[value_dict['uuid']], 'sh': value_dict['attributes'][0][1]}
29+
return {"target": target, "targetPort": key, "source": nodes_mapping_dict[value_dict["uuid"]], "sourcePort": value_dict["attributes"][0][1]}
3030
else:
31-
return {'tn': target, 'th': key, "sn": nodes_mapping_dict[value_dict['uuid']], 'sh': None}
31+
return {"target": target, "targetPort": key, "source": nodes_mapping_dict[value_dict["uuid"]], "sourcePort": None}
3232

3333

3434
def _get_edges_and_extend_nodes(flow_dict, nodes_mapping_dict, nodes_dict):
3535
edges_lst = []
36-
for job in flow_dict['jobs']:
37-
for k, v in job['function_kwargs'].items():
38-
if isinstance(v, dict) and '@module' in v and '@class' in v and '@version' in v:
36+
for job in flow_dict["jobs"]:
37+
for k, v in job["function_kwargs"].items():
38+
if isinstance(v, dict) and "@module" in v and "@class" in v and "@version" in v:
3939
edges_lst.append(_get_edge_from_dict(
4040
target=nodes_mapping_dict[job["uuid"]],
4141
key=k,
4242
value_dict=v,
4343
nodes_mapping_dict=nodes_mapping_dict,
4444
))
45-
elif isinstance(v, dict) and any([isinstance(el, dict) and '@module' in el and '@class' in el and '@version' in el for el in v.values()]):
45+
elif isinstance(v, dict) and any([isinstance(el, dict) and "@module" in el and "@class" in el and "@version" in el for el in v.values()]):
4646
node_dict_index = len(nodes_dict)
4747
nodes_dict[node_dict_index] = get_dict
4848
for kt, vt in v.items():
49-
if isinstance(vt, dict) and '@module' in vt and '@class' in vt and '@version' in vt:
49+
if isinstance(vt, dict) and "@module" in vt and "@class" in vt and "@version" in vt:
5050
edges_lst.append(_get_edge_from_dict(
5151
target=node_dict_index,
5252
key=kt,
@@ -59,13 +59,13 @@ def _get_edges_and_extend_nodes(flow_dict, nodes_mapping_dict, nodes_dict):
5959
nodes_dict[node_index] = vt
6060
else:
6161
node_index = {str(tv): tk for tk, tv in nodes_dict.items()}[str(vt)]
62-
edges_lst.append({'tn': node_dict_index, 'th': kt, "sn": node_index, 'sh': None})
63-
edges_lst.append({'tn': nodes_mapping_dict[job["uuid"]], 'th': k, "sn": node_dict_index, 'sh': None})
64-
elif isinstance(v, list) and any([isinstance(el, dict) and '@module' in el and '@class' in el and '@version' in el for el in v]):
62+
edges_lst.append({"target": node_dict_index, "targetPort": kt, "source": node_index, "sourcePort": None})
63+
edges_lst.append({"target": nodes_mapping_dict[job["uuid"]], "targetPort": k, "source": node_dict_index, "sourcePort": None})
64+
elif isinstance(v, list) and any([isinstance(el, dict) and "@module" in el and "@class" in el and "@version" in el for el in v]):
6565
node_list_index = len(nodes_dict)
6666
nodes_dict[node_list_index] = get_list
6767
for kt, vt in enumerate(v):
68-
if isinstance(vt, dict) and '@module' in vt and '@class' in vt and '@version' in vt:
68+
if isinstance(vt, dict) and "@module" in vt and "@class" in vt and "@version" in vt:
6969
edges_lst.append(_get_edge_from_dict(
7070
target=node_list_index,
7171
key=str(kt),
@@ -78,15 +78,15 @@ def _get_edges_and_extend_nodes(flow_dict, nodes_mapping_dict, nodes_dict):
7878
nodes_dict[node_index] = vt
7979
else:
8080
node_index = {str(tv): tk for tk, tv in nodes_dict.items()}[str(vt)]
81-
edges_lst.append({'tn': node_list_index, 'th': kt, "sn": node_index, 'sh': None})
82-
edges_lst.append({'tn': nodes_mapping_dict[job["uuid"]], 'th': k, "sn": node_list_index, 'sh': None})
81+
edges_lst.append({"target": node_list_index, "targetPort": kt, "source": node_index, "sourcePort": None})
82+
edges_lst.append({"target": nodes_mapping_dict[job["uuid"]], "targetPort": k, "source": node_list_index, "sourcePort": None})
8383
else:
8484
if v not in nodes_dict.values():
8585
node_index = len(nodes_dict)
8686
nodes_dict[node_index] = v
8787
else:
8888
node_index = {tv: tk for tk, tv in nodes_dict.items()}[v]
89-
edges_lst.append({'tn': nodes_mapping_dict[job["uuid"]], 'th': k, "sn": node_index, 'sh': None})
89+
edges_lst.append({"target": nodes_mapping_dict[job["uuid"]], "targetPort": k, "source": node_index, "sourcePort": None})
9090
return edges_lst, nodes_dict
9191

9292

@@ -99,7 +99,7 @@ def _resort_total_lst(total_dict, nodes_dict):
9999
for ind in sorted(total_dict.keys()):
100100
connect = total_dict[ind]
101101
if ind not in ordered_lst:
102-
source_lst = [sd["sn"] for sd in connect.values()]
102+
source_lst = [sd["source"] for sd in connect.values()]
103103
if all([s in ordered_lst or s in nodes_without_dep_lst for s in source_lst]):
104104
ordered_lst.append(ind)
105105
total_new_dict[ind] = connect
@@ -109,11 +109,11 @@ def _resort_total_lst(total_dict, nodes_dict):
109109
def _group_edges(edges_lst):
110110
total_dict = {}
111111
for ed_major in edges_lst:
112-
target_id = ed_major["tn"]
112+
target_id = ed_major["target"]
113113
tmp_lst = []
114114
if target_id not in total_dict.keys():
115115
for ed in edges_lst:
116-
if target_id == ed["tn"]:
116+
if target_id == ed["target"]:
117117
tmp_lst.append(ed)
118118
total_dict[target_id] = get_kwargs(lst=tmp_lst)
119119
return total_dict
@@ -139,8 +139,8 @@ def get_attr_helper(obj, source_handle):
139139
else:
140140
fn = job(method=v)
141141
kwargs = {
142-
kw: input_dict[vw['sn']] if vw['sn'] in input_dict else get_attr_helper(
143-
obj=memory_dict[vw['sn']], source_handle=vw['sh'])
142+
kw: input_dict[vw["source"]] if vw["source"] in input_dict else get_attr_helper(
143+
obj=memory_dict[vw["source"]], source_handle=vw["sourcePort"])
144144
for kw, vw in total_dict[k].items()
145145
}
146146
memory_dict[k] = fn(**kwargs)
@@ -160,15 +160,15 @@ def load_workflow_json(file_name):
160160

161161
edges_new_lst = []
162162
for edge in content["edges"]:
163-
if edge['sh'] is None:
163+
if edge["sourcePort"] is None:
164164
edges_new_lst.append(edge)
165165
else:
166166
edges_new_lst.append(
167167
{
168-
'tn': edge['tn'],
169-
'th': edge['th'],
170-
'sn': edge['sn'],
171-
'sh': str(edge['sh']),
168+
"target": edge["target"],
169+
"targetPort": edge["targetPort"],
170+
"source": edge["source"],
171+
"sourcePort": str(edge["sourcePort"]),
172172
}
173173
)
174174

python_workflow_definition/src/python_workflow_definition/purepython.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,30 +13,30 @@ def resort_total_lst(total_lst, nodes_dict):
1313
while len(total_new_lst) < len(total_lst):
1414
for ind, connect in total_lst:
1515
if ind not in ordered_lst:
16-
source_lst = [sd["sn"] for sd in connect.values()]
16+
source_lst = [sd["source"] for sd in connect.values()]
1717
if all([s in ordered_lst or s in nodes_without_dep_lst for s in source_lst]):
1818
ordered_lst.append(ind)
1919
total_new_lst.append([ind, connect])
2020
return total_new_lst
2121

2222

2323
def group_edges(edges_lst):
24-
edges_sorted_lst = sorted(edges_lst, key=lambda x: x["tn"], reverse=True)
24+
edges_sorted_lst = sorted(edges_lst, key=lambda x: x["target"], reverse=True)
2525
total_lst, tmp_lst = [], []
26-
target_id = edges_sorted_lst[0]["tn"]
26+
target_id = edges_sorted_lst[0]["target"]
2727
for ed in edges_sorted_lst:
28-
if target_id == ed["tn"]:
28+
if target_id == ed["target"]:
2929
tmp_lst.append(ed)
3030
else:
3131
total_lst.append((target_id, get_kwargs(lst=tmp_lst)))
32-
target_id = ed["tn"]
32+
target_id = ed["target"]
3333
tmp_lst = [ed]
3434
total_lst.append((target_id, get_kwargs(lst=tmp_lst)))
3535
return total_lst
3636

3737

3838
def _get_value(result_dict, nodes_new_dict, link_dict):
39-
source, source_handle = link_dict["sn"], link_dict["sh"]
39+
source, source_handle = link_dict["source"], link_dict["sourcePort"]
4040
if source in result_dict.keys():
4141
result = result_dict[source]
4242
elif source in nodes_new_dict.keys():

0 commit comments

Comments
 (0)