meerschaum 2.3.0rc5__py3-none-any.whl → 2.3.2__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 +2 -3
- meerschaum/_internal/arguments/_parse_arguments.py +16 -10
- meerschaum/_internal/arguments/_parser.py +1 -1
- meerschaum/_internal/docs/index.py +265 -8
- meerschaum/actions/__init__.py +21 -11
- meerschaum/actions/restart.py +7 -1
- meerschaum/actions/start.py +3 -4
- meerschaum/api/routes/_jobs.py +9 -2
- meerschaum/config/_default.py +1 -0
- meerschaum/config/_version.py +1 -1
- meerschaum/connectors/__init__.py +1 -2
- meerschaum/connectors/api/_jobs.py +16 -3
- meerschaum/jobs/_Executor.py +8 -2
- meerschaum/jobs/_Job.py +31 -1
- meerschaum/jobs/__init__.py +45 -7
- meerschaum/jobs/{_SystemdExecutor.py → systemd.py} +43 -9
- meerschaum/plugins/_Plugin.py +1 -1
- meerschaum/plugins/__init__.py +2 -1
- meerschaum/utils/daemon/Daemon.py +14 -0
- {meerschaum-2.3.0rc5.dist-info → meerschaum-2.3.2.dist-info}/METADATA +1 -1
- {meerschaum-2.3.0rc5.dist-info → meerschaum-2.3.2.dist-info}/RECORD +27 -28
- meerschaum/jobs/_LocalExecutor.py +0 -88
- {meerschaum-2.3.0rc5.dist-info → meerschaum-2.3.2.dist-info}/LICENSE +0 -0
- {meerschaum-2.3.0rc5.dist-info → meerschaum-2.3.2.dist-info}/NOTICE +0 -0
- {meerschaum-2.3.0rc5.dist-info → meerschaum-2.3.2.dist-info}/WHEEL +0 -0
- {meerschaum-2.3.0rc5.dist-info → meerschaum-2.3.2.dist-info}/entry_points.txt +0 -0
- {meerschaum-2.3.0rc5.dist-info → meerschaum-2.3.2.dist-info}/top_level.txt +0 -0
- {meerschaum-2.3.0rc5.dist-info → meerschaum-2.3.2.dist-info}/zip-safe +0 -0
meerschaum/__init__.py
CHANGED
@@ -24,7 +24,7 @@ from meerschaum.utils.packages import attempt_import
|
|
24
24
|
from meerschaum.core.Pipe import Pipe
|
25
25
|
from meerschaum.plugins import Plugin
|
26
26
|
from meerschaum.utils.venv import Venv
|
27
|
-
from meerschaum.jobs import Job,
|
27
|
+
from meerschaum.jobs import Job, make_executor
|
28
28
|
from meerschaum.connectors import get_connector, Connector, make_connector
|
29
29
|
from meerschaum.utils import get_pipes
|
30
30
|
from meerschaum.utils.formatting import pprint
|
@@ -45,13 +45,12 @@ __all__ = (
|
|
45
45
|
"Venv",
|
46
46
|
"Plugin",
|
47
47
|
"Job",
|
48
|
-
"Executor",
|
49
|
-
"make_executor",
|
50
48
|
"pprint",
|
51
49
|
"attempt_import",
|
52
50
|
"actions",
|
53
51
|
"config",
|
54
52
|
"connectors",
|
53
|
+
"jobs",
|
55
54
|
"plugins",
|
56
55
|
"utils",
|
57
56
|
"SuccessTuple",
|
@@ -106,8 +106,8 @@ def parse_arguments(sysargs: List[str]) -> Dict[str, Any]:
|
|
106
106
|
for i, word in enumerate(sysargs):
|
107
107
|
is_sub_arg = False
|
108
108
|
if not found_begin_decorator:
|
109
|
-
found_begin_decorator = word.startswith(begin_decorator)
|
110
|
-
found_end_decorator = word.endswith(end_decorator)
|
109
|
+
found_begin_decorator = str(word).startswith(begin_decorator)
|
110
|
+
found_end_decorator = str(word).endswith(end_decorator)
|
111
111
|
|
112
112
|
if found_begin_decorator:
|
113
113
|
### check if sub arg is ever closed
|
@@ -117,15 +117,15 @@ def parse_arguments(sysargs: List[str]) -> Dict[str, Any]:
|
|
117
117
|
found_begin_decorator = False
|
118
118
|
elif found_end_decorator:
|
119
119
|
for a in sysargs[:i]:
|
120
|
-
if a.startswith(begin_decorator):
|
120
|
+
if str(a).startswith(begin_decorator):
|
121
121
|
is_sub_arg = True
|
122
122
|
found_begin_decorator = False
|
123
123
|
if is_sub_arg:
|
124
124
|
### remove decorators
|
125
125
|
sa = word
|
126
|
-
if sa.startswith(begin_decorator):
|
126
|
+
if str(sa).startswith(begin_decorator):
|
127
127
|
sa = sa[len(begin_decorator):]
|
128
|
-
if sa.endswith(end_decorator):
|
128
|
+
if str(sa).endswith(end_decorator):
|
129
129
|
sa = sa[:-1 * len(end_decorator)]
|
130
130
|
sub_arguments.append(sa)
|
131
131
|
### remove sub-argument from action list
|
@@ -144,7 +144,7 @@ def parse_arguments(sysargs: List[str]) -> Dict[str, Any]:
|
|
144
144
|
except Exception as e:
|
145
145
|
_action = []
|
146
146
|
for a in filtered_sysargs:
|
147
|
-
if a.startswith('-'):
|
147
|
+
if str(a).startswith('-'):
|
148
148
|
break
|
149
149
|
_action.append(a)
|
150
150
|
args_dict = {'action': _action, 'sysargs': sysargs}
|
@@ -267,7 +267,7 @@ def parse_dict_to_sysargs(
|
|
267
267
|
action = args_dict.get('action', None)
|
268
268
|
sysargs: List[str] = []
|
269
269
|
sysargs.extend(action or [])
|
270
|
-
allow_none_args = {'location_keys'}
|
270
|
+
allow_none_args = {'location_keys', 'begin', 'end', 'executor_keys'}
|
271
271
|
|
272
272
|
triggers = get_arguments_triggers()
|
273
273
|
|
@@ -278,12 +278,18 @@ def parse_dict_to_sysargs(
|
|
278
278
|
### Add boolean flags
|
279
279
|
if isinstance(args_dict[a], bool):
|
280
280
|
if args_dict[a] is True:
|
281
|
-
sysargs
|
281
|
+
sysargs.extend([t[0]])
|
282
282
|
else:
|
283
283
|
### Add list flags
|
284
284
|
if isinstance(args_dict[a], (list, tuple)):
|
285
285
|
if len(args_dict[a]) > 0:
|
286
|
-
sysargs
|
286
|
+
sysargs.extend(
|
287
|
+
[t[0]]
|
288
|
+
+ [
|
289
|
+
str(item)
|
290
|
+
for item in args_dict[a]
|
291
|
+
]
|
292
|
+
)
|
287
293
|
|
288
294
|
### Add dict flags
|
289
295
|
elif isinstance(args_dict[a], dict):
|
@@ -292,7 +298,7 @@ def parse_dict_to_sysargs(
|
|
292
298
|
|
293
299
|
### Account for None and other values
|
294
300
|
elif (args_dict[a] is not None) or (args_dict[a] is None and a in allow_none_args):
|
295
|
-
sysargs += [t[0], args_dict[a]]
|
301
|
+
sysargs += [t[0], str(args_dict[a])]
|
296
302
|
|
297
303
|
return sysargs
|
298
304
|
|
@@ -36,8 +36,9 @@ For your convenience, the following classes and functions may be imported from t
|
|
36
36
|
<li><code>meerschaum.Connector</code></li>
|
37
37
|
<li><code>meerschaum.Pipe</code></li>
|
38
38
|
<li><code>meerschaum.Plugin</code></li>
|
39
|
-
<li><code>meerschaum.
|
39
|
+
<li><code>meerschaum.Job</code></li>
|
40
40
|
<li><code>meerschaum.Venv</code></li>
|
41
|
+
<li><code>meerschaum.SuccessTuple</code></li>
|
41
42
|
</ul>
|
42
43
|
|
43
44
|
</div>
|
@@ -54,6 +55,7 @@ For your convenience, the following classes and functions may be imported from t
|
|
54
55
|
<li><code>meerschaum.make_connector()</code></li>
|
55
56
|
<li><code>meerschaum.pprint()</code></li>
|
56
57
|
<li><code>meerschaum.attempt_import()</code></li>
|
58
|
+
<li><code>meerschaum.entry()</code></li>
|
57
59
|
</ul>
|
58
60
|
|
59
61
|
</div>
|
@@ -61,7 +63,10 @@ For your convenience, the following classes and functions may be imported from t
|
|
61
63
|
|
62
64
|
### Examples
|
63
65
|
|
64
|
-
|
66
|
+
<details>
|
67
|
+
<summary><b>Build a Connector</b></summary>
|
68
|
+
|
69
|
+
Get existing connectors or build a new one in-memory with the `meerschaum.get_connector()` factory function:
|
65
70
|
|
66
71
|
```python
|
67
72
|
import meerschaum as mrsm
|
@@ -80,9 +85,14 @@ sql_conn.to_sql(df, 'foo')
|
|
80
85
|
print(sql_conn.read('foo'))
|
81
86
|
# foo
|
82
87
|
# 0 1
|
88
|
+
|
83
89
|
```
|
90
|
+
</details>
|
91
|
+
|
92
|
+
<details>
|
93
|
+
<summary><b>Create a Custom Connector Class</b></summary>
|
84
94
|
|
85
|
-
|
95
|
+
Decorate your connector classes with `meerschaum.make_connector()` to designate it as a custom connector:
|
86
96
|
|
87
97
|
```python
|
88
98
|
from datetime import datetime, timezone
|
@@ -113,8 +123,12 @@ foo_conn = mrsm.get_connector(
|
|
113
123
|
)
|
114
124
|
docs = foo_conn.fetch()
|
115
125
|
```
|
126
|
+
</details>
|
116
127
|
|
117
|
-
|
128
|
+
<details>
|
129
|
+
<summary><b>Build a Pipe</b></summary>
|
130
|
+
|
131
|
+
Build a `meerschaum.Pipe` in-memory:
|
118
132
|
|
119
133
|
```python
|
120
134
|
from datetime import datetime
|
@@ -135,7 +149,23 @@ print(df)
|
|
135
149
|
# 2 2024-01-01 3 96
|
136
150
|
```
|
137
151
|
|
138
|
-
|
152
|
+
Add `temporary=True` to skip registering the pipe in the pipes table.
|
153
|
+
|
154
|
+
</details>
|
155
|
+
|
156
|
+
<details>
|
157
|
+
<summary><b>Get Registered Pipes</b></summary>
|
158
|
+
|
159
|
+
The `meerschaum.get_pipes()` function returns a dictionary hierarchy of pipes by connector, metric, and location:
|
160
|
+
|
161
|
+
```python
|
162
|
+
import meerschaum as mrsm
|
163
|
+
|
164
|
+
pipes = mrsm.get_pipes(instance='sql:temp')
|
165
|
+
pipe = pipes['foo:bar']['demo'][None]
|
166
|
+
```
|
167
|
+
|
168
|
+
Add `as_list=True` to flatten the hierarchy:
|
139
169
|
|
140
170
|
```python
|
141
171
|
import meerschaum as mrsm
|
@@ -148,8 +178,12 @@ pipes = mrsm.get_pipes(
|
|
148
178
|
print(pipes)
|
149
179
|
# [Pipe('foo:bar', 'demo', instance='sql:temp')]
|
150
180
|
```
|
181
|
+
</details>
|
151
182
|
|
152
|
-
|
183
|
+
<details>
|
184
|
+
<summary><b>Import Plugins</b></summary>
|
185
|
+
|
186
|
+
You can import a plugin's module through `meerschaum.Plugin.module`:
|
153
187
|
|
154
188
|
```python
|
155
189
|
import meerschaum as mrsm
|
@@ -157,10 +191,211 @@ import meerschaum as mrsm
|
|
157
191
|
plugin = mrsm.Plugin('noaa')
|
158
192
|
with mrsm.Venv(plugin):
|
159
193
|
noaa = plugin.module
|
160
|
-
print(noaa.get_station_info('KGMU'))
|
161
|
-
# {'name': 'Greenville Downtown Airport', 'geometry': {'type': 'Point', 'coordinates': [-82.35004, 34.84873]}}
|
162
194
|
```
|
163
195
|
|
196
|
+
If your plugin has submodules, use `meerschaum.plugins.from_plugin_import`:
|
197
|
+
|
198
|
+
```python
|
199
|
+
from meerschaum.plugins import from_plugin_import
|
200
|
+
get_defined_pipes = from_plugin_import('compose.utils.pipes', 'get_defined_pipes')
|
201
|
+
```
|
202
|
+
|
203
|
+
Import multiple plugins with `meerschaum.plugins.import_plugins`:
|
204
|
+
|
205
|
+
```python
|
206
|
+
from meerschaum.plugins import import_plugins
|
207
|
+
noaa, compose = import_plugins('noaa', 'compose')
|
208
|
+
```
|
209
|
+
|
210
|
+
</details>
|
211
|
+
|
212
|
+
<details>
|
213
|
+
<summary><b>Create a Job</b></summary>
|
214
|
+
|
215
|
+
Create a `meerschaum.Job` with `name` and `sysargs`:
|
216
|
+
|
217
|
+
```python
|
218
|
+
import meerschaum as mrsm
|
219
|
+
|
220
|
+
job = mrsm.Job('syncing-engine', 'sync pipes --loop')
|
221
|
+
success, msg = job.start()
|
222
|
+
```
|
223
|
+
|
224
|
+
Pass `executor_keys` as the connectors keys of an API instance to create a remote job:
|
225
|
+
|
226
|
+
```python
|
227
|
+
import meerschaum as mrsm
|
228
|
+
|
229
|
+
job = mrsm.Job(
|
230
|
+
'foo',
|
231
|
+
'sync pipes -s daily',
|
232
|
+
executor_keys='api:main',
|
233
|
+
)
|
234
|
+
```
|
235
|
+
|
236
|
+
</details>
|
237
|
+
|
238
|
+
<details>
|
239
|
+
<summary><b>Import from a Virtual Environment</b></summary>
|
240
|
+
Use the `meerschaum.Venv` context manager to activate a virtual environment:
|
241
|
+
```python
|
242
|
+
import meerschaum as mrsm
|
243
|
+
|
244
|
+
with mrsm.Venv('noaa'):
|
245
|
+
import requests
|
246
|
+
|
247
|
+
print(requests.__file__)
|
248
|
+
# /home/bmeares/.config/meerschaum/venvs/noaa/lib/python3.12/site-packages/requests/__init__.py
|
249
|
+
```
|
250
|
+
|
251
|
+
To import packages which may not be installed, use `meerschaum.attempt_import()`:
|
252
|
+
|
253
|
+
```python
|
254
|
+
import meerschaum as mrsm
|
255
|
+
|
256
|
+
requests = mrsm.attempt_import('requests', venv='noaa')
|
257
|
+
print(requests.__file__)
|
258
|
+
# /home/bmeares/.config/meerschaum/venvs/noaa/lib/python3.12/site-packages/requests/__init__.py
|
259
|
+
```
|
260
|
+
|
261
|
+
</details>
|
262
|
+
|
263
|
+
<details>
|
264
|
+
<summary><b>Run Actions</b></summary>
|
265
|
+
|
266
|
+
Run `sysargs` with `meerschaum.entry()`:
|
267
|
+
|
268
|
+
```python
|
269
|
+
import meerschaum as mrsm
|
270
|
+
|
271
|
+
success, msg = mrsm.entry('show pipes + show version : x2')
|
272
|
+
```
|
273
|
+
|
274
|
+
Use `meerschaum.actions.get_action()` to access an action function directly:
|
275
|
+
|
276
|
+
```python
|
277
|
+
from meerschaum.actions import get_action
|
278
|
+
|
279
|
+
show_pipes = get_action(['show', 'pipes'])
|
280
|
+
success, msg = show_pipes(connector_keys=['plugin:noaa'])
|
281
|
+
```
|
282
|
+
|
283
|
+
Get a dictionary of available subactions with `meerschaum.actions.get_subactions()`:
|
284
|
+
|
285
|
+
```python
|
286
|
+
from meerschaum.actions import get_subactions
|
287
|
+
|
288
|
+
subactions = get_subactions('show')
|
289
|
+
success, msg = subactions['pipes']()
|
290
|
+
```
|
291
|
+
|
292
|
+
</details>
|
293
|
+
|
294
|
+
<details>
|
295
|
+
<summary><b>Create a Plugin</b></summary>
|
296
|
+
|
297
|
+
Run `bootstrap plugin` to create a new plugin:
|
298
|
+
|
299
|
+
```
|
300
|
+
mrsm bootstrap plugin example
|
301
|
+
```
|
302
|
+
|
303
|
+
This will create `example.py` in your plugins directory (default `~/.config/meerschaum/plugins/`, Windows: `%APPDATA%\Meerschaum\plugins`). You may paste the example code from the "Create a Custom Action" example below.
|
304
|
+
|
305
|
+
Open your plugin with `edit plugin`:
|
306
|
+
|
307
|
+
```
|
308
|
+
mrsm edit plugin example
|
309
|
+
```
|
310
|
+
|
311
|
+
*Run `edit plugin` and paste the example code below to try out the features.*
|
312
|
+
|
313
|
+
See the [writing plugins guide](https://meerschaum.io/reference/plugins/writing-plugins/) for more in-depth documentation.
|
314
|
+
|
315
|
+
</details>
|
316
|
+
|
317
|
+
<details>
|
318
|
+
<summary><b>Create a Custom Action</b></summary>
|
319
|
+
|
320
|
+
Decorate a function with `meerschaum.actions.make_action` to designate it as an action. Subactions will be automatically detected if not decorated:
|
321
|
+
|
322
|
+
```python
|
323
|
+
from meerschaum.actions import make_action
|
324
|
+
|
325
|
+
@make_action
|
326
|
+
def sing():
|
327
|
+
print('What would you like me to sing?')
|
328
|
+
return True, "Success"
|
329
|
+
|
330
|
+
def sing_tune():
|
331
|
+
return False, "I don't know that song!"
|
332
|
+
|
333
|
+
def sing_song():
|
334
|
+
print('Hello, World!')
|
335
|
+
return True, "Success"
|
336
|
+
|
337
|
+
```
|
338
|
+
|
339
|
+
Use `meerschaum.plugins.add_plugin_argument()` to create new parameters for your action:
|
340
|
+
|
341
|
+
```python
|
342
|
+
from meerschaum.plugins import make_action, add_plugin_argument
|
343
|
+
|
344
|
+
add_plugin_argument(
|
345
|
+
'--song', type=str, help='What song to sing.',
|
346
|
+
)
|
347
|
+
|
348
|
+
@make_action
|
349
|
+
def sing_melody(action=None, song=None):
|
350
|
+
to_sing = action[0] if action else song
|
351
|
+
if not to_sing:
|
352
|
+
return False, "Please tell me what to sing!"
|
353
|
+
|
354
|
+
return True, f'~I am singing {to_sing}~'
|
355
|
+
```
|
356
|
+
|
357
|
+
```
|
358
|
+
mrsm sing melody lalala
|
359
|
+
|
360
|
+
mrsm sing melody --song do-re-mi
|
361
|
+
```
|
362
|
+
|
363
|
+
</details>
|
364
|
+
|
365
|
+
<details>
|
366
|
+
<summary><b>Add a Page to the Web Dashboard</b></summary>
|
367
|
+
Use the decorators `meerschaum.plugins.dash_plugin()` and `meerschaum.plugins.web_page()` to add new pages to the web dashboard:
|
368
|
+
|
369
|
+
```python
|
370
|
+
from meerschaum.plugins import dash_plugin, web_page
|
371
|
+
|
372
|
+
@dash_plugin
|
373
|
+
def init_dash(dash_app):
|
374
|
+
|
375
|
+
import dash.html as html
|
376
|
+
import dash_bootstrap_components as dbc
|
377
|
+
from dash import Input, Output, no_update
|
378
|
+
|
379
|
+
### Routes to '/dash/my-page'
|
380
|
+
@web_page('/my-page', login_required=False)
|
381
|
+
def my_page():
|
382
|
+
return dbc.Container([
|
383
|
+
html.H1("Hello, World!"),
|
384
|
+
dbc.Button("Click me", id='my-button'),
|
385
|
+
html.Div(id="my-output-div"),
|
386
|
+
])
|
387
|
+
|
388
|
+
@dash_app.callback(
|
389
|
+
Output('my-output-div', 'children'),
|
390
|
+
Input('my-button', 'n_clicks'),
|
391
|
+
)
|
392
|
+
def my_button_click(n_clicks):
|
393
|
+
if not n_clicks:
|
394
|
+
return no_update
|
395
|
+
return html.P(f'You clicked {n_clicks} times!')
|
396
|
+
```
|
397
|
+
</details>
|
398
|
+
|
164
399
|
## Submodules
|
165
400
|
|
166
401
|
<details>
|
@@ -206,6 +441,28 @@ with mrsm.Venv(plugin):
|
|
206
441
|
|
207
442
|
</details>
|
208
443
|
|
444
|
+
<details>
|
445
|
+
<summary>
|
446
|
+
`meerschaum.jobs`<br>
|
447
|
+
Start background jobs.
|
448
|
+
</summary>
|
449
|
+
|
450
|
+
- `meerschaum.jobs.Job`
|
451
|
+
- `meerschaum.jobs.Executor`
|
452
|
+
- `meerschaum.jobs.systemd.SystemdExecutor`
|
453
|
+
- `meerschaum.jobs.get_jobs()`
|
454
|
+
- `meerschaum.jobs.get_filtered_jobs()`
|
455
|
+
- `meerschaum.jobs.get_running_jobs()`
|
456
|
+
- `meerschaum.jobs.get_stopped_jobs()`
|
457
|
+
- `meerschaum.jobs.get_paused_jobs()`
|
458
|
+
- `meerschaum.jobs.get_restart_jobs()`
|
459
|
+
- `meerschaum.jobs.make_executor()`
|
460
|
+
- `meerschaum.jobs.check_restart_jobs()`
|
461
|
+
- `meerschaum.jobs.start_check_jobs_thread()`
|
462
|
+
- `meerschaum.jobs.stop_check_jobs_thread()`
|
463
|
+
|
464
|
+
</details>
|
465
|
+
|
209
466
|
<details>
|
210
467
|
<summary>
|
211
468
|
`meerschaum.plugins`<br>
|
meerschaum/actions/__init__.py
CHANGED
@@ -11,6 +11,16 @@ from meerschaum.utils.typing import Callable, Any, Optional, Union, List, Dict,
|
|
11
11
|
from meerschaum.utils.packages import get_modules_from_package
|
12
12
|
_custom_actions = []
|
13
13
|
|
14
|
+
__all__ = (
|
15
|
+
'get_action',
|
16
|
+
'get_subactions',
|
17
|
+
'make_action',
|
18
|
+
'pre_sync_hook',
|
19
|
+
'post_sync_hook',
|
20
|
+
'get_main_action_name',
|
21
|
+
'get_completer',
|
22
|
+
)
|
23
|
+
|
14
24
|
def get_subactions(
|
15
25
|
action: Union[str, List[str]],
|
16
26
|
_actions: Optional[Dict[str, Callable[[Any], Any]]] = None,
|
@@ -101,9 +111,9 @@ def get_action(
|
|
101
111
|
|
102
112
|
|
103
113
|
def get_main_action_name(
|
104
|
-
|
105
|
-
|
106
|
-
|
114
|
+
action: Union[List[str], str],
|
115
|
+
_actions: Optional[Dict[str, Callable[[Any], SuccessTuple]]] = None,
|
116
|
+
) -> Union[str, None]:
|
107
117
|
"""
|
108
118
|
Given an action list, return the name of the main function.
|
109
119
|
For subactions, this will return the root function.
|
@@ -140,9 +150,9 @@ def get_main_action_name(
|
|
140
150
|
|
141
151
|
|
142
152
|
def get_completer(
|
143
|
-
|
144
|
-
|
145
|
-
|
153
|
+
action: Union[List[str], str],
|
154
|
+
_actions: Optional[Dict[str, Callable[[Any], SuccessTuple]]] = None,
|
155
|
+
) -> Union[
|
146
156
|
Callable[['meerschaum._internal.shell.Shell', str, str, int, int], List[str]], None
|
147
157
|
]:
|
148
158
|
"""Search for a custom completer function for an action."""
|
@@ -179,10 +189,10 @@ def get_completer(
|
|
179
189
|
|
180
190
|
|
181
191
|
def choose_subaction(
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
192
|
+
action: Optional[List[str]] = None,
|
193
|
+
options: Optional[Dict[str, Any]] = None,
|
194
|
+
**kw
|
195
|
+
) -> SuccessTuple:
|
186
196
|
"""
|
187
197
|
Given a dictionary of options and the standard Meerschaum actions list,
|
188
198
|
check if choice is valid and execute chosen function, else show available
|
@@ -247,7 +257,7 @@ def _get_subaction_names(action: str, globs: dict = None) -> List[str]:
|
|
247
257
|
return subactions
|
248
258
|
|
249
259
|
|
250
|
-
def choices_docstring(action: str, globs
|
260
|
+
def choices_docstring(action: str, globs: Optional[Dict[str, Any]] = None) -> str:
|
251
261
|
"""
|
252
262
|
Append the an action's available options to the module docstring.
|
253
263
|
This function is to be placed at the bottom of each action module.
|
meerschaum/actions/restart.py
CHANGED
@@ -79,7 +79,13 @@ def _restart_jobs(
|
|
79
79
|
action = action or []
|
80
80
|
|
81
81
|
while True:
|
82
|
-
jobs = get_filtered_jobs(
|
82
|
+
jobs = get_filtered_jobs(
|
83
|
+
executor_keys or 'local',
|
84
|
+
action,
|
85
|
+
include_hidden=True,
|
86
|
+
combine_local_and_systemd=False,
|
87
|
+
debug=debug,
|
88
|
+
)
|
83
89
|
restart_jobs = get_restart_jobs(executor_keys, jobs, debug=debug) if not action else jobs
|
84
90
|
if not restart_jobs and not loop:
|
85
91
|
return True, "No jobs need to be restarted."
|
meerschaum/actions/start.py
CHANGED
@@ -99,7 +99,7 @@ def _start_jobs(
|
|
99
99
|
To start a stopped job, pass the job name after `start job`.
|
100
100
|
|
101
101
|
You may also run a background job with the `-d` or `--daemon` flags.
|
102
|
-
|
102
|
+
|
103
103
|
Examples:
|
104
104
|
|
105
105
|
Create new jobs:
|
@@ -108,9 +108,9 @@ def _start_jobs(
|
|
108
108
|
Run the action `sync pipes --loop` as a background job.
|
109
109
|
Generates a random name; e.g. 'happy_seal'.
|
110
110
|
|
111
|
-
- `start api --daemon --name
|
111
|
+
- `start api --daemon --name api-server`
|
112
112
|
Run the action `start api` as a background job, and assign the job
|
113
|
-
the name '
|
113
|
+
the name 'api-server'.
|
114
114
|
|
115
115
|
Start stopped jobs:
|
116
116
|
|
@@ -119,7 +119,6 @@ def _start_jobs(
|
|
119
119
|
|
120
120
|
- `start job --name happy_seal`
|
121
121
|
Start the job 'happy_seal' but via the `--name` flag.
|
122
|
-
This only applies when no text follows the words 'start job'.
|
123
122
|
"""
|
124
123
|
from meerschaum.utils.warnings import warn, info
|
125
124
|
from meerschaum.utils.daemon._names import get_new_daemon_name
|
meerschaum/api/routes/_jobs.py
CHANGED
@@ -128,7 +128,7 @@ def clean_sysargs(sysargs: List[str]) -> List[str]:
|
|
128
128
|
@app.post(endpoints['jobs'] + '/{name}', tags=['Jobs'])
|
129
129
|
def create_job(
|
130
130
|
name: str,
|
131
|
-
|
131
|
+
metadata: Union[List[str], Dict[str, Any]],
|
132
132
|
curr_user=(
|
133
133
|
fastapi.Depends(manager) if not no_auth else None
|
134
134
|
),
|
@@ -136,7 +136,14 @@ def create_job(
|
|
136
136
|
"""
|
137
137
|
Create and start a new job.
|
138
138
|
"""
|
139
|
-
|
139
|
+
sysargs = metadata if isinstance(metadata, list) else metadata['sysargs']
|
140
|
+
properties = metadata['properties'] if isinstance(metadata, dict) else None
|
141
|
+
job = Job(
|
142
|
+
name,
|
143
|
+
clean_sysargs(sysargs),
|
144
|
+
executor_keys=EXECUTOR_KEYS,
|
145
|
+
_properties=properties,
|
146
|
+
)
|
140
147
|
if job.exists():
|
141
148
|
raise fastapi.HTTPException(
|
142
149
|
status_code=409,
|
meerschaum/config/_default.py
CHANGED
meerschaum/config/_version.py
CHANGED
@@ -12,7 +12,7 @@ import json
|
|
12
12
|
from datetime import datetime
|
13
13
|
|
14
14
|
import meerschaum as mrsm
|
15
|
-
from meerschaum.utils.typing import Dict, Any, SuccessTuple, List, Union, Callable
|
15
|
+
from meerschaum.utils.typing import Dict, Any, SuccessTuple, List, Union, Callable, Optional
|
16
16
|
from meerschaum.jobs import Job
|
17
17
|
from meerschaum.config.static import STATIC_CONFIG
|
18
18
|
from meerschaum.utils.warnings import warn, dprint
|
@@ -184,11 +184,24 @@ def start_job(self, name: str, debug: bool = False) -> SuccessTuple:
|
|
184
184
|
return tuple(response.json())
|
185
185
|
|
186
186
|
|
187
|
-
def create_job(
|
187
|
+
def create_job(
|
188
|
+
self,
|
189
|
+
name: str,
|
190
|
+
sysargs: List[str],
|
191
|
+
properties: Optional[Dict[str, str]] = None,
|
192
|
+
debug: bool = False,
|
193
|
+
) -> SuccessTuple:
|
188
194
|
"""
|
189
195
|
Create a job.
|
190
196
|
"""
|
191
|
-
response = self.post(
|
197
|
+
response = self.post(
|
198
|
+
JOBS_ENDPOINT + f"/{name}",
|
199
|
+
json={
|
200
|
+
'sysargs': sysargs,
|
201
|
+
'properties': properties,
|
202
|
+
},
|
203
|
+
debug=debug,
|
204
|
+
)
|
192
205
|
if not response:
|
193
206
|
if 'detail' in response.text:
|
194
207
|
return False, response.json()['detail']
|
meerschaum/jobs/_Executor.py
CHANGED
@@ -10,7 +10,7 @@ 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 List, Dict, SuccessTuple, TYPE_CHECKING
|
13
|
+
from meerschaum.utils.typing import List, Dict, SuccessTuple, TYPE_CHECKING, Optional, Any
|
14
14
|
|
15
15
|
if TYPE_CHECKING:
|
16
16
|
from meerschaum.jobs import Job
|
@@ -33,7 +33,13 @@ class Executor(Connector):
|
|
33
33
|
"""
|
34
34
|
|
35
35
|
@abstractmethod
|
36
|
-
def create_job(
|
36
|
+
def create_job(
|
37
|
+
self,
|
38
|
+
name: str,
|
39
|
+
sysargs: List[str],
|
40
|
+
properties: Optional[Dict[str, Any]] = None,
|
41
|
+
debug: bool = False,
|
42
|
+
) -> SuccessTuple:
|
37
43
|
"""
|
38
44
|
Create a new job.
|
39
45
|
"""
|