hpcflow-new2 0.2.0a179__py3-none-any.whl → 0.2.0a180__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.
- hpcflow/_version.py +1 -1
- hpcflow/data/demo_data_manifest/__init__.py +3 -0
- hpcflow/sdk/__init__.py +4 -1
- hpcflow/sdk/app.py +160 -15
- hpcflow/sdk/cli.py +14 -0
- hpcflow/sdk/cli_common.py +83 -0
- hpcflow/sdk/config/__init__.py +4 -0
- hpcflow/sdk/config/callbacks.py +25 -2
- hpcflow/sdk/config/cli.py +4 -1
- hpcflow/sdk/config/config.py +188 -14
- hpcflow/sdk/config/config_file.py +91 -3
- hpcflow/sdk/config/errors.py +33 -0
- hpcflow/sdk/core/__init__.py +2 -0
- hpcflow/sdk/core/actions.py +492 -35
- hpcflow/sdk/core/cache.py +22 -0
- hpcflow/sdk/core/command_files.py +221 -5
- hpcflow/sdk/core/commands.py +57 -0
- hpcflow/sdk/core/element.py +407 -8
- hpcflow/sdk/core/environment.py +92 -0
- hpcflow/sdk/core/errors.py +245 -61
- hpcflow/sdk/core/json_like.py +72 -14
- hpcflow/sdk/core/loop.py +122 -21
- hpcflow/sdk/core/loop_cache.py +34 -9
- hpcflow/sdk/core/object_list.py +172 -26
- hpcflow/sdk/core/parallel.py +14 -0
- hpcflow/sdk/core/parameters.py +478 -25
- hpcflow/sdk/core/rule.py +31 -1
- hpcflow/sdk/core/run_dir_files.py +12 -2
- hpcflow/sdk/core/task.py +407 -80
- hpcflow/sdk/core/task_schema.py +70 -9
- hpcflow/sdk/core/test_utils.py +35 -0
- hpcflow/sdk/core/utils.py +101 -4
- hpcflow/sdk/core/validation.py +13 -1
- hpcflow/sdk/core/workflow.py +316 -96
- hpcflow/sdk/core/zarr_io.py +23 -0
- hpcflow/sdk/data/__init__.py +13 -0
- hpcflow/sdk/demo/__init__.py +3 -0
- hpcflow/sdk/helper/__init__.py +3 -0
- hpcflow/sdk/helper/cli.py +9 -0
- hpcflow/sdk/helper/helper.py +28 -0
- hpcflow/sdk/helper/watcher.py +33 -0
- hpcflow/sdk/log.py +40 -0
- hpcflow/sdk/persistence/__init__.py +14 -4
- hpcflow/sdk/persistence/base.py +289 -23
- hpcflow/sdk/persistence/json.py +29 -0
- hpcflow/sdk/persistence/pending.py +217 -107
- hpcflow/sdk/persistence/store_resource.py +58 -2
- hpcflow/sdk/persistence/utils.py +8 -0
- hpcflow/sdk/persistence/zarr.py +68 -1
- hpcflow/sdk/runtime.py +52 -10
- hpcflow/sdk/submission/__init__.py +3 -0
- hpcflow/sdk/submission/jobscript.py +198 -9
- hpcflow/sdk/submission/jobscript_info.py +13 -0
- hpcflow/sdk/submission/schedulers/__init__.py +60 -0
- hpcflow/sdk/submission/schedulers/direct.py +53 -0
- hpcflow/sdk/submission/schedulers/sge.py +45 -7
- hpcflow/sdk/submission/schedulers/slurm.py +45 -8
- hpcflow/sdk/submission/schedulers/utils.py +4 -0
- hpcflow/sdk/submission/shells/__init__.py +11 -1
- hpcflow/sdk/submission/shells/base.py +32 -1
- hpcflow/sdk/submission/shells/bash.py +36 -1
- hpcflow/sdk/submission/shells/os_version.py +18 -6
- hpcflow/sdk/submission/shells/powershell.py +22 -0
- hpcflow/sdk/submission/submission.py +88 -3
- hpcflow/sdk/typing.py +10 -1
- {hpcflow_new2-0.2.0a179.dist-info → hpcflow_new2-0.2.0a180.dist-info}/METADATA +1 -1
- {hpcflow_new2-0.2.0a179.dist-info → hpcflow_new2-0.2.0a180.dist-info}/RECORD +70 -70
- {hpcflow_new2-0.2.0a179.dist-info → hpcflow_new2-0.2.0a180.dist-info}/LICENSE +0 -0
- {hpcflow_new2-0.2.0a179.dist-info → hpcflow_new2-0.2.0a180.dist-info}/WHEEL +0 -0
- {hpcflow_new2-0.2.0a179.dist-info → hpcflow_new2-0.2.0a180.dist-info}/entry_points.txt +0 -0
hpcflow/sdk/cli_common.py
CHANGED
@@ -7,10 +7,14 @@ from hpcflow.sdk.persistence import ALL_STORE_FORMATS, DEFAULT_STORE_FORMAT
|
|
7
7
|
|
8
8
|
|
9
9
|
def sub_tasks_callback(ctx, param, value):
|
10
|
+
"""
|
11
|
+
Parse subtasks.
|
12
|
+
"""
|
10
13
|
if value:
|
11
14
|
return [int(i) for i in value.split(",")]
|
12
15
|
|
13
16
|
|
17
|
+
#: Standard option
|
14
18
|
format_option = click.option(
|
15
19
|
"--format",
|
16
20
|
type=click.Choice(ALL_TEMPLATE_FORMATS),
|
@@ -20,11 +24,13 @@ format_option = click.option(
|
|
20
24
|
"particular format."
|
21
25
|
),
|
22
26
|
)
|
27
|
+
#: Standard option
|
23
28
|
path_option = click.option(
|
24
29
|
"--path",
|
25
30
|
type=click.Path(exists=True),
|
26
31
|
help="The directory path into which the new workflow will be generated.",
|
27
32
|
)
|
33
|
+
#: Standard option
|
28
34
|
name_option = click.option(
|
29
35
|
"--name",
|
30
36
|
help=(
|
@@ -33,6 +39,7 @@ name_option = click.option(
|
|
33
39
|
"will be used, in combination with a date-timestamp."
|
34
40
|
),
|
35
41
|
)
|
42
|
+
#: Standard option
|
36
43
|
overwrite_option = click.option(
|
37
44
|
"--overwrite",
|
38
45
|
is_flag=True,
|
@@ -42,12 +49,15 @@ overwrite_option = click.option(
|
|
42
49
|
"the existing directory will be overwritten."
|
43
50
|
),
|
44
51
|
)
|
52
|
+
#: Standard option
|
45
53
|
store_option = click.option(
|
46
54
|
"--store",
|
47
55
|
type=click.Choice(ALL_STORE_FORMATS),
|
48
56
|
help="The persistent store type to use.",
|
49
57
|
default=DEFAULT_STORE_FORMAT,
|
50
58
|
)
|
59
|
+
|
60
|
+
#: Standard option
|
51
61
|
ts_fmt_option = click.option(
|
52
62
|
"--ts-fmt",
|
53
63
|
help=(
|
@@ -56,6 +66,7 @@ ts_fmt_option = click.option(
|
|
56
66
|
"should not include a time zone name."
|
57
67
|
),
|
58
68
|
)
|
69
|
+
#: Standard option
|
59
70
|
ts_name_fmt_option = click.option(
|
60
71
|
"--ts-name-fmt",
|
61
72
|
help=(
|
@@ -63,6 +74,8 @@ ts_name_fmt_option = click.option(
|
|
63
74
|
"includes a timestamp."
|
64
75
|
),
|
65
76
|
)
|
77
|
+
|
78
|
+
#: Standard option
|
66
79
|
variables_option = click.option(
|
67
80
|
"-v",
|
68
81
|
"--var",
|
@@ -74,6 +87,7 @@ variables_option = click.option(
|
|
74
87
|
"string. Multiple variable values can be specified."
|
75
88
|
),
|
76
89
|
)
|
90
|
+
#: Standard option
|
77
91
|
js_parallelism_option = click.option(
|
78
92
|
"--js-parallelism",
|
79
93
|
help=(
|
@@ -84,23 +98,27 @@ js_parallelism_option = click.option(
|
|
84
98
|
),
|
85
99
|
type=click.BOOL,
|
86
100
|
)
|
101
|
+
#: Standard option
|
87
102
|
wait_option = click.option(
|
88
103
|
"--wait",
|
89
104
|
help=("If True, this command will block until the workflow execution is complete."),
|
90
105
|
is_flag=True,
|
91
106
|
default=False,
|
92
107
|
)
|
108
|
+
#: Standard option
|
93
109
|
add_to_known_opt = click.option(
|
94
110
|
"--add-to-known/--no-add-to-known",
|
95
111
|
default=True,
|
96
112
|
help="If True, add this submission to the known-submissions file.",
|
97
113
|
)
|
114
|
+
#: Standard option
|
98
115
|
print_idx_opt = click.option(
|
99
116
|
"--print-idx",
|
100
117
|
help="If True, print the submitted jobscript indices for each submission index.",
|
101
118
|
is_flag=True,
|
102
119
|
default=False,
|
103
120
|
)
|
121
|
+
#: Standard option
|
104
122
|
tasks_opt = click.option(
|
105
123
|
"--tasks",
|
106
124
|
help=(
|
@@ -109,22 +127,27 @@ tasks_opt = click.option(
|
|
109
127
|
),
|
110
128
|
callback=sub_tasks_callback,
|
111
129
|
)
|
130
|
+
#: Standard option
|
112
131
|
cancel_opt = click.option(
|
113
132
|
"--cancel",
|
114
133
|
help="Immediately cancel the submission. Useful for testing and benchmarking.",
|
115
134
|
is_flag=True,
|
116
135
|
default=False,
|
117
136
|
)
|
137
|
+
#: Standard option
|
118
138
|
submit_status_opt = click.option(
|
119
139
|
"--status/--no-status",
|
120
140
|
help="If True, display a live status to track submission progress.",
|
121
141
|
default=True,
|
122
142
|
)
|
143
|
+
#: Standard option
|
123
144
|
make_status_opt = click.option(
|
124
145
|
"--status/--no-status",
|
125
146
|
help="If True, display a live status to track workflow creation progress.",
|
126
147
|
default=True,
|
127
148
|
)
|
149
|
+
|
150
|
+
#: Standard option
|
128
151
|
zip_path_opt = click.option(
|
129
152
|
"--path",
|
130
153
|
default=".",
|
@@ -134,15 +157,21 @@ zip_path_opt = click.option(
|
|
134
157
|
"path is assumed to be the full file path to the new zip file."
|
135
158
|
),
|
136
159
|
)
|
160
|
+
#: Standard option
|
137
161
|
zip_overwrite_opt = click.option(
|
138
162
|
"--overwrite",
|
139
163
|
is_flag=True,
|
140
164
|
default=False,
|
141
165
|
help="If set, any existing file will be overwritten.",
|
142
166
|
)
|
167
|
+
#: Standard option
|
143
168
|
zip_log_opt = click.option("--log", help="Path to a log file to use during zipping.")
|
169
|
+
#: Standard option
|
144
170
|
zip_include_execute_opt = click.option("--include-execute", is_flag=True)
|
171
|
+
#: Standard option
|
145
172
|
zip_include_rechunk_backups_opt = click.option("--include-rechunk-backups", is_flag=True)
|
173
|
+
|
174
|
+
#: Standard option
|
146
175
|
unzip_path_opt = click.option(
|
147
176
|
"--path",
|
148
177
|
default=".",
|
@@ -152,12 +181,16 @@ unzip_path_opt = click.option(
|
|
152
181
|
"Otherwise, this path will represent the new workflow directory path."
|
153
182
|
),
|
154
183
|
)
|
184
|
+
#: Standard option
|
155
185
|
unzip_log_opt = click.option("--log", help="Path to a log file to use during unzipping.")
|
186
|
+
|
187
|
+
#: Standard option
|
156
188
|
rechunk_backup_opt = click.option(
|
157
189
|
"--backup/--no-backup",
|
158
190
|
default=True,
|
159
191
|
help=("First copy a backup of the array to a directory ending in `.bak`."),
|
160
192
|
)
|
193
|
+
#: Standard option
|
161
194
|
rechunk_chunk_size_opt = click.option(
|
162
195
|
"--chunk-size",
|
163
196
|
type=click.INT,
|
@@ -168,8 +201,58 @@ rechunk_chunk_size_opt = click.option(
|
|
168
201
|
"array's shape)."
|
169
202
|
),
|
170
203
|
)
|
204
|
+
#: Standard option
|
171
205
|
rechunk_status_opt = click.option(
|
172
206
|
"--status/--no-status",
|
173
207
|
default=True,
|
174
208
|
help="If True, display a live status to track rechunking progress.",
|
175
209
|
)
|
210
|
+
|
211
|
+
|
212
|
+
def _add_doc_from_help(*args):
|
213
|
+
"""
|
214
|
+
Attach the ``help`` field of each of its arguments as its ``__doc__``.
|
215
|
+
Only necessary because the wrappers in Click don't do this for us.
|
216
|
+
|
217
|
+
:meta private:
|
218
|
+
"""
|
219
|
+
# Yes, this is ugly!
|
220
|
+
from types import SimpleNamespace
|
221
|
+
|
222
|
+
for opt in args:
|
223
|
+
ns = SimpleNamespace()
|
224
|
+
params = getattr(opt(ns), "__click_params__", [])
|
225
|
+
if params:
|
226
|
+
help = getattr(params[0], "help", "")
|
227
|
+
if help:
|
228
|
+
opt.__doc__ = f"Click option decorator: {help}"
|
229
|
+
|
230
|
+
|
231
|
+
_add_doc_from_help(
|
232
|
+
format_option,
|
233
|
+
path_option,
|
234
|
+
name_option,
|
235
|
+
overwrite_option,
|
236
|
+
store_option,
|
237
|
+
ts_fmt_option,
|
238
|
+
ts_name_fmt_option,
|
239
|
+
variables_option,
|
240
|
+
js_parallelism_option,
|
241
|
+
wait_option,
|
242
|
+
add_to_known_opt,
|
243
|
+
print_idx_opt,
|
244
|
+
tasks_opt,
|
245
|
+
cancel_opt,
|
246
|
+
submit_status_opt,
|
247
|
+
make_status_opt,
|
248
|
+
zip_path_opt,
|
249
|
+
zip_overwrite_opt,
|
250
|
+
zip_log_opt,
|
251
|
+
zip_include_execute_opt,
|
252
|
+
zip_include_rechunk_backups_opt,
|
253
|
+
unzip_path_opt,
|
254
|
+
unzip_log_opt,
|
255
|
+
rechunk_backup_opt,
|
256
|
+
rechunk_chunk_size_opt,
|
257
|
+
rechunk_status_opt,
|
258
|
+
)
|
hpcflow/sdk/config/__init__.py
CHANGED
hpcflow/sdk/config/callbacks.py
CHANGED
@@ -10,7 +10,9 @@ from hpcflow.sdk.submission.shells import get_supported_shells
|
|
10
10
|
|
11
11
|
|
12
12
|
def callback_vars(config, value):
|
13
|
-
"""
|
13
|
+
"""
|
14
|
+
Callback that substitutes configuration variables.
|
15
|
+
"""
|
14
16
|
|
15
17
|
def vars_repl(match_obj):
|
16
18
|
var_name = match_obj.groups()[0]
|
@@ -27,6 +29,9 @@ def callback_vars(config, value):
|
|
27
29
|
|
28
30
|
|
29
31
|
def callback_file_paths(config, file_path):
|
32
|
+
"""
|
33
|
+
Callback that resolves file paths.
|
34
|
+
"""
|
30
35
|
if isinstance(file_path, list):
|
31
36
|
return [config._resolve_path(i) for i in file_path]
|
32
37
|
else:
|
@@ -34,6 +39,9 @@ def callback_file_paths(config, file_path):
|
|
34
39
|
|
35
40
|
|
36
41
|
def callback_bool(config, value):
|
42
|
+
"""
|
43
|
+
Callback that coerces values to boolean.
|
44
|
+
"""
|
37
45
|
if not isinstance(value, bool):
|
38
46
|
if value.lower() == "true":
|
39
47
|
return True
|
@@ -45,6 +53,9 @@ def callback_bool(config, value):
|
|
45
53
|
|
46
54
|
|
47
55
|
def callback_lowercase(config, value):
|
56
|
+
"""
|
57
|
+
Callback that forces a string to lower case.
|
58
|
+
"""
|
48
59
|
if isinstance(value, list):
|
49
60
|
return [i.lower() for i in value]
|
50
61
|
elif isinstance(value, dict):
|
@@ -54,6 +65,9 @@ def callback_lowercase(config, value):
|
|
54
65
|
|
55
66
|
|
56
67
|
def exists_in_schedulers(config, value):
|
68
|
+
"""
|
69
|
+
Callback that tests that a value is a supported scheduler name.
|
70
|
+
"""
|
57
71
|
if value not in config.schedulers:
|
58
72
|
raise ValueError(
|
59
73
|
f"Cannot set default scheduler; {value!r} is not a supported scheduler "
|
@@ -64,6 +78,9 @@ def exists_in_schedulers(config, value):
|
|
64
78
|
|
65
79
|
|
66
80
|
def callback_supported_schedulers(config, schedulers):
|
81
|
+
"""
|
82
|
+
Callback that tests that all values are names of supported schedulers.
|
83
|
+
"""
|
67
84
|
# validate against supported schedulers according to the OS - this won't validate that
|
68
85
|
# a particular scheduler actually exists on this system:
|
69
86
|
available = config._app.get_OS_supported_schedulers()
|
@@ -122,6 +139,9 @@ def callback_scheduler_set_up(config, schedulers):
|
|
122
139
|
|
123
140
|
|
124
141
|
def callback_supported_shells(config, shell_name):
|
142
|
+
"""
|
143
|
+
Callback that tests if a shell names is supported on this OS.
|
144
|
+
"""
|
125
145
|
supported = get_supported_shells(os.name)
|
126
146
|
if shell_name not in supported:
|
127
147
|
raise UnsupportedShellError(shell=shell_name, supported=supported)
|
@@ -146,11 +166,14 @@ def set_callback_file_paths(config, value):
|
|
146
166
|
|
147
167
|
|
148
168
|
def check_load_data_files(config, value):
|
149
|
-
"""Check data files (e.g
|
169
|
+
"""Check data files (e.g., task schema files) can be loaded successfully. This is only
|
150
170
|
done on `config.set` (and not on `config.get` or `config._validate`) because it could
|
151
171
|
be expensive in the case of remote files."""
|
152
172
|
config._app.reload_template_components(warn=False)
|
153
173
|
|
154
174
|
|
155
175
|
def callback_update_log_console_level(config, value):
|
176
|
+
"""
|
177
|
+
Callback to set the logging level.
|
178
|
+
"""
|
156
179
|
config._app.log.update_console_level(value)
|
hpcflow/sdk/config/cli.py
CHANGED
@@ -44,7 +44,10 @@ def warning_formatter(func=custom_warning_formatter):
|
|
44
44
|
|
45
45
|
|
46
46
|
def CLI_exception_wrapper_gen(*exception_cls):
|
47
|
-
"""
|
47
|
+
"""
|
48
|
+
Decorator factory that enhances the wrapped function to display a nice message on
|
49
|
+
success or failure.
|
50
|
+
"""
|
48
51
|
|
49
52
|
def CLI_exception_wrapper(func):
|
50
53
|
"""Decorator
|
hpcflow/sdk/config/config.py
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
"""
|
2
|
+
Configuration system class.
|
3
|
+
"""
|
4
|
+
|
1
5
|
from __future__ import annotations
|
2
6
|
import contextlib
|
3
7
|
|
@@ -61,6 +65,7 @@ from .errors import (
|
|
61
65
|
logger = logging.getLogger(__name__)
|
62
66
|
|
63
67
|
_DEFAULT_SHELL = DEFAULT_SHELL_NAMES[os.name]
|
68
|
+
#: The default configuration descriptor.
|
64
69
|
DEFAULT_CONFIG = {
|
65
70
|
"invocation": {"environment_setup": None, "match": {}},
|
66
71
|
"config": {
|
@@ -82,12 +87,17 @@ DEFAULT_CONFIG = {
|
|
82
87
|
class ConfigOptions:
|
83
88
|
"""Application-level options for configuration"""
|
84
89
|
|
90
|
+
#: The default directory.
|
85
91
|
default_directory: Union[Path, str]
|
92
|
+
#: The environment variable containing the directory name.
|
86
93
|
directory_env_var: str
|
94
|
+
#: The default configuration.
|
87
95
|
default_config: Optional[Dict] = field(
|
88
96
|
default_factory=lambda: deepcopy(DEFAULT_CONFIG)
|
89
97
|
)
|
98
|
+
#: Any extra schemas to apply.
|
90
99
|
extra_schemas: Optional[List[Schema]] = field(default_factory=lambda: [])
|
100
|
+
#: Default directory of known configurations.
|
91
101
|
default_known_configs_dir: Optional[str] = None
|
92
102
|
|
93
103
|
def __post_init__(self):
|
@@ -96,7 +106,9 @@ class ConfigOptions:
|
|
96
106
|
self._configurable_keys = cfg_keys
|
97
107
|
|
98
108
|
def init_schemas(self):
|
99
|
-
|
109
|
+
"""
|
110
|
+
Get allowed configurable keys from config schemas.
|
111
|
+
"""
|
100
112
|
cfg_schemas = [get_schema("config_schema.yaml")] + self.extra_schemas
|
101
113
|
cfg_keys = []
|
102
114
|
for cfg_schema in cfg_schemas:
|
@@ -130,18 +142,114 @@ class ConfigOptions:
|
|
130
142
|
class Config:
|
131
143
|
"""Application configuration as defined in one or more config files.
|
132
144
|
|
145
|
+
This class supports indexing into the collection of properties via Python dot notation.
|
146
|
+
|
133
147
|
Notes
|
134
148
|
-----
|
135
149
|
On modifying/setting existing values, modifications are not automatically copied
|
136
|
-
to the configuration file; use
|
150
|
+
to the configuration file; use :meth:`save()` to save to the file. Items in `overrides`
|
137
151
|
are not saved into the file.
|
138
152
|
|
139
153
|
`schedulers` is used for specifying the available schedulers on this machine, and the
|
140
|
-
default arguments that should be used when initialising the
|
154
|
+
default arguments that should be used when initialising the
|
155
|
+
:py:class:`Scheduler` object.
|
141
156
|
|
142
157
|
`shells` is used for specifying the default arguments that should be used when
|
143
|
-
initialising the
|
144
|
-
|
158
|
+
initialising the :py:class:`Shell` object.
|
159
|
+
|
160
|
+
Parameters
|
161
|
+
----------
|
162
|
+
app:
|
163
|
+
The main hpcflow application instance.
|
164
|
+
config_file:
|
165
|
+
The configuration file that contains this config.
|
166
|
+
options:
|
167
|
+
Configuration options to be applied.
|
168
|
+
logger:
|
169
|
+
Where to log messages relating to configuration.
|
170
|
+
config_key:
|
171
|
+
The name of the configuration within the configuration file.
|
172
|
+
uid: int
|
173
|
+
User ID.
|
174
|
+
callbacks: dict
|
175
|
+
Overrides for the callback system.
|
176
|
+
variables: dict[str, str]
|
177
|
+
Variables to substitute when processing the configuration.
|
178
|
+
|
179
|
+
Attributes
|
180
|
+
----------
|
181
|
+
config_directory:
|
182
|
+
The directory containing the configuration file.
|
183
|
+
config_file_name:
|
184
|
+
The name of the configuration file.
|
185
|
+
config_file_path:
|
186
|
+
The full path to the configuration file.
|
187
|
+
config_file_contents:
|
188
|
+
The cached contents of the configuration file.
|
189
|
+
config_key:
|
190
|
+
The primary key to select the configuration within the configuration file.
|
191
|
+
config_schemas:
|
192
|
+
The schemas that apply to the configuration file.
|
193
|
+
host_user_id:
|
194
|
+
User ID as understood by the script.
|
195
|
+
host_user_id_file_path:
|
196
|
+
Where user ID information is stored.
|
197
|
+
invoking_user_id:
|
198
|
+
User ID that created the workflow.
|
199
|
+
machine:
|
200
|
+
Machine to submit to.
|
201
|
+
Mapped to a field in the configuration file.
|
202
|
+
user_name:
|
203
|
+
User to submit as.
|
204
|
+
Mapped to a field in the configuration file.
|
205
|
+
user_orcid:
|
206
|
+
User's ORCID.
|
207
|
+
Mapped to a field in the configuration file.
|
208
|
+
user_affiliation:
|
209
|
+
User's institutional affiliation.
|
210
|
+
Mapped to a field in the configuration file.
|
211
|
+
linux_release_file:
|
212
|
+
Where to get the description of the Linux release version data.
|
213
|
+
Mapped to a field in the configuration file.
|
214
|
+
log_file_path:
|
215
|
+
Where to log to.
|
216
|
+
Mapped to a field in the configuration file.
|
217
|
+
log_file_level:
|
218
|
+
At what level to do logging to the file.
|
219
|
+
Mapped to a field in the configuration file.
|
220
|
+
log_console_level:
|
221
|
+
At what level to do logging to the console. Usually coarser than to a file.
|
222
|
+
Mapped to a field in the configuration file.
|
223
|
+
task_schema_sources:
|
224
|
+
Where to get task schemas.
|
225
|
+
Mapped to a field in the configuration file.
|
226
|
+
parameter_sources:
|
227
|
+
Where to get parameter descriptors.
|
228
|
+
Mapped to a field in the configuration file.
|
229
|
+
command_file_sources:
|
230
|
+
Where to get command files.
|
231
|
+
Mapped to a field in the configuration file.
|
232
|
+
environment_sources:
|
233
|
+
Where to get execution environment descriptors.
|
234
|
+
Mapped to a field in the configuration file.
|
235
|
+
default_scheduler:
|
236
|
+
The name of the default scheduler.
|
237
|
+
Mapped to a field in the configuration file.
|
238
|
+
default_shell:
|
239
|
+
The name of the default shell.
|
240
|
+
Mapped to a field in the configuration file.
|
241
|
+
schedulers:
|
242
|
+
Settings for supported scheduler(s).
|
243
|
+
Mapped to a field in the configuration file.
|
244
|
+
shells:
|
245
|
+
Settings for supported shell(s).
|
246
|
+
Mapped to a field in the configuration file.
|
247
|
+
demo_data_dir:
|
248
|
+
Location of demo data.
|
249
|
+
Mapped to a field in the configuration file.
|
250
|
+
demo_data_manifest_file:
|
251
|
+
Where the manifest describing the demo data is.
|
252
|
+
Mapped to a field in the configuration file.
|
145
253
|
"""
|
146
254
|
|
147
255
|
def __init__(
|
@@ -517,7 +625,16 @@ class Config:
|
|
517
625
|
print(f"value is already: {callback_val!r}")
|
518
626
|
|
519
627
|
def set(self, path: str, value, is_json=False, quiet=False):
|
520
|
-
"""
|
628
|
+
"""
|
629
|
+
Set the value of a configuration item.
|
630
|
+
|
631
|
+
Parameters
|
632
|
+
----------
|
633
|
+
path:
|
634
|
+
Which configuration item to set.
|
635
|
+
value:
|
636
|
+
What to set it to.
|
637
|
+
"""
|
521
638
|
self._logger.debug(f"Attempting to set config item {path!r} to {value!r}.")
|
522
639
|
|
523
640
|
if is_json:
|
@@ -542,7 +659,18 @@ class Config:
|
|
542
659
|
self._set(name, root, quiet=quiet)
|
543
660
|
|
544
661
|
def unset(self, name):
|
545
|
-
"""
|
662
|
+
"""
|
663
|
+
Unset the value of a configuration item.
|
664
|
+
|
665
|
+
Parameters
|
666
|
+
----------
|
667
|
+
name: str
|
668
|
+
The name of the configuration item.
|
669
|
+
|
670
|
+
Notes
|
671
|
+
-----
|
672
|
+
Only top level configuration items may be unset.
|
673
|
+
"""
|
546
674
|
if name not in self._configurable_keys:
|
547
675
|
raise ConfigNonConfigurableError(name=name)
|
548
676
|
if name in self._unset_keys or not self._file.is_item_set(self._config_key, name):
|
@@ -564,6 +692,14 @@ class Config:
|
|
564
692
|
ret_parts=False,
|
565
693
|
default=None,
|
566
694
|
):
|
695
|
+
"""
|
696
|
+
Get the value of a configuration item.
|
697
|
+
|
698
|
+
Parameters
|
699
|
+
----------
|
700
|
+
path: str
|
701
|
+
The name of or path to the configuration item.
|
702
|
+
"""
|
567
703
|
parts = path.split(".")
|
568
704
|
root = deepcopy(self._get(parts[0], callback=callback))
|
569
705
|
try:
|
@@ -582,7 +718,16 @@ class Config:
|
|
582
718
|
return tuple(ret)
|
583
719
|
|
584
720
|
def append(self, path, value, is_json=False):
|
585
|
-
"""
|
721
|
+
"""
|
722
|
+
Append a value to a list-like configuration item.
|
723
|
+
|
724
|
+
Parameters
|
725
|
+
----------
|
726
|
+
path: str
|
727
|
+
The name of or path to the configuration item.
|
728
|
+
value:
|
729
|
+
The value to append.
|
730
|
+
"""
|
586
731
|
if is_json:
|
587
732
|
value = self._parse_JSON(path, value)
|
588
733
|
|
@@ -612,7 +757,16 @@ class Config:
|
|
612
757
|
self._set(parts[0], root)
|
613
758
|
|
614
759
|
def prepend(self, path, value, is_json=False):
|
615
|
-
"""
|
760
|
+
"""
|
761
|
+
Prepend a value to a list-like configuration item.
|
762
|
+
|
763
|
+
Parameters
|
764
|
+
----------
|
765
|
+
path: str
|
766
|
+
The name of or path to the configuration item.
|
767
|
+
value:
|
768
|
+
The value to prepend.
|
769
|
+
"""
|
616
770
|
if is_json:
|
617
771
|
value = self._parse_JSON(path, value)
|
618
772
|
|
@@ -638,7 +792,16 @@ class Config:
|
|
638
792
|
self._set(parts[0], root)
|
639
793
|
|
640
794
|
def pop(self, path, index):
|
641
|
-
"""
|
795
|
+
"""
|
796
|
+
Remove a value from a specified index of a list-like configuration item.
|
797
|
+
|
798
|
+
Parameters
|
799
|
+
----------
|
800
|
+
path: str
|
801
|
+
The name of or path to the configuration item.
|
802
|
+
index: int
|
803
|
+
Where to remove the value from. 0 for the first item, -1 for the last.
|
804
|
+
"""
|
642
805
|
|
643
806
|
existing, root, parts = self.get(
|
644
807
|
path,
|
@@ -674,8 +837,10 @@ class Config:
|
|
674
837
|
|
675
838
|
Parameters
|
676
839
|
----------
|
677
|
-
path
|
840
|
+
path: str
|
678
841
|
A dot-delimited string of the nested path to update.
|
842
|
+
value: dict
|
843
|
+
A dictionary to merge in.
|
679
844
|
"""
|
680
845
|
|
681
846
|
if is_json:
|
@@ -739,12 +904,18 @@ class Config:
|
|
739
904
|
self._app.reset_config()
|
740
905
|
|
741
906
|
def add_scheduler(self, scheduler, **defaults):
|
907
|
+
"""
|
908
|
+
Add a scheduler.
|
909
|
+
"""
|
742
910
|
if scheduler in self.get("schedulers"):
|
743
911
|
print(f"Scheduler {scheduler!r} already exists.")
|
744
912
|
return
|
745
913
|
self.update(f"schedulers.{scheduler}.defaults", defaults)
|
746
914
|
|
747
915
|
def add_shell(self, shell, **defaults):
|
916
|
+
"""
|
917
|
+
Add a shell.
|
918
|
+
"""
|
748
919
|
if shell in self.get("shells"):
|
749
920
|
return
|
750
921
|
if shell.lower() == "wsl":
|
@@ -753,6 +924,9 @@ class Config:
|
|
753
924
|
self.update(f"shells.{shell}.defaults", defaults)
|
754
925
|
|
755
926
|
def add_shell_WSL(self, **defaults):
|
927
|
+
"""
|
928
|
+
Add shell with WSL prefix.
|
929
|
+
"""
|
756
930
|
if "WSL_executable" not in defaults:
|
757
931
|
defaults["WSL_executable"] = "wsl.exe"
|
758
932
|
self.add_shell("wsl", **defaults)
|
@@ -763,13 +937,13 @@ class Config:
|
|
763
937
|
|
764
938
|
Parameters
|
765
939
|
----------
|
766
|
-
file_path
|
940
|
+
file_path:
|
767
941
|
Local or remote path to a config import YAML file which may have top-level
|
768
942
|
keys "invocation" and "config".
|
769
|
-
rename
|
943
|
+
rename:
|
770
944
|
If True, the current config will be renamed to the stem of the file specified
|
771
945
|
in `file_path`. Ignored if `make_new` is True.
|
772
|
-
make_new
|
946
|
+
make_new:
|
773
947
|
If True, add the config items as a new config, rather than modifying the
|
774
948
|
current config. The name of the new config will be the stem of the file
|
775
949
|
specified in `file_path`.
|