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.
Files changed (94) hide show
  1. meerschaum/_internal/arguments/_parse_arguments.py +2 -5
  2. meerschaum/_internal/docs/index.py +3 -2
  3. meerschaum/_internal/entry.py +13 -7
  4. meerschaum/_internal/shell/Shell.py +38 -44
  5. meerschaum/_internal/term/TermPageHandler.py +2 -3
  6. meerschaum/_internal/term/__init__.py +13 -11
  7. meerschaum/actions/api.py +10 -7
  8. meerschaum/actions/bootstrap.py +38 -11
  9. meerschaum/actions/copy.py +3 -3
  10. meerschaum/actions/delete.py +4 -1
  11. meerschaum/actions/register.py +1 -3
  12. meerschaum/actions/stack.py +24 -19
  13. meerschaum/actions/start.py +38 -40
  14. meerschaum/actions/sync.py +53 -52
  15. meerschaum/api/__init__.py +48 -14
  16. meerschaum/api/_events.py +15 -10
  17. meerschaum/api/_oauth2.py +2 -2
  18. meerschaum/api/_websockets.py +5 -4
  19. meerschaum/api/dash/__init__.py +7 -16
  20. meerschaum/api/dash/callbacks/__init__.py +1 -0
  21. meerschaum/api/dash/callbacks/dashboard.py +52 -58
  22. meerschaum/api/dash/callbacks/jobs.py +15 -16
  23. meerschaum/api/dash/callbacks/login.py +16 -10
  24. meerschaum/api/dash/callbacks/pipes.py +41 -0
  25. meerschaum/api/dash/callbacks/plugins.py +1 -1
  26. meerschaum/api/dash/callbacks/register.py +15 -11
  27. meerschaum/api/dash/components.py +54 -59
  28. meerschaum/api/dash/jobs.py +5 -9
  29. meerschaum/api/dash/pages/__init__.py +1 -0
  30. meerschaum/api/dash/pages/pipes.py +19 -0
  31. meerschaum/api/dash/pipes.py +86 -58
  32. meerschaum/api/dash/plugins.py +6 -4
  33. meerschaum/api/dash/sessions.py +176 -0
  34. meerschaum/api/dash/users.py +3 -41
  35. meerschaum/api/dash/webterm.py +12 -17
  36. meerschaum/api/resources/static/js/terminado.js +1 -1
  37. meerschaum/api/routes/_actions.py +4 -20
  38. meerschaum/api/routes/_jobs.py +8 -7
  39. meerschaum/api/routes/_login.py +4 -4
  40. meerschaum/api/routes/_pipes.py +3 -3
  41. meerschaum/api/routes/_webterm.py +5 -6
  42. meerschaum/config/_default.py +15 -2
  43. meerschaum/config/_version.py +1 -1
  44. meerschaum/config/stack/__init__.py +64 -19
  45. meerschaum/config/static/__init__.py +4 -0
  46. meerschaum/connectors/{Connector.py → _Connector.py} +19 -13
  47. meerschaum/connectors/__init__.py +24 -14
  48. meerschaum/connectors/api/{APIConnector.py → _APIConnector.py} +3 -1
  49. meerschaum/connectors/api/__init__.py +2 -1
  50. meerschaum/connectors/parse.py +18 -16
  51. meerschaum/connectors/poll.py +30 -24
  52. meerschaum/connectors/sql/__init__.py +3 -1
  53. meerschaum/connectors/sql/_pipes.py +172 -197
  54. meerschaum/connectors/sql/_plugins.py +45 -43
  55. meerschaum/connectors/sql/_users.py +46 -38
  56. meerschaum/connectors/valkey/_ValkeyConnector.py +535 -0
  57. meerschaum/connectors/valkey/__init__.py +10 -0
  58. meerschaum/connectors/valkey/_fetch.py +75 -0
  59. meerschaum/connectors/valkey/_pipes.py +844 -0
  60. meerschaum/connectors/valkey/_plugins.py +265 -0
  61. meerschaum/connectors/valkey/_users.py +305 -0
  62. meerschaum/core/Pipe/__init__.py +3 -0
  63. meerschaum/core/Pipe/_attributes.py +1 -2
  64. meerschaum/core/Pipe/_clear.py +16 -13
  65. meerschaum/core/Pipe/_copy.py +106 -0
  66. meerschaum/core/Pipe/_data.py +165 -101
  67. meerschaum/core/Pipe/_drop.py +4 -4
  68. meerschaum/core/Pipe/_dtypes.py +14 -14
  69. meerschaum/core/Pipe/_edit.py +15 -14
  70. meerschaum/core/Pipe/_sync.py +134 -53
  71. meerschaum/core/Pipe/_verify.py +11 -11
  72. meerschaum/core/User/_User.py +14 -12
  73. meerschaum/jobs/_Job.py +1 -6
  74. meerschaum/jobs/__init__.py +7 -2
  75. meerschaum/plugins/_Plugin.py +17 -13
  76. meerschaum/utils/_get_pipes.py +14 -20
  77. meerschaum/utils/dataframe.py +291 -101
  78. meerschaum/utils/dtypes/__init__.py +31 -6
  79. meerschaum/utils/dtypes/sql.py +4 -4
  80. meerschaum/utils/formatting/_shell.py +5 -6
  81. meerschaum/utils/misc.py +3 -3
  82. meerschaum/utils/packages/__init__.py +14 -9
  83. meerschaum/utils/packages/_packages.py +2 -0
  84. meerschaum/utils/schedule.py +1 -0
  85. {meerschaum-2.3.6.dist-info → meerschaum-2.4.0.dist-info}/METADATA +7 -1
  86. {meerschaum-2.3.6.dist-info → meerschaum-2.4.0.dist-info}/RECORD +93 -84
  87. {meerschaum-2.3.6.dist-info → meerschaum-2.4.0.dist-info}/WHEEL +1 -1
  88. meerschaum/api/dash/actions.py +0 -255
  89. /meerschaum/connectors/sql/{SQLConnector.py → _SQLConnector.py} +0 -0
  90. {meerschaum-2.3.6.dist-info → meerschaum-2.4.0.dist-info}/LICENSE +0 -0
  91. {meerschaum-2.3.6.dist-info → meerschaum-2.4.0.dist-info}/NOTICE +0 -0
  92. {meerschaum-2.3.6.dist-info → meerschaum-2.4.0.dist-info}/entry_points.txt +0 -0
  93. {meerschaum-2.3.6.dist-info → meerschaum-2.4.0.dist-info}/top_level.txt +0 -0
  94. {meerschaum-2.3.6.dist-info → meerschaum-2.4.0.dist-info}/zip-safe +0 -0
@@ -16,7 +16,6 @@ flask_compress = attempt_import('flask_compress', lazy=False)
16
16
  _monkey_patch_get_distribution('flask-compress', flask_compress.__version__)
17
17
  dash = attempt_import('dash', lazy=False)
18
18
 
19
-
20
19
  from meerschaum.utils.typing import List, Optional
21
20
  from meerschaum.config.static import _static_config
22
21
  from meerschaum.api import (
@@ -38,14 +37,6 @@ with warnings.catch_warnings():
38
37
  html, dcc = import_html(), import_dcc()
39
38
  from meerschaum.api.dash.components import location
40
39
 
41
- active_sessions = {}
42
- authenticated_sessions = {}
43
- unauthenticated_sessions = {}
44
- running_jobs = {}
45
- running_monitors = {}
46
- stopped_jobs = {}
47
- stopped_monitors = {}
48
-
49
40
  stylesheets = [
50
41
  '/static/css/bootstrap.min.css',
51
42
  '/static/css/dbc_dark.css',
@@ -54,12 +45,12 @@ stylesheets = [
54
45
  scripts = ['/static/js/node_modules/xterm/lib/xterm.js']
55
46
  dash_app = enrich.DashProxy(
56
47
  __name__,
57
- title = 'Meerschaum Web',
58
- requests_pathname_prefix = endpoints['dash'] + '/',
59
- external_stylesheets = stylesheets,
60
- update_title = None,
61
- suppress_callback_exceptions = True,
62
- transforms = [
48
+ title='Meerschaum Web',
49
+ requests_pathname_prefix=endpoints['dash'] + '/',
50
+ external_stylesheets=stylesheets,
51
+ update_title=None,
52
+ suppress_callback_exceptions=True,
53
+ transforms=[
63
54
  enrich.TriggerTransform(),
64
55
  enrich.MultiplexerTransform(),
65
56
  ],
@@ -67,7 +58,7 @@ dash_app = enrich.DashProxy(
67
58
 
68
59
  dash_app.layout = html.Div([
69
60
  location,
70
- dcc.Store(id='session-store', storage_type='session', data={}),
61
+ dcc.Store(id='session-store', storage_type='local', data={}),
71
62
  html.Div([], id='page-layout-div'),
72
63
  ])
73
64
 
@@ -11,6 +11,7 @@ import meerschaum.api.dash.callbacks.login
11
11
  import meerschaum.api.dash.callbacks.plugins
12
12
  import meerschaum.api.dash.callbacks.jobs
13
13
  import meerschaum.api.dash.callbacks.register
14
+ import meerschaum.api.dash.callbacks.pipes
14
15
  from meerschaum.api.dash.callbacks.custom import init_dash_plugins, add_plugin_pages
15
16
 
16
17
  init_dash_plugins()
@@ -7,18 +7,21 @@ Callbacks for the main dashboard.
7
7
  """
8
8
 
9
9
  from __future__ import annotations
10
- import sys, textwrap, json, datetime, uuid
10
+
11
+ import textwrap
12
+ import json
13
+ import uuid
11
14
  from dash.dependencies import Input, Output, State, ALL, MATCH
12
15
  from dash.exceptions import PreventUpdate
13
- from meerschaum.config import get_config
14
- from meerschaum.config.static import _static_config
15
16
  from meerschaum.utils.typing import List, Optional, Any, Tuple
16
17
  from meerschaum.api import get_api_connector, endpoints, no_auth, CHECK_UPDATE
17
- from meerschaum.api.dash import (
18
- dash_app, debug, pipes, _get_pipes,
19
- active_sessions, authenticated_sessions, unauthenticated_sessions,
18
+ from meerschaum.api.dash import dash_app, debug
19
+ from meerschaum.api.dash.sessions import (
20
+ is_session_active,
21
+ delete_session,
22
+ set_session,
20
23
  )
21
- from meerschaum.api.dash.users import is_session_authenticated
24
+ from meerschaum.api.dash.sessions import is_session_authenticated
22
25
  from meerschaum.api.dash.connectors import get_web_connector
23
26
  from meerschaum.connectors.parse import parse_instance_keys
24
27
  from meerschaum.api.dash.pipes import get_pipes_cards, pipe_from_ctx, accordion_items_from_pipe
@@ -30,21 +33,14 @@ from meerschaum.api.dash.webterm import get_webterm
30
33
  from meerschaum.api.dash.components import (
31
34
  alert_from_success_tuple, console_div, build_cards_grid,
32
35
  )
33
- from meerschaum.api.dash.actions import execute_action, stop_action
34
- import meerschaum.api.dash.pages as pages
36
+ from meerschaum.api.dash import pages
35
37
  from meerschaum.utils.typing import Dict
36
- from meerschaum.utils.debug import dprint
37
38
  from meerschaum.utils.packages import attempt_import, import_html, import_dcc
38
- from meerschaum.utils.misc import (
39
- string_to_dict, get_connector_labels, json_serialize_datetime, filter_keywords,
40
- flatten_list,
41
- )
39
+ from meerschaum.utils.misc import filter_keywords, flatten_list
42
40
  from meerschaum.utils.yaml import yaml
43
41
  from meerschaum.actions import get_subactions, actions
44
- from meerschaum._internal.arguments._parser import get_arguments_triggers, parser
42
+ from meerschaum._internal.arguments._parser import parser
45
43
  from meerschaum.connectors.sql._fetch import set_pipe_query
46
- import meerschaum as mrsm
47
- import json
48
44
  dash = attempt_import('dash', lazy=False, check_update=CHECK_UPDATE)
49
45
  dbc = attempt_import('dash_bootstrap_components', lazy=False, check_update=CHECK_UPDATE)
50
46
  dcc, html = import_dcc(check_update=CHECK_UPDATE), import_html(check_update=CHECK_UPDATE)
@@ -101,6 +97,7 @@ _paths = {
101
97
  '' : pages.dashboard.layout,
102
98
  'plugins' : pages.plugins.layout,
103
99
  'register': pages.register.layout,
100
+ 'pipes' : pages.pipes.layout,
104
101
  }
105
102
  _required_login = {''}
106
103
 
@@ -108,21 +105,21 @@ _required_login = {''}
108
105
  @dash_app.callback(
109
106
  Output('page-layout-div', 'children'),
110
107
  Output('session-store', 'data'),
111
- Input('location', 'pathname'),
108
+ Input('mrsm-location', 'pathname'),
112
109
  Input('session-store', 'data'),
113
- State('location', 'href'),
110
+ State('mrsm-location', 'href'),
114
111
  )
115
112
  def update_page_layout_div(
116
- pathname: str,
117
- session_store_data: Dict[str, Any],
118
- location_href: str,
119
- ) -> Tuple[List[Any], Dict[str, Any]]:
113
+ pathname: str,
114
+ session_store_data: Dict[str, Any],
115
+ location_href: str,
116
+ ) -> Tuple[List[Any], Dict[str, Any]]:
120
117
  """
121
118
  Route the user to the correct page.
122
119
 
123
120
  Parameters
124
121
  ----------
125
- pathname: str :
122
+ pathname: str
126
123
  The path in the browser.
127
124
 
128
125
  session_store_data: Dict[str, Any]:
@@ -132,20 +129,19 @@ def update_page_layout_div(
132
129
  -------
133
130
  A tuple of the page layout and new session store data.
134
131
  """
135
- ctx = dash.callback_context
136
132
  dash_endpoint = endpoints['dash']
137
133
  try:
138
- session_id = session_store_data.get('session-id', None)
134
+ session_id = session_store_data.get('session-id', None)
139
135
  except AttributeError:
140
136
  session_id = None
141
137
 
142
138
  ### Bypass login if `--no-auth` is specified.
143
- if session_id not in active_sessions and no_auth:
139
+ if not is_session_active(session_id) and no_auth:
144
140
  session_store_data['session-id'] = str(uuid.uuid4())
145
- active_sessions[session_store_data['session-id']] = {'username': 'no-auth'}
141
+ set_session(session_id, {'username': 'no-auth'})
146
142
 
147
143
  ### Sometimes the href is an empty string, so store it here for later.
148
- session_store_data['location.href'] = location_href
144
+ session_store_data['mrsm-location.href'] = location_href
149
145
  session_store_to_return = session_store_data
150
146
  else:
151
147
  session_store_to_return = dash.no_update
@@ -175,7 +171,7 @@ def update_page_layout_div(
175
171
  path_str
176
172
  if no_auth or path_str not in _required_login else (
177
173
  path_str
178
- if session_id in active_sessions
174
+ if is_session_active(session_id)
179
175
  else 'login'
180
176
  )
181
177
  )
@@ -194,7 +190,7 @@ def update_page_layout_div(
194
190
  Input('get-plugins-button', 'n_clicks'),
195
191
  Input('get-users-button', 'n_clicks'),
196
192
  Input('get-graphs-button', 'n_clicks'),
197
- State('location', 'href'),
193
+ State('mrsm-location', 'href'),
198
194
  State('session-store', 'data'),
199
195
  State('webterm-div', 'children'),
200
196
  *keys_state,
@@ -205,7 +201,6 @@ def update_content(*args):
205
201
  and execute the appropriate function.
206
202
  """
207
203
  ctx = dash.callback_context
208
- location_href = ctx.states['session-store.data'].get('location.href', None)
209
204
  session_id = ctx.states['session-store.data'].get('session-id', None)
210
205
  authenticated = is_session_authenticated(str(session_id))
211
206
 
@@ -237,9 +232,6 @@ def update_content(*args):
237
232
  'get-pipes-button': 1,
238
233
  'get-jobs-button': 2,
239
234
  }
240
-
241
- ### NOTE: stop the running action if it exists
242
- stop_action(ctx.states)
243
235
 
244
236
  content, alerts = triggers[trigger](
245
237
  ctx.states,
@@ -311,9 +303,9 @@ dash_app.clientside_callback(
311
303
  return url;
312
304
  }
313
305
  """,
314
- Output('location', 'href'),
306
+ Output('mrsm-location', 'href'),
315
307
  Input('go-button', 'n_clicks'),
316
- State('location', 'href'),
308
+ State('mrsm-location', 'href'),
317
309
  State('connector-keys-dropdown', 'value'),
318
310
  State('metric-keys-dropdown', 'value'),
319
311
  State('location-keys-dropdown', 'value'),
@@ -490,12 +482,12 @@ def update_flags(input_flags_dropdown_values, n_clicks, input_flags_texts):
490
482
  *keys_state
491
483
  )
492
484
  def update_keys_options(
493
- connector_keys: Optional[List[str]],
494
- metric_keys: Optional[List[str]],
495
- location_keys: Optional[List[str]],
496
- instance_keys: Optional[str],
497
- *keys
498
- ):
485
+ connector_keys: Optional[List[str]],
486
+ metric_keys: Optional[List[str]],
487
+ location_keys: Optional[List[str]],
488
+ instance_keys: Optional[str],
489
+ *keys
490
+ ):
499
491
  """
500
492
  Update the keys dropdown menus' options.
501
493
  """
@@ -543,9 +535,9 @@ def update_keys_options(
543
535
  _keys = fetch_pipes_keys(
544
536
  'registered',
545
537
  get_web_connector(ctx.states),
546
- connector_keys = _ck_filter,
547
- metric_keys = _mk_filter,
548
- location_keys = _lk_filter,
538
+ connector_keys=_ck_filter,
539
+ metric_keys=_mk_filter,
540
+ location_keys=_lk_filter,
549
541
  )
550
542
  except Exception as e:
551
543
  instance_alerts += [alert_from_success_tuple((False, str(e)))]
@@ -637,7 +629,7 @@ dash_app.clientside_callback(
637
629
  return url;
638
630
  }
639
631
  """,
640
- Output('location', 'href'),
632
+ Output('mrsm-location', 'href'),
641
633
  Input('instance-select', 'value'),
642
634
  )
643
635
 
@@ -710,11 +702,12 @@ dash_app.clientside_callback(
710
702
  return url;
711
703
  }
712
704
  """,
713
- Output('location', 'href'),
705
+ Output('mrsm-location', 'href'),
714
706
  Input('console-pre', 'children'),
715
- State('location', 'href'),
707
+ State('mrsm-location', 'href'),
716
708
  )
717
709
 
710
+
718
711
  @dash_app.callback(
719
712
  Output("download-dataframe-csv", "data"),
720
713
  Input({'type': 'pipe-download-csv-button', 'index': ALL}, 'n_clicks'),
@@ -736,7 +729,7 @@ def download_pipe_csv(n_clicks):
736
729
  filename = str(pipe.target) + f" {begin} - {end}.csv"
737
730
  try:
738
731
  df = pipe.get_data(begin=begin, end=end, debug=debug)
739
- except Exception as e:
732
+ except Exception:
740
733
  df = None
741
734
  if df is not None:
742
735
  return dcc.send_data_frame(df.to_csv, filename, index=False)
@@ -749,6 +742,9 @@ def download_pipe_csv(n_clicks):
749
742
  State('session-store', 'data'),
750
743
  )
751
744
  def update_pipe_accordion(item, session_store_data):
745
+ """
746
+ Expand the pipe accordion item and lazy load.
747
+ """
752
748
  if item is None:
753
749
  raise PreventUpdate
754
750
 
@@ -918,7 +914,7 @@ dash_app.clientside_callback(
918
914
  """,
919
915
  Output('content-div-right', 'children'),
920
916
  Input({'type': 'manage-pipe-button', 'index': ALL, 'action': ALL}, 'n_clicks'),
921
- State('location', 'href'),
917
+ State('mrsm-location', 'href'),
922
918
  )
923
919
 
924
920
  @dash_app.callback(
@@ -948,15 +944,15 @@ def toggle_navbar_collapse(n_clicks: Optional[int], is_open: bool) -> bool:
948
944
 
949
945
 
950
946
  @dash_app.callback(
951
- Output('location', 'pathname'),
947
+ Output('mrsm-location', 'pathname'),
952
948
  Output('session-store', 'data'),
953
949
  Input("sign-out-button", "n_clicks"),
954
950
  State('session-store', 'data'),
955
951
  )
956
952
  def sign_out_button_click(
957
- n_clicks: Optional[int],
958
- session_store_data: Dict[str, Any],
959
- ):
953
+ n_clicks: Optional[int],
954
+ session_store_data: Dict[str, Any],
955
+ ):
960
956
  """
961
957
  When the sign out button is clicked, remove the session data and redirect to the login page.
962
958
  """
@@ -964,9 +960,7 @@ def sign_out_button_click(
964
960
  raise PreventUpdate
965
961
  session_id = session_store_data.get('session-id', None)
966
962
  if session_id:
967
- _ = active_sessions.pop(session_id, None)
968
- _ = authenticated_sessions.pop(session_id, None)
969
- _ = unauthenticated_sessions.pop(session_id, None)
963
+ delete_session(session_id)
970
964
  return endpoints['dash'], {}
971
965
 
972
966
 
@@ -7,36 +7,35 @@ Callbacks for jobs' cards.
7
7
  """
8
8
 
9
9
  from __future__ import annotations
10
+
10
11
  import json
11
- import functools
12
12
  import time
13
13
  import traceback
14
14
  from datetime import datetime, timezone
15
- import meerschaum as mrsm
16
15
  from meerschaum.utils.typing import Optional, Dict, Any
17
- from meerschaum.api import get_api_connector, endpoints, CHECK_UPDATE
18
- from meerschaum.api.dash import dash_app, debug, active_sessions
16
+ from meerschaum.api import CHECK_UPDATE
17
+ from meerschaum.api.dash import dash_app
18
+ from meerschaum.api.dash.sessions import get_username_from_session
19
19
  from meerschaum.utils.packages import attempt_import, import_dcc, import_html
20
- dash = attempt_import('dash', lazy=False, check_update=CHECK_UPDATE)
21
- from dash.exceptions import PreventUpdate
22
- from dash.dependencies import Input, Output, State, ALL, MATCH
23
- from dash import Patch
24
- html, dcc = import_html(check_update=CHECK_UPDATE), import_dcc(check_update=CHECK_UPDATE)
25
- import dash_bootstrap_components as dbc
26
- from meerschaum.api.dash.components import alert_from_success_tuple, build_cards_grid
27
- from dash.exceptions import PreventUpdate
20
+ from meerschaum.api.dash.components import alert_from_success_tuple
28
21
  from meerschaum.api.dash.jobs import (
29
22
  build_manage_job_buttons_div_children,
30
23
  build_status_children,
31
24
  build_process_timestamps_children,
32
25
  )
33
26
  from meerschaum.jobs import Job
34
- from meerschaum.api.dash.users import is_session_authenticated
27
+ from meerschaum.api.dash.sessions import is_session_authenticated
28
+ dash = attempt_import('dash', lazy=False, check_update=CHECK_UPDATE)
29
+ html, dcc = import_html(check_update=CHECK_UPDATE), import_dcc(check_update=CHECK_UPDATE)
30
+ from dash.exceptions import PreventUpdate
31
+ from dash.dependencies import Input, Output, State, ALL, MATCH
32
+ import dash_bootstrap_components as dbc
33
+
35
34
 
36
35
  @dash_app.callback(
37
36
  Output("download-logs", "data"),
38
37
  Input({'type': 'job-download-logs-button', 'index': ALL}, 'n_clicks'),
39
- prevent_initial_call = True,
38
+ prevent_initial_call=True,
40
39
  )
41
40
  def download_job_logs(n_clicks):
42
41
  """
@@ -84,7 +83,7 @@ def manage_job_button_click(
84
83
  raise PreventUpdate
85
84
 
86
85
  session_id = session_data.get('session-id', None)
87
- username = active_sessions.get(session_id, {}).get('username', None)
86
+ username = get_username_from_session(session_id)
88
87
 
89
88
  if not is_session_authenticated(session_id):
90
89
  success, msg = False, f"User '{username}' is not authenticated to manage jobs."
@@ -182,7 +181,7 @@ dash_app.clientside_callback(
182
181
  """,
183
182
  Output('content-div-right', 'children'),
184
183
  Input({'type': 'follow-logs-button', 'index': ALL}, 'n_clicks'),
185
- State('location', 'href'),
184
+ State('mrsm-location', 'href'),
186
185
  )
187
186
 
188
187
 
@@ -7,14 +7,17 @@ Callbacks for the login page.
7
7
  """
8
8
 
9
9
  from __future__ import annotations
10
- from meerschaum.api import endpoints, no_auth, CHECK_UPDATE
11
- from meerschaum.utils.packages import attempt_import, import_html, import_dcc
12
- dash = attempt_import('dash', lazy=False, check_update=CHECK_UPDATE)
13
10
  import uuid
11
+
12
+ from meerschaum.api import CHECK_UPDATE
13
+ from meerschaum.utils.packages import attempt_import, import_html, import_dcc
14
14
  from meerschaum.utils.typing import Optional
15
+
16
+ dash = attempt_import('dash', lazy=False, check_update=CHECK_UPDATE)
15
17
  from dash.exceptions import PreventUpdate
16
18
  from dash.dependencies import Input, Output, State
17
- from meerschaum.api.dash import dash_app, debug, pipes, _get_pipes, active_sessions
19
+ from meerschaum.api.dash import dash_app, debug, pipes, _get_pipes
20
+ from meerschaum.api.dash.sessions import set_session
18
21
  from meerschaum.api.dash.connectors import get_web_connector
19
22
  from meerschaum.api.routes._login import login
20
23
  from meerschaum.api.dash.components import alert_from_success_tuple
@@ -23,6 +26,7 @@ from fastapi.exceptions import HTTPException
23
26
  dbc = attempt_import('dash_bootstrap_components', lazy=False, check_update=CHECK_UPDATE)
24
27
  html, dcc = import_html(check_update=CHECK_UPDATE), import_dcc(check_update=CHECK_UPDATE)
25
28
 
29
+
26
30
  @dash_app.callback(
27
31
  Output('user-registration-disabled-collapse', 'is_open'),
28
32
  Input('show-user-registration-disabled-button', 'n_clicks'),
@@ -36,18 +40,19 @@ def show_registration_disabled_collapse(n_clicks, is_open):
36
40
  return not is_open
37
41
  return is_open
38
42
 
43
+
39
44
  @dash_app.callback(
40
45
  Output('session-store', 'data'),
41
46
  Output('username-input', 'className'),
42
- Output('location', 'pathname'),
47
+ Output('mrsm-location', 'pathname'),
43
48
  Output('login-alert-div', 'children'),
44
49
  Input('username-input', 'n_submit'),
45
50
  Input('password-input', 'n_submit'),
46
51
  Input('login-button', 'n_clicks'),
47
52
  State('username-input', 'value'),
48
53
  State('password-input', 'value'),
49
- State('location', 'href'),
50
- State('location', 'pathname'),
54
+ State('mrsm-location', 'href'),
55
+ State('mrsm-location', 'pathname'),
51
56
  )
52
57
  def login_button_click(
53
58
  username_submit,
@@ -69,11 +74,12 @@ def login_button_click(
69
74
 
70
75
  try:
71
76
  _ = login({'username': username, 'password': password})
77
+ session_id = str(uuid.uuid4())
72
78
  session_data = {
73
- 'session-id': str(uuid.uuid4()),
74
- 'location.href': location_href,
79
+ 'session-id': session_id,
80
+ 'mrsm-location.href': location_href,
75
81
  }
76
- active_sessions[session_data['session-id']] = {'username': username}
82
+ set_session(session_id, {'username': username})
77
83
  alerts = []
78
84
  except HTTPException:
79
85
  form_class += ' is-invalid'
@@ -0,0 +1,41 @@
1
+ #! /usr/bin/env python3
2
+ # vim:fenc=utf-8
3
+
4
+ """
5
+ Define callbacks for the `/dash/pipes/` page.
6
+ """
7
+
8
+ from dash.dependencies import Input, Output
9
+ from dash import no_update
10
+
11
+ import meerschaum as mrsm
12
+ from meerschaum.api.dash import dash_app
13
+ from meerschaum.api.dash.pipes import build_pipe_card
14
+ from meerschaum.api import CHECK_UPDATE
15
+ from meerschaum.utils.packages import import_html, import_dcc
16
+ html, dcc = import_html(check_update=CHECK_UPDATE), import_dcc(check_update=CHECK_UPDATE)
17
+
18
+
19
+ @dash_app.callback(
20
+ Output('pipe-output-div', 'children'),
21
+ Input('pipes-location', 'pathname'),
22
+ )
23
+ def render_page_from_url(pathname):
24
+ if not str(pathname).startswith('/dash/pipes'):
25
+ return no_update
26
+
27
+ keys = pathname.replace('/dash/pipes', '').lstrip('/').rstrip('/').split('/')
28
+ if len(keys) not in (2, 3):
29
+ return no_update
30
+
31
+ ck = keys[0]
32
+ mk = keys[1]
33
+ lk = keys[2] if len(keys) == 3 else None
34
+
35
+ pipe = mrsm.Pipe(ck, mk, lk)
36
+ ### TODO Check if logged in
37
+ return [
38
+ html.Br(),
39
+ build_pipe_card(pipe, authenticated=False),
40
+ html.Br(),
41
+ ]
@@ -9,7 +9,7 @@ Callbacks for the plugins page.
9
9
  from __future__ import annotations
10
10
  import json
11
11
  from meerschaum.utils.typing import Optional, Dict, Any
12
- from meerschaum.api.dash import dash_app, debug, active_sessions
12
+ from meerschaum.api.dash import dash_app, debug
13
13
  from meerschaum.api import get_api_connector, endpoints, CHECK_UPDATE
14
14
  from meerschaum.core import Plugin
15
15
  from meerschaum.utils.packages import attempt_import, import_dcc, import_html
@@ -8,7 +8,8 @@ Callbacks for the registration page.
8
8
 
9
9
  import uuid
10
10
  from meerschaum.api import get_api_connector, endpoints, CHECK_UPDATE
11
- from meerschaum.api.dash import dash_app, debug, active_sessions
11
+ from meerschaum.api.dash import dash_app, debug
12
+ from meerschaum.api.dash.sessions import set_session
12
13
  from dash.dependencies import Input, Output, State, ALL, MATCH
13
14
  from dash.exceptions import PreventUpdate
14
15
  from meerschaum.core import User
@@ -57,7 +58,7 @@ def validate_email(email):
57
58
  @dash_app.callback(
58
59
  Output('session-store', 'data'),
59
60
  Output('register-username-input', 'className'),
60
- Output('location', 'pathname'),
61
+ Output('mrsm-location', 'pathname'),
61
62
  Input('register-username-input', 'n_submit'),
62
63
  Input('register-password-input', 'n_submit'),
63
64
  Input('register-button', 'n_clicks'),
@@ -66,13 +67,16 @@ def validate_email(email):
66
67
  State("register-email-input", "value"),
67
68
  )
68
69
  def register_button_click(
69
- username_submit,
70
- password_submit,
71
- n_clicks,
72
- username,
73
- password,
74
- email,
75
- ):
70
+ username_submit,
71
+ password_submit,
72
+ n_clicks,
73
+ username,
74
+ password,
75
+ email,
76
+ ):
77
+ """
78
+ Register the user and redirect to the console.
79
+ """
76
80
  if not n_clicks:
77
81
  raise PreventUpdate
78
82
  form_class = 'form-control'
@@ -93,9 +97,9 @@ def register_button_click(
93
97
  form_class += ' is-invalid'
94
98
  return {}, form_class, dash.no_update
95
99
  try:
96
- token_dict = login({'username': username, 'password': password})
100
+ _ = login({'username': username, 'password': password})
97
101
  session_data = {'session-id': str(uuid.uuid4())}
98
- active_sessions[session_data['session-id']] = {'username': username}
102
+ set_session(session_data['session-id'], {'username': username})
99
103
  except HTTPException as e:
100
104
  form_class += ' is-invalid'
101
105
  session_data = None