jobflow 0.1.19__tar.gz → 0.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {jobflow-0.1.19/src/jobflow.egg-info → jobflow-0.2.1}/PKG-INFO +32 -30
- {jobflow-0.1.19 → jobflow-0.2.1}/pyproject.toml +30 -27
- {jobflow-0.1.19 → jobflow-0.2.1}/src/jobflow/core/flow.py +7 -2
- {jobflow-0.1.19 → jobflow-0.2.1}/src/jobflow/core/job.py +45 -25
- {jobflow-0.1.19 → jobflow-0.2.1}/src/jobflow/core/reference.py +1 -1
- {jobflow-0.1.19 → jobflow-0.2.1}/src/jobflow/utils/graph.py +1 -1
- {jobflow-0.1.19 → jobflow-0.2.1}/src/jobflow/utils/uuid.py +4 -1
- {jobflow-0.1.19 → jobflow-0.2.1/src/jobflow.egg-info}/PKG-INFO +32 -30
- jobflow-0.2.1/src/jobflow.egg-info/requires.txt +52 -0
- {jobflow-0.1.19 → jobflow-0.2.1}/tests/test_settings.py +1 -1
- jobflow-0.1.19/src/jobflow.egg-info/requires.txt +0 -52
- {jobflow-0.1.19 → jobflow-0.2.1}/LICENSE +0 -0
- {jobflow-0.1.19 → jobflow-0.2.1}/README.md +0 -0
- {jobflow-0.1.19 → jobflow-0.2.1}/setup.cfg +0 -0
- {jobflow-0.1.19 → jobflow-0.2.1}/src/jobflow/__init__.py +0 -0
- {jobflow-0.1.19 → jobflow-0.2.1}/src/jobflow/_version.py +0 -0
- {jobflow-0.1.19 → jobflow-0.2.1}/src/jobflow/core/__init__.py +0 -0
- {jobflow-0.1.19 → jobflow-0.2.1}/src/jobflow/core/maker.py +0 -0
- {jobflow-0.1.19 → jobflow-0.2.1}/src/jobflow/core/schemas.py +0 -0
- {jobflow-0.1.19 → jobflow-0.2.1}/src/jobflow/core/state.py +0 -0
- {jobflow-0.1.19 → jobflow-0.2.1}/src/jobflow/core/store.py +0 -0
- {jobflow-0.1.19 → jobflow-0.2.1}/src/jobflow/managers/__init__.py +0 -0
- {jobflow-0.1.19 → jobflow-0.2.1}/src/jobflow/managers/fireworks.py +0 -0
- {jobflow-0.1.19 → jobflow-0.2.1}/src/jobflow/managers/local.py +0 -0
- {jobflow-0.1.19 → jobflow-0.2.1}/src/jobflow/py.typed +0 -0
- {jobflow-0.1.19 → jobflow-0.2.1}/src/jobflow/settings.py +0 -0
- {jobflow-0.1.19 → jobflow-0.2.1}/src/jobflow/utils/__init__.py +0 -0
- {jobflow-0.1.19 → jobflow-0.2.1}/src/jobflow/utils/dict_mods.py +0 -0
- {jobflow-0.1.19 → jobflow-0.2.1}/src/jobflow/utils/enum.py +0 -0
- {jobflow-0.1.19 → jobflow-0.2.1}/src/jobflow/utils/find.py +0 -0
- {jobflow-0.1.19 → jobflow-0.2.1}/src/jobflow/utils/log.py +0 -0
- {jobflow-0.1.19 → jobflow-0.2.1}/src/jobflow/utils/uid.py +0 -0
- {jobflow-0.1.19 → jobflow-0.2.1}/src/jobflow.egg-info/SOURCES.txt +0 -0
- {jobflow-0.1.19 → jobflow-0.2.1}/src/jobflow.egg-info/dependency_links.txt +0 -0
- {jobflow-0.1.19 → jobflow-0.2.1}/src/jobflow.egg-info/top_level.txt +0 -0
- {jobflow-0.1.19 → jobflow-0.2.1}/tests/test_version.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: jobflow
|
|
3
|
-
Version: 0.1
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: jobflow is a library for writing computational workflows
|
|
5
5
|
Author-email: Alex Ganose <a.ganose@imperial.ac.uk>
|
|
6
6
|
License: modified BSD
|
|
@@ -17,56 +17,58 @@ Classifier: Operating System :: OS Independent
|
|
|
17
17
|
Classifier: Programming Language :: Python :: 3
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.10
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
22
|
Classifier: Topic :: Database :: Front-Ends
|
|
22
23
|
Classifier: Topic :: Other/Nonlisted Topic
|
|
23
24
|
Classifier: Topic :: Scientific/Engineering
|
|
24
|
-
Requires-Python: >=3.
|
|
25
|
+
Requires-Python: >=3.10
|
|
25
26
|
Description-Content-Type: text/markdown
|
|
26
27
|
License-File: LICENSE
|
|
27
|
-
Requires-Dist: PyYAML
|
|
28
|
-
Requires-Dist: maggma>=0.
|
|
28
|
+
Requires-Dist: PyYAML>=6.0.1
|
|
29
|
+
Requires-Dist: maggma>=0.72.0
|
|
29
30
|
Requires-Dist: monty>=2023.9.25
|
|
30
|
-
Requires-Dist: networkx
|
|
31
|
+
Requires-Dist: networkx>=3.2.1
|
|
31
32
|
Requires-Dist: pydantic-settings>=2.0.3
|
|
32
|
-
Requires-Dist: pydantic>=2.
|
|
33
|
-
Requires-Dist: pydash
|
|
33
|
+
Requires-Dist: pydantic>=2.4
|
|
34
|
+
Requires-Dist: pydash>=8.0.1
|
|
34
35
|
Provides-Extra: ulid
|
|
35
36
|
Requires-Dist: python-ulid; extra == "ulid"
|
|
36
37
|
Provides-Extra: docs
|
|
37
|
-
Requires-Dist: autodoc_pydantic==2.
|
|
38
|
-
Requires-Dist: furo==
|
|
39
|
-
Requires-Dist: ipython==
|
|
40
|
-
Requires-Dist: myst_parser==4.0.
|
|
41
|
-
Requires-Dist: nbsphinx==0.9.
|
|
38
|
+
Requires-Dist: autodoc_pydantic==2.2.0; extra == "docs"
|
|
39
|
+
Requires-Dist: furo==2025.9.25; extra == "docs"
|
|
40
|
+
Requires-Dist: ipython==9.3.0; extra == "docs"
|
|
41
|
+
Requires-Dist: myst_parser==4.0.1; extra == "docs"
|
|
42
|
+
Requires-Dist: nbsphinx==0.9.7; extra == "docs"
|
|
42
43
|
Requires-Dist: sphinx-copybutton==0.5.2; extra == "docs"
|
|
43
44
|
Requires-Dist: sphinx==8.1.3; extra == "docs"
|
|
44
45
|
Provides-Extra: dev
|
|
45
46
|
Requires-Dist: pre-commit>=2.12.1; extra == "dev"
|
|
46
47
|
Requires-Dist: typing_extensions; python_version < "3.11" and extra == "dev"
|
|
47
48
|
Provides-Extra: tests
|
|
48
|
-
Requires-Dist: moto==
|
|
49
|
-
Requires-Dist: pytest-cov==
|
|
50
|
-
Requires-Dist: pytest==8.
|
|
49
|
+
Requires-Dist: moto==5.1.16; extra == "tests"
|
|
50
|
+
Requires-Dist: pytest-cov==7.0.0; extra == "tests"
|
|
51
|
+
Requires-Dist: pytest==8.4.2; extra == "tests"
|
|
51
52
|
Provides-Extra: vis
|
|
52
53
|
Requires-Dist: matplotlib; extra == "vis"
|
|
53
54
|
Requires-Dist: pydot; extra == "vis"
|
|
54
55
|
Provides-Extra: fireworks
|
|
55
56
|
Requires-Dist: FireWorks; extra == "fireworks"
|
|
56
57
|
Provides-Extra: strict
|
|
57
|
-
Requires-Dist: FireWorks==2.0.
|
|
58
|
-
Requires-Dist: PyYAML==6.0.
|
|
59
|
-
Requires-Dist: maggma==0.
|
|
60
|
-
Requires-Dist: matplotlib==3.
|
|
61
|
-
Requires-Dist: monty==
|
|
62
|
-
Requires-Dist: moto==
|
|
63
|
-
Requires-Dist: networkx==3.2
|
|
64
|
-
Requires-Dist: pydantic-settings==2.
|
|
65
|
-
Requires-Dist: pydantic==2.
|
|
66
|
-
Requires-Dist: pydash==8.0.
|
|
67
|
-
Requires-Dist: pydot==
|
|
68
|
-
Requires-Dist: python-ulid==3.
|
|
69
|
-
Requires-Dist: typing-extensions==4.
|
|
58
|
+
Requires-Dist: FireWorks==2.0.6; extra == "strict"
|
|
59
|
+
Requires-Dist: PyYAML==6.0.3; extra == "strict"
|
|
60
|
+
Requires-Dist: maggma==0.72.0; extra == "strict"
|
|
61
|
+
Requires-Dist: matplotlib==3.10.7; extra == "strict"
|
|
62
|
+
Requires-Dist: monty==2025.3.3; extra == "strict"
|
|
63
|
+
Requires-Dist: moto==5.1.16; extra == "strict"
|
|
64
|
+
Requires-Dist: networkx==3.4.2; extra == "strict"
|
|
65
|
+
Requires-Dist: pydantic-settings==2.11.0; extra == "strict"
|
|
66
|
+
Requires-Dist: pydantic==2.12.3; extra == "strict"
|
|
67
|
+
Requires-Dist: pydash==8.0.5; extra == "strict"
|
|
68
|
+
Requires-Dist: pydot==4.0.1; extra == "strict"
|
|
69
|
+
Requires-Dist: python-ulid==3.1.0; extra == "strict"
|
|
70
|
+
Requires-Dist: typing-extensions==4.15.0; extra == "strict"
|
|
71
|
+
Dynamic: license-file
|
|
70
72
|
|
|
71
73
|
<div align="center">
|
|
72
74
|
|
|
@@ -19,51 +19,52 @@ classifiers = [
|
|
|
19
19
|
"Programming Language :: Python :: 3",
|
|
20
20
|
"Programming Language :: Python :: 3.10",
|
|
21
21
|
"Programming Language :: Python :: 3.11",
|
|
22
|
-
"Programming Language :: Python :: 3.
|
|
22
|
+
"Programming Language :: Python :: 3.12",
|
|
23
|
+
"Programming Language :: Python :: 3.13",
|
|
23
24
|
"Topic :: Database :: Front-Ends",
|
|
24
25
|
"Topic :: Other/Nonlisted Topic",
|
|
25
26
|
"Topic :: Scientific/Engineering",
|
|
26
27
|
]
|
|
27
|
-
requires-python = ">=3.
|
|
28
|
+
requires-python = ">=3.10"
|
|
28
29
|
dependencies = [
|
|
29
|
-
"PyYAML",
|
|
30
|
-
"maggma>=0.
|
|
30
|
+
"PyYAML>=6.0.1",
|
|
31
|
+
"maggma>=0.72.0",
|
|
31
32
|
"monty>=2023.9.25",
|
|
32
|
-
"networkx",
|
|
33
|
+
"networkx>=3.2.1",
|
|
33
34
|
"pydantic-settings>=2.0.3",
|
|
34
|
-
"pydantic>=2.
|
|
35
|
-
"pydash",
|
|
35
|
+
"pydantic>=2.4",
|
|
36
|
+
"pydash>=8.0.1",
|
|
36
37
|
]
|
|
37
38
|
|
|
38
39
|
[project.optional-dependencies]
|
|
39
40
|
ulid = ["python-ulid"]
|
|
40
41
|
docs = [
|
|
41
|
-
"autodoc_pydantic==2.
|
|
42
|
-
"furo==
|
|
43
|
-
"ipython==
|
|
44
|
-
"myst_parser==4.0.
|
|
45
|
-
"nbsphinx==0.9.
|
|
42
|
+
"autodoc_pydantic==2.2.0",
|
|
43
|
+
"furo==2025.9.25",
|
|
44
|
+
"ipython==9.3.0",
|
|
45
|
+
"myst_parser==4.0.1",
|
|
46
|
+
"nbsphinx==0.9.7",
|
|
46
47
|
"sphinx-copybutton==0.5.2",
|
|
47
48
|
"sphinx==8.1.3",
|
|
48
49
|
]
|
|
49
50
|
dev = ["pre-commit>=2.12.1", "typing_extensions; python_version < '3.11'"]
|
|
50
|
-
tests = ["moto==
|
|
51
|
+
tests = ["moto==5.1.16", "pytest-cov==7.0.0", "pytest==8.4.2"]
|
|
51
52
|
vis = ["matplotlib", "pydot"]
|
|
52
53
|
fireworks = ["FireWorks"]
|
|
53
54
|
strict = [
|
|
54
|
-
"FireWorks==2.0.
|
|
55
|
-
"PyYAML==6.0.
|
|
56
|
-
"maggma==0.
|
|
57
|
-
"matplotlib==3.
|
|
58
|
-
"monty==
|
|
59
|
-
"moto==
|
|
60
|
-
"networkx==3.2
|
|
61
|
-
"pydantic-settings==2.
|
|
62
|
-
"pydantic==2.
|
|
63
|
-
"pydash==8.0.
|
|
64
|
-
"pydot==
|
|
65
|
-
"python-ulid==3.
|
|
66
|
-
"typing-extensions==4.
|
|
55
|
+
"FireWorks==2.0.6",
|
|
56
|
+
"PyYAML==6.0.3",
|
|
57
|
+
"maggma==0.72.0",
|
|
58
|
+
"matplotlib==3.10.7",
|
|
59
|
+
"monty==2025.3.3",
|
|
60
|
+
"moto==5.1.16",
|
|
61
|
+
"networkx==3.4.2",
|
|
62
|
+
"pydantic-settings==2.11.0",
|
|
63
|
+
"pydantic==2.12.3",
|
|
64
|
+
"pydash==8.0.5",
|
|
65
|
+
"pydot==4.0.1",
|
|
66
|
+
"python-ulid==3.1.0",
|
|
67
|
+
"typing-extensions==4.15.0",
|
|
67
68
|
]
|
|
68
69
|
|
|
69
70
|
[project.urls]
|
|
@@ -84,7 +85,7 @@ max-line-length = 88
|
|
|
84
85
|
max-doc-length = 88
|
|
85
86
|
select = "C, E, F, W, B"
|
|
86
87
|
extend-ignore = "E203, W503, E501, F401, RST21"
|
|
87
|
-
min-python-version = "3.
|
|
88
|
+
min-python-version = "3.10.0"
|
|
88
89
|
docstring-convention = "numpy"
|
|
89
90
|
rst-roles = "class, func, ref, obj"
|
|
90
91
|
|
|
@@ -162,6 +163,7 @@ ignore = [
|
|
|
162
163
|
"FBT001",
|
|
163
164
|
"FBT002",
|
|
164
165
|
"ISC001",
|
|
166
|
+
"PLC0415", # import should be at the top-level of a file
|
|
165
167
|
"PLR0911", # too-many-return-statements
|
|
166
168
|
"PLR0912", # too-many-branches
|
|
167
169
|
"PLR0913", # too-many-arguments
|
|
@@ -179,5 +181,6 @@ isort.known-first-party = ["jobflow"]
|
|
|
179
181
|
# D: pydocstyle
|
|
180
182
|
# PLR2004: magic-value-comparison
|
|
181
183
|
# PT004: pytest-missing-fixture-name-underscore
|
|
184
|
+
|
|
182
185
|
"**/tests/*" = ["ANN", "ARG001", "D", "PLR2004", "PT004", "S101"]
|
|
183
186
|
"docs/tutorials/*" = ["D", "PLR2004"]
|
|
@@ -617,7 +617,7 @@ class Flow(MSONable):
|
|
|
617
617
|
function_filter: Callable = None,
|
|
618
618
|
dict_mod: bool = False,
|
|
619
619
|
dynamic: bool = True,
|
|
620
|
-
callback_filter: Callable[[Flow | Job], bool]
|
|
620
|
+
callback_filter: Callable[[Flow | Job], bool] | None = None,
|
|
621
621
|
):
|
|
622
622
|
"""
|
|
623
623
|
Update the metadata of the Flow and/or its Jobs.
|
|
@@ -681,7 +681,7 @@ class Flow(MSONable):
|
|
|
681
681
|
callback_filter=callback_filter,
|
|
682
682
|
)
|
|
683
683
|
|
|
684
|
-
if callback_filter(self) is False:
|
|
684
|
+
if callback_filter is not None and callback_filter(self) is False:
|
|
685
685
|
return
|
|
686
686
|
|
|
687
687
|
if dict_mod:
|
|
@@ -706,6 +706,7 @@ class Flow(MSONable):
|
|
|
706
706
|
function_filter: Callable = None,
|
|
707
707
|
attributes: list[str] | str = None,
|
|
708
708
|
dynamic: bool = True,
|
|
709
|
+
dict_mod: bool = False,
|
|
709
710
|
):
|
|
710
711
|
"""
|
|
711
712
|
Update the job config of all Jobs in the Flow.
|
|
@@ -728,6 +729,9 @@ class Flow(MSONable):
|
|
|
728
729
|
dynamic
|
|
729
730
|
The updates will be propagated to Jobs/Flows dynamically generated at
|
|
730
731
|
runtime.
|
|
732
|
+
dict_mod
|
|
733
|
+
Use the dict mod language to apply updates. See :obj:`.DictMods` for more
|
|
734
|
+
details.
|
|
731
735
|
|
|
732
736
|
Examples
|
|
733
737
|
--------
|
|
@@ -767,6 +771,7 @@ class Flow(MSONable):
|
|
|
767
771
|
function_filter=function_filter,
|
|
768
772
|
attributes=attributes,
|
|
769
773
|
dynamic=dynamic,
|
|
774
|
+
dict_mod=dict_mod,
|
|
770
775
|
)
|
|
771
776
|
|
|
772
777
|
def add_hosts_uuids(
|
|
@@ -926,7 +926,7 @@ class Job(MSONable):
|
|
|
926
926
|
function_filter: Callable = None,
|
|
927
927
|
dict_mod: bool = False,
|
|
928
928
|
dynamic: bool = True,
|
|
929
|
-
callback_filter: Callable[[jobflow.Flow | Job], bool]
|
|
929
|
+
callback_filter: Callable[[jobflow.Flow | Job], bool] | None = None,
|
|
930
930
|
):
|
|
931
931
|
"""
|
|
932
932
|
Update the metadata of the job.
|
|
@@ -1006,7 +1006,7 @@ class Job(MSONable):
|
|
|
1006
1006
|
):
|
|
1007
1007
|
return
|
|
1008
1008
|
|
|
1009
|
-
if callback_filter(self) is False:
|
|
1009
|
+
if callback_filter is not None and callback_filter(self) is False:
|
|
1010
1010
|
return
|
|
1011
1011
|
|
|
1012
1012
|
# if we get to here then we pass all the filters
|
|
@@ -1022,6 +1022,7 @@ class Job(MSONable):
|
|
|
1022
1022
|
function_filter: Callable = None,
|
|
1023
1023
|
attributes: list[str] | str = None,
|
|
1024
1024
|
dynamic: bool = True,
|
|
1025
|
+
dict_mod: bool = False,
|
|
1025
1026
|
):
|
|
1026
1027
|
"""
|
|
1027
1028
|
Update the job config.
|
|
@@ -1045,6 +1046,9 @@ class Job(MSONable):
|
|
|
1045
1046
|
dynamic
|
|
1046
1047
|
The updates will be propagated to Jobs/Flows dynamically generated at
|
|
1047
1048
|
runtime.
|
|
1049
|
+
dict_mod
|
|
1050
|
+
Use the dict mod language to apply updates. See :obj:`.DictMods` for more
|
|
1051
|
+
details.
|
|
1048
1052
|
|
|
1049
1053
|
Examples
|
|
1050
1054
|
--------
|
|
@@ -1096,12 +1100,23 @@ class Job(MSONable):
|
|
|
1096
1100
|
At variance, if `dynamic` is set to `False` the `manager_config` option will
|
|
1097
1101
|
only be set for the `test_job` and not for the generated Jobs.
|
|
1098
1102
|
"""
|
|
1103
|
+
from jobflow.utils.dict_mods import apply_mod
|
|
1104
|
+
|
|
1105
|
+
if dict_mod and attributes:
|
|
1106
|
+
raise ValueError("dict_mod and attributes options cannot be used together")
|
|
1107
|
+
|
|
1108
|
+
if dict_mod and isinstance(config, JobConfig):
|
|
1109
|
+
raise ValueError(
|
|
1110
|
+
"If dict_mod is selected the update config cannot be a JobConfig object"
|
|
1111
|
+
)
|
|
1112
|
+
|
|
1099
1113
|
if dynamic:
|
|
1100
1114
|
dict_input = {
|
|
1101
1115
|
"config": config,
|
|
1102
1116
|
"name_filter": name_filter,
|
|
1103
1117
|
"function_filter": function_filter,
|
|
1104
1118
|
"attributes": attributes,
|
|
1119
|
+
"dict_mod": dict_mod,
|
|
1105
1120
|
}
|
|
1106
1121
|
self.config_updates.append(dict_input)
|
|
1107
1122
|
|
|
@@ -1119,29 +1134,34 @@ class Job(MSONable):
|
|
|
1119
1134
|
return
|
|
1120
1135
|
|
|
1121
1136
|
# if we get to here then we pass all the filters
|
|
1122
|
-
if
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
attributes = [attributes] if isinstance(attributes, str) else attributes
|
|
1128
|
-
if not set(attributes).issubset(set(config.keys())):
|
|
1129
|
-
raise ValueError(
|
|
1130
|
-
"Specified attributes include a key that is not present in the "
|
|
1131
|
-
"config dictionary."
|
|
1132
|
-
)
|
|
1133
|
-
config = JobConfig(**config)
|
|
1134
|
-
|
|
1135
|
-
if attributes is None:
|
|
1136
|
-
# overwrite the whole config
|
|
1137
|
-
self.config = config
|
|
1137
|
+
if dict_mod:
|
|
1138
|
+
conf_dict = self.config.as_dict()
|
|
1139
|
+
apply_mod(config, conf_dict)
|
|
1140
|
+
self.config = JobConfig.from_dict(conf_dict)
|
|
1138
1141
|
else:
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1142
|
+
if isinstance(config, dict):
|
|
1143
|
+
# convert dict specification to a JobConfig but set the attributes
|
|
1144
|
+
if attributes is None:
|
|
1145
|
+
attributes = list(config.keys())
|
|
1146
|
+
|
|
1147
|
+
attributes = [attributes] if isinstance(attributes, str) else attributes
|
|
1148
|
+
if not set(attributes).issubset(set(config.keys())):
|
|
1149
|
+
raise ValueError(
|
|
1150
|
+
"Specified attributes include a key that is not present in the "
|
|
1151
|
+
"config dictionary."
|
|
1152
|
+
)
|
|
1153
|
+
config = JobConfig(**config)
|
|
1154
|
+
|
|
1155
|
+
if attributes is None:
|
|
1156
|
+
# overwrite the whole config
|
|
1157
|
+
self.config = config
|
|
1158
|
+
else:
|
|
1159
|
+
# only update the specified attributes
|
|
1160
|
+
attributes = [attributes] if isinstance(attributes, str) else attributes
|
|
1161
|
+
for attr in attributes:
|
|
1162
|
+
if not hasattr(self.config, attr):
|
|
1163
|
+
raise ValueError(f"Unknown JobConfig attribute: {attr}")
|
|
1164
|
+
setattr(self.config, attr, getattr(config, attr))
|
|
1145
1165
|
|
|
1146
1166
|
def as_dict(self) -> dict:
|
|
1147
1167
|
"""Serialize the job as a dictionary."""
|
|
@@ -1265,7 +1285,7 @@ class Response(typing.Generic[T]):
|
|
|
1265
1285
|
job_returns.output = apply_schema(job_returns.output, output_schema)
|
|
1266
1286
|
|
|
1267
1287
|
job_returns.job_dir = job_dir
|
|
1268
|
-
return cast(Self, job_returns)
|
|
1288
|
+
return cast("Self", job_returns)
|
|
1269
1289
|
|
|
1270
1290
|
if isinstance(job_returns, (list, tuple)):
|
|
1271
1291
|
# check that a Response object is not given as one of many outputs
|
|
@@ -513,7 +513,7 @@ def validate_schema_access(
|
|
|
513
513
|
the bool is ``True`` if the schema access was valid.
|
|
514
514
|
The BaseModel class associated with the item, if any.
|
|
515
515
|
"""
|
|
516
|
-
schema_dict = schema.
|
|
516
|
+
schema_dict = schema.model_json_schema()
|
|
517
517
|
if item not in schema_dict["properties"]:
|
|
518
518
|
raise AttributeError(f"{schema.__name__} does not have attribute '{item}'.")
|
|
519
519
|
|
|
@@ -170,7 +170,7 @@ def to_pydot(flow: jobflow.Flow):
|
|
|
170
170
|
if isinstance(job, Flow):
|
|
171
171
|
add_cluster(job, cluster)
|
|
172
172
|
else:
|
|
173
|
-
cluster.add_node(pydot_graph.get_node(f
|
|
173
|
+
cluster.add_node(pydot_graph.get_node(f"{job.uuid}")[0])
|
|
174
174
|
|
|
175
175
|
outer_graph.add_subgraph(cluster)
|
|
176
176
|
|
|
@@ -4,7 +4,10 @@ from monty.dev import deprecated
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
@deprecated(
|
|
7
|
-
message=
|
|
7
|
+
message=(
|
|
8
|
+
"The UUID system will be replaced with a UID that "
|
|
9
|
+
"contains both the UUID and ULID."
|
|
10
|
+
)
|
|
8
11
|
)
|
|
9
12
|
def suuid() -> str:
|
|
10
13
|
"""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: jobflow
|
|
3
|
-
Version: 0.1
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: jobflow is a library for writing computational workflows
|
|
5
5
|
Author-email: Alex Ganose <a.ganose@imperial.ac.uk>
|
|
6
6
|
License: modified BSD
|
|
@@ -17,56 +17,58 @@ Classifier: Operating System :: OS Independent
|
|
|
17
17
|
Classifier: Programming Language :: Python :: 3
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.10
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
22
|
Classifier: Topic :: Database :: Front-Ends
|
|
22
23
|
Classifier: Topic :: Other/Nonlisted Topic
|
|
23
24
|
Classifier: Topic :: Scientific/Engineering
|
|
24
|
-
Requires-Python: >=3.
|
|
25
|
+
Requires-Python: >=3.10
|
|
25
26
|
Description-Content-Type: text/markdown
|
|
26
27
|
License-File: LICENSE
|
|
27
|
-
Requires-Dist: PyYAML
|
|
28
|
-
Requires-Dist: maggma>=0.
|
|
28
|
+
Requires-Dist: PyYAML>=6.0.1
|
|
29
|
+
Requires-Dist: maggma>=0.72.0
|
|
29
30
|
Requires-Dist: monty>=2023.9.25
|
|
30
|
-
Requires-Dist: networkx
|
|
31
|
+
Requires-Dist: networkx>=3.2.1
|
|
31
32
|
Requires-Dist: pydantic-settings>=2.0.3
|
|
32
|
-
Requires-Dist: pydantic>=2.
|
|
33
|
-
Requires-Dist: pydash
|
|
33
|
+
Requires-Dist: pydantic>=2.4
|
|
34
|
+
Requires-Dist: pydash>=8.0.1
|
|
34
35
|
Provides-Extra: ulid
|
|
35
36
|
Requires-Dist: python-ulid; extra == "ulid"
|
|
36
37
|
Provides-Extra: docs
|
|
37
|
-
Requires-Dist: autodoc_pydantic==2.
|
|
38
|
-
Requires-Dist: furo==
|
|
39
|
-
Requires-Dist: ipython==
|
|
40
|
-
Requires-Dist: myst_parser==4.0.
|
|
41
|
-
Requires-Dist: nbsphinx==0.9.
|
|
38
|
+
Requires-Dist: autodoc_pydantic==2.2.0; extra == "docs"
|
|
39
|
+
Requires-Dist: furo==2025.9.25; extra == "docs"
|
|
40
|
+
Requires-Dist: ipython==9.3.0; extra == "docs"
|
|
41
|
+
Requires-Dist: myst_parser==4.0.1; extra == "docs"
|
|
42
|
+
Requires-Dist: nbsphinx==0.9.7; extra == "docs"
|
|
42
43
|
Requires-Dist: sphinx-copybutton==0.5.2; extra == "docs"
|
|
43
44
|
Requires-Dist: sphinx==8.1.3; extra == "docs"
|
|
44
45
|
Provides-Extra: dev
|
|
45
46
|
Requires-Dist: pre-commit>=2.12.1; extra == "dev"
|
|
46
47
|
Requires-Dist: typing_extensions; python_version < "3.11" and extra == "dev"
|
|
47
48
|
Provides-Extra: tests
|
|
48
|
-
Requires-Dist: moto==
|
|
49
|
-
Requires-Dist: pytest-cov==
|
|
50
|
-
Requires-Dist: pytest==8.
|
|
49
|
+
Requires-Dist: moto==5.1.16; extra == "tests"
|
|
50
|
+
Requires-Dist: pytest-cov==7.0.0; extra == "tests"
|
|
51
|
+
Requires-Dist: pytest==8.4.2; extra == "tests"
|
|
51
52
|
Provides-Extra: vis
|
|
52
53
|
Requires-Dist: matplotlib; extra == "vis"
|
|
53
54
|
Requires-Dist: pydot; extra == "vis"
|
|
54
55
|
Provides-Extra: fireworks
|
|
55
56
|
Requires-Dist: FireWorks; extra == "fireworks"
|
|
56
57
|
Provides-Extra: strict
|
|
57
|
-
Requires-Dist: FireWorks==2.0.
|
|
58
|
-
Requires-Dist: PyYAML==6.0.
|
|
59
|
-
Requires-Dist: maggma==0.
|
|
60
|
-
Requires-Dist: matplotlib==3.
|
|
61
|
-
Requires-Dist: monty==
|
|
62
|
-
Requires-Dist: moto==
|
|
63
|
-
Requires-Dist: networkx==3.2
|
|
64
|
-
Requires-Dist: pydantic-settings==2.
|
|
65
|
-
Requires-Dist: pydantic==2.
|
|
66
|
-
Requires-Dist: pydash==8.0.
|
|
67
|
-
Requires-Dist: pydot==
|
|
68
|
-
Requires-Dist: python-ulid==3.
|
|
69
|
-
Requires-Dist: typing-extensions==4.
|
|
58
|
+
Requires-Dist: FireWorks==2.0.6; extra == "strict"
|
|
59
|
+
Requires-Dist: PyYAML==6.0.3; extra == "strict"
|
|
60
|
+
Requires-Dist: maggma==0.72.0; extra == "strict"
|
|
61
|
+
Requires-Dist: matplotlib==3.10.7; extra == "strict"
|
|
62
|
+
Requires-Dist: monty==2025.3.3; extra == "strict"
|
|
63
|
+
Requires-Dist: moto==5.1.16; extra == "strict"
|
|
64
|
+
Requires-Dist: networkx==3.4.2; extra == "strict"
|
|
65
|
+
Requires-Dist: pydantic-settings==2.11.0; extra == "strict"
|
|
66
|
+
Requires-Dist: pydantic==2.12.3; extra == "strict"
|
|
67
|
+
Requires-Dist: pydash==8.0.5; extra == "strict"
|
|
68
|
+
Requires-Dist: pydot==4.0.1; extra == "strict"
|
|
69
|
+
Requires-Dist: python-ulid==3.1.0; extra == "strict"
|
|
70
|
+
Requires-Dist: typing-extensions==4.15.0; extra == "strict"
|
|
71
|
+
Dynamic: license-file
|
|
70
72
|
|
|
71
73
|
<div align="center">
|
|
72
74
|
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
PyYAML>=6.0.1
|
|
2
|
+
maggma>=0.72.0
|
|
3
|
+
monty>=2023.9.25
|
|
4
|
+
networkx>=3.2.1
|
|
5
|
+
pydantic-settings>=2.0.3
|
|
6
|
+
pydantic>=2.4
|
|
7
|
+
pydash>=8.0.1
|
|
8
|
+
|
|
9
|
+
[dev]
|
|
10
|
+
pre-commit>=2.12.1
|
|
11
|
+
|
|
12
|
+
[dev:python_version < "3.11"]
|
|
13
|
+
typing_extensions
|
|
14
|
+
|
|
15
|
+
[docs]
|
|
16
|
+
autodoc_pydantic==2.2.0
|
|
17
|
+
furo==2025.9.25
|
|
18
|
+
ipython==9.3.0
|
|
19
|
+
myst_parser==4.0.1
|
|
20
|
+
nbsphinx==0.9.7
|
|
21
|
+
sphinx-copybutton==0.5.2
|
|
22
|
+
sphinx==8.1.3
|
|
23
|
+
|
|
24
|
+
[fireworks]
|
|
25
|
+
FireWorks
|
|
26
|
+
|
|
27
|
+
[strict]
|
|
28
|
+
FireWorks==2.0.6
|
|
29
|
+
PyYAML==6.0.3
|
|
30
|
+
maggma==0.72.0
|
|
31
|
+
matplotlib==3.10.7
|
|
32
|
+
monty==2025.3.3
|
|
33
|
+
moto==5.1.16
|
|
34
|
+
networkx==3.4.2
|
|
35
|
+
pydantic-settings==2.11.0
|
|
36
|
+
pydantic==2.12.3
|
|
37
|
+
pydash==8.0.5
|
|
38
|
+
pydot==4.0.1
|
|
39
|
+
python-ulid==3.1.0
|
|
40
|
+
typing-extensions==4.15.0
|
|
41
|
+
|
|
42
|
+
[tests]
|
|
43
|
+
moto==5.1.16
|
|
44
|
+
pytest-cov==7.0.0
|
|
45
|
+
pytest==8.4.2
|
|
46
|
+
|
|
47
|
+
[ulid]
|
|
48
|
+
python-ulid
|
|
49
|
+
|
|
50
|
+
[vis]
|
|
51
|
+
matplotlib
|
|
52
|
+
pydot
|
|
@@ -79,7 +79,7 @@ def test_settings_object(clean_dir, test_data):
|
|
|
79
79
|
with open(config_file_path, "w") as f:
|
|
80
80
|
pass
|
|
81
81
|
|
|
82
|
-
with pytest.warns(UserWarning):
|
|
82
|
+
with pytest.warns(UserWarning, match="An empty JobFlow config file was located at"):
|
|
83
83
|
settings = JobflowSettings()
|
|
84
84
|
|
|
85
85
|
# An error should be thrown if the file exists and
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
PyYAML
|
|
2
|
-
maggma>=0.57.0
|
|
3
|
-
monty>=2023.9.25
|
|
4
|
-
networkx
|
|
5
|
-
pydantic-settings>=2.0.3
|
|
6
|
-
pydantic>=2.0.1
|
|
7
|
-
pydash
|
|
8
|
-
|
|
9
|
-
[dev]
|
|
10
|
-
pre-commit>=2.12.1
|
|
11
|
-
|
|
12
|
-
[dev:python_version < "3.11"]
|
|
13
|
-
typing_extensions
|
|
14
|
-
|
|
15
|
-
[docs]
|
|
16
|
-
autodoc_pydantic==2.1.0
|
|
17
|
-
furo==2024.8.6
|
|
18
|
-
ipython==8.29.0
|
|
19
|
-
myst_parser==4.0.0
|
|
20
|
-
nbsphinx==0.9.5
|
|
21
|
-
sphinx-copybutton==0.5.2
|
|
22
|
-
sphinx==8.1.3
|
|
23
|
-
|
|
24
|
-
[fireworks]
|
|
25
|
-
FireWorks
|
|
26
|
-
|
|
27
|
-
[strict]
|
|
28
|
-
FireWorks==2.0.3
|
|
29
|
-
PyYAML==6.0.2
|
|
30
|
-
maggma==0.70.0
|
|
31
|
-
matplotlib==3.9.2
|
|
32
|
-
monty==2024.10.21
|
|
33
|
-
moto==4.2.13
|
|
34
|
-
networkx==3.2.1
|
|
35
|
-
pydantic-settings==2.6.1
|
|
36
|
-
pydantic==2.9.2
|
|
37
|
-
pydash==8.0.4
|
|
38
|
-
pydot==2.0.0
|
|
39
|
-
python-ulid==3.0.0
|
|
40
|
-
typing-extensions==4.12.2
|
|
41
|
-
|
|
42
|
-
[tests]
|
|
43
|
-
moto==4.2.13
|
|
44
|
-
pytest-cov==6.0.0
|
|
45
|
-
pytest==8.3.3
|
|
46
|
-
|
|
47
|
-
[ulid]
|
|
48
|
-
python-ulid
|
|
49
|
-
|
|
50
|
-
[vis]
|
|
51
|
-
matplotlib
|
|
52
|
-
pydot
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|