hpcflow-new2 0.2.0a189__py3-none-any.whl → 0.2.0a199__py3-none-any.whl

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.
Files changed (176) hide show
  1. hpcflow/__pyinstaller/hook-hpcflow.py +9 -6
  2. hpcflow/_version.py +1 -1
  3. hpcflow/app.py +1 -0
  4. hpcflow/data/scripts/bad_script.py +2 -0
  5. hpcflow/data/scripts/do_nothing.py +2 -0
  6. hpcflow/data/scripts/env_specifier_test/input_file_generator_pass_env_spec.py +4 -0
  7. hpcflow/data/scripts/env_specifier_test/main_script_test_pass_env_spec.py +8 -0
  8. hpcflow/data/scripts/env_specifier_test/output_file_parser_pass_env_spec.py +4 -0
  9. hpcflow/data/scripts/env_specifier_test/v1/input_file_generator_basic.py +4 -0
  10. hpcflow/data/scripts/env_specifier_test/v1/main_script_test_direct_in_direct_out.py +7 -0
  11. hpcflow/data/scripts/env_specifier_test/v1/output_file_parser_basic.py +4 -0
  12. hpcflow/data/scripts/env_specifier_test/v2/main_script_test_direct_in_direct_out.py +7 -0
  13. hpcflow/data/scripts/input_file_generator_basic.py +3 -0
  14. hpcflow/data/scripts/input_file_generator_basic_FAIL.py +3 -0
  15. hpcflow/data/scripts/input_file_generator_test_stdout_stderr.py +8 -0
  16. hpcflow/data/scripts/main_script_test_direct_in.py +3 -0
  17. hpcflow/data/scripts/main_script_test_direct_in_direct_out_2.py +6 -0
  18. hpcflow/data/scripts/main_script_test_direct_in_direct_out_2_fail_allowed.py +6 -0
  19. hpcflow/data/scripts/main_script_test_direct_in_direct_out_2_fail_allowed_group.py +7 -0
  20. hpcflow/data/scripts/main_script_test_direct_in_direct_out_3.py +6 -0
  21. hpcflow/data/scripts/main_script_test_direct_in_group_direct_out_3.py +6 -0
  22. hpcflow/data/scripts/main_script_test_direct_in_group_one_fail_direct_out_3.py +6 -0
  23. hpcflow/data/scripts/main_script_test_hdf5_in_obj.py +1 -1
  24. hpcflow/data/scripts/main_script_test_hdf5_in_obj_2.py +12 -0
  25. hpcflow/data/scripts/main_script_test_hdf5_out_obj.py +1 -1
  26. hpcflow/data/scripts/main_script_test_json_out_FAIL.py +3 -0
  27. hpcflow/data/scripts/main_script_test_shell_env_vars.py +12 -0
  28. hpcflow/data/scripts/main_script_test_std_out_std_err.py +6 -0
  29. hpcflow/data/scripts/output_file_parser_basic.py +3 -0
  30. hpcflow/data/scripts/output_file_parser_basic_FAIL.py +7 -0
  31. hpcflow/data/scripts/output_file_parser_test_stdout_stderr.py +8 -0
  32. hpcflow/data/scripts/script_exit_test.py +5 -0
  33. hpcflow/data/template_components/environments.yaml +1 -1
  34. hpcflow/sdk/__init__.py +26 -15
  35. hpcflow/sdk/app.py +2192 -768
  36. hpcflow/sdk/cli.py +506 -296
  37. hpcflow/sdk/cli_common.py +105 -7
  38. hpcflow/sdk/config/__init__.py +1 -1
  39. hpcflow/sdk/config/callbacks.py +115 -43
  40. hpcflow/sdk/config/cli.py +126 -103
  41. hpcflow/sdk/config/config.py +674 -318
  42. hpcflow/sdk/config/config_file.py +131 -95
  43. hpcflow/sdk/config/errors.py +125 -84
  44. hpcflow/sdk/config/types.py +148 -0
  45. hpcflow/sdk/core/__init__.py +25 -1
  46. hpcflow/sdk/core/actions.py +1771 -1059
  47. hpcflow/sdk/core/app_aware.py +24 -0
  48. hpcflow/sdk/core/cache.py +139 -79
  49. hpcflow/sdk/core/command_files.py +263 -287
  50. hpcflow/sdk/core/commands.py +145 -112
  51. hpcflow/sdk/core/element.py +828 -535
  52. hpcflow/sdk/core/enums.py +192 -0
  53. hpcflow/sdk/core/environment.py +74 -93
  54. hpcflow/sdk/core/errors.py +455 -52
  55. hpcflow/sdk/core/execute.py +207 -0
  56. hpcflow/sdk/core/json_like.py +540 -272
  57. hpcflow/sdk/core/loop.py +751 -347
  58. hpcflow/sdk/core/loop_cache.py +164 -47
  59. hpcflow/sdk/core/object_list.py +370 -207
  60. hpcflow/sdk/core/parameters.py +1100 -627
  61. hpcflow/sdk/core/rule.py +59 -41
  62. hpcflow/sdk/core/run_dir_files.py +21 -37
  63. hpcflow/sdk/core/skip_reason.py +7 -0
  64. hpcflow/sdk/core/task.py +1649 -1339
  65. hpcflow/sdk/core/task_schema.py +308 -196
  66. hpcflow/sdk/core/test_utils.py +191 -114
  67. hpcflow/sdk/core/types.py +440 -0
  68. hpcflow/sdk/core/utils.py +485 -309
  69. hpcflow/sdk/core/validation.py +82 -9
  70. hpcflow/sdk/core/workflow.py +2544 -1178
  71. hpcflow/sdk/core/zarr_io.py +98 -137
  72. hpcflow/sdk/data/workflow_spec_schema.yaml +2 -0
  73. hpcflow/sdk/demo/cli.py +53 -33
  74. hpcflow/sdk/helper/cli.py +18 -15
  75. hpcflow/sdk/helper/helper.py +75 -63
  76. hpcflow/sdk/helper/watcher.py +61 -28
  77. hpcflow/sdk/log.py +122 -71
  78. hpcflow/sdk/persistence/__init__.py +8 -31
  79. hpcflow/sdk/persistence/base.py +1360 -606
  80. hpcflow/sdk/persistence/defaults.py +6 -0
  81. hpcflow/sdk/persistence/discovery.py +38 -0
  82. hpcflow/sdk/persistence/json.py +568 -188
  83. hpcflow/sdk/persistence/pending.py +382 -179
  84. hpcflow/sdk/persistence/store_resource.py +39 -23
  85. hpcflow/sdk/persistence/types.py +318 -0
  86. hpcflow/sdk/persistence/utils.py +14 -11
  87. hpcflow/sdk/persistence/zarr.py +1337 -433
  88. hpcflow/sdk/runtime.py +44 -41
  89. hpcflow/sdk/submission/{jobscript_info.py → enums.py} +39 -12
  90. hpcflow/sdk/submission/jobscript.py +1651 -692
  91. hpcflow/sdk/submission/schedulers/__init__.py +167 -39
  92. hpcflow/sdk/submission/schedulers/direct.py +121 -81
  93. hpcflow/sdk/submission/schedulers/sge.py +170 -129
  94. hpcflow/sdk/submission/schedulers/slurm.py +291 -268
  95. hpcflow/sdk/submission/schedulers/utils.py +12 -2
  96. hpcflow/sdk/submission/shells/__init__.py +14 -15
  97. hpcflow/sdk/submission/shells/base.py +150 -29
  98. hpcflow/sdk/submission/shells/bash.py +283 -173
  99. hpcflow/sdk/submission/shells/os_version.py +31 -30
  100. hpcflow/sdk/submission/shells/powershell.py +228 -170
  101. hpcflow/sdk/submission/submission.py +1014 -335
  102. hpcflow/sdk/submission/types.py +140 -0
  103. hpcflow/sdk/typing.py +182 -12
  104. hpcflow/sdk/utils/arrays.py +71 -0
  105. hpcflow/sdk/utils/deferred_file.py +55 -0
  106. hpcflow/sdk/utils/hashing.py +16 -0
  107. hpcflow/sdk/utils/patches.py +12 -0
  108. hpcflow/sdk/utils/strings.py +33 -0
  109. hpcflow/tests/api/test_api.py +32 -0
  110. hpcflow/tests/conftest.py +27 -6
  111. hpcflow/tests/data/multi_path_sequences.yaml +29 -0
  112. hpcflow/tests/data/workflow_test_run_abort.yaml +34 -35
  113. hpcflow/tests/schedulers/sge/test_sge_submission.py +36 -0
  114. hpcflow/tests/schedulers/slurm/test_slurm_submission.py +5 -2
  115. hpcflow/tests/scripts/test_input_file_generators.py +282 -0
  116. hpcflow/tests/scripts/test_main_scripts.py +866 -85
  117. hpcflow/tests/scripts/test_non_snippet_script.py +46 -0
  118. hpcflow/tests/scripts/test_ouput_file_parsers.py +353 -0
  119. hpcflow/tests/shells/wsl/test_wsl_submission.py +12 -4
  120. hpcflow/tests/unit/test_action.py +262 -75
  121. hpcflow/tests/unit/test_action_rule.py +9 -4
  122. hpcflow/tests/unit/test_app.py +33 -6
  123. hpcflow/tests/unit/test_cache.py +46 -0
  124. hpcflow/tests/unit/test_cli.py +134 -1
  125. hpcflow/tests/unit/test_command.py +71 -54
  126. hpcflow/tests/unit/test_config.py +142 -16
  127. hpcflow/tests/unit/test_config_file.py +21 -18
  128. hpcflow/tests/unit/test_element.py +58 -62
  129. hpcflow/tests/unit/test_element_iteration.py +50 -1
  130. hpcflow/tests/unit/test_element_set.py +29 -19
  131. hpcflow/tests/unit/test_group.py +4 -2
  132. hpcflow/tests/unit/test_input_source.py +116 -93
  133. hpcflow/tests/unit/test_input_value.py +29 -24
  134. hpcflow/tests/unit/test_jobscript_unit.py +757 -0
  135. hpcflow/tests/unit/test_json_like.py +44 -35
  136. hpcflow/tests/unit/test_loop.py +1396 -84
  137. hpcflow/tests/unit/test_meta_task.py +325 -0
  138. hpcflow/tests/unit/test_multi_path_sequences.py +229 -0
  139. hpcflow/tests/unit/test_object_list.py +17 -12
  140. hpcflow/tests/unit/test_parameter.py +29 -7
  141. hpcflow/tests/unit/test_persistence.py +237 -42
  142. hpcflow/tests/unit/test_resources.py +20 -18
  143. hpcflow/tests/unit/test_run.py +117 -6
  144. hpcflow/tests/unit/test_run_directories.py +29 -0
  145. hpcflow/tests/unit/test_runtime.py +2 -1
  146. hpcflow/tests/unit/test_schema_input.py +23 -15
  147. hpcflow/tests/unit/test_shell.py +23 -2
  148. hpcflow/tests/unit/test_slurm.py +8 -7
  149. hpcflow/tests/unit/test_submission.py +38 -89
  150. hpcflow/tests/unit/test_task.py +352 -247
  151. hpcflow/tests/unit/test_task_schema.py +33 -20
  152. hpcflow/tests/unit/test_utils.py +9 -11
  153. hpcflow/tests/unit/test_value_sequence.py +15 -12
  154. hpcflow/tests/unit/test_workflow.py +114 -83
  155. hpcflow/tests/unit/test_workflow_template.py +0 -1
  156. hpcflow/tests/unit/utils/test_arrays.py +40 -0
  157. hpcflow/tests/unit/utils/test_deferred_file_writer.py +34 -0
  158. hpcflow/tests/unit/utils/test_hashing.py +65 -0
  159. hpcflow/tests/unit/utils/test_patches.py +5 -0
  160. hpcflow/tests/unit/utils/test_redirect_std.py +50 -0
  161. hpcflow/tests/workflows/__init__.py +0 -0
  162. hpcflow/tests/workflows/test_directory_structure.py +31 -0
  163. hpcflow/tests/workflows/test_jobscript.py +334 -1
  164. hpcflow/tests/workflows/test_run_status.py +198 -0
  165. hpcflow/tests/workflows/test_skip_downstream.py +696 -0
  166. hpcflow/tests/workflows/test_submission.py +140 -0
  167. hpcflow/tests/workflows/test_workflows.py +160 -15
  168. hpcflow/tests/workflows/test_zip.py +18 -0
  169. hpcflow/viz_demo.ipynb +6587 -3
  170. {hpcflow_new2-0.2.0a189.dist-info → hpcflow_new2-0.2.0a199.dist-info}/METADATA +8 -4
  171. hpcflow_new2-0.2.0a199.dist-info/RECORD +221 -0
  172. hpcflow/sdk/core/parallel.py +0 -21
  173. hpcflow_new2-0.2.0a189.dist-info/RECORD +0 -158
  174. {hpcflow_new2-0.2.0a189.dist-info → hpcflow_new2-0.2.0a199.dist-info}/LICENSE +0 -0
  175. {hpcflow_new2-0.2.0a189.dist-info → hpcflow_new2-0.2.0a199.dist-info}/WHEEL +0 -0
  176. {hpcflow_new2-0.2.0a189.dist-info → hpcflow_new2-0.2.0a199.dist-info}/entry_points.txt +0 -0
@@ -4,9 +4,8 @@ from hpcflow.sdk import sdk_classes
4
4
 
5
5
 
6
6
  # most of the modules in `sdk_classes` are imported on-demand via the app object:
7
- hiddenimports = list(sdk_classes.values())
8
-
9
- hiddenimports += [
7
+ hiddenimports = [
8
+ *sdk_classes.values(),
10
9
  "hpcflow.sdk.data",
11
10
  "hpcflow.data.demo_data_manifest",
12
11
  "hpcflow.data.scripts",
@@ -14,18 +13,22 @@ hiddenimports += [
14
13
  "hpcflow.data.workflows",
15
14
  "hpcflow.tests.data",
16
15
  "hpcflow.sdk.core.test_utils",
16
+ "hpcflow.sdk.utils.patches",
17
17
  "click.testing",
18
18
  "requests", # for GitHub fsspec file system
19
19
  "fsspec.implementations.github", # for GitHub fsspec file system
20
20
  ]
21
21
 
22
- py_include_kwargs = dict(include_py_files=True, excludes=("**/__pycache__",))
23
22
  datas = (
24
23
  collect_data_files("hpcflow.sdk.data")
25
24
  + collect_data_files("hpcflow.data.demo_data_manifest")
26
- + collect_data_files("hpcflow.data.scripts", **py_include_kwargs)
25
+ + collect_data_files(
26
+ "hpcflow.data.scripts", include_py_files=True, excludes=("**/__pycache__",)
27
+ )
27
28
  + collect_data_files("hpcflow.data.template_components")
28
29
  + collect_data_files("hpcflow.data.workflows")
29
- + collect_data_files("hpcflow.tests", **py_include_kwargs)
30
+ + collect_data_files(
31
+ "hpcflow.tests", include_py_files=True, excludes=("**/__pycache__",)
32
+ )
30
33
  + collect_data_files("hpcflow.tests.data")
31
34
  )
hpcflow/_version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.2.0a189"
1
+ __version__ = "0.2.0a199"
hpcflow/app.py CHANGED
@@ -1,3 +1,4 @@
1
+ from __future__ import annotations
1
2
  from hpcflow import __version__, _app_name
2
3
  from hpcflow.sdk import app as sdk_app
3
4
  from hpcflow.sdk.config import ConfigOptions
@@ -0,0 +1,2 @@
1
+ def bad_script():
2
+ raise SyntaxError("oh no!")
@@ -0,0 +1,2 @@
1
+ def do_nothing():
2
+ pass
@@ -0,0 +1,4 @@
1
+ def input_file_generator_pass_env_spec(path, p1, env_spec):
2
+ print(env_spec)
3
+ with path.open("w") as fp:
4
+ fp.write(f"{p1}\n")
@@ -0,0 +1,8 @@
1
+ def main_script_test_pass_env_spec(p1, env_spec):
2
+ # process
3
+ p2 = p1 + 100
4
+
5
+ print(env_spec)
6
+
7
+ # return outputs
8
+ return {"p2": p2}
@@ -0,0 +1,4 @@
1
+ def output_file_parser_pass_env_spec(my_output_file, env_spec):
2
+ print(env_spec)
3
+ with my_output_file.open("r") as fp:
4
+ return int(fp.read().strip())
@@ -0,0 +1,4 @@
1
+ # version: v1
2
+ def input_file_generator_basic(path, p1):
3
+ with path.open("w") as fp:
4
+ fp.write(f"{p1}\n")
@@ -0,0 +1,7 @@
1
+ # version: v1
2
+ def main_script_test_direct_in_direct_out(p1):
3
+ # process
4
+ p2 = p1 + 100
5
+
6
+ # return outputs
7
+ return {"p2": p2}
@@ -0,0 +1,4 @@
1
+ # version: v1
2
+ def output_file_parser_basic(my_output_file):
3
+ with my_output_file.open("r") as fp:
4
+ return int(fp.read().strip())
@@ -0,0 +1,7 @@
1
+ # version: v2
2
+ def main_script_test_direct_in_direct_out(p1):
3
+ # process
4
+ p2 = p1 + 200
5
+
6
+ # return outputs
7
+ return {"p2": p2}
@@ -0,0 +1,3 @@
1
+ def input_file_generator_basic(path, p1):
2
+ with path.open("w") as fp:
3
+ fp.write(f"{p1}\n")
@@ -0,0 +1,3 @@
1
+ def input_file_generator_basic_FAIL(path, p1):
2
+ # silently fail to generate the input file!
3
+ pass
@@ -0,0 +1,8 @@
1
+ import sys
2
+
3
+
4
+ def input_file_generator_test_stdout_stderr(path, p1):
5
+ print(p1)
6
+ print(p1, file=sys.stderr)
7
+ with path.open("w") as fp:
8
+ fp.write(f"{p1}\n")
@@ -0,0 +1,3 @@
1
+ def main_script_test_direct_in(p1):
2
+ # process
3
+ print(p1 + 100)
@@ -0,0 +1,6 @@
1
+ def main_script_test_direct_in_direct_out_2(p2):
2
+ # process
3
+ p3 = p2 + 100
4
+
5
+ # return outputs
6
+ return {"p3": p3}
@@ -0,0 +1,6 @@
1
+ def main_script_test_direct_in_direct_out_2_fail_allowed(p2):
2
+ # process, accounting for possible unset data:
3
+ p3 = (p2 if p2 is not None else 0) + 100
4
+
5
+ # return outputs
6
+ return {"p3": p3}
@@ -0,0 +1,7 @@
1
+ def main_script_test_direct_in_direct_out_2_fail_allowed_group(p2):
2
+ # process, accounting for possible unset data:
3
+ p2_sum = sum(i for i in p2 if i is not None)
4
+ p3 = p2_sum + 100
5
+
6
+ # return outputs
7
+ return {"p3": p3}
@@ -0,0 +1,6 @@
1
+ def main_script_test_direct_in_direct_out_3(p3):
2
+ # process
3
+ p4 = p3 + 100
4
+
5
+ # return outputs
6
+ return {"p4": p4}
@@ -0,0 +1,6 @@
1
+ def main_script_test_direct_in_group_direct_out_3(p3):
2
+ # process
3
+ p4 = sum(p3) + 100
4
+
5
+ # return outputs
6
+ return {"p4": p4}
@@ -0,0 +1,6 @@
1
+ def main_script_test_direct_in_group_one_fail_direct_out_3(p3):
2
+ # process, ignore some un-set inputs:
3
+ p4 = sum([i for i in p3 if i is not None]) + 100
4
+
5
+ # return outputs
6
+ return {"p4": p4}
@@ -1,4 +1,4 @@
1
- import h5py
1
+ import h5py # type: ignore[import-untyped]
2
2
 
3
3
 
4
4
  def main_script_test_hdf5_in_obj(_input_files):
@@ -0,0 +1,12 @@
1
+ import h5py # type: ignore
2
+
3
+
4
+ def main_script_test_hdf5_in_obj_2(p2, _input_files):
5
+ # read inputs
6
+ with h5py.File(_input_files["hdf5"], mode="r") as fh:
7
+ a = fh["p1c"].attrs["a"].item()
8
+
9
+ # process
10
+ p3 = a + 100
11
+
12
+ return {"p3": p3}
@@ -1,4 +1,4 @@
1
- import h5py
1
+ import h5py # type: ignore[import-untyped]
2
2
 
3
3
 
4
4
  def main_script_test_hdf5_out_obj(p1, _output_files):
@@ -0,0 +1,3 @@
1
+ def main_script_test_json_out_FAIL(_output_files):
2
+ pass
3
+ # don't generate a JSON output file!
@@ -0,0 +1,12 @@
1
+ import json
2
+ import os
3
+
4
+
5
+ def main_script_test_shell_env_vars(p1):
6
+ with open("env_vars.json", "wt") as fp:
7
+ json.dump(
8
+ {k: v for k, v in os.environ.items() if k.startswith("HPCFLOW")},
9
+ fp,
10
+ indent=4,
11
+ )
12
+ return {"p1": p1 + 1}
@@ -0,0 +1,6 @@
1
+ import sys
2
+
3
+
4
+ def main_script_test_std_out_std_err(stdout_msg, stderr_msg):
5
+ print(stdout_msg)
6
+ print(stderr_msg, file=sys.stderr)
@@ -0,0 +1,3 @@
1
+ def output_file_parser_basic(my_output_file):
2
+ with my_output_file.open("r") as fp:
3
+ return int(fp.read().strip())
@@ -0,0 +1,7 @@
1
+ def output_file_parser_basic_FAIL(my_output_file):
2
+ # parse the output file, but then delete it, so it cannot be saved (when run with
3
+ # `OFP.save_files=True`):
4
+ with my_output_file.open("r") as fp:
5
+ out = int(fp.read().strip())
6
+ my_output_file.unlink()
7
+ return out
@@ -0,0 +1,8 @@
1
+ import sys
2
+
3
+
4
+ def output_file_parser_test_stdout_stderr(my_output_file, p1):
5
+ print(p1)
6
+ print(p1, file=sys.stderr)
7
+ with my_output_file.open("r") as fp:
8
+ return int(fp.read().strip())
@@ -0,0 +1,5 @@
1
+ import sys
2
+
3
+
4
+ def script_exit_test(exit_code):
5
+ sys.exit(exit_code)
@@ -5,7 +5,7 @@
5
5
  executables:
6
6
  - label: python_script
7
7
  instances:
8
- - command: python <<script_name>> <<args>>
8
+ - command: python <<script_path>> <<args>>
9
9
  num_cores: 1
10
10
  parallel_mode: null
11
11
  doc: |
hpcflow/sdk/__init__.py CHANGED
@@ -1,15 +1,19 @@
1
1
  """Sub-package to define an extensible hpcflow application."""
2
2
 
3
+ from __future__ import annotations
4
+ from collections.abc import Mapping
3
5
  import logging
4
6
  import os
5
7
  import sys
8
+ from typing import Final
6
9
 
7
10
  #: Classes used in the construction of a workflow.
8
11
  #: :meta hide-value:
9
- sdk_classes = {
12
+ sdk_classes: Final[Mapping[str, str]] = {
10
13
  "Workflow": "hpcflow.sdk.core.workflow",
11
14
  "Task": "hpcflow.sdk.core.task",
12
- "ActionScopeType": "hpcflow.sdk.core.actions",
15
+ "MetaTask": "hpcflow.sdk.core.task",
16
+ "ActionScopeType": "hpcflow.sdk.core.enums",
13
17
  "ActionScope": "hpcflow.sdk.core.actions",
14
18
  "ActionRule": "hpcflow.sdk.core.actions",
15
19
  "Rule": "hpcflow.sdk.core.rule",
@@ -43,6 +47,7 @@ sdk_classes = {
43
47
  "NumCores": "hpcflow.sdk.core.environment",
44
48
  "ExecutableInstance": "hpcflow.sdk.core.environment",
45
49
  "Executable": "hpcflow.sdk.core.environment",
50
+ "Executor": "hpcflow.sdk.core.execute",
46
51
  "Environment": "hpcflow.sdk.core.environment",
47
52
  "Loop": "hpcflow.sdk.core.loop",
48
53
  "WorkflowLoop": "hpcflow.sdk.core.loop",
@@ -65,15 +70,17 @@ sdk_classes = {
65
70
  "SchemaInput": "hpcflow.sdk.core.parameters",
66
71
  "SchemaOutput": "hpcflow.sdk.core.parameters",
67
72
  "ValueSequence": "hpcflow.sdk.core.parameters",
73
+ "MultiPathSequence": "hpcflow.sdk.core.parameters",
68
74
  "ValuePerturbation": "hpcflow.sdk.core.parameters",
69
75
  "InputValue": "hpcflow.sdk.core.parameters",
70
76
  "ResourceSpec": "hpcflow.sdk.core.parameters",
71
- "TaskSourceType": "hpcflow.sdk.core.parameters",
72
- "InputSourceType": "hpcflow.sdk.core.parameters",
73
- "ParameterPropagationMode": "hpcflow.sdk.core.parameters",
77
+ "TaskSourceType": "hpcflow.sdk.core.enums",
78
+ "InputSourceType": "hpcflow.sdk.core.enums",
79
+ "ParameterPropagationMode": "hpcflow.sdk.core.enums",
74
80
  "InputSource": "hpcflow.sdk.core.parameters",
75
81
  "TaskObjective": "hpcflow.sdk.core.task_schema",
76
82
  "TaskSchema": "hpcflow.sdk.core.task_schema",
83
+ "MetaTaskSchema": "hpcflow.sdk.core.task_schema",
77
84
  "ElementSet": "hpcflow.sdk.core.task",
78
85
  "Task": "hpcflow.sdk.core.task",
79
86
  "WorkflowTask": "hpcflow.sdk.core.task",
@@ -86,7 +93,9 @@ sdk_classes = {
86
93
  "Workflow": "hpcflow.sdk.core.workflow",
87
94
  "WorkflowBlueprint": "hpcflow.sdk.core.workflow",
88
95
  "Jobscript": "hpcflow.sdk.submission.jobscript",
96
+ "JobscriptBlock": "hpcflow.sdk.submission.jobscript",
89
97
  "Submission": "hpcflow.sdk.submission.submission",
98
+ "QueuedScheduler": "hpcflow.sdk.submission.schedulers",
90
99
  "DirectWindows": "hpcflow.sdk.submission.schedulers.direct",
91
100
  "DirectPosix": "hpcflow.sdk.submission.schedulers.direct",
92
101
  "SlurmPosix": "hpcflow.sdk.submission.schedulers.slurm",
@@ -98,7 +107,7 @@ sdk_classes = {
98
107
  # these are defined as `BaseApp` methods with an underscore prefix:
99
108
  #: Functions exported by the application.
100
109
  #: :meta hide-value:
101
- sdk_funcs = (
110
+ sdk_funcs: Final[tuple[str, ...]] = (
102
111
  "make_workflow",
103
112
  "make_demo_workflow",
104
113
  "make_and_submit_workflow",
@@ -114,24 +123,26 @@ sdk_funcs = (
114
123
  "cancel",
115
124
  )
116
125
 
117
- _SDK_CONSOLE_LOG_LEVEL = os.environ.get("HPCFLOW_SDK_CONSOLE_LOG_LEVEL", "ERROR")
118
126
 
119
-
120
- def get_SDK_logger(name=None):
127
+ def get_SDK_logger(name: str | None = None) -> logging.Logger:
121
128
  """Get a logger with prefix of "hpcflow_sdk" instead of "hpcflow.sdk" to ensure the
122
129
  handlers of the SDK logger and app logger are distinct."""
123
130
  name = ".".join(["hpcflow_sdk"] + (name or __name__).split(".")[2:])
124
131
  return logging.getLogger(name)
125
132
 
126
133
 
127
- _SDK_logger = get_SDK_logger()
128
- _SDK_logger.setLevel("DEBUG")
134
+ def _init_logger() -> None:
135
+ level = os.environ.get("HPCFLOW_SDK_CONSOLE_LOG_LEVEL", "ERROR")
136
+ SDK_logger = get_SDK_logger()
137
+ SDK_logger.setLevel("DEBUG")
138
+
139
+ sh = logging.StreamHandler()
140
+ sh.setFormatter(logging.Formatter("%(levelname)s %(name)s: %(message)s"))
141
+ sh.setLevel(level)
142
+ SDK_logger.addHandler(sh)
129
143
 
130
- _sh = logging.StreamHandler()
131
- _sh.setFormatter(logging.Formatter("%(levelname)s %(name)s: %(message)s"))
132
- _sh.setLevel(_SDK_CONSOLE_LOG_LEVEL)
133
- _SDK_logger.addHandler(_sh)
134
144
 
145
+ _init_logger()
135
146
  if getattr(sys, "frozen", False) and hasattr(sys, "_MEIPASS"):
136
147
  import multiprocessing
137
148