meerschaum 3.0.0rc2__py3-none-any.whl → 3.0.0rc4__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/_events.py +5 -0
- meerschaum/api/dash/callbacks/__init__.py +1 -0
- meerschaum/api/dash/callbacks/dashboard.py +93 -115
- meerschaum/api/dash/callbacks/jobs.py +11 -5
- meerschaum/api/dash/callbacks/pipes.py +194 -14
- meerschaum/api/dash/callbacks/settings/__init__.py +0 -1
- meerschaum/api/dash/callbacks/{settings/tokens.py → tokens.py} +3 -2
- meerschaum/api/dash/components.py +6 -7
- meerschaum/api/dash/jobs.py +1 -1
- meerschaum/api/dash/keys.py +17 -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 +16 -5
- 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 +219 -3
- meerschaum/api/dash/tokens.py +27 -30
- 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 +63 -23
- meerschaum/connectors/sql/tables/__init__.py +254 -122
- meerschaum/core/Pipe/__init__.py +17 -1
- 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 +31 -5
- meerschaum/utils/dataframe.py +8 -2
- meerschaum/utils/dtypes/__init__.py +2 -3
- meerschaum/utils/dtypes/sql.py +11 -11
- meerschaum/utils/formatting/_pprint.py +1 -0
- meerschaum/utils/pipes.py +6 -2
- meerschaum/utils/sql.py +1 -1
- {meerschaum-3.0.0rc2.dist-info → meerschaum-3.0.0rc4.dist-info}/METADATA +1 -1
- {meerschaum-3.0.0rc2.dist-info → meerschaum-3.0.0rc4.dist-info}/RECORD +47 -47
- {meerschaum-3.0.0rc2.dist-info → meerschaum-3.0.0rc4.dist-info}/WHEEL +0 -0
- {meerschaum-3.0.0rc2.dist-info → meerschaum-3.0.0rc4.dist-info}/entry_points.txt +0 -0
- {meerschaum-3.0.0rc2.dist-info → meerschaum-3.0.0rc4.dist-info}/licenses/LICENSE +0 -0
- {meerschaum-3.0.0rc2.dist-info → meerschaum-3.0.0rc4.dist-info}/licenses/NOTICE +0 -0
- {meerschaum-3.0.0rc2.dist-info → meerschaum-3.0.0rc4.dist-info}/top_level.txt +0 -0
- {meerschaum-3.0.0rc2.dist-info → meerschaum-3.0.0rc4.dist-info}/zip-safe +0 -0
@@ -5,22 +5,35 @@
|
|
5
5
|
Define callbacks for the `/dash/pipes/` page.
|
6
6
|
"""
|
7
7
|
|
8
|
-
from urllib.parse import parse_qs
|
8
|
+
from urllib.parse import parse_qs, quote_plus
|
9
|
+
from typing import List, Optional, Dict, Any
|
9
10
|
|
11
|
+
import dash
|
10
12
|
from dash.dependencies import Input, Output, State
|
11
13
|
from dash import no_update
|
14
|
+
from dash.exceptions import PreventUpdate
|
15
|
+
import dash_bootstrap_components as dbc
|
12
16
|
|
13
17
|
import meerschaum as mrsm
|
14
18
|
from meerschaum.api.dash import dash_app
|
15
|
-
from meerschaum.api.dash.
|
16
|
-
|
19
|
+
from meerschaum.api.dash.components import (
|
20
|
+
alert_from_success_tuple,
|
21
|
+
build_cards_grid,
|
22
|
+
)
|
23
|
+
from meerschaum.api.dash.pipes import (
|
24
|
+
build_pipe_card,
|
25
|
+
build_pipes_dropdown_keys_row,
|
26
|
+
build_pipes_tags_dropdown,
|
27
|
+
build_pipes_navbar,
|
28
|
+
)
|
29
|
+
from meerschaum.api import CHECK_UPDATE, get_api_connector
|
17
30
|
from meerschaum.utils.packages import import_html, import_dcc
|
18
31
|
from meerschaum.api.dash.sessions import is_session_authenticated
|
19
|
-
from meerschaum.utils.typing import Optional, Dict, Any
|
20
32
|
html, dcc = import_html(check_update=CHECK_UPDATE), import_dcc(check_update=CHECK_UPDATE)
|
21
33
|
|
22
34
|
|
23
35
|
@dash_app.callback(
|
36
|
+
Output('pipes-navbar-div', 'children'),
|
24
37
|
Output('pipe-output-div', 'children'),
|
25
38
|
Input('pipes-location', 'pathname'),
|
26
39
|
State('pipes-location', 'search'),
|
@@ -32,24 +45,191 @@ def render_pipe_page_from_url(
|
|
32
45
|
session_data: Optional[Dict[str, Any]],
|
33
46
|
):
|
34
47
|
if not str(pathname).startswith('/dash/pipes'):
|
35
|
-
|
48
|
+
raise PreventUpdate
|
36
49
|
|
37
50
|
session_id = (session_data or {}).get('session-id', None)
|
38
51
|
authenticated = is_session_authenticated(str(session_id))
|
52
|
+
query_params = parse_qs(pipe_search.lstrip('?')) if pipe_search else {}
|
53
|
+
instance = query_params.get('instance', [None])[0] or str(get_api_connector())
|
54
|
+
tags = query_params.get('tags', [None])[0] or []
|
55
|
+
if isinstance(tags, str):
|
56
|
+
tags = tags.split(',')
|
57
|
+
|
58
|
+
connector_keys = query_params.get('connector_keys', [None])[0] or []
|
59
|
+
if isinstance(connector_keys, str):
|
60
|
+
connector_keys = connector_keys.split(',')
|
61
|
+
|
62
|
+
metric_keys = query_params.get('metric_keys', [None])[0] or []
|
63
|
+
if isinstance(metric_keys, str):
|
64
|
+
metric_keys = metric_keys.split(',')
|
65
|
+
|
66
|
+
location_keys = query_params.get('location_keys', [None])[0] or []
|
67
|
+
if isinstance(location_keys, str):
|
68
|
+
location_keys = location_keys.split(',')
|
39
69
|
|
40
70
|
keys = pathname.replace('/dash/pipes', '').lstrip('/').rstrip('/').split('/')
|
41
|
-
|
42
|
-
|
71
|
+
instance_connector = mrsm.get_connector(instance)
|
72
|
+
viewing_single_pipe = len(keys) in (2, 3)
|
73
|
+
if instance_connector is None:
|
74
|
+
return (
|
75
|
+
build_pipes_navbar(instance, with_instance_select=(not viewing_single_pipe)),
|
76
|
+
[
|
77
|
+
html.Br(),
|
78
|
+
alert_from_success_tuple((False, f"Invalid instance keys '{instance}'.")),
|
79
|
+
html.Br(),
|
80
|
+
]
|
81
|
+
)
|
82
|
+
|
83
|
+
if not viewing_single_pipe:
|
84
|
+
try:
|
85
|
+
pipes = mrsm.get_pipes(
|
86
|
+
as_list=True,
|
87
|
+
connector_keys=connector_keys,
|
88
|
+
metric_keys=metric_keys,
|
89
|
+
location_keys=location_keys,
|
90
|
+
tags=tags,
|
91
|
+
instance=instance_connector,
|
92
|
+
)
|
93
|
+
except Exception as e:
|
94
|
+
return (
|
95
|
+
build_pipes_navbar(instance, with_instance_select=False),
|
96
|
+
[
|
97
|
+
html.Br(),
|
98
|
+
alert_from_success_tuple(
|
99
|
+
(False, f"Failed to get pipes for instance '{instance}':\n{e}")
|
100
|
+
),
|
101
|
+
html.Br(),
|
102
|
+
dbc.Row(
|
103
|
+
[
|
104
|
+
dbc.Button(
|
105
|
+
"Reload",
|
106
|
+
id='pipes-reload-button',
|
107
|
+
size='lg',
|
108
|
+
href=(
|
109
|
+
"/dash/pipes"
|
110
|
+
if pathname.startswith('/dash/pipes/')
|
111
|
+
else "/dash/pipes/"
|
112
|
+
)
|
113
|
+
),
|
114
|
+
],
|
115
|
+
justify='center',
|
116
|
+
align='center',
|
117
|
+
className='h-50',
|
118
|
+
),
|
119
|
+
]
|
120
|
+
)
|
121
|
+
|
122
|
+
cards = [
|
123
|
+
build_pipe_card(pipe, authenticated=authenticated, include_manage=False)
|
124
|
+
for pipe in pipes
|
125
|
+
]
|
126
|
+
return (
|
127
|
+
build_pipes_navbar(instance, with_instance_select=True),
|
128
|
+
[
|
129
|
+
html.Div([
|
130
|
+
html.Br(),
|
131
|
+
build_pipes_dropdown_keys_row(
|
132
|
+
connector_keys,
|
133
|
+
metric_keys,
|
134
|
+
location_keys,
|
135
|
+
tags,
|
136
|
+
pipes,
|
137
|
+
instance_connector,
|
138
|
+
),
|
139
|
+
html.Br(),
|
140
|
+
build_pipes_tags_dropdown(
|
141
|
+
connector_keys,
|
142
|
+
metric_keys,
|
143
|
+
location_keys,
|
144
|
+
tags,
|
145
|
+
instance,
|
146
|
+
),
|
147
|
+
]),
|
148
|
+
html.Br(),
|
149
|
+
build_cards_grid(cards, 1),
|
150
|
+
html.Br(),
|
151
|
+
]
|
152
|
+
)
|
43
153
|
|
44
154
|
ck = keys[0]
|
45
155
|
mk = keys[1]
|
46
156
|
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
157
|
|
50
158
|
pipe = mrsm.Pipe(ck, mk, lk, instance=instance)
|
51
|
-
return
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
159
|
+
return (
|
160
|
+
build_pipes_navbar(instance, with_instance_select=False),
|
161
|
+
[
|
162
|
+
html.Br(),
|
163
|
+
build_pipe_card(pipe, authenticated=authenticated, include_manage=False),
|
164
|
+
html.Br(),
|
165
|
+
]
|
166
|
+
)
|
167
|
+
|
168
|
+
|
169
|
+
@dash_app.callback(
|
170
|
+
Output('pipes-location', 'search'),
|
171
|
+
Input('pipes-connector-keys-dropdown', 'value'),
|
172
|
+
Input('pipes-metric-keys-dropdown', 'value'),
|
173
|
+
Input('pipes-location-keys-dropdown', 'value'),
|
174
|
+
Input('pipes-tags-dropdown', 'value'),
|
175
|
+
Input('instance-select', 'value'),
|
176
|
+
Input('pipes-clear-all-button', 'n_clicks'),
|
177
|
+
)
|
178
|
+
def update_location_on_pipes_filter_change(
|
179
|
+
connector_keys: Optional[List[str]],
|
180
|
+
metric_keys: Optional[List[str]],
|
181
|
+
location_keys: Optional[List[str]],
|
182
|
+
tags: Optional[List[str]],
|
183
|
+
instance_keys: str,
|
184
|
+
clear_all_button_n_clicks: Optional[int],
|
185
|
+
):
|
186
|
+
"""
|
187
|
+
Update the URL parameters when clicking the dropdowns.
|
188
|
+
"""
|
189
|
+
ctx = dash.callback_context.triggered
|
190
|
+
if len(ctx) != 1:
|
191
|
+
raise PreventUpdate
|
192
|
+
|
193
|
+
if not any(
|
194
|
+
(connector_keys or [])
|
195
|
+
+ (metric_keys or [])
|
196
|
+
+ (location_keys or [])
|
197
|
+
+ (tags or [])
|
198
|
+
+ ([instance_keys] if instance_keys else [])
|
199
|
+
):
|
200
|
+
return ''
|
201
|
+
|
202
|
+
if ctx[0].get('prop_id', None) == 'pipes-clear-all-button.n_clicks':
|
203
|
+
connector_keys = []
|
204
|
+
metric_keys = []
|
205
|
+
location_keys = []
|
206
|
+
tags = []
|
207
|
+
|
208
|
+
include_instance_keys = instance_keys and instance_keys != str(get_api_connector())
|
209
|
+
search_str = ""
|
210
|
+
|
211
|
+
if connector_keys:
|
212
|
+
search_str += "connector_keys=" + ','.join((quote_plus(ck) for ck in connector_keys))
|
213
|
+
if metric_keys or location_keys or tags or include_instance_keys:
|
214
|
+
search_str += '&'
|
215
|
+
|
216
|
+
if metric_keys:
|
217
|
+
search_str += "metric_keys=" + ','.join((quote_plus(mk) for mk in metric_keys))
|
218
|
+
if location_keys or tags or include_instance_keys:
|
219
|
+
search_str += '&'
|
220
|
+
|
221
|
+
if location_keys:
|
222
|
+
search_str += "location_keys=" + ','.join((quote_plus(str(lk)) for lk in location_keys))
|
223
|
+
if tags or include_instance_keys:
|
224
|
+
search_str += '&'
|
225
|
+
|
226
|
+
if tags:
|
227
|
+
search_str += "tags=" + ','.join((quote_plus(tag) for tag in tags))
|
228
|
+
if include_instance_keys:
|
229
|
+
search_str += '&'
|
230
|
+
|
231
|
+
if instance_keys:
|
232
|
+
if include_instance_keys:
|
233
|
+
search_str += "instance=" + quote_plus(instance_keys)
|
234
|
+
|
235
|
+
return ('?' + search_str) if search_str else ''
|
@@ -54,7 +54,8 @@ def refresh_tokens_button_click(
|
|
54
54
|
html.H4('No tokens registered.'),
|
55
55
|
html.P('Click the `+` button to register a new token.'),
|
56
56
|
],
|
57
|
-
|
57
|
+
build_tokens_register_input_modal(),
|
58
|
+
alerts,
|
58
59
|
)
|
59
60
|
|
60
61
|
return tokens_table, build_tokens_register_input_modal(), alerts
|
@@ -163,7 +164,7 @@ def register_token_click(
|
|
163
164
|
token = Token(
|
164
165
|
label=(name or None),
|
165
166
|
user=get_user_from_session(session_id),
|
166
|
-
expiration=(datetime.fromisoformat(f"{expiration}
|
167
|
+
expiration=(datetime.fromisoformat(f"{expiration}") if expiration is not None else None),
|
167
168
|
)
|
168
169
|
return False, True, build_tokens_register_output_modal(token)
|
169
170
|
|
@@ -13,7 +13,7 @@ from meerschaum.utils.typing import SuccessTuple, List
|
|
13
13
|
from meerschaum._internal.static import STATIC_CONFIG
|
14
14
|
from meerschaum.utils.misc import remove_ansi
|
15
15
|
from meerschaum._internal.shell.Shell import get_shell_intro
|
16
|
-
from meerschaum.api import endpoints, CHECK_UPDATE, docs_enabled
|
16
|
+
from meerschaum.api import endpoints, CHECK_UPDATE, docs_enabled, get_api_connector
|
17
17
|
from meerschaum.connectors import instance_types, _load_builtin_custom_connectors
|
18
18
|
from meerschaum.utils.misc import get_connector_labels
|
19
19
|
from meerschaum.config import __doc__ as doc
|
@@ -104,7 +104,7 @@ instance_select = dbc.Select(
|
|
104
104
|
id='instance-select',
|
105
105
|
size='sm',
|
106
106
|
options=[
|
107
|
-
{'label': i, 'value': i}
|
107
|
+
{'label': (i[:32] + '…') if len(i) > 32 else i, 'value': i}
|
108
108
|
for i in get_connector_labels(*instance_types)
|
109
109
|
],
|
110
110
|
class_name='dbc_dark custom-select custom-select-sm',
|
@@ -163,6 +163,7 @@ pages_navbar = html.Div(
|
|
163
163
|
id='pages-navbar-div',
|
164
164
|
)
|
165
165
|
|
166
|
+
|
166
167
|
navbar = dbc.Navbar(
|
167
168
|
dbc.Container(
|
168
169
|
[
|
@@ -171,13 +172,11 @@ navbar = dbc.Navbar(
|
|
171
172
|
dbc.Collapse(
|
172
173
|
dbc.Row(
|
173
174
|
[
|
174
|
-
dbc.Col(instance_select),
|
175
|
-
dbc.Col(
|
176
|
-
sign_out_button,
|
177
|
-
className="ms-auto",
|
178
|
-
),
|
175
|
+
dbc.Col(instance_select, width="auto"),
|
176
|
+
dbc.Col(sign_out_button, width="auto"),
|
179
177
|
],
|
180
178
|
className="g-0 ms-auto flex-nowrap mt-3 mt-md-0",
|
179
|
+
align="center",
|
181
180
|
),
|
182
181
|
id='navbar-collapse',
|
183
182
|
is_open=False,
|
meerschaum/api/dash/jobs.py
CHANGED
meerschaum/api/dash/keys.py
CHANGED
@@ -227,7 +227,23 @@ dropdown_tab_content = html.Div([
|
|
227
227
|
[
|
228
228
|
dropdown_keys_row,
|
229
229
|
html.Br(),
|
230
|
-
|
230
|
+
dbc.Row(
|
231
|
+
[
|
232
|
+
dbc.Col(tags_dropdown, width=True),
|
233
|
+
dbc.Col(
|
234
|
+
dbc.Button(
|
235
|
+
"Clear all",
|
236
|
+
id='clear-all-keys-button',
|
237
|
+
color='link',
|
238
|
+
size='sm',
|
239
|
+
style={'text-decoration': 'none'},
|
240
|
+
),
|
241
|
+
width='auto',
|
242
|
+
),
|
243
|
+
],
|
244
|
+
className='g-0',
|
245
|
+
align='center',
|
246
|
+
),
|
231
247
|
], ### end of card children
|
232
248
|
className='card-text',
|
233
249
|
)
|
@@ -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,27 @@ 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
|
10
|
+
from meerschaum.api.dash.components import (
|
11
|
+
download_dataframe,
|
12
|
+
)
|
11
13
|
|
12
14
|
html, dcc = import_html(check_update=CHECK_UPDATE), import_dcc(check_update=CHECK_UPDATE)
|
13
15
|
import dash_bootstrap_components as dbc
|
14
16
|
|
15
17
|
layout = [
|
16
|
-
|
18
|
+
html.Div(id='pipes-navbar-div'),
|
19
|
+
dcc.Location('pipes-location'),
|
20
|
+
download_dataframe,
|
17
21
|
dbc.Container([
|
18
|
-
dcc.
|
19
|
-
|
20
|
-
|
22
|
+
dcc.Loading(
|
23
|
+
html.Div(id='pipe-output-div'),
|
24
|
+
id='pipes-loading',
|
25
|
+
type='circle',
|
26
|
+
delay_hide=1000,
|
27
|
+
delay_show=1000,
|
28
|
+
style={
|
29
|
+
'padding-top': '100px',
|
30
|
+
},
|
31
|
+
),
|
21
32
|
])
|
22
33
|
]
|
@@ -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,18 +12,26 @@ 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
|
-
from meerschaum.utils.misc import
|
17
|
+
from meerschaum.utils.misc import get_connector_labels
|
18
|
+
from meerschaum.connectors import instance_types
|
17
19
|
from meerschaum.utils.packages import attempt_import, import_dcc, import_html, import_pandas
|
18
20
|
from meerschaum.utils.sql import get_pd_type
|
19
21
|
from meerschaum.utils.yaml import yaml
|
20
22
|
from meerschaum.utils.warnings import warn
|
21
23
|
from meerschaum.utils.dataframe import to_json, to_simple_lines
|
22
24
|
from meerschaum.connectors.sql._fetch import get_pipe_query
|
23
|
-
from meerschaum.api import CHECK_UPDATE
|
25
|
+
from meerschaum.api import CHECK_UPDATE, get_api_connector
|
24
26
|
from meerschaum.api.dash import debug, _get_pipes
|
25
27
|
from meerschaum.api.dash.connectors import get_web_connector
|
26
|
-
from meerschaum.api.dash.components import
|
28
|
+
from meerschaum.api.dash.components import (
|
29
|
+
alert_from_success_tuple,
|
30
|
+
build_cards_grid,
|
31
|
+
sign_out_button,
|
32
|
+
logo_row,
|
33
|
+
pages_offcanvas,
|
34
|
+
)
|
27
35
|
from meerschaum.api.dash.sessions import is_session_authenticated
|
28
36
|
from meerschaum.config import get_config
|
29
37
|
import meerschaum as mrsm
|
@@ -817,3 +825,211 @@ def get_backtrack_text(
|
|
817
825
|
json_text = '[]'
|
818
826
|
|
819
827
|
return json.dumps(json.loads(json_text), indent=4, separators=(',', ': '))
|
828
|
+
|
829
|
+
|
830
|
+
def build_pipes_dropdown_keys_row(
|
831
|
+
connector_keys: List[str],
|
832
|
+
metric_keys: List[str],
|
833
|
+
location_keys: List[str],
|
834
|
+
tags: List[str],
|
835
|
+
pipes: List[mrsm.Pipe],
|
836
|
+
instance_connector: mrsm.connectors.InstanceConnector,
|
837
|
+
) -> dbc.Row:
|
838
|
+
"""
|
839
|
+
Return the dropdown keys row for the dedicated pipes page.
|
840
|
+
"""
|
841
|
+
ck_alone = connector_keys and not any([str(x) for x in (tags + metric_keys + location_keys)])
|
842
|
+
mk_alone = metric_keys and not any([str(x) for x in (connector_keys + tags + location_keys)])
|
843
|
+
lk_alone = location_keys and not any([str(x) for x in (connector_keys + metric_keys + tags)])
|
844
|
+
all_keys = fetch_pipes_keys('registered', instance_connector)
|
845
|
+
|
846
|
+
ck_options_source = (
|
847
|
+
{keys_tuple[0] for keys_tuple in all_keys}
|
848
|
+
if ck_alone
|
849
|
+
else {p.connector_keys for p in pipes}
|
850
|
+
)
|
851
|
+
ck_options = sorted(ck_options_source.union(connector_keys))
|
852
|
+
|
853
|
+
mk_options_source = (
|
854
|
+
{keys_tuple[1] for keys_tuple in all_keys}
|
855
|
+
if mk_alone
|
856
|
+
else {p.metric_key for p in pipes}
|
857
|
+
)
|
858
|
+
mk_options = sorted(mk_options_source.union(metric_keys))
|
859
|
+
|
860
|
+
lk_options_source = (
|
861
|
+
{str(keys_tuple[2]) for keys_tuple in all_keys}
|
862
|
+
if lk_alone
|
863
|
+
else {str(p.location_key) for p in pipes}
|
864
|
+
)
|
865
|
+
lk_options = sorted(lk_options_source.union({str(lk) for lk in location_keys}))
|
866
|
+
|
867
|
+
return dbc.Row(
|
868
|
+
[
|
869
|
+
dbc.Col(
|
870
|
+
html.Div(
|
871
|
+
[
|
872
|
+
dcc.Dropdown(
|
873
|
+
id='pipes-connector-keys-dropdown',
|
874
|
+
options=ck_options,
|
875
|
+
value=[str(ck) for ck in connector_keys],
|
876
|
+
placeholder='Connectors',
|
877
|
+
multi=True,
|
878
|
+
),
|
879
|
+
],
|
880
|
+
className='dbc_dark',
|
881
|
+
),
|
882
|
+
lg=4,
|
883
|
+
md=12,
|
884
|
+
sm=12,
|
885
|
+
),
|
886
|
+
dbc.Col(
|
887
|
+
html.Div(
|
888
|
+
[
|
889
|
+
dcc.Dropdown(
|
890
|
+
id='pipes-metric-keys-dropdown',
|
891
|
+
options=mk_options,
|
892
|
+
value=[str(mk) for mk in metric_keys],
|
893
|
+
placeholder='Metrics',
|
894
|
+
multi=True,
|
895
|
+
),
|
896
|
+
],
|
897
|
+
className='dbc_dark'
|
898
|
+
),
|
899
|
+
lg=4,
|
900
|
+
md=12,
|
901
|
+
sm=12,
|
902
|
+
),
|
903
|
+
dbc.Col(
|
904
|
+
html.Div(
|
905
|
+
[
|
906
|
+
dcc.Dropdown(
|
907
|
+
id='pipes-location-keys-dropdown',
|
908
|
+
options=lk_options,
|
909
|
+
value=[str(lk) for lk in location_keys],
|
910
|
+
placeholder='Locations',
|
911
|
+
multi=True,
|
912
|
+
),
|
913
|
+
],
|
914
|
+
className='dbc_dark'
|
915
|
+
),
|
916
|
+
lg=4,
|
917
|
+
md=12,
|
918
|
+
sm=12,
|
919
|
+
),
|
920
|
+
] ### end of filters row children
|
921
|
+
)
|
922
|
+
|
923
|
+
|
924
|
+
def build_pipes_tags_dropdown(
|
925
|
+
connector_keys: List[str],
|
926
|
+
metric_keys: List[str],
|
927
|
+
location_keys: List[str],
|
928
|
+
tags: List[str],
|
929
|
+
instance: str,
|
930
|
+
) -> dbc.Row:
|
931
|
+
"""
|
932
|
+
Build the tags dropdown for the dedicated pipes page.
|
933
|
+
"""
|
934
|
+
_tags_alone = tags and not any([str(x) for x in (connector_keys + metric_keys + location_keys)])
|
935
|
+
_tags_pipes = mrsm.get_pipes(
|
936
|
+
connector_keys=connector_keys,
|
937
|
+
metric_keys=metric_keys,
|
938
|
+
location_keys=location_keys,
|
939
|
+
tags=tags,
|
940
|
+
instance=instance,
|
941
|
+
as_tags_dict=True,
|
942
|
+
)
|
943
|
+
|
944
|
+
_all_tags = list(
|
945
|
+
mrsm.get_pipes(
|
946
|
+
instance=instance,
|
947
|
+
as_tags_dict=True,
|
948
|
+
)
|
949
|
+
) if _tags_alone else []
|
950
|
+
|
951
|
+
tags_options = [
|
952
|
+
str(tag)
|
953
|
+
for tag in (_all_tags if _tags_alone else _tags_pipes)
|
954
|
+
]
|
955
|
+
if tags:
|
956
|
+
tags_options += [tag for tag in tags if tag not in tags_options]
|
957
|
+
|
958
|
+
return dbc.Row(
|
959
|
+
[
|
960
|
+
dbc.Col(
|
961
|
+
html.Div(
|
962
|
+
dcc.Dropdown(
|
963
|
+
id='pipes-tags-dropdown',
|
964
|
+
options=tags_options,
|
965
|
+
value=tags,
|
966
|
+
placeholder='Tags',
|
967
|
+
multi=True,
|
968
|
+
searchable=True,
|
969
|
+
),
|
970
|
+
className="dbc_dark",
|
971
|
+
id="pipes-tags-dropdown-div",
|
972
|
+
),
|
973
|
+
width=True,
|
974
|
+
),
|
975
|
+
dbc.Col(
|
976
|
+
dbc.Button(
|
977
|
+
"Clear all",
|
978
|
+
color='link',
|
979
|
+
size='sm',
|
980
|
+
style={'text-decoration': 'none'},
|
981
|
+
id='pipes-clear-all-button',
|
982
|
+
),
|
983
|
+
width='auto',
|
984
|
+
),
|
985
|
+
],
|
986
|
+
className='g-0',
|
987
|
+
align='center',
|
988
|
+
)
|
989
|
+
|
990
|
+
|
991
|
+
def build_pipes_navbar(instance_keys: Optional[str] = None, with_instance_select: bool = True):
|
992
|
+
"""
|
993
|
+
Build the navbar from the selected instance keys.
|
994
|
+
"""
|
995
|
+
instance_select = dbc.Select(
|
996
|
+
id='instance-select',
|
997
|
+
size='sm',
|
998
|
+
value=instance_keys or str(get_api_connector()),
|
999
|
+
options=[
|
1000
|
+
{'label': (i[:32] + '…') if len(i) > 32 else i, 'value': i}
|
1001
|
+
for i in get_connector_labels(*instance_types)
|
1002
|
+
],
|
1003
|
+
class_name='dbc_dark custom-select custom-select-sm',
|
1004
|
+
)
|
1005
|
+
instance_select_div_style = {} if with_instance_select else {'visibility': 'hidden'}
|
1006
|
+
instance_select_div = html.Div(instance_select, style=instance_select_div_style)
|
1007
|
+
return html.Div(
|
1008
|
+
[
|
1009
|
+
pages_offcanvas,
|
1010
|
+
dbc.Navbar(
|
1011
|
+
dbc.Container(
|
1012
|
+
[
|
1013
|
+
logo_row,
|
1014
|
+
dbc.NavbarToggler(id="navbar-toggler", n_clicks=0),
|
1015
|
+
dbc.Collapse(
|
1016
|
+
dbc.Row(
|
1017
|
+
[
|
1018
|
+
dbc.Col(instance_select_div, width='auto'),
|
1019
|
+
dbc.Col(sign_out_button, width='auto'),
|
1020
|
+
],
|
1021
|
+
className="g-0 ms-auto flex-nowrap mt-3 mt-md-0",
|
1022
|
+
align='center',
|
1023
|
+
),
|
1024
|
+
id='navbar-collapse',
|
1025
|
+
is_open=False,
|
1026
|
+
navbar=True,
|
1027
|
+
),
|
1028
|
+
]
|
1029
|
+
),
|
1030
|
+
dark=True,
|
1031
|
+
color='dark'
|
1032
|
+
),
|
1033
|
+
],
|
1034
|
+
id='pages-navbar-div',
|
1035
|
+
)
|