meerschaum 3.0.0rc2__py3-none-any.whl → 3.0.0rc3__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/shell/Shell.py +5 -4
- meerschaum/actions/bootstrap.py +1 -1
- meerschaum/actions/edit.py +6 -3
- meerschaum/actions/start.py +1 -1
- meerschaum/api/dash/callbacks/__init__.py +1 -0
- meerschaum/api/dash/callbacks/dashboard.py +19 -18
- meerschaum/api/dash/callbacks/jobs.py +11 -5
- meerschaum/api/dash/callbacks/pipes.py +106 -5
- meerschaum/api/dash/callbacks/settings/__init__.py +0 -1
- meerschaum/api/dash/callbacks/{settings/tokens.py → tokens.py} +1 -1
- meerschaum/api/dash/jobs.py +1 -1
- meerschaum/api/dash/pages/__init__.py +2 -1
- meerschaum/api/dash/pages/{job.py → jobs.py} +10 -7
- meerschaum/api/dash/pages/pipes.py +4 -3
- meerschaum/api/dash/pages/settings/__init__.py +0 -1
- meerschaum/api/dash/pages/{settings/tokens.py → tokens.py} +6 -8
- meerschaum/api/dash/pipes.py +131 -0
- meerschaum/api/dash/tokens.py +26 -29
- meerschaum/config/_default.py +5 -4
- meerschaum/config/_paths.py +1 -0
- meerschaum/config/_version.py +1 -1
- meerschaum/connectors/instance/_tokens.py +6 -2
- meerschaum/connectors/sql/_SQLConnector.py +14 -0
- meerschaum/connectors/sql/_pipes.py +57 -22
- meerschaum/connectors/sql/tables/__init__.py +237 -122
- meerschaum/core/Pipe/_attributes.py +5 -2
- meerschaum/core/Token/_Token.py +1 -1
- meerschaum/plugins/bootstrap.py +508 -3
- meerschaum/utils/_get_pipes.py +1 -1
- meerschaum/utils/dataframe.py +8 -2
- meerschaum/utils/dtypes/__init__.py +2 -3
- meerschaum/utils/dtypes/sql.py +11 -11
- meerschaum/utils/sql.py +1 -1
- {meerschaum-3.0.0rc2.dist-info → meerschaum-3.0.0rc3.dist-info}/METADATA +1 -1
- {meerschaum-3.0.0rc2.dist-info → meerschaum-3.0.0rc3.dist-info}/RECORD +41 -41
- {meerschaum-3.0.0rc2.dist-info → meerschaum-3.0.0rc3.dist-info}/WHEEL +0 -0
- {meerschaum-3.0.0rc2.dist-info → meerschaum-3.0.0rc3.dist-info}/entry_points.txt +0 -0
- {meerschaum-3.0.0rc2.dist-info → meerschaum-3.0.0rc3.dist-info}/licenses/LICENSE +0 -0
- {meerschaum-3.0.0rc2.dist-info → meerschaum-3.0.0rc3.dist-info}/licenses/NOTICE +0 -0
- {meerschaum-3.0.0rc2.dist-info → meerschaum-3.0.0rc3.dist-info}/top_level.txt +0 -0
- {meerschaum-3.0.0rc2.dist-info → meerschaum-3.0.0rc3.dist-info}/zip-safe +0 -0
@@ -781,10 +781,11 @@ class Shell(cmd.Cmd):
|
|
781
781
|
instance_keys += ':main'
|
782
782
|
|
783
783
|
conn_attrs = parse_instance_keys(instance_keys, construct=False, debug=debug)
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
784
|
+
conn_keys = (
|
785
|
+
str(get_connector(debug=debug))
|
786
|
+
if conn_attrs is None
|
787
|
+
else instance_keys
|
788
|
+
)
|
788
789
|
|
789
790
|
shell_attrs['instance_keys'] = conn_keys
|
790
791
|
|
meerschaum/actions/bootstrap.py
CHANGED
@@ -429,7 +429,7 @@ def _bootstrap_plugins(
|
|
429
429
|
action = [prompt("Enter the name of your new plugin:")]
|
430
430
|
|
431
431
|
for plugin_name in action:
|
432
|
-
bootstrap_success, bootstrap_msg = bootstrap_plugin(plugin_name)
|
432
|
+
bootstrap_success, bootstrap_msg = bootstrap_plugin(plugin_name, debug=debug)
|
433
433
|
if not bootstrap_success:
|
434
434
|
return bootstrap_success, bootstrap_msg
|
435
435
|
|
meerschaum/actions/edit.py
CHANGED
@@ -552,7 +552,12 @@ def _edit_tokens(
|
|
552
552
|
dateutil_parser = mrsm.attempt_import('dateutil.parser')
|
553
553
|
|
554
554
|
if not action:
|
555
|
-
return
|
555
|
+
return (
|
556
|
+
False, (
|
557
|
+
"Provide token labels or IDs for the tokens to edit\n"
|
558
|
+
" (run `show tokens` to see registered tokens)."
|
559
|
+
)
|
560
|
+
)
|
556
561
|
|
557
562
|
conn = parse_instance_keys(mrsm_instance)
|
558
563
|
|
@@ -628,8 +633,6 @@ def _edit_tokens(
|
|
628
633
|
|
629
634
|
return True, msg
|
630
635
|
|
631
|
-
|
632
|
-
|
633
636
|
|
634
637
|
### NOTE: This must be the final statement of the module.
|
635
638
|
### Any subactions added below these lines will not
|
meerschaum/actions/start.py
CHANGED
@@ -10,6 +10,7 @@ from meerschaum.api import debug as _debug
|
|
10
10
|
import meerschaum.api.dash.callbacks.dashboard
|
11
11
|
import meerschaum.api.dash.callbacks.login
|
12
12
|
import meerschaum.api.dash.callbacks.plugins
|
13
|
+
import meerschaum.api.dash.callbacks.tokens
|
13
14
|
import meerschaum.api.dash.callbacks.jobs
|
14
15
|
import meerschaum.api.dash.callbacks.register
|
15
16
|
import meerschaum.api.dash.callbacks.pipes
|
@@ -72,8 +72,6 @@ keys_state = (
|
|
72
72
|
State({'type': 'input-flags-dropdown', 'index': ALL}, 'value'),
|
73
73
|
State({'type': 'input-flags-dropdown-text', 'index': ALL}, 'value'),
|
74
74
|
State('instance-select', 'value'),
|
75
|
-
State('content-div-right', 'children'),
|
76
|
-
State('success-alert-div', 'children'),
|
77
75
|
State('session-store', 'data'),
|
78
76
|
)
|
79
77
|
|
@@ -103,15 +101,20 @@ omit_actions = {
|
|
103
101
|
_paths = {
|
104
102
|
'login' : pages.login.layout,
|
105
103
|
'' : pages.dashboard.layout,
|
104
|
+
'pipes' : pages.pipes.layout,
|
106
105
|
'plugins' : pages.plugins.layout,
|
106
|
+
'tokens' : pages.tokens.layout,
|
107
107
|
'register': pages.register.layout,
|
108
108
|
'pipes' : pages.pipes.layout,
|
109
|
-
'
|
109
|
+
'jobs' : pages.jobs.layout,
|
110
110
|
}
|
111
|
-
_required_login = {''}
|
111
|
+
_required_login = {'', 'tokens', 'jobs', 'pipes'}
|
112
112
|
_pages = {
|
113
113
|
'Web Console': '/dash/',
|
114
|
+
'Pipes': '/dash/pipes',
|
114
115
|
'Plugins': '/dash/plugins',
|
116
|
+
'Tokens': '/dash/tokens',
|
117
|
+
'Jobs': '/dash/jobs',
|
115
118
|
}
|
116
119
|
|
117
120
|
|
@@ -495,16 +498,12 @@ def update_flags(input_flags_dropdown_values, n_clicks, input_flags_texts):
|
|
495
498
|
|
496
499
|
@dash_app.callback(
|
497
500
|
Output('connector-keys-dropdown', 'options'),
|
498
|
-
Output('connector-keys-list', 'children'),
|
499
501
|
Output('connector-keys-dropdown', 'value'),
|
500
502
|
Output('metric-keys-dropdown', 'options'),
|
501
|
-
Output('metric-keys-list', 'children'),
|
502
503
|
Output('metric-keys-dropdown', 'value'),
|
503
504
|
Output('location-keys-dropdown', 'options'),
|
504
|
-
Output('location-keys-list', 'children'),
|
505
505
|
Output('location-keys-dropdown', 'value'),
|
506
506
|
Output('tags-dropdown', 'options'),
|
507
|
-
Output('tags-list', 'children'),
|
508
507
|
Output('tags-dropdown', 'value'),
|
509
508
|
Output('instance-select', 'value'),
|
510
509
|
Output('instance-alert-div', 'children'),
|
@@ -664,22 +663,14 @@ def update_keys_options(
|
|
664
663
|
for _tag in _tags_options
|
665
664
|
]
|
666
665
|
]
|
667
|
-
_connectors_datalist = [html.Option(value=o['value']) for o in _connectors_options]
|
668
|
-
_metrics_datalist = [html.Option(value=o['value']) for o in _metrics_options]
|
669
|
-
_locations_datalist = [html.Option(value=o['value']) for o in _locations_options]
|
670
|
-
_tags_datalist = [html.Option(value=o['value']) for o in _tags_options]
|
671
666
|
return (
|
672
667
|
_connectors_options,
|
673
|
-
_connectors_datalist,
|
674
668
|
connector_keys,
|
675
669
|
_metrics_options,
|
676
|
-
_metrics_datalist,
|
677
670
|
metric_keys,
|
678
671
|
_locations_options,
|
679
|
-
_locations_datalist,
|
680
672
|
location_keys,
|
681
673
|
_tags_options,
|
682
|
-
_tags_datalist,
|
683
674
|
tags,
|
684
675
|
(instance_keys if update_instance_keys else dash.no_update),
|
685
676
|
instance_alerts,
|
@@ -856,6 +847,7 @@ dash_app.clientside_callback(
|
|
856
847
|
@dash_app.callback(
|
857
848
|
Output("download-dataframe-csv", "data"),
|
858
849
|
Input({'type': 'pipe-download-csv-button', 'index': ALL}, 'n_clicks'),
|
850
|
+
prevent_initial_call=True,
|
859
851
|
)
|
860
852
|
def download_pipe_csv(n_clicks):
|
861
853
|
"""
|
@@ -885,6 +877,7 @@ def download_pipe_csv(n_clicks):
|
|
885
877
|
Output({'type': 'pipe-accordion', 'index': MATCH}, 'children'),
|
886
878
|
Input({'type': 'pipe-accordion', 'index': MATCH}, 'active_item'),
|
887
879
|
State('session-store', 'data'),
|
880
|
+
prevent_initial_call=True,
|
888
881
|
)
|
889
882
|
def update_pipe_accordion(item, session_store_data):
|
890
883
|
"""
|
@@ -908,7 +901,8 @@ def update_pipe_accordion(item, session_store_data):
|
|
908
901
|
@dash_app.callback(
|
909
902
|
Output({'type': 'update-parameters-success-div', 'index': MATCH}, 'children'),
|
910
903
|
Input({'type': 'update-parameters-button', 'index': MATCH}, 'n_clicks'),
|
911
|
-
State({'type': 'parameters-editor', 'index': MATCH}, 'value')
|
904
|
+
State({'type': 'parameters-editor', 'index': MATCH}, 'value'),
|
905
|
+
prevent_initial_call=True,
|
912
906
|
)
|
913
907
|
def update_pipe_parameters_click(n_clicks, parameters_editor_text):
|
914
908
|
if not n_clicks:
|
@@ -942,6 +936,7 @@ def update_pipe_parameters_click(n_clicks, parameters_editor_text):
|
|
942
936
|
Output({'type': 'update-sql-success-div', 'index': MATCH}, 'children'),
|
943
937
|
Input({'type': 'update-sql-button', 'index': MATCH}, 'n_clicks'),
|
944
938
|
State({'type': 'sql-editor', 'index': MATCH}, 'value'),
|
939
|
+
prevent_initial_call=True,
|
945
940
|
)
|
946
941
|
def update_pipe_sql_click(n_clicks, sql_editor_text):
|
947
942
|
if not n_clicks:
|
@@ -968,7 +963,8 @@ def update_pipe_sql_click(n_clicks, sql_editor_text):
|
|
968
963
|
@dash_app.callback(
|
969
964
|
Output({'type': 'sync-success-div', 'index': MATCH}, 'children'),
|
970
965
|
Input({'type': 'update-sync-button', 'index': MATCH}, 'n_clicks'),
|
971
|
-
State({'type': 'sync-editor', 'index': MATCH}, 'value')
|
966
|
+
State({'type': 'sync-editor', 'index': MATCH}, 'value'),
|
967
|
+
prevent_initial_call=True,
|
972
968
|
)
|
973
969
|
def sync_documents_click(n_clicks, sync_editor_text):
|
974
970
|
if not n_clicks:
|
@@ -1014,6 +1010,7 @@ def sync_documents_click(n_clicks, sync_editor_text):
|
|
1014
1010
|
State({'type': 'limit-input', 'index': MATCH}, 'value'),
|
1015
1011
|
State({'type': 'query-data-begin-input', 'index': MATCH}, 'value'),
|
1016
1012
|
State({'type': 'query-data-end-input', 'index': MATCH}, 'value'),
|
1013
|
+
prevent_initial_call=True,
|
1017
1014
|
)
|
1018
1015
|
def query_data_click(n_clicks, query_editor_text, limit_value, begin, end):
|
1019
1016
|
triggered = dash.callback_context.triggered
|
@@ -1130,6 +1127,7 @@ def toggle_navbar_collapse(n_clicks: Optional[int], is_open: bool) -> bool:
|
|
1130
1127
|
Output('session-store', 'data'),
|
1131
1128
|
Input("sign-out-button", "n_clicks"),
|
1132
1129
|
State('session-store', 'data'),
|
1130
|
+
prevent_initial_call=True,
|
1133
1131
|
)
|
1134
1132
|
def sign_out_button_click(
|
1135
1133
|
n_clicks: Optional[int],
|
@@ -1150,6 +1148,7 @@ def sign_out_button_click(
|
|
1150
1148
|
Output({'type': 'parameters-editor', 'index': MATCH}, 'value'),
|
1151
1149
|
Input({'type': 'parameters-as-yaml-button', 'index': MATCH}, 'n_clicks'),
|
1152
1150
|
Input({'type': 'parameters-as-json-button', 'index': MATCH}, 'n_clicks'),
|
1151
|
+
prevent_initial_call=True,
|
1153
1152
|
)
|
1154
1153
|
def parameters_as_yaml_or_json_click(
|
1155
1154
|
yaml_n_clicks: Optional[int],
|
@@ -1178,6 +1177,7 @@ def parameters_as_yaml_or_json_click(
|
|
1178
1177
|
Output({'type': 'sync-editor', 'index': MATCH}, 'value'),
|
1179
1178
|
Input({'type': 'sync-as-json-button', 'index': MATCH}, 'n_clicks'),
|
1180
1179
|
Input({'type': 'sync-as-lines-button', 'index': MATCH}, 'n_clicks'),
|
1180
|
+
prevent_initial_call=True,
|
1181
1181
|
)
|
1182
1182
|
def sync_as_json_or_lines_click(
|
1183
1183
|
json_n_clicks: Optional[int],
|
@@ -1206,6 +1206,7 @@ def sync_as_json_or_lines_click(
|
|
1206
1206
|
Output('pages-offcanvas', 'children'),
|
1207
1207
|
Input('logo-img', 'n_clicks'),
|
1208
1208
|
State('pages-offcanvas', 'is_open'),
|
1209
|
+
prevent_initial_call=True,
|
1209
1210
|
)
|
1210
1211
|
def toggle_pages_offcanvas(n_clicks: Optional[int], is_open: bool):
|
1211
1212
|
"""
|
@@ -13,12 +13,13 @@ import time
|
|
13
13
|
import traceback
|
14
14
|
from datetime import datetime, timezone
|
15
15
|
|
16
|
+
from meerschaum.jobs import get_jobs
|
16
17
|
from meerschaum.utils.typing import Optional, Dict, Any
|
17
18
|
from meerschaum.api import CHECK_UPDATE
|
18
19
|
from meerschaum.api.dash import dash_app
|
19
20
|
from meerschaum.api.dash.sessions import get_username_from_session
|
20
21
|
from meerschaum.utils.packages import attempt_import, import_dcc, import_html
|
21
|
-
from meerschaum.api.dash.components import alert_from_success_tuple
|
22
|
+
from meerschaum.api.dash.components import alert_from_success_tuple, build_cards_grid
|
22
23
|
from meerschaum.api.dash.jobs import (
|
23
24
|
build_job_card,
|
24
25
|
build_manage_job_buttons_div_children,
|
@@ -251,17 +252,22 @@ def render_job_page_from_url(
|
|
251
252
|
session_data: Optional[Dict[str, Any]],
|
252
253
|
):
|
253
254
|
"""
|
254
|
-
Load the `/
|
255
|
+
Load the `/dash/jobs/{name}` page.
|
255
256
|
"""
|
256
|
-
if not str(pathname).startswith('/dash/
|
257
|
+
if not str(pathname).startswith('/dash/jobs'):
|
257
258
|
return no_update
|
258
259
|
|
259
260
|
session_id = (session_data or {}).get('session-id', None)
|
260
261
|
authenticated = is_session_authenticated(str(session_id))
|
261
262
|
|
262
|
-
job_name = pathname.replace('/dash/
|
263
|
+
job_name = pathname.replace('/dash/jobs', '').lstrip('/').rstrip('/')
|
263
264
|
if not job_name:
|
264
|
-
|
265
|
+
jobs = get_jobs(executor_keys='local', combine_local_and_systemd=True)
|
266
|
+
cards = [
|
267
|
+
build_job_card(job, authenticated=authenticated, include_follow=False)
|
268
|
+
for job in jobs.values()
|
269
|
+
]
|
270
|
+
return [html.Br(), build_cards_grid(cards, 3), html.Br()]
|
265
271
|
|
266
272
|
job = _get_job(job_name)
|
267
273
|
if not job.exists():
|
@@ -9,11 +9,17 @@ from urllib.parse import parse_qs
|
|
9
9
|
|
10
10
|
from dash.dependencies import Input, Output, State
|
11
11
|
from dash import no_update
|
12
|
+
from dash.exceptions import PreventUpdate
|
12
13
|
|
13
14
|
import meerschaum as mrsm
|
14
15
|
from meerschaum.api.dash import dash_app
|
15
|
-
from meerschaum.api.dash.
|
16
|
-
from meerschaum.api import
|
16
|
+
from meerschaum.api.dash.components import alert_from_success_tuple, build_cards_grid
|
17
|
+
from meerschaum.api.dash.pipes import (
|
18
|
+
build_pipe_card,
|
19
|
+
build_pipes_dropdown_keys_row,
|
20
|
+
build_pipes_tags_dropdown,
|
21
|
+
)
|
22
|
+
from meerschaum.api import CHECK_UPDATE, get_api_connector
|
17
23
|
from meerschaum.utils.packages import import_html, import_dcc
|
18
24
|
from meerschaum.api.dash.sessions import is_session_authenticated
|
19
25
|
from meerschaum.utils.typing import Optional, Dict, Any
|
@@ -36,16 +42,74 @@ def render_pipe_page_from_url(
|
|
36
42
|
|
37
43
|
session_id = (session_data or {}).get('session-id', None)
|
38
44
|
authenticated = is_session_authenticated(str(session_id))
|
45
|
+
query_params = parse_qs(pipe_search.lstrip('?')) if pipe_search else {}
|
46
|
+
instance = query_params.get('instance', [None])[0] or str(get_api_connector())
|
47
|
+
tags = query_params.get('tags', [None])[0] or []
|
48
|
+
if isinstance(tags, str):
|
49
|
+
tags = tags.split(',')
|
50
|
+
|
51
|
+
connector_keys = query_params.get('connector_keys', [None])[0] or []
|
52
|
+
if isinstance(connector_keys, str):
|
53
|
+
connector_keys = connector_keys.split(',')
|
54
|
+
|
55
|
+
metric_keys = query_params.get('metric_keys', [None])[0] or []
|
56
|
+
if isinstance(metric_keys, str):
|
57
|
+
metric_keys = metric_keys.split(',')
|
58
|
+
|
59
|
+
location_keys = query_params.get('location_keys', [None])[0] or []
|
60
|
+
if isinstance(location_keys, str):
|
61
|
+
location_keys = location_keys.split(',')
|
62
|
+
|
63
|
+
instance_connector = mrsm.get_connector(instance)
|
64
|
+
if instance_connector is None:
|
65
|
+
return [
|
66
|
+
html.Br(),
|
67
|
+
alert_from_success_tuple((False, f"Invalid instance keys '{instance}'.")),
|
68
|
+
html.Br(),
|
69
|
+
]
|
39
70
|
|
40
71
|
keys = pathname.replace('/dash/pipes', '').lstrip('/').rstrip('/').split('/')
|
41
72
|
if len(keys) not in (2, 3):
|
42
|
-
|
73
|
+
pipes = mrsm.get_pipes(
|
74
|
+
as_list=True,
|
75
|
+
connector_keys=connector_keys,
|
76
|
+
metric_keys=metric_keys,
|
77
|
+
location_keys=location_keys,
|
78
|
+
tags=tags,
|
79
|
+
instance=instance_connector,
|
80
|
+
)
|
81
|
+
cards = [
|
82
|
+
build_pipe_card(pipe, authenticated=authenticated, include_manage=False)
|
83
|
+
for pipe in pipes
|
84
|
+
]
|
85
|
+
return [
|
86
|
+
html.Div([
|
87
|
+
html.Br(),
|
88
|
+
build_pipes_dropdown_keys_row(
|
89
|
+
connector_keys,
|
90
|
+
metric_keys,
|
91
|
+
location_keys,
|
92
|
+
tags,
|
93
|
+
pipes,
|
94
|
+
instance_connector,
|
95
|
+
),
|
96
|
+
html.Br(),
|
97
|
+
build_pipes_tags_dropdown(
|
98
|
+
connector_keys,
|
99
|
+
metric_keys,
|
100
|
+
location_keys,
|
101
|
+
tags,
|
102
|
+
instance,
|
103
|
+
),
|
104
|
+
]),
|
105
|
+
html.Br(),
|
106
|
+
build_cards_grid(cards, 1),
|
107
|
+
html.Br(),
|
108
|
+
]
|
43
109
|
|
44
110
|
ck = keys[0]
|
45
111
|
mk = keys[1]
|
46
112
|
lk = keys[2] if len(keys) == 3 else None
|
47
|
-
query_params = parse_qs(pipe_search.lstrip('?')) if pipe_search else {}
|
48
|
-
instance = query_params.get('instance', [None])[0]
|
49
113
|
|
50
114
|
pipe = mrsm.Pipe(ck, mk, lk, instance=instance)
|
51
115
|
return [
|
@@ -53,3 +117,40 @@ def render_pipe_page_from_url(
|
|
53
117
|
build_pipe_card(pipe, authenticated=authenticated, include_manage=False),
|
54
118
|
html.Br(),
|
55
119
|
]
|
120
|
+
|
121
|
+
|
122
|
+
@dash_app.callback(
|
123
|
+
Output('pipes-location', 'search'),
|
124
|
+
Input('pipes-connector-keys-dropdown', 'value'),
|
125
|
+
Input('pipes-metric-keys-dropdown', 'value'),
|
126
|
+
Input('pipes-location-keys-dropdown', 'value'),
|
127
|
+
Input('pipes-tags-dropdown', 'value'),
|
128
|
+
)
|
129
|
+
def update_location_on_pipes_filter_change(connector_keys, metric_keys, location_keys, tags):
|
130
|
+
"""
|
131
|
+
Update the URL parameters when clicking the dropdowns.
|
132
|
+
"""
|
133
|
+
if not any((connector_keys or []) + (metric_keys or []) + (location_keys or []) + (tags or [])):
|
134
|
+
return ''
|
135
|
+
|
136
|
+
search_str = "?"
|
137
|
+
|
138
|
+
if connector_keys:
|
139
|
+
search_str += "connector_keys=" + ','.join(connector_keys)
|
140
|
+
if metric_keys or location_keys or tags:
|
141
|
+
search_str += '&'
|
142
|
+
|
143
|
+
if metric_keys:
|
144
|
+
search_str += "metric_keys=" + ','.join(metric_keys)
|
145
|
+
if location_keys or tags:
|
146
|
+
search_str += '&'
|
147
|
+
|
148
|
+
if location_keys:
|
149
|
+
search_str += "location_keys=" + ','.join(location_keys)
|
150
|
+
if tags:
|
151
|
+
search_str += '&'
|
152
|
+
|
153
|
+
if tags:
|
154
|
+
search_str += "tags=" + ','.join(tags)
|
155
|
+
|
156
|
+
return search_str
|
@@ -163,7 +163,7 @@ def register_token_click(
|
|
163
163
|
token = Token(
|
164
164
|
label=(name or None),
|
165
165
|
user=get_user_from_session(session_id),
|
166
|
-
expiration=(datetime.fromisoformat(f"{expiration}
|
166
|
+
expiration=(datetime.fromisoformat(f"{expiration}") if expiration is not None else None),
|
167
167
|
)
|
168
168
|
return False, True, build_tokens_register_output_modal(token)
|
169
169
|
|
meerschaum/api/dash/jobs.py
CHANGED
@@ -9,7 +9,8 @@ import meerschaum.api.dash.pages.error
|
|
9
9
|
import meerschaum.api.dash.pages.login
|
10
10
|
import meerschaum.api.dash.pages.dashboard
|
11
11
|
import meerschaum.api.dash.pages.plugins
|
12
|
+
import meerschaum.api.dash.pages.tokens
|
12
13
|
import meerschaum.api.dash.pages.register
|
13
14
|
import meerschaum.api.dash.pages.pipes
|
14
|
-
import meerschaum.api.dash.pages.
|
15
|
+
import meerschaum.api.dash.pages.jobs
|
15
16
|
import meerschaum.api.dash.pages.settings
|
@@ -11,11 +11,14 @@ from meerschaum.utils.packages import import_html, import_dcc
|
|
11
11
|
html, dcc = import_html(check_update=CHECK_UPDATE), import_dcc(check_update=CHECK_UPDATE)
|
12
12
|
import dash_bootstrap_components as dbc
|
13
13
|
|
14
|
-
from meerschaum.api.dash.components import download_logs, refresh_jobs_interval
|
14
|
+
from meerschaum.api.dash.components import download_logs, refresh_jobs_interval, pages_navbar
|
15
15
|
|
16
|
-
layout =
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
16
|
+
layout = [
|
17
|
+
pages_navbar,
|
18
|
+
dbc.Container([
|
19
|
+
dcc.Location('job-location'),
|
20
|
+
html.Div(id='job-output-div'),
|
21
|
+
download_logs,
|
22
|
+
refresh_jobs_interval,
|
23
|
+
]),
|
24
|
+
]
|
@@ -7,16 +7,17 @@ Display pipes via a shareable URL.
|
|
7
7
|
|
8
8
|
from meerschaum.api import CHECK_UPDATE
|
9
9
|
from meerschaum.utils.packages import import_html, import_dcc
|
10
|
-
from meerschaum.api.dash.components import download_dataframe, pages_navbar
|
10
|
+
from meerschaum.api.dash.components import download_dataframe, pages_navbar, navbar
|
11
11
|
|
12
12
|
html, dcc = import_html(check_update=CHECK_UPDATE), import_dcc(check_update=CHECK_UPDATE)
|
13
13
|
import dash_bootstrap_components as dbc
|
14
14
|
|
15
|
+
|
15
16
|
layout = [
|
16
17
|
pages_navbar,
|
18
|
+
dcc.Location('pipes-location'),
|
19
|
+
download_dataframe,
|
17
20
|
dbc.Container([
|
18
|
-
dcc.Location('pipes-location'),
|
19
|
-
download_dataframe,
|
20
21
|
html.Div(id='pipe-output-div'),
|
21
22
|
])
|
22
23
|
]
|
@@ -8,16 +8,13 @@ Define the tokens page layout.
|
|
8
8
|
import dash_bootstrap_components as dbc
|
9
9
|
import dash.html as html
|
10
10
|
import dash.dcc as dcc
|
11
|
-
from meerschaum.plugins import web_page
|
12
11
|
from meerschaum._internal.static import STATIC_CONFIG
|
12
|
+
from meerschaum.api.dash.components import pages_navbar
|
13
13
|
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
Return the layout for the tokens page.
|
19
|
-
"""
|
20
|
-
return dbc.Container([
|
15
|
+
layout = [
|
16
|
+
pages_navbar,
|
17
|
+
dbc.Container([
|
21
18
|
html.Br(),
|
22
19
|
html.H3('Tokens'),
|
23
20
|
html.Div(id="tokens-alert-div"),
|
@@ -52,4 +49,5 @@ def page_layout():
|
|
52
49
|
style={'text-align': 'right'},
|
53
50
|
),
|
54
51
|
html.Div(id='tokens-output-div'),
|
55
|
-
])
|
52
|
+
]),
|
53
|
+
]
|
meerschaum/api/dash/pipes.py
CHANGED
@@ -12,6 +12,7 @@ import shlex
|
|
12
12
|
from textwrap import dedent
|
13
13
|
from urllib.parse import urlencode
|
14
14
|
|
15
|
+
from meerschaum.utils import fetch_pipes_keys
|
15
16
|
from meerschaum.utils.typing import List, Optional, Dict, Any, Tuple, Union
|
16
17
|
from meerschaum.utils.misc import string_to_dict
|
17
18
|
from meerschaum.utils.packages import attempt_import, import_dcc, import_html, import_pandas
|
@@ -817,3 +818,133 @@ def get_backtrack_text(
|
|
817
818
|
json_text = '[]'
|
818
819
|
|
819
820
|
return json.dumps(json.loads(json_text), indent=4, separators=(',', ': '))
|
821
|
+
|
822
|
+
|
823
|
+
def build_pipes_dropdown_keys_row(
|
824
|
+
connector_keys: List[str],
|
825
|
+
metric_keys: List[str],
|
826
|
+
location_keys: List[str],
|
827
|
+
tags: List[str],
|
828
|
+
pipes: List[mrsm.Pipe],
|
829
|
+
instance_connector: mrsm.connectors.InstanceConnector,
|
830
|
+
) -> dbc.Row:
|
831
|
+
"""
|
832
|
+
Return the dropdown keys row for the dedicated pipes page.
|
833
|
+
"""
|
834
|
+
ck_alone = connector_keys and not any([str(x) for x in (tags + metric_keys + location_keys)])
|
835
|
+
mk_alone = metric_keys and not any([str(x) for x in (connector_keys + tags + location_keys)])
|
836
|
+
lk_alone = location_keys and not any([str(x) for x in (connector_keys + metric_keys + tags)])
|
837
|
+
all_keys = fetch_pipes_keys('registered', instance_connector)
|
838
|
+
return dbc.Row(
|
839
|
+
[
|
840
|
+
dbc.Col(
|
841
|
+
html.Div(
|
842
|
+
[
|
843
|
+
dcc.Dropdown(
|
844
|
+
id='pipes-connector-keys-dropdown',
|
845
|
+
options=(
|
846
|
+
sorted(list({pipe.connector_keys for pipe in pipes}))
|
847
|
+
if not ck_alone
|
848
|
+
else sorted(list({ck for ck, _, _ in all_keys}))
|
849
|
+
),
|
850
|
+
value=[str(ck) for ck in connector_keys],
|
851
|
+
placeholder='Connectors',
|
852
|
+
multi=True,
|
853
|
+
),
|
854
|
+
],
|
855
|
+
className='dbc_dark',
|
856
|
+
),
|
857
|
+
lg=4,
|
858
|
+
md=12,
|
859
|
+
sm=12,
|
860
|
+
),
|
861
|
+
dbc.Col(
|
862
|
+
html.Div(
|
863
|
+
[
|
864
|
+
dcc.Dropdown(
|
865
|
+
id='pipes-metric-keys-dropdown',
|
866
|
+
options=(
|
867
|
+
sorted(list({pipe.metric_key for pipe in pipes}))
|
868
|
+
if not mk_alone
|
869
|
+
else sorted(list({mk for _, mk, _ in all_keys}))
|
870
|
+
),
|
871
|
+
value=[str(mk) for mk in metric_keys],
|
872
|
+
placeholder='Metrics',
|
873
|
+
multi=True,
|
874
|
+
),
|
875
|
+
],
|
876
|
+
className='dbc_dark'
|
877
|
+
),
|
878
|
+
lg=4,
|
879
|
+
md=12,
|
880
|
+
sm=12,
|
881
|
+
),
|
882
|
+
dbc.Col(
|
883
|
+
html.Div(
|
884
|
+
[
|
885
|
+
dcc.Dropdown(
|
886
|
+
id='pipes-location-keys-dropdown',
|
887
|
+
options=(
|
888
|
+
sorted(list({str(pipe.location_key) for pipe in pipes}))
|
889
|
+
if not lk_alone
|
890
|
+
else sorted(list({str(lk) for _, _, lk in all_keys}))
|
891
|
+
),
|
892
|
+
value=[str(lk) for lk in location_keys],
|
893
|
+
placeholder='Locations',
|
894
|
+
multi=True,
|
895
|
+
),
|
896
|
+
],
|
897
|
+
className='dbc_dark'
|
898
|
+
),
|
899
|
+
lg=4,
|
900
|
+
md=12,
|
901
|
+
sm=12,
|
902
|
+
),
|
903
|
+
] ### end of filters row children
|
904
|
+
)
|
905
|
+
|
906
|
+
|
907
|
+
def build_pipes_tags_dropdown(
|
908
|
+
connector_keys: List[str],
|
909
|
+
metric_keys: List[str],
|
910
|
+
location_keys: List[str],
|
911
|
+
tags: List[str],
|
912
|
+
instance: str,
|
913
|
+
) -> html.Div:
|
914
|
+
"""
|
915
|
+
Build the tags dropdown for the dedicated pipes page.
|
916
|
+
"""
|
917
|
+
_tags_alone = tags and not any([str(x) for x in (connector_keys + metric_keys + location_keys)])
|
918
|
+
_tags_pipes = mrsm.get_pipes(
|
919
|
+
connector_keys=connector_keys,
|
920
|
+
metric_keys=metric_keys,
|
921
|
+
location_keys=location_keys,
|
922
|
+
tags=tags,
|
923
|
+
instance=instance,
|
924
|
+
as_tags_dict=True,
|
925
|
+
)
|
926
|
+
|
927
|
+
_all_tags = list(
|
928
|
+
mrsm.get_pipes(
|
929
|
+
instance=instance,
|
930
|
+
as_tags_dict=True,
|
931
|
+
)
|
932
|
+
) if _tags_alone else []
|
933
|
+
|
934
|
+
tags_options = [
|
935
|
+
str(tag)
|
936
|
+
for tag in (_all_tags if _tags_alone else _tags_pipes)
|
937
|
+
]
|
938
|
+
|
939
|
+
return html.Div(
|
940
|
+
dcc.Dropdown(
|
941
|
+
id='pipes-tags-dropdown',
|
942
|
+
options=tags_options,
|
943
|
+
value=tags,
|
944
|
+
placeholder='Tags',
|
945
|
+
multi=True,
|
946
|
+
searchable=True,
|
947
|
+
),
|
948
|
+
className="dbc_dark",
|
949
|
+
id="pipes-tags-dropdown-div",
|
950
|
+
)
|