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
@@ -7,86 +7,133 @@ Print jobs information.
|
|
7
7
|
"""
|
8
8
|
|
9
9
|
from __future__ import annotations
|
10
|
-
|
11
|
-
from
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
10
|
+
|
11
|
+
from datetime import datetime, timezone
|
12
|
+
|
13
|
+
import meerschaum as mrsm
|
14
|
+
from meerschaum.utils.typing import List, Optional, Any, is_success_tuple, Dict
|
15
|
+
from meerschaum.utils.jobs import (
|
16
|
+
Job,
|
17
|
+
get_jobs,
|
18
|
+
get_running_jobs,
|
19
|
+
get_stopped_jobs,
|
20
|
+
get_paused_jobs,
|
17
21
|
)
|
22
|
+
from meerschaum.config import get_config
|
23
|
+
|
18
24
|
|
19
25
|
def pprint_jobs(
|
20
|
-
|
21
|
-
|
22
|
-
|
26
|
+
jobs: Dict[str, Job],
|
27
|
+
nopretty: bool = False,
|
28
|
+
):
|
23
29
|
"""Pretty-print a list of Daemons."""
|
24
30
|
from meerschaum.utils.formatting import make_header
|
25
31
|
|
26
|
-
|
27
|
-
|
28
|
-
|
32
|
+
running_jobs = get_running_jobs(jobs=jobs)
|
33
|
+
paused_jobs = get_paused_jobs(jobs=jobs)
|
34
|
+
stopped_jobs = get_stopped_jobs(jobs=jobs)
|
35
|
+
executor_keys = (list(jobs.values())[0].executor_keys if jobs else None) or 'local'
|
29
36
|
|
30
37
|
def _nopretty_print():
|
31
38
|
from meerschaum.utils.misc import print_options
|
32
|
-
if
|
39
|
+
if running_jobs:
|
33
40
|
if not nopretty:
|
34
41
|
print('\n' + make_header('Running jobs'))
|
35
|
-
for
|
36
|
-
pprint_job(
|
42
|
+
for name, job in running_jobs.items():
|
43
|
+
pprint_job(job, nopretty=nopretty)
|
37
44
|
|
38
|
-
if
|
45
|
+
if paused_jobs:
|
39
46
|
if not nopretty:
|
40
47
|
print('\n' + make_header('Paused jobs'))
|
41
|
-
for
|
42
|
-
pprint_job(
|
48
|
+
for name, job in paused_jobs.items():
|
49
|
+
pprint_job(job, nopretty=nopretty)
|
43
50
|
|
44
|
-
if
|
51
|
+
if stopped_jobs:
|
45
52
|
if not nopretty:
|
46
53
|
print('\n' + make_header('Stopped jobs'))
|
47
|
-
for
|
48
|
-
pprint_job(
|
54
|
+
for name, job in stopped_jobs.items():
|
55
|
+
pprint_job(job, nopretty=nopretty)
|
49
56
|
|
50
57
|
def _pretty_print():
|
51
|
-
from meerschaum.utils.formatting import get_console, UNICODE, ANSI
|
58
|
+
from meerschaum.utils.formatting import get_console, UNICODE, ANSI, format_success_tuple
|
52
59
|
from meerschaum.utils.packages import import_rich, attempt_import
|
53
60
|
rich = import_rich()
|
54
|
-
rich_table, rich_text, rich_box = attempt_import(
|
61
|
+
rich_table, rich_text, rich_box, rich_json, rich_panel, rich_console = attempt_import(
|
62
|
+
'rich.table', 'rich.text', 'rich.box', 'rich.json', 'rich.panel', 'rich.console',
|
63
|
+
)
|
55
64
|
table = rich_table.Table(
|
56
|
-
title
|
57
|
-
box
|
58
|
-
show_lines
|
59
|
-
show_header
|
65
|
+
title=rich_text.Text(f"\nJobs on Executor '{executor_keys}'"),
|
66
|
+
box=(rich_box.ROUNDED if UNICODE else rich_box.ASCII),
|
67
|
+
show_lines=True,
|
68
|
+
show_header=ANSI,
|
60
69
|
)
|
61
70
|
table.add_column("Name", justify='right', style=('magenta' if ANSI else ''))
|
62
71
|
table.add_column("Command")
|
63
72
|
table.add_column("Status")
|
64
73
|
|
65
|
-
|
66
|
-
|
74
|
+
def get_success_text(job):
|
75
|
+
success_tuple = job.result
|
76
|
+
if not is_success_tuple(success_tuple):
|
77
|
+
return rich_text.Text('')
|
78
|
+
|
79
|
+
success = success_tuple[0]
|
80
|
+
msg = success_tuple[1]
|
81
|
+
lines = msg.split('\n')
|
82
|
+
msg = '\n'.join(line.lstrip().rstrip() for line in lines)
|
83
|
+
success_tuple = success, msg
|
84
|
+
success_tuple_str = (
|
85
|
+
format_success_tuple(success_tuple, left_padding=1)
|
86
|
+
if success_tuple is not None
|
87
|
+
else None
|
88
|
+
)
|
89
|
+
success_tuple_text = (
|
90
|
+
rich_text.Text.from_ansi(success_tuple_str)
|
91
|
+
) if success_tuple_str is not None else None
|
92
|
+
|
93
|
+
if success_tuple_text is None:
|
94
|
+
return rich_text.Text('')
|
95
|
+
|
96
|
+
return rich_text.Text('\n') + success_tuple_text
|
97
|
+
|
98
|
+
|
99
|
+
for name, job in running_jobs.items():
|
100
|
+
if job.hidden:
|
67
101
|
continue
|
102
|
+
|
103
|
+
status_text = (
|
104
|
+
rich_text.Text(job.status, style=('green' if ANSI else ''))
|
105
|
+
if not job.is_blocking_on_stdin()
|
106
|
+
else rich_text.Text('waiting for input', style=('yellow' if ANSI else ''))
|
107
|
+
)
|
108
|
+
|
68
109
|
table.add_row(
|
69
|
-
|
70
|
-
|
71
|
-
|
110
|
+
job.name,
|
111
|
+
job.label,
|
112
|
+
rich_console.Group(status_text),
|
72
113
|
)
|
73
114
|
|
74
|
-
for
|
75
|
-
if
|
115
|
+
for name, job in paused_jobs.items():
|
116
|
+
if job.hidden:
|
76
117
|
continue
|
77
118
|
table.add_row(
|
78
|
-
|
79
|
-
|
80
|
-
|
119
|
+
job.name,
|
120
|
+
job.label,
|
121
|
+
rich_console.Group(
|
122
|
+
rich_text.Text(job.status, style=('yellow' if ANSI else '')),
|
123
|
+
),
|
81
124
|
)
|
82
125
|
|
83
|
-
for
|
84
|
-
if
|
126
|
+
for name, job in stopped_jobs.items():
|
127
|
+
if job.hidden:
|
85
128
|
continue
|
129
|
+
|
86
130
|
table.add_row(
|
87
|
-
|
88
|
-
|
89
|
-
|
131
|
+
job.name,
|
132
|
+
job.label,
|
133
|
+
rich_console.Group(
|
134
|
+
rich_text.Text(job.status, style=('red' if ANSI else '')),
|
135
|
+
get_success_text(job)
|
136
|
+
),
|
90
137
|
)
|
91
138
|
get_console().print(table)
|
92
139
|
|
@@ -95,15 +142,35 @@ def pprint_jobs(
|
|
95
142
|
|
96
143
|
|
97
144
|
def pprint_job(
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
"""Pretty-print a single
|
102
|
-
if
|
145
|
+
job: Job,
|
146
|
+
nopretty: bool = False,
|
147
|
+
):
|
148
|
+
"""Pretty-print a single `Job`."""
|
149
|
+
if job.hidden:
|
103
150
|
return
|
151
|
+
|
104
152
|
from meerschaum.utils.warnings import info
|
105
153
|
if not nopretty:
|
106
|
-
info(f"Command for job '{
|
107
|
-
print('\n' +
|
154
|
+
info(f"Command for job '{job.name}':")
|
155
|
+
print('\n' + job.label + '\n')
|
108
156
|
else:
|
109
|
-
print(
|
157
|
+
print(job.name)
|
158
|
+
|
159
|
+
|
160
|
+
def strip_timestamp_from_line(line: str) -> str:
|
161
|
+
"""
|
162
|
+
Remove the leading timestamp from a job's line (if present).
|
163
|
+
"""
|
164
|
+
now = datetime.now(timezone.utc)
|
165
|
+
timestamp_format = get_config('jobs', 'logs', 'timestamps', 'format')
|
166
|
+
now_str = now.strftime(timestamp_format)
|
167
|
+
|
168
|
+
date_prefix_str = line[:len(now_str)]
|
169
|
+
try:
|
170
|
+
line_timestamp = datetime.strptime(date_prefix_str, timestamp_format)
|
171
|
+
except Exception:
|
172
|
+
line_timestamp = None
|
173
|
+
if line_timestamp:
|
174
|
+
line = line[(len(now_str) + 3):]
|
175
|
+
|
176
|
+
return line
|
@@ -47,9 +47,15 @@ def clear_screen(debug: bool = False) -> bool:
|
|
47
47
|
from meerschaum.utils.formatting import ANSI, get_console
|
48
48
|
from meerschaum.utils.debug import dprint
|
49
49
|
from meerschaum.config import get_config
|
50
|
+
from meerschaum.utils.daemon import running_in_daemon
|
50
51
|
global _tried_clear_command
|
52
|
+
|
53
|
+
if running_in_daemon():
|
54
|
+
return True
|
55
|
+
|
51
56
|
if not get_config('shell', 'clear_screen'):
|
52
57
|
return True
|
58
|
+
|
53
59
|
print("", end="", flush=True)
|
54
60
|
if debug:
|
55
61
|
dprint("Skipping screen clear.")
|