meerschaum 2.2.6__py3-none-any.whl → 2.3.0.dev1__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/__init__.py +4 -1
- meerschaum/__main__.py +10 -5
- meerschaum/_internal/arguments/_parser.py +44 -15
- meerschaum/_internal/entry.py +35 -14
- meerschaum/_internal/shell/Shell.py +155 -53
- meerschaum/_internal/shell/updates.py +175 -0
- meerschaum/actions/api.py +12 -12
- meerschaum/actions/attach.py +95 -0
- meerschaum/actions/delete.py +35 -26
- meerschaum/actions/register.py +19 -5
- meerschaum/actions/show.py +119 -148
- meerschaum/actions/start.py +85 -75
- meerschaum/actions/stop.py +68 -39
- meerschaum/actions/sync.py +3 -3
- meerschaum/actions/upgrade.py +28 -36
- meerschaum/api/_events.py +18 -1
- meerschaum/api/_oauth2.py +2 -0
- meerschaum/api/_websockets.py +2 -2
- meerschaum/api/dash/jobs.py +5 -2
- meerschaum/api/routes/__init__.py +1 -0
- meerschaum/api/routes/_actions.py +122 -44
- meerschaum/api/routes/_jobs.py +340 -0
- meerschaum/api/routes/_pipes.py +25 -25
- meerschaum/config/_default.py +1 -0
- meerschaum/config/_formatting.py +1 -0
- meerschaum/config/_paths.py +5 -0
- meerschaum/config/_shell.py +84 -67
- meerschaum/config/_version.py +1 -1
- meerschaum/config/static/__init__.py +9 -0
- meerschaum/connectors/__init__.py +9 -11
- meerschaum/connectors/api/APIConnector.py +18 -1
- meerschaum/connectors/api/_actions.py +60 -71
- meerschaum/connectors/api/_jobs.py +260 -0
- meerschaum/connectors/api/_misc.py +1 -1
- meerschaum/connectors/api/_request.py +13 -9
- meerschaum/connectors/parse.py +23 -7
- meerschaum/core/Pipe/_sync.py +3 -0
- meerschaum/plugins/__init__.py +89 -5
- meerschaum/utils/daemon/Daemon.py +333 -149
- meerschaum/utils/daemon/FileDescriptorInterceptor.py +19 -10
- meerschaum/utils/daemon/RotatingFile.py +18 -7
- meerschaum/utils/daemon/StdinFile.py +110 -0
- meerschaum/utils/daemon/__init__.py +40 -27
- meerschaum/utils/formatting/__init__.py +83 -37
- meerschaum/utils/formatting/_jobs.py +118 -51
- meerschaum/utils/formatting/_shell.py +6 -0
- meerschaum/utils/jobs/_Job.py +684 -0
- meerschaum/utils/jobs/__init__.py +245 -0
- meerschaum/utils/misc.py +18 -17
- meerschaum/utils/packages/__init__.py +21 -15
- meerschaum/utils/packages/_packages.py +2 -2
- meerschaum/utils/prompt.py +20 -7
- meerschaum/utils/schedule.py +21 -15
- {meerschaum-2.2.6.dist-info → meerschaum-2.3.0.dev1.dist-info}/METADATA +9 -9
- {meerschaum-2.2.6.dist-info → meerschaum-2.3.0.dev1.dist-info}/RECORD +61 -54
- {meerschaum-2.2.6.dist-info → meerschaum-2.3.0.dev1.dist-info}/WHEEL +1 -1
- {meerschaum-2.2.6.dist-info → meerschaum-2.3.0.dev1.dist-info}/LICENSE +0 -0
- {meerschaum-2.2.6.dist-info → meerschaum-2.3.0.dev1.dist-info}/NOTICE +0 -0
- {meerschaum-2.2.6.dist-info → meerschaum-2.3.0.dev1.dist-info}/entry_points.txt +0 -0
- {meerschaum-2.2.6.dist-info → meerschaum-2.3.0.dev1.dist-info}/top_level.txt +0 -0
- {meerschaum-2.2.6.dist-info → meerschaum-2.3.0.dev1.dist-info}/zip-safe +0 -0
meerschaum/__init__.py
CHANGED
@@ -20,15 +20,16 @@ limitations under the License.
|
|
20
20
|
|
21
21
|
import atexit
|
22
22
|
from meerschaum.utils.typing import SuccessTuple
|
23
|
+
from meerschaum.utils.packages import attempt_import
|
23
24
|
from meerschaum.core.Pipe import Pipe
|
24
25
|
from meerschaum.plugins import Plugin
|
25
26
|
from meerschaum.utils.venv import Venv
|
27
|
+
from meerschaum.utils.jobs import Job
|
26
28
|
from meerschaum.connectors import get_connector, Connector, make_connector
|
27
29
|
from meerschaum.utils import get_pipes
|
28
30
|
from meerschaum.utils.formatting import pprint
|
29
31
|
from meerschaum._internal.docs import index as __doc__
|
30
32
|
from meerschaum.config import __version__, get_config
|
31
|
-
from meerschaum.utils.packages import attempt_import
|
32
33
|
from meerschaum.__main__ import _close_pools
|
33
34
|
|
34
35
|
atexit.register(_close_pools)
|
@@ -42,6 +43,8 @@ __all__ = (
|
|
42
43
|
"Plugin",
|
43
44
|
"Venv",
|
44
45
|
"Plugin",
|
46
|
+
"Job",
|
47
|
+
"Daemon",
|
45
48
|
"pprint",
|
46
49
|
"attempt_import",
|
47
50
|
"actions",
|
meerschaum/__main__.py
CHANGED
@@ -19,9 +19,15 @@ See the License for the specific language governing permissions and
|
|
19
19
|
limitations under the License.
|
20
20
|
"""
|
21
21
|
|
22
|
-
import sys
|
22
|
+
import sys
|
23
|
+
import os
|
24
|
+
import copy
|
23
25
|
|
24
|
-
|
26
|
+
from meerschaum.utils.typing import List, Optional
|
27
|
+
from meerschaum.utils.formatting import print_tuple as _print_tuple
|
28
|
+
|
29
|
+
|
30
|
+
def main(sysargs: Optional[List[str]] = None) -> None:
|
25
31
|
"""Main CLI entry point."""
|
26
32
|
if sysargs is None:
|
27
33
|
sysargs = copy.deepcopy(sys.argv[1:])
|
@@ -41,7 +47,7 @@ def main(sysargs: list = None) -> None:
|
|
41
47
|
|
42
48
|
if ('-d' in sysargs or '--daemon' in sysargs) and ('stack' not in sysargs):
|
43
49
|
from meerschaum.utils.daemon import daemon_entry
|
44
|
-
daemon_entry(sysargs)
|
50
|
+
_print_tuple(daemon_entry(sysargs), upper_padding=1)
|
45
51
|
return _exit(old_cwd=old_cwd)
|
46
52
|
|
47
53
|
from meerschaum._internal.entry import entry, get_shell
|
@@ -57,8 +63,7 @@ def main(sysargs: list = None) -> None:
|
|
57
63
|
return_tuple = entry(sysargs)
|
58
64
|
rc = 0
|
59
65
|
if isinstance(return_tuple, tuple) and '--nopretty' not in sysargs:
|
60
|
-
|
61
|
-
print_tuple(return_tuple, upper_padding=1)
|
66
|
+
_print_tuple(return_tuple, upper_padding=1)
|
62
67
|
rc = 0 if (return_tuple[0] is True) else 1
|
63
68
|
|
64
69
|
return _exit(rc, old_cwd=old_cwd)
|
@@ -62,7 +62,24 @@ def parse_datetime(dt_str: str) -> Union[datetime, int, str]:
|
|
62
62
|
return dt
|
63
63
|
|
64
64
|
|
65
|
-
def
|
65
|
+
def parse_executor_keys(executor_keys_str: str) -> Union[str, None]:
|
66
|
+
"""
|
67
|
+
Ensure that only API keys are provided for executor_keys.
|
68
|
+
"""
|
69
|
+
if executor_keys_str == 'local':
|
70
|
+
return executor_keys_str
|
71
|
+
|
72
|
+
if executor_keys_str.lower() == 'none':
|
73
|
+
return 'local'
|
74
|
+
|
75
|
+
if not executor_keys_str.startswith('api:'):
|
76
|
+
from meerschaum.utils.warnings import error
|
77
|
+
error(f"Invalid exectutor keys '{executor_keys_str}'.", stack=False)
|
78
|
+
|
79
|
+
return executor_keys_str
|
80
|
+
|
81
|
+
|
82
|
+
def parse_help(sysargs: Union[List[str], Dict[str, Any]]) -> None:
|
66
83
|
"""Parse the `--help` flag to determine which help message to print."""
|
67
84
|
from meerschaum._internal.arguments._parse_arguments import parse_arguments, parse_line
|
68
85
|
from meerschaum.actions import actions, get_subactions
|
@@ -135,6 +152,7 @@ _seen_plugin_args = {}
|
|
135
152
|
|
136
153
|
groups = {}
|
137
154
|
groups['actions'] = parser.add_argument_group(title='Actions options')
|
155
|
+
groups['jobs'] = parser.add_argument_group(title='Jobs options')
|
138
156
|
groups['pipes'] = parser.add_argument_group(title='Pipes options')
|
139
157
|
groups['sync'] = parser.add_argument_group(title='Sync options')
|
140
158
|
groups['api'] = parser.add_argument_group(title='API options')
|
@@ -166,18 +184,25 @@ groups['actions'].add_argument(
|
|
166
184
|
help="Automatically choose the defaults answers to questions. Does not result in data loss.",
|
167
185
|
)
|
168
186
|
groups['actions'].add_argument(
|
169
|
-
'-
|
170
|
-
help =
|
187
|
+
'-A', '--sub-args', nargs=argparse.REMAINDER,
|
188
|
+
help = (
|
189
|
+
"Provide a list of arguments for subprocesses. " +
|
190
|
+
"You can also type sub-arguments in [] instead." +
|
191
|
+
" E.g. `stack -A='--version'`, `ls [-lh]`, `echo -A these are sub-arguments`"
|
192
|
+
)
|
171
193
|
)
|
172
|
-
|
173
|
-
|
194
|
+
|
195
|
+
### Jobs options
|
196
|
+
groups['jobs'].add_argument(
|
197
|
+
'-d', '--daemon', action='store_true',
|
198
|
+
help = "Run an action as a background daemon to create a job."
|
174
199
|
)
|
175
|
-
groups['
|
200
|
+
groups['jobs'].add_argument(
|
176
201
|
'--name', '--job-name', type=parse_name, help=(
|
177
202
|
"Assign a name to a job. If no name is provided, a random name will be assigned."
|
178
203
|
),
|
179
204
|
)
|
180
|
-
groups['
|
205
|
+
groups['jobs'].add_argument(
|
181
206
|
'-s', '--schedule', '--cron', type=str,
|
182
207
|
help = (
|
183
208
|
"Continue executing the action according to a schedule (e.g. 'every 1 seconds'). \n"
|
@@ -185,15 +210,19 @@ groups['actions'].add_argument(
|
|
185
210
|
+ "https://red-engine.readthedocs.io/en/stable/condition_syntax/index.html"
|
186
211
|
)
|
187
212
|
)
|
188
|
-
groups['
|
189
|
-
'
|
190
|
-
help
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
213
|
+
groups['jobs'].add_argument(
|
214
|
+
'--restart', action='store_true',
|
215
|
+
help=("Restart a job if not stopped manually."),
|
216
|
+
)
|
217
|
+
groups['jobs'].add_argument(
|
218
|
+
'--executor-keys', '--executor', '-e', type=parse_executor_keys,
|
219
|
+
help=(
|
220
|
+
"Remotely execute jobs on an API instance."
|
221
|
+
),
|
222
|
+
)
|
223
|
+
groups['jobs'].add_argument(
|
224
|
+
'--rm', action='store_true', help="Delete a job once it has finished executing."
|
195
225
|
)
|
196
|
-
|
197
226
|
### Pipes options
|
198
227
|
groups['pipes'].add_argument(
|
199
228
|
'-c', '-C', '--connector-keys', nargs='+',
|
meerschaum/_internal/entry.py
CHANGED
@@ -8,20 +8,15 @@ The entry point for launching Meerschaum actions.
|
|
8
8
|
"""
|
9
9
|
|
10
10
|
from __future__ import annotations
|
11
|
-
from meerschaum.utils.typing import SuccessTuple, List, Optional, Dict
|
11
|
+
from meerschaum.utils.typing import SuccessTuple, List, Optional, Dict, Callable, Any
|
12
12
|
|
13
13
|
def entry(sysargs: Optional[List[str]] = None) -> SuccessTuple:
|
14
|
-
"""
|
15
|
-
|
16
|
-
|
17
|
-
Examples of action:
|
18
|
-
'show actions' -> ['actions']
|
19
|
-
'show' -> []
|
14
|
+
"""
|
15
|
+
Parse arguments and launch a Meerschaum action.
|
20
16
|
|
21
17
|
Returns
|
22
18
|
-------
|
23
|
-
A `SuccessTuple` indicating success.
|
24
|
-
|
19
|
+
A `SuccessTuple` indicating success.
|
25
20
|
"""
|
26
21
|
from meerschaum._internal.arguments import parse_arguments
|
27
22
|
from meerschaum.config.static import STATIC_CONFIG
|
@@ -51,14 +46,15 @@ def entry(sysargs: Optional[List[str]] = None) -> SuccessTuple:
|
|
51
46
|
|
52
47
|
|
53
48
|
def entry_with_args(
|
54
|
-
|
55
|
-
|
56
|
-
|
49
|
+
_actions: Optional[Dict[str, Callable[[Any], SuccessTuple]]] = None,
|
50
|
+
**kw
|
51
|
+
) -> SuccessTuple:
|
57
52
|
"""Execute a Meerschaum action with keyword arguments.
|
58
53
|
Use `_entry()` for parsing sysargs before executing.
|
59
54
|
"""
|
60
55
|
import sys
|
61
56
|
import functools
|
57
|
+
import inspect
|
62
58
|
from meerschaum.actions import get_action, get_main_action_name
|
63
59
|
from meerschaum._internal.arguments import remove_leading_action
|
64
60
|
from meerschaum.utils.venv import Venv, active_venvs, deactivate_venv
|
@@ -72,6 +68,25 @@ def entry_with_args(
|
|
72
68
|
):
|
73
69
|
return get_shell().cmdloop()
|
74
70
|
|
71
|
+
skip_schedule = False
|
72
|
+
|
73
|
+
executor_keys = kw.get('executor_keys', None)
|
74
|
+
if executor_keys is None:
|
75
|
+
executor_keys = 'local'
|
76
|
+
|
77
|
+
if executor_keys.startswith('api:'):
|
78
|
+
intended_action_function = get_action(kw['action'], _actions=_actions)
|
79
|
+
function_accepts_executor_keys = (
|
80
|
+
'executor_keys' in inspect.signature(intended_action_function).parameters
|
81
|
+
if intended_action_function is not None
|
82
|
+
else False
|
83
|
+
)
|
84
|
+
if not function_accepts_executor_keys:
|
85
|
+
api_label = executor_keys.split(':')[-1]
|
86
|
+
kw['action'].insert(0, 'api')
|
87
|
+
kw['action'].insert(1, api_label)
|
88
|
+
skip_schedule = True
|
89
|
+
|
75
90
|
action_function = get_action(kw['action'], _actions=_actions)
|
76
91
|
|
77
92
|
### If action does not exist, execute in a subshell.
|
@@ -86,7 +101,6 @@ def entry_with_args(
|
|
86
101
|
) else None
|
87
102
|
)
|
88
103
|
|
89
|
-
skip_schedule = False
|
90
104
|
if (
|
91
105
|
kw['action']
|
92
106
|
and kw['action'][0] == 'start'
|
@@ -96,7 +110,14 @@ def entry_with_args(
|
|
96
110
|
|
97
111
|
kw['action'] = remove_leading_action(kw['action'], _actions=_actions)
|
98
112
|
|
99
|
-
do_action = functools.partial(
|
113
|
+
do_action = functools.partial(
|
114
|
+
_do_action_wrapper,
|
115
|
+
action_function,
|
116
|
+
plugin_name,
|
117
|
+
**kw
|
118
|
+
)
|
119
|
+
|
120
|
+
|
100
121
|
if kw.get('schedule', None) and not skip_schedule:
|
101
122
|
from meerschaum.utils.schedule import schedule_function
|
102
123
|
from meerschaum.utils.misc import interval_str
|
@@ -28,7 +28,7 @@ prompt_toolkit = attempt_import('prompt_toolkit', lazy=False, warn=False, instal
|
|
28
28
|
from meerschaum._internal.shell.ValidAutoSuggest import ValidAutoSuggest
|
29
29
|
from meerschaum._internal.shell.ShellCompleter import ShellCompleter
|
30
30
|
_clear_screen = get_config('shell', 'clear_screen', patch=True)
|
31
|
-
from meerschaum.utils.misc import string_width
|
31
|
+
from meerschaum.utils.misc import string_width, remove_ansi
|
32
32
|
|
33
33
|
patch = True
|
34
34
|
### remove default cmd2 commands
|
@@ -56,7 +56,7 @@ hidden_commands = {
|
|
56
56
|
'ipy',
|
57
57
|
}
|
58
58
|
reserved_completers = {
|
59
|
-
'instance', 'repo'
|
59
|
+
'instance', 'repo', 'executor',
|
60
60
|
}
|
61
61
|
|
62
62
|
### To handle dynamic reloading, store shell attributes externally.
|
@@ -95,8 +95,8 @@ def _insert_shell_actions(
|
|
95
95
|
setattr(_shell_class, 'complete_' + a, completer)
|
96
96
|
|
97
97
|
def _completer_wrapper(
|
98
|
-
|
99
|
-
|
98
|
+
target: Callable[[Any], List[str]]
|
99
|
+
) -> Callable[['meerschaum._internal.shell.Shell', str, str, int, int], Any]:
|
100
100
|
"""
|
101
101
|
Wrapper for `complete_` functions so they can instead use Meerschaum arguments.
|
102
102
|
"""
|
@@ -125,13 +125,13 @@ def _completer_wrapper(
|
|
125
125
|
|
126
126
|
|
127
127
|
def default_action_completer(
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
128
|
+
text: Optional[str] = None,
|
129
|
+
line: Optional[str] = None,
|
130
|
+
begin_index: Optional[int] = None,
|
131
|
+
end_index: Optional[int] = None,
|
132
|
+
action: Optional[List[str]] = None,
|
133
|
+
**kw: Any
|
134
|
+
) -> List[str]:
|
135
135
|
"""
|
136
136
|
Search for subactions by default. This may be overridden by each action.
|
137
137
|
"""
|
@@ -206,13 +206,11 @@ def get_shell_intro(with_color: bool = True) -> str:
|
|
206
206
|
"""
|
207
207
|
from meerschaum.utils.formatting import CHARSET, ANSI, colored
|
208
208
|
intro = get_config('shell', CHARSET, 'intro', patch=patch)
|
209
|
-
intro +=
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
]
|
215
|
-
) + 'v' + version
|
209
|
+
intro += (
|
210
|
+
'\n'
|
211
|
+
+ (' ' * (string_width(intro) - len('v' + version)))
|
212
|
+
+ f'v{version}'
|
213
|
+
)
|
216
214
|
|
217
215
|
if not with_color or not ANSI:
|
218
216
|
return intro
|
@@ -225,10 +223,10 @@ def get_shell_intro(with_color: bool = True) -> str:
|
|
225
223
|
|
226
224
|
class Shell(cmd.Cmd):
|
227
225
|
def __init__(
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
226
|
+
self,
|
227
|
+
actions: Optional[Dict[str, Any]] = None,
|
228
|
+
sysargs: Optional[List[str]] = None
|
229
|
+
):
|
232
230
|
"""
|
233
231
|
Customize the CLI from configuration
|
234
232
|
"""
|
@@ -249,11 +247,11 @@ class Shell(cmd.Cmd):
|
|
249
247
|
|
250
248
|
from meerschaum.config._paths import SHELL_HISTORY_PATH
|
251
249
|
shell_attrs['session'] = prompt_toolkit_shortcuts.PromptSession(
|
252
|
-
history
|
253
|
-
auto_suggest
|
254
|
-
completer
|
255
|
-
complete_while_typing
|
256
|
-
reserve_space_for_menu
|
250
|
+
history=prompt_toolkit_history.FileHistory(SHELL_HISTORY_PATH.as_posix()),
|
251
|
+
auto_suggest=ValidAutoSuggest(),
|
252
|
+
completer=ShellCompleter(),
|
253
|
+
complete_while_typing=True,
|
254
|
+
reserve_space_for_menu=False,
|
257
255
|
)
|
258
256
|
|
259
257
|
try: ### try cmd2 arguments first
|
@@ -283,6 +281,7 @@ class Shell(cmd.Cmd):
|
|
283
281
|
shell_attrs['_sysargs'] = sysargs
|
284
282
|
shell_attrs['_actions']['instance'] = self.do_instance
|
285
283
|
shell_attrs['_actions']['repo'] = self.do_repo
|
284
|
+
shell_attrs['_actions']['executor'] = self.do_executor
|
286
285
|
shell_attrs['_actions']['debug'] = self.do_debug
|
287
286
|
shell_attrs['_update_bottom_toolbar'] = True
|
288
287
|
shell_attrs['_old_bottom_toolbar'] = ''
|
@@ -297,19 +296,25 @@ class Shell(cmd.Cmd):
|
|
297
296
|
except Exception as e:
|
298
297
|
pass
|
299
298
|
|
299
|
+
### Finally, spawn the version update thread.
|
300
|
+
from meerschaum._internal.shell.updates import run_version_check_thread
|
301
|
+
self._update_thread = run_version_check_thread(debug=shell_attrs.get('debug', False))
|
302
|
+
|
303
|
+
|
300
304
|
def load_config(self, instance: Optional[str] = None):
|
301
305
|
"""
|
302
306
|
Set attributes from the shell configuration.
|
303
307
|
"""
|
304
308
|
from meerschaum.utils.misc import remove_ansi
|
305
309
|
from meerschaum.utils.formatting import CHARSET, ANSI, colored
|
306
|
-
|
310
|
+
from meerschaum._internal.shell.updates import get_update_message
|
311
|
+
|
307
312
|
if shell_attrs.get('intro', None) != '':
|
308
313
|
self.intro = (
|
309
314
|
get_shell_intro(with_color=False)
|
310
315
|
if shell_attrs.get('intro', None) != ''
|
311
316
|
else ""
|
312
|
-
)
|
317
|
+
) + get_update_message()
|
313
318
|
|
314
319
|
shell_attrs['intro'] = self.intro
|
315
320
|
shell_attrs['_prompt'] = get_config('shell', CHARSET, 'prompt', patch=patch)
|
@@ -333,6 +338,12 @@ class Shell(cmd.Cmd):
|
|
333
338
|
shell_attrs['instance_keys'] = remove_ansi(str(instance))
|
334
339
|
if shell_attrs.get('repo_keys', None) is None:
|
335
340
|
shell_attrs['repo_keys'] = get_config('meerschaum', 'default_repository', patch=patch)
|
341
|
+
if shell_attrs.get('executor_keys', None) is None:
|
342
|
+
shell_attrs['executor_keys'] = get_config(
|
343
|
+
'meerschaum', 'default_executor',
|
344
|
+
patch=patch,
|
345
|
+
) or 'local'
|
346
|
+
|
336
347
|
### this will be updated later in update_prompt ONLY IF {username} is in the prompt
|
337
348
|
shell_attrs['username'] = ''
|
338
349
|
|
@@ -358,14 +369,19 @@ class Shell(cmd.Cmd):
|
|
358
369
|
def insert_actions(self):
|
359
370
|
from meerschaum.actions import actions
|
360
371
|
|
361
|
-
def update_prompt(
|
372
|
+
def update_prompt(
|
373
|
+
self,
|
374
|
+
instance: Optional[str] = None,
|
375
|
+
username: Optional[str] = None,
|
376
|
+
executor_keys: Optional[str] = None,
|
377
|
+
):
|
362
378
|
from meerschaum.utils.formatting import ANSI, colored
|
363
379
|
from meerschaum._internal.entry import _shell, get_shell
|
364
380
|
|
365
381
|
cmd.__builtins__['input'] = input_with_sigint(
|
366
382
|
_old_input,
|
367
383
|
shell_attrs['session'],
|
368
|
-
shell
|
384
|
+
shell=self,
|
369
385
|
)
|
370
386
|
prompt = shell_attrs['_prompt']
|
371
387
|
mask = prompt
|
@@ -391,7 +407,8 @@ class Shell(cmd.Cmd):
|
|
391
407
|
from meerschaum.connectors.sql import SQLConnector
|
392
408
|
try:
|
393
409
|
conn_attrs = parse_instance_keys(
|
394
|
-
remove_ansi(shell_attrs['instance_keys']),
|
410
|
+
remove_ansi(shell_attrs['instance_keys']),
|
411
|
+
construct=False,
|
395
412
|
)
|
396
413
|
if 'username' not in conn_attrs:
|
397
414
|
if 'uri' in conn_attrs:
|
@@ -405,12 +422,27 @@ class Shell(cmd.Cmd):
|
|
405
422
|
if username is None:
|
406
423
|
username = '(no username)'
|
407
424
|
shell_attrs['username'] = (
|
408
|
-
username
|
409
|
-
|
425
|
+
username
|
426
|
+
if not ANSI
|
427
|
+
else colored(username, **get_config('shell', 'ansi', 'username', 'rich'))
|
410
428
|
)
|
411
429
|
prompt = prompt.replace('{username}', shell_attrs['username'])
|
412
430
|
mask = mask.replace('{username}', ''.join(['\0' for c in '{username}']))
|
413
431
|
|
432
|
+
if '{executor_keys}' in shell_attrs['_prompt']:
|
433
|
+
if executor_keys is None:
|
434
|
+
executor_keys = shell_attrs.get('executor_keys', None) or 'local'
|
435
|
+
shell_attrs['executor_keys'] = (
|
436
|
+
executor_keys
|
437
|
+
if not ANSI
|
438
|
+
else colored(
|
439
|
+
remove_ansi(executor_keys),
|
440
|
+
**get_config('shell', 'ansi', 'executor', 'rich')
|
441
|
+
)
|
442
|
+
)
|
443
|
+
prompt = prompt.replace('{executor_keys}', shell_attrs['executor_keys'])
|
444
|
+
mask = mask.replace('{executor_keys}', ''.join(['\0' for c in '{executor_keys}']))
|
445
|
+
|
414
446
|
remainder_prompt = list(shell_attrs['_prompt'])
|
415
447
|
for i, c in enumerate(mask):
|
416
448
|
if c != '\0':
|
@@ -418,10 +450,13 @@ class Shell(cmd.Cmd):
|
|
418
450
|
if ANSI:
|
419
451
|
_c = colored(_c, **get_config('shell', 'ansi', 'prompt', 'rich'))
|
420
452
|
remainder_prompt[i] = _c
|
453
|
+
|
421
454
|
self.prompt = ''.join(remainder_prompt).replace(
|
422
455
|
'{username}', shell_attrs['username']
|
423
456
|
).replace(
|
424
457
|
'{instance}', shell_attrs['instance']
|
458
|
+
).replace(
|
459
|
+
'{executor_keys}', shell_attrs['executor_keys']
|
425
460
|
)
|
426
461
|
shell_attrs['prompt'] = self.prompt
|
427
462
|
### flush stdout
|
@@ -521,6 +556,9 @@ class Shell(cmd.Cmd):
|
|
521
556
|
if 'repository' not in args and main_action_name != 'api':
|
522
557
|
args['repository'] = str(shell_attrs['repo_keys'])
|
523
558
|
|
559
|
+
if 'executor_keys' not in args:
|
560
|
+
args['executor_keys'] = remove_ansi(str(shell_attrs['executor_keys']))
|
561
|
+
|
524
562
|
### parse out empty strings
|
525
563
|
if args['action'][0].strip("\"'") == '':
|
526
564
|
self.emptyline()
|
@@ -565,12 +603,12 @@ class Shell(cmd.Cmd):
|
|
565
603
|
if stop:
|
566
604
|
return True
|
567
605
|
|
568
|
-
def do_pass(self, line):
|
606
|
+
def do_pass(self, line, executor_keys=None):
|
569
607
|
"""
|
570
608
|
Do nothing.
|
571
609
|
"""
|
572
610
|
|
573
|
-
def do_debug(self, action: Optional[List[str]] = None, **kw):
|
611
|
+
def do_debug(self, action: Optional[List[str]] = None, executor_keys=None, **kw):
|
574
612
|
"""
|
575
613
|
Toggle the shell's debug mode.
|
576
614
|
If debug = on, append `--debug` to all commands.
|
@@ -601,9 +639,10 @@ class Shell(cmd.Cmd):
|
|
601
639
|
|
602
640
|
def do_instance(
|
603
641
|
self,
|
604
|
-
action
|
605
|
-
|
606
|
-
|
642
|
+
action: Optional[List[str]] = None,
|
643
|
+
executor_keys=None,
|
644
|
+
debug: bool = False,
|
645
|
+
**kw: Any
|
607
646
|
) -> SuccessTuple:
|
608
647
|
"""
|
609
648
|
Temporarily set a default Meerschaum instance for the duration of the shell.
|
@@ -672,11 +711,12 @@ class Shell(cmd.Cmd):
|
|
672
711
|
|
673
712
|
|
674
713
|
def do_repo(
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
714
|
+
self,
|
715
|
+
action: Optional[List[str]] = None,
|
716
|
+
executor_keys=None,
|
717
|
+
debug: bool = False,
|
718
|
+
**kw: Any
|
719
|
+
) -> SuccessTuple:
|
680
720
|
"""
|
681
721
|
Temporarily set a default Meerschaum repository for the duration of the shell.
|
682
722
|
The default repository (mrsm.io) is loaded from the Meerschaum configuraton file
|
@@ -723,9 +763,59 @@ class Shell(cmd.Cmd):
|
|
723
763
|
return True, "Success"
|
724
764
|
|
725
765
|
def complete_repo(self, *args) -> List[str]:
|
726
|
-
|
766
|
+
results = self.complete_instance(*args)
|
767
|
+
return [result for result in results if result.startswith('api:')]
|
768
|
+
|
769
|
+
def do_executor(
|
770
|
+
self,
|
771
|
+
action: Optional[List[str]] = None,
|
772
|
+
executor_keys=None,
|
773
|
+
debug: bool = False,
|
774
|
+
**kw: Any
|
775
|
+
) -> SuccessTuple:
|
776
|
+
"""
|
777
|
+
Temporarily set a default Meerschaum executor for the duration of the shell.
|
778
|
+
|
779
|
+
You can change the default repository with `edit config`.
|
780
|
+
|
781
|
+
Usage:
|
782
|
+
executor {API label}
|
783
|
+
|
784
|
+
Examples:
|
785
|
+
### reset to default executor
|
786
|
+
executor
|
787
|
+
|
788
|
+
### set the executor to 'api:main'
|
789
|
+
executor api:main
|
790
|
+
|
791
|
+
Note that executors are API instances.
|
792
|
+
"""
|
793
|
+
from meerschaum import get_connector
|
794
|
+
from meerschaum.connectors.parse import parse_executor_keys
|
795
|
+
from meerschaum.utils.warnings import warn, info
|
796
|
+
|
797
|
+
if action is None:
|
798
|
+
action = []
|
799
|
+
|
800
|
+
try:
|
801
|
+
executor_keys = action[0]
|
802
|
+
except (IndexError, AttributeError):
|
803
|
+
executor_keys = ''
|
804
|
+
if executor_keys == '':
|
805
|
+
executor_keys = get_config('meerschaum', 'default_executor') or 'local'
|
806
|
+
|
807
|
+
conn = parse_executor_keys(executor_keys, debug=debug)
|
808
|
+
|
809
|
+
shell_attrs['executor_keys'] = str(conn)
|
810
|
+
|
811
|
+
info(f"Default executor for the current shell: {executor_keys}")
|
812
|
+
return True, "Success"
|
727
813
|
|
728
|
-
def
|
814
|
+
def complete_executor(self, *args) -> List[str]:
|
815
|
+
results = self.complete_instance(*args)
|
816
|
+
return ['local'] + [result for result in results if result.startswith('api:')]
|
817
|
+
|
818
|
+
def do_help(self, line: str, executor_keys=None) -> List[str]:
|
729
819
|
"""
|
730
820
|
Show help for Meerschaum actions.
|
731
821
|
|
@@ -796,7 +886,7 @@ class Shell(cmd.Cmd):
|
|
796
886
|
possibilities.append(name.replace('do_', ''))
|
797
887
|
return possibilities
|
798
888
|
|
799
|
-
def do_exit(self, params) -> True:
|
889
|
+
def do_exit(self, params, executor_keys=None) -> True:
|
800
890
|
"""
|
801
891
|
Exit the Meerschaum shell.
|
802
892
|
"""
|
@@ -861,21 +951,29 @@ def input_with_sigint(_input, session, shell: Optional[Shell] = None):
|
|
861
951
|
|
862
952
|
instance_colored = (
|
863
953
|
colored(
|
864
|
-
shell_attrs['instance_keys'],
|
865
|
-
|
866
|
-
)
|
954
|
+
remove_ansi(shell_attrs['instance_keys']),
|
955
|
+
'on ' + get_config('shell', 'ansi', 'instance', 'rich', 'style')
|
867
956
|
)
|
868
957
|
if ANSI
|
869
958
|
else colored(shell_attrs['instance_keys'], 'on white')
|
870
959
|
)
|
871
960
|
repo_colored = (
|
872
961
|
colored(
|
873
|
-
shell_attrs['repo_keys'],
|
962
|
+
remove_ansi(shell_attrs['repo_keys']),
|
874
963
|
'on ' + get_config('shell', 'ansi', 'repo', 'rich', 'style')
|
875
964
|
)
|
876
965
|
if ANSI
|
877
966
|
else colored(shell_attrs['repo_keys'], 'on white')
|
878
967
|
)
|
968
|
+
executor_colored = (
|
969
|
+
colored(
|
970
|
+
remove_ansi(shell_attrs['executor_keys']),
|
971
|
+
'on ' + get_config('shell', 'ansi', 'executor', 'rich', 'style')
|
972
|
+
)
|
973
|
+
if ANSI
|
974
|
+
else colored(remove_ansi(shell_attrs['executor_keys']), 'on white')
|
975
|
+
)
|
976
|
+
|
879
977
|
try:
|
880
978
|
typ, label = shell_attrs['instance_keys'].split(':')
|
881
979
|
connected = typ in connectors and label in connectors[typ]
|
@@ -894,8 +992,12 @@ def input_with_sigint(_input, session, shell: Optional[Shell] = None):
|
|
894
992
|
)
|
895
993
|
|
896
994
|
left = (
|
897
|
-
|
898
|
-
+
|
995
|
+
' '
|
996
|
+
+ instance_colored
|
997
|
+
+ colored(' | ', 'on white')
|
998
|
+
+ executor_colored
|
999
|
+
+ colored(' | ', 'on white')
|
1000
|
+
+ repo_colored
|
899
1001
|
)
|
900
1002
|
right = connection_text
|
901
1003
|
buffer_size = (
|