meerschaum 2.1.2__py3-none-any.whl → 2.1.3.dev3__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 +10 -4
- meerschaum/_internal/docs/index.py +32 -37
- meerschaum/_internal/entry.py +3 -0
- meerschaum/_internal/shell/Shell.py +106 -78
- meerschaum/_internal/shell/ShellCompleter.py +8 -4
- meerschaum/actions/__init__.py +2 -1
- meerschaum/actions/reload.py +2 -5
- meerschaum/actions/show.py +72 -1
- meerschaum/actions/sync.py +45 -17
- meerschaum/config/_edit.py +10 -34
- meerschaum/config/_formatting.py +4 -0
- meerschaum/config/_version.py +1 -1
- meerschaum/config/static/__init__.py +2 -0
- meerschaum/connectors/sql/_pipes.py +26 -20
- meerschaum/core/Pipe/_data.py +11 -11
- meerschaum/core/Pipe/_fetch.py +4 -4
- meerschaum/plugins/_Plugin.py +6 -8
- meerschaum/plugins/__init__.py +76 -1
- meerschaum/utils/__init__.py +21 -6
- meerschaum/utils/daemon/__init__.py +1 -1
- meerschaum/utils/formatting/__init__.py +4 -0
- meerschaum/utils/formatting/_pipes.py +2 -2
- meerschaum/utils/get_pipes.py +1 -1
- meerschaum/utils/misc.py +2 -1
- meerschaum/utils/packages/__init__.py +46 -7
- meerschaum/utils/schedule.py +1 -1
- meerschaum/utils/venv/__init__.py +22 -3
- {meerschaum-2.1.2.dist-info → meerschaum-2.1.3.dev3.dist-info}/METADATA +2 -2
- {meerschaum-2.1.2.dist-info → meerschaum-2.1.3.dev3.dist-info}/RECORD +35 -35
- {meerschaum-2.1.2.dist-info → meerschaum-2.1.3.dev3.dist-info}/LICENSE +0 -0
- {meerschaum-2.1.2.dist-info → meerschaum-2.1.3.dev3.dist-info}/NOTICE +0 -0
- {meerschaum-2.1.2.dist-info → meerschaum-2.1.3.dev3.dist-info}/WHEEL +0 -0
- {meerschaum-2.1.2.dist-info → meerschaum-2.1.3.dev3.dist-info}/entry_points.txt +0 -0
- {meerschaum-2.1.2.dist-info → meerschaum-2.1.3.dev3.dist-info}/top_level.txt +0 -0
- {meerschaum-2.1.2.dist-info → meerschaum-2.1.3.dev3.dist-info}/zip-safe +0 -0
meerschaum/actions/show.py
CHANGED
@@ -7,7 +7,8 @@ This module contains functions for printing elements.
|
|
7
7
|
"""
|
8
8
|
|
9
9
|
from __future__ import annotations
|
10
|
-
|
10
|
+
import meerschaum as mrsm
|
11
|
+
from meerschaum.utils.typing import SuccessTuple, Union, Sequence, Any, Optional, List, Dict, Tuple
|
11
12
|
|
12
13
|
def show(
|
13
14
|
action: Optional[List[str]] = None,
|
@@ -39,6 +40,7 @@ def show(
|
|
39
40
|
'users' : _show_users,
|
40
41
|
'jobs' : _show_jobs,
|
41
42
|
'logs' : _show_logs,
|
43
|
+
'tags' : _show_tags,
|
42
44
|
}
|
43
45
|
return choose_subaction(action, show_options, **kw)
|
44
46
|
|
@@ -735,6 +737,75 @@ def _show_environment(
|
|
735
737
|
return True, "Success"
|
736
738
|
|
737
739
|
|
740
|
+
def _show_tags(
|
741
|
+
tags: Optional[List[str]] = None,
|
742
|
+
workers: Optional[int] = None,
|
743
|
+
nopretty: bool = False,
|
744
|
+
**kwargs
|
745
|
+
) -> SuccessTuple:
|
746
|
+
"""
|
747
|
+
Show the existing tags and their associated pipes.
|
748
|
+
"""
|
749
|
+
import json
|
750
|
+
from collections import defaultdict
|
751
|
+
import meerschaum as mrsm
|
752
|
+
from meerschaum.utils.formatting import pipe_repr, UNICODE, ANSI
|
753
|
+
from meerschaum.utils.pool import get_pool
|
754
|
+
from meerschaum.config import get_config
|
755
|
+
rich_tree, rich_panel, rich_text, rich_console, rich_columns = (
|
756
|
+
mrsm.attempt_import('rich.tree', 'rich.panel', 'rich.text', 'rich.console', 'rich.columns')
|
757
|
+
)
|
758
|
+
panel = rich_panel.Panel.fit('Tags')
|
759
|
+
tree = rich_tree.Tree(panel)
|
760
|
+
pipes = mrsm.get_pipes(as_list=True, **kwargs)
|
761
|
+
pool = get_pool(workers=workers)
|
762
|
+
tag_prefix = get_config('formatting', 'pipes', 'unicode', 'icons', 'tag') if UNICODE else ''
|
763
|
+
tag_style = get_config('formatting', 'pipes', 'ansi', 'styles', 'tags') if ANSI else None
|
764
|
+
|
765
|
+
tags_pipes = defaultdict(lambda: [])
|
766
|
+
gather_pipe_tags = lambda pipe: (pipe, (pipe.tags or []))
|
767
|
+
|
768
|
+
pipes_tags = dict(pool.map(gather_pipe_tags, pipes))
|
769
|
+
|
770
|
+
for pipe, tags in pipes_tags.items():
|
771
|
+
for tag in tags:
|
772
|
+
tags_pipes[tag].append(pipe)
|
773
|
+
|
774
|
+
columns = []
|
775
|
+
sorted_tags = sorted([tag for tag in tags_pipes])
|
776
|
+
for tag in sorted_tags:
|
777
|
+
_pipes = tags_pipes[tag]
|
778
|
+
tag_text = (
|
779
|
+
rich_text.Text(tag_prefix)
|
780
|
+
+ rich_text.Text(
|
781
|
+
tag,
|
782
|
+
style = tag_style,
|
783
|
+
)
|
784
|
+
)
|
785
|
+
pipes_texts = [
|
786
|
+
pipe_repr(pipe, as_rich_text=True)
|
787
|
+
for pipe in _pipes
|
788
|
+
]
|
789
|
+
tag_group = rich_console.Group(*pipes_texts)
|
790
|
+
tag_panel = rich_panel.Panel(tag_group, title=tag_text, title_align='left')
|
791
|
+
columns.append(tag_panel)
|
792
|
+
|
793
|
+
if not nopretty:
|
794
|
+
mrsm.pprint(
|
795
|
+
rich_columns.Columns(
|
796
|
+
columns,
|
797
|
+
equal = True,
|
798
|
+
),
|
799
|
+
)
|
800
|
+
else:
|
801
|
+
for tag, _pipes in tags_pipes.items():
|
802
|
+
print(tag)
|
803
|
+
for pipe in _pipes:
|
804
|
+
print(json.dumps(pipe.meta))
|
805
|
+
|
806
|
+
return True, "Success"
|
807
|
+
|
808
|
+
|
738
809
|
|
739
810
|
### NOTE: This must be the final statement of the module.
|
740
811
|
### Any subactions added below these lines will not
|
meerschaum/actions/sync.py
CHANGED
@@ -10,6 +10,7 @@ NOTE: `sync` required a SQL connection and is not intended for client use
|
|
10
10
|
|
11
11
|
from __future__ import annotations
|
12
12
|
from datetime import timedelta
|
13
|
+
import meerschaum as mrsm
|
13
14
|
from meerschaum.utils.typing import SuccessTuple, Any, List, Optional, Tuple, Union
|
14
15
|
|
15
16
|
def sync(
|
@@ -400,33 +401,60 @@ def _wrap_pipe(
|
|
400
401
|
"""
|
401
402
|
Wrapper function for handling exceptions.
|
402
403
|
"""
|
404
|
+
import time
|
403
405
|
from meerschaum.connectors import get_connector_plugin
|
404
406
|
from meerschaum.utils.venv import Venv
|
407
|
+
from meerschaum.plugins import _pre_sync_hooks, _post_sync_hooks
|
408
|
+
from meerschaum.utils.misc import filter_keywords
|
409
|
+
|
410
|
+
sync_start = time.perf_counter()
|
411
|
+
sync_kwargs = {k: v for k, v in kw.items() if k != 'blocking'}
|
412
|
+
sync_kwargs.update({
|
413
|
+
'blocking': (not unblock),
|
414
|
+
'force': force,
|
415
|
+
'debug': debug,
|
416
|
+
'min_seconds': min_seconds,
|
417
|
+
'workers': workers,
|
418
|
+
'bounded': 'bounded',
|
419
|
+
'chunk_interval': chunk_interval,
|
420
|
+
})
|
421
|
+
if not verify and not deduplicate:
|
422
|
+
sync_method = pipe.sync
|
423
|
+
elif not verify and deduplicate:
|
424
|
+
sync_method = pipe.deduplicate
|
425
|
+
else:
|
426
|
+
sync_method = pipe.verify
|
427
|
+
sync_kwargs['deduplicate'] = deduplicate
|
428
|
+
|
429
|
+
for module_name, pre_sync_hooks in _pre_sync_hooks.items():
|
430
|
+
plugin_name = module_name.split('.')[-1] if module_name.startswith('plugins.') else None
|
431
|
+
plugin = mrsm.Plugin(plugin_name) if plugin_name else None
|
432
|
+
with Venv(plugin):
|
433
|
+
for pre_sync_hook in pre_sync_hooks:
|
434
|
+
_ = pre_sync_hook(pipe, **filter_keywords(pre_sync_hook, **sync_kwargs))
|
435
|
+
|
405
436
|
try:
|
406
437
|
with Venv(get_connector_plugin(pipe.connector), debug=debug):
|
407
|
-
|
408
|
-
sync_method = pipe.sync
|
409
|
-
elif not verify and deduplicate:
|
410
|
-
sync_method = pipe.deduplicate
|
411
|
-
else:
|
412
|
-
sync_method = pipe.verify
|
413
|
-
kw['deduplicate'] = deduplicate
|
414
|
-
return_tuple = sync_method(
|
415
|
-
blocking = (not unblock),
|
416
|
-
force = force,
|
417
|
-
debug = debug,
|
418
|
-
min_seconds = min_seconds,
|
419
|
-
workers = workers,
|
420
|
-
bounded = bounded,
|
421
|
-
chunk_interval = chunk_interval,
|
422
|
-
**{k: v for k, v in kw.items() if k != 'blocking'}
|
423
|
-
)
|
438
|
+
return_tuple = sync_method(**sync_kwargs)
|
424
439
|
except Exception as e:
|
425
440
|
import traceback
|
426
441
|
traceback.print_exception(type(e), e, e.__traceback__)
|
427
442
|
print("Error: " + str(e))
|
428
443
|
return_tuple = (False, f"Failed to sync {pipe} with exception:" + "\n" + str(e))
|
429
444
|
|
445
|
+
duration = time.perf_counter() - sync_start
|
446
|
+
sync_kwargs['duration'] = duration
|
447
|
+
for module_name, post_sync_hooks in _post_sync_hooks.items():
|
448
|
+
plugin_name = module_name.split('.')[-1] if module_name.startswith('plugins.') else None
|
449
|
+
plugin = mrsm.Plugin(plugin_name) if plugin_name else None
|
450
|
+
with Venv(plugin):
|
451
|
+
for post_sync_hook in post_sync_hooks:
|
452
|
+
_ = post_sync_hook(
|
453
|
+
pipe,
|
454
|
+
return_tuple,
|
455
|
+
**filter_keywords(post_sync_hook, **sync_kwargs)
|
456
|
+
)
|
457
|
+
|
430
458
|
return return_tuple
|
431
459
|
|
432
460
|
|
meerschaum/config/_edit.py
CHANGED
@@ -6,9 +6,9 @@
|
|
6
6
|
Functions for editing the configuration file
|
7
7
|
"""
|
8
8
|
|
9
|
-
# from meerschaum.utils.debug import dprint
|
10
9
|
from __future__ import annotations
|
11
10
|
import sys
|
11
|
+
import pathlib
|
12
12
|
from meerschaum.utils.typing import Optional, Any, SuccessTuple, Mapping, Dict, List, Union
|
13
13
|
|
14
14
|
def edit_config(
|
@@ -21,7 +21,7 @@ def edit_config(
|
|
21
21
|
from meerschaum.config import get_config, config
|
22
22
|
from meerschaum.config._read_config import get_keyfile_path
|
23
23
|
from meerschaum.config._paths import CONFIG_DIR_PATH
|
24
|
-
from meerschaum.utils.packages import
|
24
|
+
from meerschaum.utils.packages import reload_meerschaum
|
25
25
|
from meerschaum.utils.misc import edit_file
|
26
26
|
from meerschaum.utils.debug import dprint
|
27
27
|
|
@@ -35,10 +35,7 @@ def edit_config(
|
|
35
35
|
get_config(k, write_missing=True, warn=False)
|
36
36
|
edit_file(get_keyfile_path(k, create_new=True))
|
37
37
|
|
38
|
-
|
39
|
-
dprint("Reloading configuration...")
|
40
|
-
reload_package('meerschaum', debug=debug, **kw)
|
41
|
-
|
38
|
+
reload_meerschaum(debug=debug)
|
42
39
|
return (True, "Success")
|
43
40
|
|
44
41
|
|
@@ -78,7 +75,7 @@ def write_config(
|
|
78
75
|
from meerschaum.utils.debug import dprint
|
79
76
|
from meerschaum.utils.yaml import yaml
|
80
77
|
from meerschaum.utils.misc import filter_keywords
|
81
|
-
import json, os
|
78
|
+
import json, os
|
82
79
|
if config_dict is None:
|
83
80
|
from meerschaum.config import _config
|
84
81
|
cf = _config()
|
@@ -162,7 +159,6 @@ def general_write_yaml_config(
|
|
162
159
|
"""
|
163
160
|
|
164
161
|
from meerschaum.utils.debug import dprint
|
165
|
-
from pathlib import Path
|
166
162
|
|
167
163
|
if files is None:
|
168
164
|
files = {}
|
@@ -172,7 +168,7 @@ def general_write_yaml_config(
|
|
172
168
|
header = None
|
173
169
|
if isinstance(value, tuple):
|
174
170
|
config, header = value
|
175
|
-
path = Path(fp)
|
171
|
+
path = pathlib.Path(fp)
|
176
172
|
path.parent.mkdir(parents=True, exist_ok=True)
|
177
173
|
path.touch(exist_ok=True)
|
178
174
|
with open(path, 'w+') as f:
|
@@ -193,32 +189,12 @@ def general_write_yaml_config(
|
|
193
189
|
return True
|
194
190
|
|
195
191
|
def general_edit_config(
|
196
|
-
action
|
197
|
-
files
|
198
|
-
default
|
199
|
-
debug
|
192
|
+
action: Optional[List[str]] = None,
|
193
|
+
files: Optional[Dict[str, Union[str, pathlib.Path]]] = None,
|
194
|
+
default: Optional[str] = None,
|
195
|
+
debug: bool = False
|
200
196
|
):
|
201
|
-
"""
|
202
|
-
|
203
|
-
Parameters
|
204
|
-
----------
|
205
|
-
action : Optional[List[str]] :
|
206
|
-
(Default value = None)
|
207
|
-
files : Optional[Dict[str :
|
208
|
-
|
209
|
-
Union[str :
|
210
|
-
|
211
|
-
pathlib.Path]]] :
|
212
|
-
(Default value = None)
|
213
|
-
default : str :
|
214
|
-
(Default value = None)
|
215
|
-
debug : bool :
|
216
|
-
(Default value = False)
|
217
|
-
|
218
|
-
Returns
|
219
|
-
-------
|
220
|
-
|
221
|
-
"""
|
197
|
+
"""Prompt the user to edit any config files."""
|
222
198
|
if default is None:
|
223
199
|
raise Exception("Provide a default choice for which file to edit")
|
224
200
|
import os
|
meerschaum/config/_formatting.py
CHANGED
@@ -35,6 +35,7 @@ default_formatting_config = {
|
|
35
35
|
'running' : '🟢',
|
36
36
|
'paused' : '🟡',
|
37
37
|
'stopped' : '🔴',
|
38
|
+
'tag' : '🏷️',
|
38
39
|
},
|
39
40
|
'pipes' : {
|
40
41
|
'unicode' : {
|
@@ -43,6 +44,7 @@ default_formatting_config = {
|
|
43
44
|
'metric' : 'MRSM{formatting:emoji:metric} ',
|
44
45
|
'location' : 'MRSM{formatting:emoji:location} ',
|
45
46
|
'key' : 'MRSM{formatting:emoji:key} ',
|
47
|
+
'tag' : 'MRSM{formatting:emoji:tag} ',
|
46
48
|
},
|
47
49
|
},
|
48
50
|
'ascii' : {
|
@@ -51,6 +53,7 @@ default_formatting_config = {
|
|
51
53
|
'metric' : '',
|
52
54
|
'location' : '',
|
53
55
|
'key' : '',
|
56
|
+
'tag' : '',
|
54
57
|
},
|
55
58
|
},
|
56
59
|
'ansi' : {
|
@@ -61,6 +64,7 @@ default_formatting_config = {
|
|
61
64
|
'key' : '',
|
62
65
|
'guide' : 'dim',
|
63
66
|
'none' : 'black on magenta',
|
67
|
+
'tags' : 'bold yellow underline',
|
64
68
|
},
|
65
69
|
},
|
66
70
|
'__repr__' : {
|
meerschaum/config/_version.py
CHANGED
@@ -56,6 +56,8 @@ STATIC_CONFIG: Dict[str, Any] = {
|
|
56
56
|
'dep_group': 'MRSM_DEP_GROUP',
|
57
57
|
'home': 'MRSM_HOME',
|
58
58
|
'src': 'MRSM_SRC',
|
59
|
+
'uid': 'MRSM_UID',
|
60
|
+
'gid': 'MRSM_GID',
|
59
61
|
'noask': 'MRSM_NOASK',
|
60
62
|
'id': 'MRSM_SERVER_ID',
|
61
63
|
'uri_regex': r'MRSM_([a-zA-Z0-9]*)_(\d*[a-zA-Z][a-zA-Z0-9-_+]*$)',
|
@@ -171,7 +171,7 @@ def fetch_pipes_keys(
|
|
171
171
|
"""
|
172
172
|
from meerschaum.utils.debug import dprint
|
173
173
|
from meerschaum.utils.packages import attempt_import
|
174
|
-
from meerschaum.utils.misc import separate_negation_values
|
174
|
+
from meerschaum.utils.misc import separate_negation_values, flatten_list
|
175
175
|
from meerschaum.utils.sql import OMIT_NULLSFIRST_FLAVORS, table_exists
|
176
176
|
from meerschaum.config.static import STATIC_CONFIG
|
177
177
|
import json
|
@@ -254,25 +254,31 @@ def fetch_pipes_keys(
|
|
254
254
|
q = q.where(coalesce(pipes_tbl.c[c], 'None').not_in(_ex_vals)) if _ex_vals else q
|
255
255
|
|
256
256
|
### Finally, parse tags.
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
257
|
+
tag_groups = [tag.split(',') for tag in tags]
|
258
|
+
in_ex_tag_groups = [separate_negation_values(tag_group) for tag_group in tag_groups]
|
259
|
+
|
260
|
+
ors, nands = [], []
|
261
|
+
for _in_tags, _ex_tags in in_ex_tag_groups:
|
262
|
+
sub_ands = []
|
263
|
+
for nt in _in_tags:
|
264
|
+
sub_ands.append(
|
265
|
+
sqlalchemy.cast(
|
266
|
+
pipes_tbl.c['parameters'],
|
267
|
+
sqlalchemy.String,
|
268
|
+
).like(f'%"tags":%"{nt}"%')
|
269
|
+
)
|
270
|
+
ors.append(sqlalchemy.and_(*sub_ands))
|
271
|
+
|
272
|
+
for xt in _ex_tags:
|
273
|
+
nands.append(
|
274
|
+
sqlalchemy.cast(
|
275
|
+
pipes_tbl.c['parameters'],
|
276
|
+
sqlalchemy.String,
|
277
|
+
).not_like(f'%"tags":%"{xt}"%')
|
278
|
+
)
|
279
|
+
|
280
|
+
q = q.where(sqlalchemy.and_(*nands)) if nands else q
|
281
|
+
q = q.where(sqlalchemy.or_(*ors)) if ors else q
|
276
282
|
loc_asc = sqlalchemy.asc(pipes_tbl.c['location_key'])
|
277
283
|
if self.flavor not in OMIT_NULLSFIRST_FLAVORS:
|
278
284
|
loc_asc = sqlalchemy.nullsfirst(loc_asc)
|
meerschaum/core/Pipe/_data.py
CHANGED
@@ -8,7 +8,7 @@ Retrieve Pipes' data from instances.
|
|
8
8
|
|
9
9
|
from __future__ import annotations
|
10
10
|
from datetime import datetime, timedelta
|
11
|
-
from meerschaum.utils.typing import Optional, Dict, Any, Union, Generator
|
11
|
+
from meerschaum.utils.typing import Optional, Dict, Any, Union, Generator, List, Tuple
|
12
12
|
from meerschaum.config import get_config
|
13
13
|
|
14
14
|
def get_data(
|
@@ -350,20 +350,20 @@ def get_backtrack_data(
|
|
350
350
|
If begin is `None` (default), use the most recent observed datetime
|
351
351
|
(AKA sync_time).
|
352
352
|
|
353
|
+
```
|
354
|
+
E.g. begin = 02:00
|
355
|
+
|
356
|
+
Search this region. Ignore this, even if there's data.
|
357
|
+
/ / / / / / / / / |
|
358
|
+
-----|----------|----------|----------|----------|----------|
|
359
|
+
00:00 01:00 02:00 03:00 04:00 05:00
|
360
|
+
|
361
|
+
```
|
362
|
+
|
353
363
|
params: Optional[Dict[str, Any]], default None
|
354
364
|
The standard Meerschaum `params` query dictionary.
|
355
365
|
|
356
366
|
|
357
|
-
```
|
358
|
-
E.g. begin = 02:00
|
359
|
-
|
360
|
-
Search this region. Ignore this, even if there's data.
|
361
|
-
/ / / / / / / / / |
|
362
|
-
-----|----------|----------|----------|----------|----------|
|
363
|
-
00:00 01:00 02:00 03:00 04:00 05:00
|
364
|
-
|
365
|
-
```
|
366
|
-
|
367
367
|
fresh: bool, default False
|
368
368
|
If `True`, Ignore local cache and pull directly from the instance connector.
|
369
369
|
Only comes into effect if a pipe was created with `cache=True`.
|
meerschaum/core/Pipe/_fetch.py
CHANGED
@@ -15,8 +15,8 @@ from meerschaum.utils.warnings import warn
|
|
15
15
|
|
16
16
|
def fetch(
|
17
17
|
self,
|
18
|
-
begin:
|
19
|
-
end: Optional[datetime
|
18
|
+
begin: Union[datetime, str, None] = '',
|
19
|
+
end: Optional[datetime] = None,
|
20
20
|
check_existing: bool = True,
|
21
21
|
sync_chunks: bool = False,
|
22
22
|
debug: bool = False,
|
@@ -27,10 +27,10 @@ def fetch(
|
|
27
27
|
|
28
28
|
Parameters
|
29
29
|
----------
|
30
|
-
begin:
|
30
|
+
begin: Union[datetime, str, None], default '':
|
31
31
|
If provided, only fetch data newer than or equal to `begin`.
|
32
32
|
|
33
|
-
end: Optional[datetime
|
33
|
+
end: Optional[datetime], default None:
|
34
34
|
If provided, only fetch data older than or equal to `end`.
|
35
35
|
|
36
36
|
check_existing: bool, default True
|
meerschaum/plugins/_Plugin.py
CHANGED
@@ -283,8 +283,8 @@ class Plugin:
|
|
283
283
|
import tarfile
|
284
284
|
import re
|
285
285
|
import ast
|
286
|
-
from meerschaum.plugins import
|
287
|
-
from meerschaum.utils.packages import attempt_import, determine_version,
|
286
|
+
from meerschaum.plugins import sync_plugins_symlinks
|
287
|
+
from meerschaum.utils.packages import attempt_import, determine_version, reload_meerschaum
|
288
288
|
from meerschaum.utils.venv import init_venv
|
289
289
|
from meerschaum.utils.misc import safely_extract_tar
|
290
290
|
old_cwd = os.getcwd()
|
@@ -415,8 +415,7 @@ class Plugin:
|
|
415
415
|
if '_module' in self.__dict__:
|
416
416
|
del self.__dict__['_module']
|
417
417
|
init_venv(venv=self.name, force=True, debug=debug)
|
418
|
-
|
419
|
-
reload_plugins([self.name], debug=debug)
|
418
|
+
reload_meerschaum(debug=debug)
|
420
419
|
|
421
420
|
### if we've already failed, return here
|
422
421
|
if not success or abort:
|
@@ -493,8 +492,8 @@ class Plugin:
|
|
493
492
|
"""
|
494
493
|
Remove a plugin, its virtual environment, and archive file.
|
495
494
|
"""
|
496
|
-
from meerschaum.utils.packages import
|
497
|
-
from meerschaum.plugins import
|
495
|
+
from meerschaum.utils.packages import reload_meerschaum
|
496
|
+
from meerschaum.plugins import sync_plugins_symlinks
|
498
497
|
from meerschaum.utils.warnings import warn, info
|
499
498
|
warnings_thrown_count: int = 0
|
500
499
|
max_warnings: int = 3
|
@@ -529,8 +528,7 @@ class Plugin:
|
|
529
528
|
success = warnings_thrown_count < max_warnings
|
530
529
|
sync_plugins_symlinks(debug=debug)
|
531
530
|
self.deactivate_venv(force=True, debug=debug)
|
532
|
-
|
533
|
-
reload_plugins(debug=debug)
|
531
|
+
reload_meerschaum(debug=debug)
|
534
532
|
return success, (
|
535
533
|
f"Successfully uninstalled plugin '{self}'." if success
|
536
534
|
else f"Failed to uninstall plugin '{self}'."
|
meerschaum/plugins/__init__.py
CHANGED
@@ -12,8 +12,12 @@ from meerschaum.utils.threading import Lock, RLock
|
|
12
12
|
from meerschaum.plugins._Plugin import Plugin
|
13
13
|
|
14
14
|
_api_plugins: Dict[str, List[Callable[['fastapi.App'], Any]]] = {}
|
15
|
+
_pre_sync_hooks: Dict[str, List[Callable[[Any], Any]]] = {}
|
16
|
+
_post_sync_hooks: Dict[str, List[Callable[[Any], Any]]] = {}
|
15
17
|
_locks = {
|
16
18
|
'_api_plugins': RLock(),
|
19
|
+
'_pre_sync_hooks': RLock(),
|
20
|
+
'_post_sync_hooks': RLock(),
|
17
21
|
'__path__': RLock(),
|
18
22
|
'sys.path': RLock(),
|
19
23
|
'internal_plugins': RLock(),
|
@@ -23,6 +27,7 @@ _locks = {
|
|
23
27
|
__all__ = (
|
24
28
|
"Plugin", "make_action", "api_plugin", "import_plugins",
|
25
29
|
"reload_plugins", "get_plugins", "get_data_plugins", "add_plugin_argument",
|
30
|
+
"pre_sync_hook", "post_sync_hook",
|
26
31
|
)
|
27
32
|
__pdoc__ = {
|
28
33
|
'venvs': False, 'data': False, 'stack': False, 'plugins': False,
|
@@ -81,6 +86,76 @@ def make_action(
|
|
81
86
|
return function
|
82
87
|
|
83
88
|
|
89
|
+
def pre_sync_hook(
|
90
|
+
function: Callable[[Any], Any],
|
91
|
+
) -> Callable[[Any], Any]:
|
92
|
+
"""
|
93
|
+
Register a function as a sync hook to be executed right before sync.
|
94
|
+
|
95
|
+
Parameters
|
96
|
+
----------
|
97
|
+
function: Callable[[Any], Any]
|
98
|
+
The function to execute right before a sync.
|
99
|
+
|
100
|
+
Returns
|
101
|
+
-------
|
102
|
+
Another function (this is a decorator function).
|
103
|
+
|
104
|
+
Examples
|
105
|
+
--------
|
106
|
+
>>> from meerschaum.plugins import pre_sync_hook
|
107
|
+
>>>
|
108
|
+
>>> @pre_sync_hook
|
109
|
+
... def log_sync(pipe, **kwargs):
|
110
|
+
... print(f"About to sync {pipe} with kwargs:\n{kwargs}.")
|
111
|
+
>>>
|
112
|
+
"""
|
113
|
+
with _locks['_pre_sync_hooks']:
|
114
|
+
try:
|
115
|
+
if function.__module__ not in _pre_sync_hooks:
|
116
|
+
_pre_sync_hooks[function.__module__] = []
|
117
|
+
_pre_sync_hooks[function.__module__].append(function)
|
118
|
+
except Exception as e:
|
119
|
+
from meerschaum.utils.warnings import warn
|
120
|
+
warn(e)
|
121
|
+
return function
|
122
|
+
|
123
|
+
|
124
|
+
def post_sync_hook(
|
125
|
+
function: Callable[[Any], Any],
|
126
|
+
) -> Callable[[Any], Any]:
|
127
|
+
"""
|
128
|
+
Register a function as a sync hook to be executed upon completion of a sync.
|
129
|
+
|
130
|
+
Parameters
|
131
|
+
----------
|
132
|
+
function: Callable[[Any], Any]
|
133
|
+
The function to execute upon completion of a sync.
|
134
|
+
|
135
|
+
Returns
|
136
|
+
-------
|
137
|
+
Another function (this is a decorator function).
|
138
|
+
|
139
|
+
Examples
|
140
|
+
--------
|
141
|
+
>>> from meerschaum.plugins import post_sync_hook
|
142
|
+
>>>
|
143
|
+
>>> @post_sync_hook
|
144
|
+
... def log_sync(pipe, success_tuple, duration=None, **kwargs):
|
145
|
+
... print(f"It took {round(duration, 2)} seconds to sync {pipe}.")
|
146
|
+
>>>
|
147
|
+
"""
|
148
|
+
with _locks['_post_sync_hooks']:
|
149
|
+
try:
|
150
|
+
if function.__module__ not in _post_sync_hooks:
|
151
|
+
_post_sync_hooks[function.__module__] = []
|
152
|
+
_post_sync_hooks[function.__module__].append(function)
|
153
|
+
except Exception as e:
|
154
|
+
from meerschaum.utils.warnings import warn
|
155
|
+
warn(e)
|
156
|
+
return function
|
157
|
+
|
158
|
+
|
84
159
|
def api_plugin(function: Callable[[Any], Any]) -> Callable[[Any], Any]:
|
85
160
|
"""
|
86
161
|
Execute the function when initializing the Meerschaum API module.
|
@@ -106,7 +181,7 @@ def api_plugin(function: Callable[[Any], Any]) -> Callable[[Any], Any]:
|
|
106
181
|
>>> def initialize_plugin(app):
|
107
182
|
... @app.get('/my/new/path')
|
108
183
|
... def new_path():
|
109
|
-
... return {'message'
|
184
|
+
... return {'message': 'It works!'}
|
110
185
|
>>>
|
111
186
|
"""
|
112
187
|
with _locks['_api_plugins']:
|
meerschaum/utils/__init__.py
CHANGED
@@ -8,10 +8,25 @@ These include tools from primary utilities (get_pipes)
|
|
8
8
|
to miscellaneous helper functions.
|
9
9
|
"""
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
__all__ = (
|
12
|
+
'daemon',
|
13
|
+
'dataframe',
|
14
|
+
'debug',
|
15
|
+
'dtypes',
|
16
|
+
'formatting',
|
17
|
+
'interactive',
|
18
|
+
'misc',
|
19
|
+
'networking',
|
20
|
+
'packages',
|
21
|
+
'pool',
|
22
|
+
'process',
|
23
|
+
'prompt',
|
24
|
+
'schedule',
|
25
|
+
'sql',
|
26
|
+
'threading',
|
27
|
+
'typing',
|
28
|
+
'venv',
|
29
|
+
'warnings',
|
30
|
+
'yaml',
|
31
|
+
)
|
17
32
|
from meerschaum.utils.get_pipes import get_pipes
|
@@ -19,6 +19,7 @@ from meerschaum.utils.formatting._pipes import (
|
|
19
19
|
format_pipe_success_tuple,
|
20
20
|
print_pipes_results,
|
21
21
|
extract_stats_from_message,
|
22
|
+
pipe_repr,
|
22
23
|
)
|
23
24
|
from meerschaum.utils.threading import Lock, RLock
|
24
25
|
|
@@ -39,6 +40,9 @@ __all__ = sorted([
|
|
39
40
|
'highlight_pipes',
|
40
41
|
'pprint_pipes',
|
41
42
|
'make_header',
|
43
|
+
'pipe_repr',
|
44
|
+
'print_pipes_results',
|
45
|
+
'extract_stats_from_message',
|
42
46
|
])
|
43
47
|
__pdoc__ = {}
|
44
48
|
_locks = {
|
meerschaum/utils/get_pipes.py
CHANGED
@@ -18,7 +18,7 @@ def get_pipes(
|
|
18
18
|
connector_keys: Union[str, List[str], None] = None,
|
19
19
|
metric_keys: Union[str, List[str], None] = None,
|
20
20
|
location_keys: Union[str, List[str], None] = None,
|
21
|
-
tags: Optional[List[str]
|
21
|
+
tags: Optional[List[str]] = None,
|
22
22
|
params: Optional[Dict[str, Any]] = None,
|
23
23
|
mrsm_instance: Union[str, InstanceConnector, None] = None,
|
24
24
|
instance: Union[str, InstanceConnector, None] = None,
|