meerschaum 2.3.6__py3-none-any.whl → 2.4.0__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/arguments/_parse_arguments.py +2 -5
- meerschaum/_internal/docs/index.py +3 -2
- meerschaum/_internal/entry.py +13 -7
- meerschaum/_internal/shell/Shell.py +38 -44
- meerschaum/_internal/term/TermPageHandler.py +2 -3
- meerschaum/_internal/term/__init__.py +13 -11
- meerschaum/actions/api.py +10 -7
- meerschaum/actions/bootstrap.py +38 -11
- meerschaum/actions/copy.py +3 -3
- meerschaum/actions/delete.py +4 -1
- meerschaum/actions/register.py +1 -3
- meerschaum/actions/stack.py +24 -19
- meerschaum/actions/start.py +38 -40
- meerschaum/actions/sync.py +53 -52
- meerschaum/api/__init__.py +48 -14
- meerschaum/api/_events.py +15 -10
- meerschaum/api/_oauth2.py +2 -2
- meerschaum/api/_websockets.py +5 -4
- meerschaum/api/dash/__init__.py +7 -16
- meerschaum/api/dash/callbacks/__init__.py +1 -0
- meerschaum/api/dash/callbacks/dashboard.py +52 -58
- meerschaum/api/dash/callbacks/jobs.py +15 -16
- meerschaum/api/dash/callbacks/login.py +16 -10
- meerschaum/api/dash/callbacks/pipes.py +41 -0
- meerschaum/api/dash/callbacks/plugins.py +1 -1
- meerschaum/api/dash/callbacks/register.py +15 -11
- meerschaum/api/dash/components.py +54 -59
- meerschaum/api/dash/jobs.py +5 -9
- meerschaum/api/dash/pages/__init__.py +1 -0
- meerschaum/api/dash/pages/pipes.py +19 -0
- meerschaum/api/dash/pipes.py +86 -58
- meerschaum/api/dash/plugins.py +6 -4
- meerschaum/api/dash/sessions.py +176 -0
- meerschaum/api/dash/users.py +3 -41
- meerschaum/api/dash/webterm.py +12 -17
- meerschaum/api/resources/static/js/terminado.js +1 -1
- meerschaum/api/routes/_actions.py +4 -20
- meerschaum/api/routes/_jobs.py +8 -7
- meerschaum/api/routes/_login.py +4 -4
- meerschaum/api/routes/_pipes.py +3 -3
- meerschaum/api/routes/_webterm.py +5 -6
- meerschaum/config/_default.py +15 -2
- meerschaum/config/_version.py +1 -1
- meerschaum/config/stack/__init__.py +64 -19
- meerschaum/config/static/__init__.py +4 -0
- meerschaum/connectors/{Connector.py → _Connector.py} +19 -13
- meerschaum/connectors/__init__.py +24 -14
- meerschaum/connectors/api/{APIConnector.py → _APIConnector.py} +3 -1
- meerschaum/connectors/api/__init__.py +2 -1
- meerschaum/connectors/parse.py +18 -16
- meerschaum/connectors/poll.py +30 -24
- meerschaum/connectors/sql/__init__.py +3 -1
- meerschaum/connectors/sql/_pipes.py +172 -197
- meerschaum/connectors/sql/_plugins.py +45 -43
- meerschaum/connectors/sql/_users.py +46 -38
- meerschaum/connectors/valkey/_ValkeyConnector.py +535 -0
- meerschaum/connectors/valkey/__init__.py +10 -0
- meerschaum/connectors/valkey/_fetch.py +75 -0
- meerschaum/connectors/valkey/_pipes.py +844 -0
- meerschaum/connectors/valkey/_plugins.py +265 -0
- meerschaum/connectors/valkey/_users.py +305 -0
- meerschaum/core/Pipe/__init__.py +3 -0
- meerschaum/core/Pipe/_attributes.py +1 -2
- meerschaum/core/Pipe/_clear.py +16 -13
- meerschaum/core/Pipe/_copy.py +106 -0
- meerschaum/core/Pipe/_data.py +165 -101
- meerschaum/core/Pipe/_drop.py +4 -4
- meerschaum/core/Pipe/_dtypes.py +14 -14
- meerschaum/core/Pipe/_edit.py +15 -14
- meerschaum/core/Pipe/_sync.py +134 -53
- meerschaum/core/Pipe/_verify.py +11 -11
- meerschaum/core/User/_User.py +14 -12
- meerschaum/jobs/_Job.py +1 -6
- meerschaum/jobs/__init__.py +7 -2
- meerschaum/plugins/_Plugin.py +17 -13
- meerschaum/utils/_get_pipes.py +14 -20
- meerschaum/utils/dataframe.py +291 -101
- meerschaum/utils/dtypes/__init__.py +31 -6
- meerschaum/utils/dtypes/sql.py +4 -4
- meerschaum/utils/formatting/_shell.py +5 -6
- meerschaum/utils/misc.py +3 -3
- meerschaum/utils/packages/__init__.py +14 -9
- meerschaum/utils/packages/_packages.py +2 -0
- meerschaum/utils/schedule.py +1 -0
- {meerschaum-2.3.6.dist-info → meerschaum-2.4.0.dist-info}/METADATA +7 -1
- {meerschaum-2.3.6.dist-info → meerschaum-2.4.0.dist-info}/RECORD +93 -84
- {meerschaum-2.3.6.dist-info → meerschaum-2.4.0.dist-info}/WHEEL +1 -1
- meerschaum/api/dash/actions.py +0 -255
- /meerschaum/connectors/sql/{SQLConnector.py → _SQLConnector.py} +0 -0
- {meerschaum-2.3.6.dist-info → meerschaum-2.4.0.dist-info}/LICENSE +0 -0
- {meerschaum-2.3.6.dist-info → meerschaum-2.4.0.dist-info}/NOTICE +0 -0
- {meerschaum-2.3.6.dist-info → meerschaum-2.4.0.dist-info}/entry_points.txt +0 -0
- {meerschaum-2.3.6.dist-info → meerschaum-2.4.0.dist-info}/top_level.txt +0 -0
- {meerschaum-2.3.6.dist-info → meerschaum-2.4.0.dist-info}/zip-safe +0 -0
@@ -7,27 +7,24 @@ Custom components are defined here.
|
|
7
7
|
"""
|
8
8
|
|
9
9
|
from __future__ import annotations
|
10
|
-
|
10
|
+
|
11
11
|
from meerschaum.utils.packages import attempt_import, import_dcc, import_html
|
12
12
|
from meerschaum.utils.typing import SuccessTuple, List
|
13
13
|
from meerschaum.config.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
16
|
from meerschaum.api import endpoints, CHECK_UPDATE
|
17
|
-
from meerschaum.connectors import instance_types
|
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
|
20
20
|
dbc = attempt_import('dash_bootstrap_components', lazy=False, check_update=CHECK_UPDATE)
|
21
21
|
html, dcc = import_html(check_update=CHECK_UPDATE), import_dcc(check_update=CHECK_UPDATE)
|
22
22
|
dex = attempt_import('dash_extensions', lazy=False, check_update=CHECK_UPDATE)
|
23
23
|
dash_ace = attempt_import('dash_ace', lazy=False, check_update=CHECK_UPDATE)
|
24
|
-
|
25
|
-
component_ids = {
|
26
|
-
|
27
|
-
}
|
24
|
+
_load_builtin_custom_connectors()
|
28
25
|
|
29
26
|
go_button = dbc.Button('Execute', id='go-button', color='primary', style={'width': '100%'})
|
30
|
-
test_button = dbc.Button('Test', id='test-button', color='danger', style={'display'
|
27
|
+
test_button = dbc.Button('Test', id='test-button', color='danger', style={'display': 'none'})
|
31
28
|
get_items_menu = dbc.DropdownMenu(
|
32
29
|
label='More', id='get-items-menu', children=[
|
33
30
|
dbc.DropdownMenuItem("Plugins", id='get-plugins-button'),
|
@@ -42,21 +39,21 @@ get_items_menu = dbc.DropdownMenu(
|
|
42
39
|
)
|
43
40
|
show_pipes_button = dbc.Button(
|
44
41
|
'Pipes',
|
45
|
-
id
|
46
|
-
color
|
47
|
-
style
|
42
|
+
id='get-pipes-button',
|
43
|
+
color='info',
|
44
|
+
style={'width': '100%'},
|
48
45
|
)
|
49
46
|
show_jobs_button = dbc.Button(
|
50
47
|
'Jobs',
|
51
|
-
id
|
52
|
-
color
|
53
|
-
style
|
48
|
+
id='get-jobs-button',
|
49
|
+
color='success',
|
50
|
+
style={'width': '100%'},
|
54
51
|
)
|
55
52
|
cancel_button = dbc.Button(
|
56
53
|
'Terminal',
|
57
|
-
id
|
58
|
-
color
|
59
|
-
style
|
54
|
+
id='cancel-button',
|
55
|
+
color='dark',
|
56
|
+
style={'width': '100%', 'background-color': 'black', 'display': 'none'},
|
60
57
|
)
|
61
58
|
bottom_buttons_content = dbc.Card(
|
62
59
|
dbc.CardBody(
|
@@ -70,28 +67,26 @@ bottom_buttons_content = dbc.Card(
|
|
70
67
|
)
|
71
68
|
)
|
72
69
|
console_div = html.Div(
|
73
|
-
id
|
74
|
-
children
|
70
|
+
id='console-div',
|
71
|
+
children=[html.Pre(get_shell_intro(), id='console-pre')],
|
75
72
|
)
|
76
73
|
|
77
|
-
location = dcc.Location(id='location', refresh=False)
|
74
|
+
location = dcc.Location(id='mrsm-location', refresh=False)
|
78
75
|
|
79
76
|
search_parameters_editor = dash_ace.DashAceEditor(
|
80
|
-
id
|
81
|
-
theme
|
82
|
-
mode
|
83
|
-
tabSize
|
84
|
-
placeholder
|
77
|
+
id='search-parameters-editor',
|
78
|
+
theme='monokai',
|
79
|
+
mode='json',
|
80
|
+
tabSize=2,
|
81
|
+
placeholder=(
|
85
82
|
'Additional search parameters. ' +
|
86
83
|
'Simple dictionary format or JSON accepted.'
|
87
84
|
),
|
88
|
-
style
|
85
|
+
style={'height': 100},
|
89
86
|
)
|
90
87
|
|
91
88
|
sidebar = dbc.Offcanvas(
|
92
|
-
children=[
|
93
|
-
|
94
|
-
],
|
89
|
+
children=[],
|
95
90
|
title='Pages',
|
96
91
|
)
|
97
92
|
|
@@ -99,13 +94,13 @@ download_dataframe = dcc.Download(id='download-dataframe-csv')
|
|
99
94
|
download_logs = dcc.Download(id='download-logs')
|
100
95
|
|
101
96
|
instance_select = dbc.Select(
|
102
|
-
id
|
103
|
-
size
|
104
|
-
options
|
97
|
+
id='instance-select',
|
98
|
+
size='sm',
|
99
|
+
options=[
|
105
100
|
{'label': i, 'value': i}
|
106
101
|
for i in get_connector_labels(*instance_types)
|
107
102
|
],
|
108
|
-
class_name
|
103
|
+
class_name='dbc_dark custom-select custom-select-sm',
|
109
104
|
)
|
110
105
|
|
111
106
|
|
@@ -116,17 +111,17 @@ navbar = dbc.Navbar(
|
|
116
111
|
dbc.Row(
|
117
112
|
[
|
118
113
|
dbc.Col(
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
114
|
+
html.Img(
|
115
|
+
src=endpoints['dash'] + "/assets/logo_48x48.png",
|
116
|
+
title=doc,
|
117
|
+
),
|
123
118
|
),
|
124
119
|
],
|
125
|
-
align
|
126
|
-
className
|
120
|
+
align='center',
|
121
|
+
className='g-0 navbar-logo-row',
|
127
122
|
),
|
128
|
-
href
|
129
|
-
style
|
123
|
+
href='/docs',
|
124
|
+
style={"textDecoration": "none"},
|
130
125
|
),
|
131
126
|
dbc.NavbarToggler(id="navbar-toggler", n_clicks=0),
|
132
127
|
dbc.Collapse(
|
@@ -136,30 +131,30 @@ navbar = dbc.Navbar(
|
|
136
131
|
dbc.Col(
|
137
132
|
dbc.Button(
|
138
133
|
"Sign out",
|
139
|
-
color
|
140
|
-
style
|
141
|
-
id
|
134
|
+
color='link',
|
135
|
+
style={'margin-left': '30px'},
|
136
|
+
id='sign-out-button',
|
142
137
|
),
|
143
138
|
),
|
144
139
|
],
|
145
|
-
className
|
140
|
+
className="g-0 ms-auto flex-nowrap mt-3 mt-md-0",
|
146
141
|
),
|
147
|
-
id
|
148
|
-
is_open
|
149
|
-
navbar
|
142
|
+
id='navbar-collapse',
|
143
|
+
is_open=False,
|
144
|
+
navbar=True,
|
150
145
|
),
|
151
146
|
],
|
152
|
-
style
|
147
|
+
style={'max-width': '96%'},
|
153
148
|
),
|
154
|
-
color
|
155
|
-
style
|
149
|
+
color='dark', dark=True,
|
150
|
+
style={'width': '100% !important'},
|
156
151
|
)
|
157
152
|
|
158
153
|
refresh_jobs_interval = dcc.Interval(
|
159
|
-
id
|
160
|
-
interval
|
161
|
-
n_intervals
|
162
|
-
disabled
|
154
|
+
id='refresh-jobs-interval',
|
155
|
+
interval=(1 * 1000),
|
156
|
+
n_intervals=0,
|
157
|
+
disabled=False,
|
163
158
|
)
|
164
159
|
|
165
160
|
def alert_from_success_tuple(success: SuccessTuple) -> dbc.Alert:
|
@@ -169,11 +164,11 @@ def alert_from_success_tuple(success: SuccessTuple) -> dbc.Alert:
|
|
169
164
|
return dbc.Alert('', is_open=False) if not isinstance(success, tuple) else (
|
170
165
|
dbc.Alert(
|
171
166
|
remove_ansi(success[1]),
|
172
|
-
id
|
173
|
-
dismissable
|
174
|
-
fade
|
175
|
-
is_open
|
176
|
-
color
|
167
|
+
id='success-alert',
|
168
|
+
dismissable=True,
|
169
|
+
fade=True,
|
170
|
+
is_open=(success[1] not in STATIC_CONFIG['system']['success']['ignore']),
|
171
|
+
color='success' if success[0] else 'danger',
|
177
172
|
)
|
178
173
|
)
|
179
174
|
|
meerschaum/api/dash/jobs.py
CHANGED
@@ -7,24 +7,20 @@ Functions for interacting with jobs via the web interface.
|
|
7
7
|
"""
|
8
8
|
|
9
9
|
from __future__ import annotations
|
10
|
-
from
|
11
|
-
from meerschaum.utils.typing import List, Optional, Dict, Any, Tuple, Union, WebState
|
10
|
+
from meerschaum.utils.typing import List, Dict, WebState
|
12
11
|
from meerschaum.utils.packages import attempt_import, import_html, import_dcc
|
13
|
-
from meerschaum.api.dash.
|
14
|
-
from meerschaum.api.dash.users import is_session_authenticated
|
12
|
+
from meerschaum.api.dash.sessions import is_session_authenticated
|
15
13
|
from meerschaum.api import CHECK_UPDATE
|
16
|
-
dbc = attempt_import('dash_bootstrap_components', lazy=False, check_update=CHECK_UPDATE)
|
17
|
-
html, dcc = import_html(), import_dcc()
|
18
14
|
from meerschaum.jobs import (
|
19
15
|
get_jobs,
|
20
|
-
get_running_jobs,
|
21
|
-
get_paused_jobs,
|
22
|
-
get_stopped_jobs,
|
23
16
|
get_executor_keys_from_context,
|
24
17
|
Job,
|
25
18
|
)
|
26
19
|
from meerschaum.config import get_config
|
27
20
|
from meerschaum.utils.misc import sorted_dict
|
21
|
+
from dash.dependencies import Input, Output, State
|
22
|
+
dbc = attempt_import('dash_bootstrap_components', lazy=False, check_update=CHECK_UPDATE)
|
23
|
+
html, dcc = import_html(), import_dcc()
|
28
24
|
|
29
25
|
STATUS_EMOJI: Dict[str, str] = {
|
30
26
|
'running': get_config('formatting', 'emoji', 'running'),
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#! /usr/bin/env python3
|
2
|
+
# vim:fenc=utf-8
|
3
|
+
|
4
|
+
"""
|
5
|
+
Display pipes via a shareable URL.
|
6
|
+
"""
|
7
|
+
|
8
|
+
from meerschaum.api import CHECK_UPDATE
|
9
|
+
from meerschaum.utils.packages import import_html, import_dcc
|
10
|
+
from meerschaum.api.dash.components import download_dataframe
|
11
|
+
|
12
|
+
html, dcc = import_html(check_update=CHECK_UPDATE), import_dcc(check_update=CHECK_UPDATE)
|
13
|
+
import dash_bootstrap_components as dbc
|
14
|
+
|
15
|
+
layout = dbc.Container([
|
16
|
+
dcc.Location('pipes-location'),
|
17
|
+
download_dataframe,
|
18
|
+
html.Div(id='pipe-output-div'),
|
19
|
+
])
|
meerschaum/api/dash/pipes.py
CHANGED
@@ -12,18 +12,16 @@ import shlex
|
|
12
12
|
from textwrap import dedent
|
13
13
|
from dash.dependencies import Input, Output, State
|
14
14
|
from meerschaum.utils.typing import List, Optional, Dict, Any, Tuple, Union
|
15
|
-
from meerschaum.utils.misc import string_to_dict
|
15
|
+
from meerschaum.utils.misc import string_to_dict
|
16
16
|
from meerschaum.utils.packages import attempt_import, import_dcc, import_html, import_pandas
|
17
17
|
from meerschaum.utils.sql import get_pd_type
|
18
18
|
from meerschaum.utils.yaml import yaml
|
19
19
|
from meerschaum.connectors.sql._fetch import get_pipe_query
|
20
|
-
from meerschaum.api import
|
21
|
-
from meerschaum.api.dash import
|
22
|
-
dash_app, debug, _get_pipes
|
23
|
-
)
|
20
|
+
from meerschaum.api import CHECK_UPDATE
|
21
|
+
from meerschaum.api.dash import debug, _get_pipes
|
24
22
|
from meerschaum.api.dash.connectors import get_web_connector
|
25
23
|
from meerschaum.api.dash.components import alert_from_success_tuple, build_cards_grid
|
26
|
-
from meerschaum.api.dash.
|
24
|
+
from meerschaum.api.dash.sessions import is_session_authenticated
|
27
25
|
from meerschaum.config import get_config
|
28
26
|
import meerschaum as mrsm
|
29
27
|
dbc = attempt_import('dash_bootstrap_components', lazy=False, check_update=CHECK_UPDATE)
|
@@ -48,13 +46,14 @@ def pipe_from_ctx(ctx, trigger_property: str = 'n_clicks') -> Union[mrsm.Pipe, N
|
|
48
46
|
return None
|
49
47
|
return mrsm.Pipe(**meta)
|
50
48
|
|
49
|
+
|
51
50
|
def keys_from_state(
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
51
|
+
state: Dict[str, Any],
|
52
|
+
with_params: bool = False
|
53
|
+
) -> Union[
|
54
|
+
Tuple[List[str], List[str], List[str]],
|
55
|
+
Tuple[List[str], List[str], List[str], str],
|
56
|
+
]:
|
58
57
|
"""
|
59
58
|
Read the current state and return the selected keys lists.
|
60
59
|
"""
|
@@ -85,10 +84,11 @@ def keys_from_state(
|
|
85
84
|
keys.append(params)
|
86
85
|
return tuple(keys)
|
87
86
|
|
87
|
+
|
88
88
|
def pipes_from_state(
|
89
|
-
|
90
|
-
|
91
|
-
|
89
|
+
state: Dict[str, Any],
|
90
|
+
**kw
|
91
|
+
):
|
92
92
|
_ck, _mk, _lk, _params = keys_from_state(state, with_params=True)
|
93
93
|
try:
|
94
94
|
_pipes = _get_pipes(
|
@@ -103,10 +103,10 @@ def pipes_from_state(
|
|
103
103
|
|
104
104
|
|
105
105
|
def build_pipe_card(
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
106
|
+
pipe: mrsm.Pipe,
|
107
|
+
authenticated: bool = False,
|
108
|
+
_build_children_num: int = 10,
|
109
|
+
) -> 'dbc.Card':
|
110
110
|
"""
|
111
111
|
Return a card for the given pipe.
|
112
112
|
|
@@ -128,11 +128,11 @@ def build_pipe_card(
|
|
128
128
|
dbc.Col(
|
129
129
|
(
|
130
130
|
dbc.DropdownMenu(
|
131
|
-
label
|
132
|
-
children
|
131
|
+
label="Manage",
|
132
|
+
children=[
|
133
133
|
dbc.DropdownMenuItem(
|
134
134
|
'Open in Python',
|
135
|
-
id
|
135
|
+
id={
|
136
136
|
'type': 'manage-pipe-button',
|
137
137
|
'index': meta_str,
|
138
138
|
'action': 'python',
|
@@ -140,7 +140,7 @@ def build_pipe_card(
|
|
140
140
|
),
|
141
141
|
dbc.DropdownMenuItem(
|
142
142
|
'Delete',
|
143
|
-
id
|
143
|
+
id={
|
144
144
|
'type': 'manage-pipe-button',
|
145
145
|
'index': meta_str,
|
146
146
|
'action': 'delete',
|
@@ -148,7 +148,7 @@ def build_pipe_card(
|
|
148
148
|
),
|
149
149
|
dbc.DropdownMenuItem(
|
150
150
|
'Drop',
|
151
|
-
id
|
151
|
+
id={
|
152
152
|
'type': 'manage-pipe-button',
|
153
153
|
'index': meta_str,
|
154
154
|
'action': 'drop',
|
@@ -156,7 +156,7 @@ def build_pipe_card(
|
|
156
156
|
),
|
157
157
|
dbc.DropdownMenuItem(
|
158
158
|
'Clear',
|
159
|
-
id
|
159
|
+
id={
|
160
160
|
'type': 'manage-pipe-button',
|
161
161
|
'index': meta_str,
|
162
162
|
'action': 'clear',
|
@@ -164,7 +164,7 @@ def build_pipe_card(
|
|
164
164
|
),
|
165
165
|
dbc.DropdownMenuItem(
|
166
166
|
'Verify',
|
167
|
-
id
|
167
|
+
id={
|
168
168
|
'type': 'manage-pipe-button',
|
169
169
|
'index': meta_str,
|
170
170
|
'action': 'verify',
|
@@ -172,56 +172,84 @@ def build_pipe_card(
|
|
172
172
|
),
|
173
173
|
dbc.DropdownMenuItem(
|
174
174
|
'Sync',
|
175
|
-
id
|
175
|
+
id={
|
176
176
|
'type': 'manage-pipe-button',
|
177
177
|
'index': meta_str,
|
178
178
|
'action': 'sync',
|
179
179
|
},
|
180
180
|
),
|
181
181
|
],
|
182
|
-
direction
|
183
|
-
menu_variant
|
184
|
-
size
|
185
|
-
color
|
182
|
+
direction="up",
|
183
|
+
menu_variant="dark",
|
184
|
+
size='sm',
|
185
|
+
color='secondary',
|
186
186
|
)
|
187
187
|
) if authenticated else [],
|
188
|
-
width
|
188
|
+
width=2,
|
189
189
|
),
|
190
190
|
dbc.Col(width=6),
|
191
191
|
dbc.Col(
|
192
192
|
dbc.Button(
|
193
193
|
'Download CSV',
|
194
|
-
size
|
195
|
-
color
|
196
|
-
style
|
197
|
-
id
|
194
|
+
size='sm',
|
195
|
+
color='link',
|
196
|
+
style={'float': 'right'},
|
197
|
+
id={'type': 'pipe-download-csv-button', 'index': meta_str},
|
198
198
|
),
|
199
|
-
width
|
199
|
+
width=4,
|
200
200
|
),
|
201
201
|
],
|
202
|
-
justify
|
202
|
+
justify='start',
|
203
203
|
)
|
204
204
|
card_body_children = [
|
205
|
-
html.H5(
|
206
|
-
html.B(str(pipe)),
|
207
|
-
className = 'card-title',
|
208
|
-
style = {'font-family': ['monospace']}
|
209
|
-
),
|
210
205
|
html.Div(
|
211
206
|
dbc.Accordion(
|
212
207
|
accordion_items_from_pipe(
|
213
208
|
pipe,
|
214
|
-
authenticated
|
215
|
-
_build_children_num
|
209
|
+
authenticated=authenticated,
|
210
|
+
_build_children_num=_build_children_num,
|
216
211
|
),
|
217
|
-
flush
|
218
|
-
start_collapsed
|
219
|
-
id
|
212
|
+
flush=True,
|
213
|
+
start_collapsed=True,
|
214
|
+
id={'type': 'pipe-accordion', 'index': meta_str},
|
220
215
|
)
|
221
216
|
)
|
222
217
|
|
223
218
|
]
|
219
|
+
|
220
|
+
pipe_url = (
|
221
|
+
f"/dash/pipes/{pipe.connector_keys}/{pipe.metric_key}/{pipe.location_key}"
|
222
|
+
)
|
223
|
+
|
224
|
+
card_header_children = dbc.Row(
|
225
|
+
[
|
226
|
+
dbc.Col(
|
227
|
+
html.H5(
|
228
|
+
html.B(str(pipe)),
|
229
|
+
className='card-title',
|
230
|
+
style={'font-family': ['monospace']}
|
231
|
+
),
|
232
|
+
width=11,
|
233
|
+
),
|
234
|
+
dbc.Col(
|
235
|
+
dbc.Button(
|
236
|
+
"🔗",
|
237
|
+
href=pipe_url,
|
238
|
+
external_link=True,
|
239
|
+
target="_blank",
|
240
|
+
style={'float': 'right'},
|
241
|
+
outline=True,
|
242
|
+
color='link',
|
243
|
+
id={'type': 'share-pipe-button', 'index': meta_str},
|
244
|
+
),
|
245
|
+
width=1,
|
246
|
+
),
|
247
|
+
],
|
248
|
+
justify='start',
|
249
|
+
)
|
250
|
+
|
224
251
|
return dbc.Card([
|
252
|
+
dbc.CardHeader(children=card_header_children),
|
225
253
|
dbc.CardBody(children=card_body_children),
|
226
254
|
dbc.CardFooter(children=footer_children),
|
227
255
|
])
|
@@ -270,11 +298,11 @@ def get_pipes_cards(*keys, session_data: Optional[Dict[str, Any]] = None):
|
|
270
298
|
|
271
299
|
|
272
300
|
def accordion_items_from_pipe(
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
301
|
+
pipe: mrsm.Pipe,
|
302
|
+
active_items: Optional[List[str]] = None,
|
303
|
+
authenticated: bool = False,
|
304
|
+
_build_children_num: int = 10,
|
305
|
+
) -> 'List[dbc.AccordionItem]':
|
278
306
|
"""
|
279
307
|
Build the accordion items for a given pipe.
|
280
308
|
"""
|
@@ -521,11 +549,11 @@ def accordion_items_from_pipe(
|
|
521
549
|
backtrack_df = pipe.get_backtrack_data(debug=debug, limit=1)
|
522
550
|
try:
|
523
551
|
json_text = backtrack_df.fillna(pd.NA).to_json(
|
524
|
-
orient
|
525
|
-
date_format
|
526
|
-
force_ascii
|
527
|
-
indent
|
528
|
-
date_unit
|
552
|
+
orient='records',
|
553
|
+
date_format='iso',
|
554
|
+
force_ascii=False,
|
555
|
+
indent=4,
|
556
|
+
date_unit='ns',
|
529
557
|
) if backtrack_df is not None else '[]'
|
530
558
|
except Exception as e:
|
531
559
|
warn(e)
|
meerschaum/api/dash/plugins.py
CHANGED
@@ -13,7 +13,8 @@ from meerschaum.api import get_api_connector, endpoints, CHECK_UPDATE
|
|
13
13
|
html, dcc = import_html(check_update=CHECK_UPDATE), import_dcc(check_update=CHECK_UPDATE)
|
14
14
|
import dash_bootstrap_components as dbc
|
15
15
|
from meerschaum.core import Plugin
|
16
|
-
from meerschaum.api.dash import dash_app, debug
|
16
|
+
from meerschaum.api.dash import dash_app, debug
|
17
|
+
from meerschaum.api.dash.sessions import get_username_from_session
|
17
18
|
|
18
19
|
|
19
20
|
def get_plugins_cards(
|
@@ -88,9 +89,10 @@ def is_plugin_owner(plugin_name: str, session_data: Dict['str', Any]) -> bool:
|
|
88
89
|
Check whether the currently logged in user is the owner of a plugin.
|
89
90
|
"""
|
90
91
|
plugin = Plugin(plugin_name)
|
91
|
-
|
92
|
-
|
93
|
-
|
92
|
+
session_id = session_data.get('session-id', None)
|
93
|
+
if session_id is None:
|
94
|
+
return False
|
95
|
+
_username = get_username_from_session(session_id)
|
94
96
|
_plugin_username = get_api_connector().get_plugin_username(plugin, debug=debug)
|
95
97
|
return (
|
96
98
|
_username is not None
|