Skip to content

Commit 20c48b7

Browse files
authored
Add pure python interface (#15)
* Add pure python interface * fix CI
1 parent 4428f03 commit 20c48b7

File tree

4 files changed

+224
-0
lines changed

4 files changed

+224
-0
lines changed

.github/workflows/python.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: python
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
8+
jobs:
9+
build:
10+
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- uses: actions/checkout@v4
15+
- uses: conda-incubator/setup-miniconda@v3
16+
with:
17+
auto-update-conda: true
18+
python-version: "3.12"
19+
environment-file: environment.yml
20+
auto-activate-base: false
21+
- name: Tests
22+
shell: bash -l {0}
23+
run: |
24+
pip install -e adis_tools
25+
pip install -e python_workflow_definition
26+
conda install -c conda-forge jupyter papermill
27+
export ESPRESSO_PSEUDO=$(pwd)/espresso/pseudo
28+
papermill universal_simple_to_python.ipynb universal_simple_to_python_out.ipynb -k "python3"
29+
papermill universal_qe_to_python.ipynb universal_qe_to_python_out.ipynb -k "python3"
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import json
2+
from importlib import import_module
3+
from inspect import isfunction
4+
5+
6+
def get_dict(**kwargs):
7+
return {k: v for k, v in kwargs.items()}
8+
9+
10+
def get_list(**kwargs):
11+
return list(kwargs.values())
12+
13+
14+
def get_kwargs(lst):
15+
return {t['targetHandle']: {'source': t['source'], 'sourceHandle': t['sourceHandle']} for t in lst}
16+
17+
18+
def resort_total_lst(total_lst, nodes_dict):
19+
nodes_with_dep_lst = list(sorted([v[0] for v in total_lst]))
20+
nodes_without_dep_lst = [k for k in nodes_dict.keys() if k not in nodes_with_dep_lst]
21+
ordered_lst, total_new_lst = [], []
22+
while len(total_new_lst) < len(total_lst):
23+
for ind, connect in total_lst:
24+
if ind not in ordered_lst:
25+
source_lst = [sd["source"] for sd in connect.values()]
26+
if all([s in ordered_lst or s in nodes_without_dep_lst for s in source_lst]):
27+
ordered_lst.append(ind)
28+
total_new_lst.append([ind, connect])
29+
return total_new_lst
30+
31+
32+
def group_edges(edges_lst):
33+
edges_sorted_lst = sorted(edges_lst, key=lambda x: x['target'], reverse=True)
34+
total_lst, tmp_lst = [], []
35+
target_id = edges_sorted_lst[0]['target']
36+
for ed in edges_sorted_lst:
37+
if target_id == ed["target"]:
38+
tmp_lst.append(ed)
39+
else:
40+
total_lst.append((target_id, get_kwargs(lst=tmp_lst)))
41+
target_id = ed["target"]
42+
tmp_lst = [ed]
43+
total_lst.append((target_id, get_kwargs(lst=tmp_lst)))
44+
return total_lst
45+
46+
47+
def get_source_handles(edges_lst):
48+
source_handle_dict = {}
49+
for ed in edges_lst:
50+
if ed['source'] not in source_handle_dict.keys():
51+
source_handle_dict[ed['source']] = [ed['sourceHandle']]
52+
else:
53+
source_handle_dict[ed['source']].append(ed['sourceHandle'])
54+
return {
55+
k: list(range(len(v))) if len(v) > 1 and all([el is None for el in v]) else v
56+
for k, v in source_handle_dict.items()
57+
}
58+
59+
60+
def get_value(result_dict, nodes_new_dict, link_dict):
61+
source, source_handle = link_dict["source"], link_dict["sourceHandle"]
62+
if source in result_dict.keys():
63+
result = result_dict[source]
64+
elif source in nodes_new_dict.keys():
65+
result = nodes_new_dict[source]
66+
else:
67+
raise KeyError()
68+
if source_handle is None:
69+
return result
70+
else:
71+
return result[source_handle]
72+
73+
74+
def load_workflow_json(file_name):
75+
with open(file_name, "r") as f:
76+
content = json.load(f)
77+
78+
edges_new_lst = content["edges"]
79+
nodes_new_dict = {}
80+
for k, v in content["nodes"].items():
81+
if isinstance(v, str) and "." in v:
82+
p, m = v.rsplit('.', 1)
83+
if p == "python_workflow_definition.pyiron_base":
84+
p = "python_workflow_definition.purepython"
85+
mod = import_module(p)
86+
nodes_new_dict[int(k)] = getattr(mod, m)
87+
else:
88+
nodes_new_dict[int(k)] = v
89+
90+
total_lst = group_edges(edges_new_lst)
91+
total_new_lst = resort_total_lst(total_lst=total_lst, nodes_dict=nodes_new_dict)
92+
93+
result_dict = {}
94+
last_key = None
95+
for lst in total_new_lst:
96+
node = nodes_new_dict[lst[0]]
97+
if isfunction(node):
98+
kwargs = {
99+
k: get_value(result_dict=result_dict, nodes_new_dict=nodes_new_dict, link_dict=v)
100+
for k, v in lst[1].items()
101+
}
102+
result_dict[lst[0]] = node(**kwargs)
103+
last_key = lst[0]
104+
105+
return result_dict[last_key]

universal_qe_to_python.ipynb

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"id": "b0f920a2-c646-485b-af0f-48251e061163",
7+
"metadata": {},
8+
"outputs": [],
9+
"source": [
10+
"from python_workflow_definition.purepython import load_workflow_json"
11+
]
12+
},
13+
{
14+
"cell_type": "code",
15+
"execution_count": null,
16+
"id": "46559120-d58a-492f-b734-db27424b5659",
17+
"metadata": {},
18+
"outputs": [],
19+
"source": [
20+
"load_workflow_json(file_name=\"workflow_qe.json\")"
21+
]
22+
}
23+
],
24+
"metadata": {
25+
"kernelspec": {
26+
"display_name": "Python 3 (ipykernel)",
27+
"language": "python",
28+
"name": "python3"
29+
},
30+
"language_info": {
31+
"codemirror_mode": {
32+
"name": "ipython",
33+
"version": 3
34+
},
35+
"file_extension": ".py",
36+
"mimetype": "text/x-python",
37+
"name": "python",
38+
"nbconvert_exporter": "python",
39+
"pygments_lexer": "ipython3",
40+
"version": "3.12.5"
41+
}
42+
},
43+
"nbformat": 4,
44+
"nbformat_minor": 5
45+
}

universal_simple_to_python.ipynb

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"id": "b0f920a2-c646-485b-af0f-48251e061163",
7+
"metadata": {},
8+
"outputs": [],
9+
"source": [
10+
"from python_workflow_definition.purepython import load_workflow_json"
11+
]
12+
},
13+
{
14+
"cell_type": "code",
15+
"execution_count": null,
16+
"id": "46559120-d58a-492f-b734-db27424b5659",
17+
"metadata": {},
18+
"outputs": [],
19+
"source": [
20+
"load_workflow_json(file_name=\"workflow_simple.json\")"
21+
]
22+
}
23+
],
24+
"metadata": {
25+
"kernelspec": {
26+
"display_name": "Python 3 (ipykernel)",
27+
"language": "python",
28+
"name": "python3"
29+
},
30+
"language_info": {
31+
"codemirror_mode": {
32+
"name": "ipython",
33+
"version": 3
34+
},
35+
"file_extension": ".py",
36+
"mimetype": "text/x-python",
37+
"name": "python",
38+
"nbconvert_exporter": "python",
39+
"pygments_lexer": "ipython3",
40+
"version": "3.12.5"
41+
}
42+
},
43+
"nbformat": 4,
44+
"nbformat_minor": 5
45+
}

0 commit comments

Comments
 (0)