meerschaum 3.0.0rc4__py3-none-any.whl → 3.0.0rc8__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.
- meerschaum/_internal/arguments/_parser.py +14 -2
- meerschaum/_internal/cli/__init__.py +6 -0
- meerschaum/_internal/cli/daemons.py +103 -0
- meerschaum/_internal/cli/entry.py +220 -0
- meerschaum/_internal/cli/workers.py +435 -0
- meerschaum/_internal/docs/index.py +1 -2
- meerschaum/_internal/entry.py +44 -8
- meerschaum/_internal/shell/Shell.py +115 -24
- meerschaum/_internal/shell/__init__.py +4 -1
- meerschaum/_internal/static.py +4 -1
- meerschaum/_internal/term/TermPageHandler.py +1 -2
- meerschaum/_internal/term/__init__.py +40 -6
- meerschaum/_internal/term/tools.py +33 -8
- meerschaum/actions/__init__.py +6 -4
- meerschaum/actions/api.py +39 -11
- meerschaum/actions/attach.py +1 -0
- meerschaum/actions/delete.py +4 -2
- meerschaum/actions/edit.py +27 -8
- meerschaum/actions/login.py +8 -8
- meerschaum/actions/register.py +13 -7
- meerschaum/actions/reload.py +22 -5
- meerschaum/actions/restart.py +14 -0
- meerschaum/actions/show.py +69 -4
- meerschaum/actions/start.py +135 -14
- meerschaum/actions/stop.py +36 -3
- meerschaum/actions/sync.py +6 -1
- meerschaum/api/__init__.py +35 -13
- meerschaum/api/_events.py +2 -2
- meerschaum/api/_oauth2.py +47 -4
- meerschaum/api/dash/callbacks/dashboard.py +29 -0
- meerschaum/api/dash/callbacks/jobs.py +3 -2
- meerschaum/api/dash/callbacks/login.py +10 -1
- meerschaum/api/dash/callbacks/register.py +9 -2
- meerschaum/api/dash/pages/login.py +2 -2
- meerschaum/api/dash/pipes.py +72 -36
- meerschaum/api/dash/webterm.py +14 -6
- meerschaum/api/models/_pipes.py +7 -1
- meerschaum/api/resources/static/js/terminado.js +3 -0
- meerschaum/api/resources/static/js/xterm-addon-unicode11.js +2 -0
- meerschaum/api/resources/templates/termpage.html +1 -0
- meerschaum/api/routes/_jobs.py +23 -11
- meerschaum/api/routes/_login.py +73 -5
- meerschaum/api/routes/_pipes.py +6 -4
- meerschaum/api/routes/_webterm.py +3 -3
- meerschaum/config/__init__.py +60 -13
- meerschaum/config/_default.py +89 -61
- meerschaum/config/_edit.py +10 -8
- meerschaum/config/_formatting.py +2 -0
- meerschaum/config/_patch.py +4 -2
- meerschaum/config/_paths.py +127 -12
- meerschaum/config/_read_config.py +32 -12
- meerschaum/config/_version.py +1 -1
- meerschaum/config/environment.py +262 -0
- meerschaum/config/stack/__init__.py +7 -5
- meerschaum/connectors/_Connector.py +1 -2
- meerschaum/connectors/__init__.py +37 -2
- meerschaum/connectors/api/_APIConnector.py +1 -1
- meerschaum/connectors/api/_jobs.py +11 -0
- meerschaum/connectors/api/_pipes.py +7 -1
- meerschaum/connectors/instance/_plugins.py +9 -1
- meerschaum/connectors/instance/_tokens.py +20 -3
- meerschaum/connectors/instance/_users.py +8 -1
- meerschaum/connectors/parse.py +1 -1
- meerschaum/connectors/sql/_create_engine.py +3 -0
- meerschaum/connectors/sql/_pipes.py +93 -79
- meerschaum/connectors/sql/_users.py +8 -1
- meerschaum/connectors/valkey/_ValkeyConnector.py +3 -3
- meerschaum/connectors/valkey/_pipes.py +7 -5
- meerschaum/core/Pipe/__init__.py +45 -71
- meerschaum/core/Pipe/_attributes.py +66 -90
- meerschaum/core/Pipe/_cache.py +555 -0
- meerschaum/core/Pipe/_clear.py +0 -11
- meerschaum/core/Pipe/_data.py +0 -50
- meerschaum/core/Pipe/_deduplicate.py +0 -13
- meerschaum/core/Pipe/_delete.py +12 -21
- meerschaum/core/Pipe/_drop.py +11 -23
- meerschaum/core/Pipe/_dtypes.py +1 -1
- meerschaum/core/Pipe/_index.py +8 -14
- meerschaum/core/Pipe/_sync.py +12 -18
- meerschaum/core/Plugin/_Plugin.py +7 -1
- meerschaum/core/Token/_Token.py +1 -1
- meerschaum/core/User/_User.py +1 -2
- meerschaum/jobs/_Executor.py +88 -4
- meerschaum/jobs/_Job.py +146 -36
- meerschaum/jobs/systemd.py +7 -2
- meerschaum/plugins/__init__.py +277 -81
- meerschaum/utils/daemon/Daemon.py +197 -42
- meerschaum/utils/daemon/FileDescriptorInterceptor.py +0 -1
- meerschaum/utils/daemon/RotatingFile.py +63 -36
- meerschaum/utils/daemon/StdinFile.py +53 -13
- meerschaum/utils/daemon/__init__.py +18 -5
- meerschaum/utils/daemon/_names.py +6 -3
- meerschaum/utils/debug.py +34 -4
- meerschaum/utils/dtypes/__init__.py +5 -1
- meerschaum/utils/formatting/__init__.py +4 -1
- meerschaum/utils/formatting/_jobs.py +1 -1
- meerschaum/utils/formatting/_pipes.py +47 -46
- meerschaum/utils/formatting/_shell.py +33 -9
- meerschaum/utils/misc.py +22 -38
- meerschaum/utils/packages/__init__.py +15 -13
- meerschaum/utils/packages/_packages.py +1 -0
- meerschaum/utils/pipes.py +33 -5
- meerschaum/utils/process.py +1 -1
- meerschaum/utils/prompt.py +172 -143
- meerschaum/utils/sql.py +12 -2
- meerschaum/utils/threading.py +42 -0
- meerschaum/utils/venv/__init__.py +2 -0
- meerschaum/utils/warnings.py +19 -13
- {meerschaum-3.0.0rc4.dist-info → meerschaum-3.0.0rc8.dist-info}/METADATA +3 -1
- {meerschaum-3.0.0rc4.dist-info → meerschaum-3.0.0rc8.dist-info}/RECORD +116 -110
- meerschaum/config/_environment.py +0 -145
- {meerschaum-3.0.0rc4.dist-info → meerschaum-3.0.0rc8.dist-info}/WHEEL +0 -0
- {meerschaum-3.0.0rc4.dist-info → meerschaum-3.0.0rc8.dist-info}/entry_points.txt +0 -0
- {meerschaum-3.0.0rc4.dist-info → meerschaum-3.0.0rc8.dist-info}/licenses/LICENSE +0 -0
- {meerschaum-3.0.0rc4.dist-info → meerschaum-3.0.0rc8.dist-info}/licenses/NOTICE +0 -0
- {meerschaum-3.0.0rc4.dist-info → meerschaum-3.0.0rc8.dist-info}/top_level.txt +0 -0
- {meerschaum-3.0.0rc4.dist-info → meerschaum-3.0.0rc8.dist-info}/zip-safe +0 -0
meerschaum/core/Pipe/_delete.py
CHANGED
@@ -9,11 +9,11 @@ Delete a Pipe's contents and registration
|
|
9
9
|
from meerschaum.utils.typing import SuccessTuple
|
10
10
|
|
11
11
|
def delete(
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
self,
|
13
|
+
drop: bool = True,
|
14
|
+
debug: bool = False,
|
15
|
+
**kw
|
16
|
+
) -> SuccessTuple:
|
17
17
|
"""
|
18
18
|
Call the Pipe's instance connector's `delete_pipe()` method.
|
19
19
|
|
@@ -30,29 +30,22 @@ def delete(
|
|
30
30
|
A `SuccessTuple` of success (`bool`), message (`str`).
|
31
31
|
|
32
32
|
"""
|
33
|
-
import os, pathlib
|
34
33
|
from meerschaum.utils.warnings import warn
|
35
34
|
from meerschaum.utils.venv import Venv
|
36
35
|
from meerschaum.connectors import get_connector_plugin
|
37
36
|
|
38
37
|
if self.temporary:
|
38
|
+
if self.cache:
|
39
|
+
invalidate_success, invalidate_msg = self._invalidate_cache(hard=True, debug=debug)
|
40
|
+
if not invalidate_success:
|
41
|
+
return invalidate_success, invalidate_msg
|
42
|
+
|
39
43
|
return (
|
40
44
|
False,
|
41
45
|
"Cannot delete pipes created with `temporary=True` (read-only). "
|
42
46
|
+ "You may want to call `pipe.drop()` instead."
|
43
47
|
)
|
44
48
|
|
45
|
-
if self.cache_pipe is not None:
|
46
|
-
_drop_cache_tuple = self.cache_pipe.drop(debug=debug, **kw)
|
47
|
-
if not _drop_cache_tuple[0]:
|
48
|
-
warn(_drop_cache_tuple[1])
|
49
|
-
if getattr(self.cache_connector, 'flavor', None) == 'sqlite':
|
50
|
-
_cache_db_path = pathlib.Path(self.cache_connector.database)
|
51
|
-
try:
|
52
|
-
os.remove(_cache_db_path)
|
53
|
-
except Exception as e:
|
54
|
-
warn(f"Could not delete cache file '{_cache_db_path}' for {self}:\n{e}")
|
55
|
-
|
56
49
|
if drop:
|
57
50
|
drop_success, drop_msg = self.drop(debug=debug)
|
58
51
|
if not drop_success:
|
@@ -65,8 +58,6 @@ def delete(
|
|
65
58
|
return False, f"Received an unexpected result from '{self.instance_connector}': {result}"
|
66
59
|
|
67
60
|
if result[0]:
|
68
|
-
|
69
|
-
|
70
|
-
if member in self.__dict__:
|
71
|
-
del self.__dict__[member]
|
61
|
+
self._invalidate_cache(hard=True, debug=debug)
|
62
|
+
|
72
63
|
return result
|
meerschaum/core/Pipe/_drop.py
CHANGED
@@ -28,15 +28,10 @@ def drop(
|
|
28
28
|
A `SuccessTuple` of success, message.
|
29
29
|
|
30
30
|
"""
|
31
|
-
self._exists = False
|
32
|
-
from meerschaum.utils.warnings import warn
|
33
31
|
from meerschaum.utils.venv import Venv
|
34
32
|
from meerschaum.connectors import get_connector_plugin
|
35
33
|
|
36
|
-
|
37
|
-
_drop_cache_tuple = self.cache_pipe.drop(debug=debug, **kw)
|
38
|
-
if not _drop_cache_tuple[0]:
|
39
|
-
warn(_drop_cache_tuple[1])
|
34
|
+
self._clear_cache_key('_exists', debug=debug)
|
40
35
|
|
41
36
|
with Venv(get_connector_plugin(self.instance_connector)):
|
42
37
|
if hasattr(self.instance_connector, 'drop_pipe'):
|
@@ -50,9 +45,8 @@ def drop(
|
|
50
45
|
)
|
51
46
|
)
|
52
47
|
|
53
|
-
|
54
|
-
|
55
|
-
_ = self.__dict__.pop('_exists_timestamp', None)
|
48
|
+
self._clear_cache_key('_exists', debug=debug)
|
49
|
+
self._clear_cache_key('_exists_timestamp', debug=debug)
|
56
50
|
|
57
51
|
return result
|
58
52
|
|
@@ -79,19 +73,13 @@ def drop_indices(
|
|
79
73
|
A `SuccessTuple` of success, message.
|
80
74
|
|
81
75
|
"""
|
82
|
-
from meerschaum.utils.warnings import warn
|
83
76
|
from meerschaum.utils.venv import Venv
|
84
77
|
from meerschaum.connectors import get_connector_plugin
|
85
78
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
if self.cache_pipe is not None:
|
92
|
-
_drop_cache_tuple = self.cache_pipe.drop_indices(columns=columns, debug=debug, **kw)
|
93
|
-
if not _drop_cache_tuple[0]:
|
94
|
-
warn(_drop_cache_tuple[1])
|
79
|
+
self._clear_cache_key('_columns_indices', debug=debug)
|
80
|
+
self._clear_cache_key('_columns_indices_timestamp', debug=debug)
|
81
|
+
self._clear_cache_key('_columns_types', debug=debug)
|
82
|
+
self._clear_cache_key('_columns_types_timestamp', debug=debug)
|
95
83
|
|
96
84
|
with Venv(get_connector_plugin(self.instance_connector)):
|
97
85
|
if hasattr(self.instance_connector, 'drop_pipe_indices'):
|
@@ -110,9 +98,9 @@ def drop_indices(
|
|
110
98
|
)
|
111
99
|
)
|
112
100
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
101
|
+
self._clear_cache_key('_columns_indices', debug=debug)
|
102
|
+
self._clear_cache_key('_columns_indices_timestamp', debug=debug)
|
103
|
+
self._clear_cache_key('_columns_types', debug=debug)
|
104
|
+
self._clear_cache_key('_columns_types_timestamp', debug=debug)
|
117
105
|
|
118
106
|
return result
|
meerschaum/core/Pipe/_dtypes.py
CHANGED
meerschaum/core/Pipe/_index.py
CHANGED
@@ -29,19 +29,13 @@ def create_indices(
|
|
29
29
|
A `SuccessTuple` of success, message.
|
30
30
|
|
31
31
|
"""
|
32
|
-
from meerschaum.utils.warnings import warn
|
33
32
|
from meerschaum.utils.venv import Venv
|
34
33
|
from meerschaum.connectors import get_connector_plugin
|
35
34
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
if self.cache_pipe is not None:
|
42
|
-
cache_success, cache_msg = self.cache_pipe.index(columns=columns, debug=debug, **kw)
|
43
|
-
if not cache_success:
|
44
|
-
warn(cache_msg)
|
35
|
+
self._clear_cache_key('_columns_indices', debug=debug)
|
36
|
+
self._clear_cache_key('_columns_indices_timestamp', debug=debug)
|
37
|
+
self._clear_cache_key('_columns_types', debug=debug)
|
38
|
+
self._clear_cache_key('_columns_types_timestamp', debug=debug)
|
45
39
|
|
46
40
|
with Venv(get_connector_plugin(self.instance_connector)):
|
47
41
|
if hasattr(self.instance_connector, 'create_pipe_indices'):
|
@@ -60,9 +54,9 @@ def create_indices(
|
|
60
54
|
)
|
61
55
|
)
|
62
56
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
57
|
+
self._clear_cache_key('_columns_indices', debug=debug)
|
58
|
+
self._clear_cache_key('_columns_indices_timestamp', debug=debug)
|
59
|
+
self._clear_cache_key('_columns_types', debug=debug)
|
60
|
+
self._clear_cache_key('_columns_types_timestamp', debug=debug)
|
67
61
|
|
68
62
|
return result
|
meerschaum/core/Pipe/_sync.py
CHANGED
@@ -166,7 +166,7 @@ def sync(
|
|
166
166
|
})
|
167
167
|
|
168
168
|
self._invalidate_cache(debug=debug)
|
169
|
-
self.
|
169
|
+
self._cache_value('sync_ts', get_current_timestamp('ms'), debug=debug)
|
170
170
|
|
171
171
|
def _sync(
|
172
172
|
p: mrsm.Pipe,
|
@@ -477,15 +477,8 @@ def sync(
|
|
477
477
|
("s" if retries != 1 else "") + "!"
|
478
478
|
)
|
479
479
|
|
480
|
-
### CHECKPOINT: Finished syncing.
|
480
|
+
### CHECKPOINT: Finished syncing.
|
481
481
|
_checkpoint(**kw)
|
482
|
-
if p.cache_pipe is not None:
|
483
|
-
if debug:
|
484
|
-
dprint("Caching retrieved dataframe.", **kw)
|
485
|
-
_sync_cache_tuple = p.cache_pipe.sync(df, debug=debug, **kw)
|
486
|
-
if not _sync_cache_tuple[0]:
|
487
|
-
warn(f"Failed to sync local cache for {self}.")
|
488
|
-
|
489
482
|
p._invalidate_cache(debug=debug)
|
490
483
|
return return_tuple
|
491
484
|
|
@@ -620,16 +613,16 @@ def exists(
|
|
620
613
|
A `bool` corresponding to whether a pipe's underlying table exists.
|
621
614
|
|
622
615
|
"""
|
623
|
-
import time
|
624
616
|
from meerschaum.utils.venv import Venv
|
625
617
|
from meerschaum.connectors import get_connector_plugin
|
626
618
|
from meerschaum.utils.debug import dprint
|
627
|
-
|
619
|
+
from meerschaum.utils.dtypes import get_current_timestamp
|
620
|
+
now = get_current_timestamp('ms', as_int=True) / 1000
|
628
621
|
cache_seconds = mrsm.get_config('pipes', 'sync', 'exists_cache_seconds')
|
629
622
|
|
630
|
-
_exists = self.
|
623
|
+
_exists = self._get_cached_value('_exists', debug=debug)
|
631
624
|
if _exists:
|
632
|
-
exists_timestamp = self.
|
625
|
+
exists_timestamp = self._get_cached_value('_exists_timestamp', debug=debug)
|
633
626
|
if exists_timestamp is not None:
|
634
627
|
delta = now - exists_timestamp
|
635
628
|
if delta < cache_seconds:
|
@@ -644,8 +637,8 @@ def exists(
|
|
644
637
|
else False
|
645
638
|
)
|
646
639
|
|
647
|
-
self.
|
648
|
-
self.
|
640
|
+
self._cache_value('_exists', _exists, debug=debug)
|
641
|
+
self._cache_value('_exists_timestamp', now, debug=debug)
|
649
642
|
return _exists
|
650
643
|
|
651
644
|
|
@@ -1058,7 +1051,7 @@ def _persist_new_special_columns(
|
|
1058
1051
|
Check for new special columns and update the parameters accordingly.
|
1059
1052
|
"""
|
1060
1053
|
from meerschaum.utils.dataframe import get_special_cols
|
1061
|
-
from meerschaum.utils.dtypes import
|
1054
|
+
from meerschaum.utils.dtypes import is_dtype_special
|
1062
1055
|
from meerschaum.utils.warnings import dprint
|
1063
1056
|
|
1064
1057
|
special_cols = get_special_cols(df)
|
@@ -1066,18 +1059,19 @@ def _persist_new_special_columns(
|
|
1066
1059
|
existing_special_cols = {
|
1067
1060
|
col: typ
|
1068
1061
|
for col, typ in dtypes.items()
|
1069
|
-
if
|
1062
|
+
if is_dtype_special(typ)
|
1070
1063
|
}
|
1071
1064
|
new_special_cols = {
|
1072
1065
|
col: typ
|
1073
1066
|
for col, typ in special_cols.items()
|
1074
1067
|
if col not in existing_special_cols
|
1075
1068
|
}
|
1069
|
+
self._cache_value('new_special_cols', new_special_cols, memory_only=True, debug=debug)
|
1076
1070
|
if not new_special_cols:
|
1077
1071
|
return True, "Success"
|
1078
1072
|
|
1079
1073
|
if debug:
|
1080
1074
|
dprint(f"New special columns:\n{new_special_cols}")
|
1081
1075
|
|
1082
|
-
self._attributes_sync_time =
|
1076
|
+
self._clear_cache_key('_attributes_sync_time', debug=debug)
|
1083
1077
|
return self.update_parameters({'dtypes': new_special_cols}, debug=debug)
|
@@ -112,8 +112,10 @@ class Plugin:
|
|
112
112
|
if '_module' not in self.__dict__ or self.__dict__.get('_module', None) is None:
|
113
113
|
if self.__file__ is None:
|
114
114
|
return None
|
115
|
+
|
115
116
|
from meerschaum.plugins import import_plugins
|
116
117
|
self._module = import_plugins(str(self), warn=False)
|
118
|
+
|
117
119
|
return self._module
|
118
120
|
|
119
121
|
|
@@ -363,6 +365,10 @@ class Plugin:
|
|
363
365
|
### Determine where to permanently store the new plugin.
|
364
366
|
plugin_installation_dir_path = PLUGINS_DIR_PATHS[0]
|
365
367
|
for path in PLUGINS_DIR_PATHS:
|
368
|
+
if not path.exists():
|
369
|
+
warn(f"Plugins path does not exist: {path}", stack=False)
|
370
|
+
continue
|
371
|
+
|
366
372
|
files_in_plugins_dir = os.listdir(path)
|
367
373
|
if (
|
368
374
|
self.name in files_in_plugins_dir
|
@@ -729,7 +735,7 @@ class Plugin:
|
|
729
735
|
_d[len('plugin:'):] for _d in _deps
|
730
736
|
if _d.startswith('plugin:') and len(_d) > len('plugin:')
|
731
737
|
]
|
732
|
-
default_repo_keys = get_config('meerschaum', '
|
738
|
+
default_repo_keys = get_config('meerschaum', 'repository')
|
733
739
|
skipped_repo_keys = set()
|
734
740
|
|
735
741
|
for _plugin_name in plugin_names:
|
meerschaum/core/Token/_Token.py
CHANGED
@@ -42,7 +42,7 @@ class Token:
|
|
42
42
|
from meerschaum._internal.static import STATIC_CONFIG
|
43
43
|
now = datetime.now(timezone.utc)
|
44
44
|
default_expiration_days = mrsm.get_config(
|
45
|
-
'
|
45
|
+
'api', 'tokens', 'default_expiration_days',
|
46
46
|
) or 366
|
47
47
|
default_expiration = round_time(
|
48
48
|
now + timedelta(days=default_expiration_days),
|
meerschaum/core/User/_User.py
CHANGED
@@ -94,14 +94,13 @@ def verify_password(
|
|
94
94
|
from meerschaum._internal.static import STATIC_CONFIG
|
95
95
|
if password is None or password_hash is None:
|
96
96
|
return False
|
97
|
-
hash_config = STATIC_CONFIG['users']['password_hash']
|
98
97
|
try:
|
99
98
|
digest, rounds_str, encoded_salt, encoded_checksum = password_hash.split('$')[1:]
|
100
99
|
algorithm_name = digest.split('-')[-1]
|
101
100
|
salt = ab64_decode(encoded_salt)
|
102
101
|
checksum = ab64_decode(encoded_checksum)
|
103
102
|
rounds = int(rounds_str)
|
104
|
-
except Exception
|
103
|
+
except Exception:
|
105
104
|
warn(f"Failed to extract context from password hash '{password_hash}'. Is it corrupted?")
|
106
105
|
return False
|
107
106
|
|
meerschaum/jobs/_Executor.py
CHANGED
@@ -10,28 +10,72 @@ from __future__ import annotations
|
|
10
10
|
from abc import abstractmethod
|
11
11
|
|
12
12
|
from meerschaum.connectors import Connector
|
13
|
-
from meerschaum.utils.typing import
|
13
|
+
from meerschaum.utils.typing import (
|
14
|
+
List, Dict, SuccessTuple, TYPE_CHECKING, Optional, Any, Union, Callable,
|
15
|
+
)
|
14
16
|
|
15
17
|
if TYPE_CHECKING:
|
16
18
|
from meerschaum.jobs import Job
|
19
|
+
from datetime import datetime
|
17
20
|
|
18
21
|
class Executor(Connector):
|
19
22
|
"""
|
20
23
|
Define the methods for managing jobs.
|
21
24
|
"""
|
22
25
|
|
26
|
+
@abstractmethod
|
27
|
+
def get_job_names(self, debug: bool = False) -> List[str]:
|
28
|
+
"""
|
29
|
+
Return a list of existing jobs, including hidden ones.
|
30
|
+
"""
|
31
|
+
|
23
32
|
@abstractmethod
|
24
33
|
def get_job_exists(self, name: str, debug: bool = False) -> bool:
|
25
34
|
"""
|
26
35
|
Return whether a job exists.
|
27
36
|
"""
|
28
|
-
|
37
|
+
|
38
|
+
@abstractmethod
|
39
|
+
def get_jobs(self, debug: bool = False) -> Dict[str, Job]:
|
40
|
+
"""
|
41
|
+
Return a dictionary of existing jobs.
|
42
|
+
"""
|
43
|
+
|
44
|
+
@abstractmethod
|
45
|
+
def get_job_metadata(self, name: str, debug: bool = False) -> Dict[str, Any]:
|
46
|
+
"""
|
47
|
+
Return a job's metadata.
|
48
|
+
"""
|
49
|
+
|
50
|
+
@abstractmethod
|
51
|
+
def get_job_properties(self, name: str, debug: bool = False) -> Dict[str, Any]:
|
52
|
+
"""
|
53
|
+
Return the underlying daemon's properties.
|
54
|
+
"""
|
29
55
|
@abstractmethod
|
30
|
-
def
|
56
|
+
def get_job_status(self, name: str, debug: bool = False) -> str:
|
31
57
|
"""
|
32
|
-
Return
|
58
|
+
Return the job's status.
|
33
59
|
"""
|
34
60
|
|
61
|
+
@abstractmethod
|
62
|
+
def get_job_began(self, name: str, debug: bool = False) -> Union[str, None]:
|
63
|
+
"""
|
64
|
+
Return when a job began running.
|
65
|
+
"""
|
66
|
+
|
67
|
+
@abstractmethod
|
68
|
+
def get_job_ended(self, name: str, debug: bool = False) -> Union[str, None]:
|
69
|
+
"""
|
70
|
+
Return when a job stopped running.
|
71
|
+
"""
|
72
|
+
|
73
|
+
@abstractmethod
|
74
|
+
def get_job_paused(self, name: str, debug: bool = False) -> Union[str, None]:
|
75
|
+
"""
|
76
|
+
Return a job's `paused` timestamp, if it exists.
|
77
|
+
"""
|
78
|
+
|
35
79
|
@abstractmethod
|
36
80
|
def create_job(
|
37
81
|
self,
|
@@ -73,3 +117,43 @@ class Executor(Connector):
|
|
73
117
|
"""
|
74
118
|
Return a job's log output.
|
75
119
|
"""
|
120
|
+
|
121
|
+
@abstractmethod
|
122
|
+
def get_job_stop_time(self, name: str, debug: bool = False) -> Union[datetime, None]:
|
123
|
+
"""
|
124
|
+
Return the job's manual stop time.
|
125
|
+
"""
|
126
|
+
|
127
|
+
@abstractmethod
|
128
|
+
async def monitor_logs_async(
|
129
|
+
self,
|
130
|
+
name: str,
|
131
|
+
callback_function: Callable[[Any], Any],
|
132
|
+
input_callback_function: Callable[[], str],
|
133
|
+
stop_callback_function: Callable[[SuccessTuple], str],
|
134
|
+
stop_on_exit: bool = False,
|
135
|
+
strip_timestamps: bool = False,
|
136
|
+
accept_input: bool = True,
|
137
|
+
debug: bool = False,
|
138
|
+
):
|
139
|
+
"""
|
140
|
+
Monitor a job's log files and await a callback with the changes.
|
141
|
+
"""
|
142
|
+
|
143
|
+
@abstractmethod
|
144
|
+
def monitor_logs(self, *args, **kwargs):
|
145
|
+
"""
|
146
|
+
Monitor a job's log files.
|
147
|
+
"""
|
148
|
+
|
149
|
+
@abstractmethod
|
150
|
+
def get_job_is_blocking_on_stdin(self, name: str, debug: bool = False) -> bool:
|
151
|
+
"""
|
152
|
+
Return whether a job is blocking on stdin.
|
153
|
+
"""
|
154
|
+
|
155
|
+
@abstractmethod
|
156
|
+
def get_job_prompt_kwargs(self, name: str, debug: bool = False) -> Dict[str, Any]:
|
157
|
+
"""
|
158
|
+
Return the kwargs to the blocking prompt.
|
159
|
+
"""
|