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.
Files changed (41) hide show
  1. meerschaum/_internal/shell/Shell.py +5 -4
  2. meerschaum/actions/bootstrap.py +1 -1
  3. meerschaum/actions/edit.py +6 -3
  4. meerschaum/actions/start.py +1 -1
  5. meerschaum/api/dash/callbacks/__init__.py +1 -0
  6. meerschaum/api/dash/callbacks/dashboard.py +19 -18
  7. meerschaum/api/dash/callbacks/jobs.py +11 -5
  8. meerschaum/api/dash/callbacks/pipes.py +106 -5
  9. meerschaum/api/dash/callbacks/settings/__init__.py +0 -1
  10. meerschaum/api/dash/callbacks/{settings/tokens.py → tokens.py} +1 -1
  11. meerschaum/api/dash/jobs.py +1 -1
  12. meerschaum/api/dash/pages/__init__.py +2 -1
  13. meerschaum/api/dash/pages/{job.py → jobs.py} +10 -7
  14. meerschaum/api/dash/pages/pipes.py +4 -3
  15. meerschaum/api/dash/pages/settings/__init__.py +0 -1
  16. meerschaum/api/dash/pages/{settings/tokens.py → tokens.py} +6 -8
  17. meerschaum/api/dash/pipes.py +131 -0
  18. meerschaum/api/dash/tokens.py +26 -29
  19. meerschaum/config/_default.py +5 -4
  20. meerschaum/config/_paths.py +1 -0
  21. meerschaum/config/_version.py +1 -1
  22. meerschaum/connectors/instance/_tokens.py +6 -2
  23. meerschaum/connectors/sql/_SQLConnector.py +14 -0
  24. meerschaum/connectors/sql/_pipes.py +57 -22
  25. meerschaum/connectors/sql/tables/__init__.py +237 -122
  26. meerschaum/core/Pipe/_attributes.py +5 -2
  27. meerschaum/core/Token/_Token.py +1 -1
  28. meerschaum/plugins/bootstrap.py +508 -3
  29. meerschaum/utils/_get_pipes.py +1 -1
  30. meerschaum/utils/dataframe.py +8 -2
  31. meerschaum/utils/dtypes/__init__.py +2 -3
  32. meerschaum/utils/dtypes/sql.py +11 -11
  33. meerschaum/utils/sql.py +1 -1
  34. {meerschaum-3.0.0rc2.dist-info → meerschaum-3.0.0rc3.dist-info}/METADATA +1 -1
  35. {meerschaum-3.0.0rc2.dist-info → meerschaum-3.0.0rc3.dist-info}/RECORD +41 -41
  36. {meerschaum-3.0.0rc2.dist-info → meerschaum-3.0.0rc3.dist-info}/WHEEL +0 -0
  37. {meerschaum-3.0.0rc2.dist-info → meerschaum-3.0.0rc3.dist-info}/entry_points.txt +0 -0
  38. {meerschaum-3.0.0rc2.dist-info → meerschaum-3.0.0rc3.dist-info}/licenses/LICENSE +0 -0
  39. {meerschaum-3.0.0rc2.dist-info → meerschaum-3.0.0rc3.dist-info}/licenses/NOTICE +0 -0
  40. {meerschaum-3.0.0rc2.dist-info → meerschaum-3.0.0rc3.dist-info}/top_level.txt +0 -0
  41. {meerschaum-3.0.0rc2.dist-info → meerschaum-3.0.0rc3.dist-info}/zip-safe +0 -0
@@ -9,7 +9,7 @@ Dash utility functions for constructing tokens components.
9
9
  from __future__ import annotations
10
10
 
11
11
  from datetime import datetime, timezone, timedelta
12
- from typing import Any, List
12
+ from typing import Any, List, Optional
13
13
 
14
14
  import meerschaum as mrsm
15
15
  from meerschaum.api import debug, CHECK_UPDATE, get_api_connector
@@ -91,39 +91,36 @@ def build_manage_token_popover(token: Token) -> dbc.Popover:
91
91
  """
92
92
  return dbc.Popover(
93
93
  [
94
- dbc.PopoverHeader(["Manage token"]),
95
- dbc.PopoverBody([
96
- dbc.ButtonGroup(
97
- ([
98
- dbc.Button(
99
- "Edit",
100
- outline=True,
101
- color='light',
102
- id={
103
- 'type': 'tokens-edit-button',
104
- 'index': str(token.id),
105
- },
106
- ),
107
- dbc.Button(
108
- "Invalidate",
109
- outline=True,
110
- color='warning',
111
- id={
112
- 'type': 'tokens-invalidate-button',
113
- 'index': str(token.id),
114
- },
115
- ),
116
- ] if token.is_valid else []) + [
94
+ dbc.ButtonGroup(
95
+ ([
117
96
  dbc.Button(
118
- "Delete",
119
- color='danger',
97
+ "Edit",
120
98
  outline=True,
99
+ color='light',
121
100
  id={
122
- 'type': 'tokens-delete-button',
101
+ 'type': 'tokens-edit-button',
123
102
  'index': str(token.id),
124
103
  },
125
104
  ),
126
- ]),
105
+ dbc.Button(
106
+ "Invalidate",
107
+ outline=True,
108
+ color='warning',
109
+ id={
110
+ 'type': 'tokens-invalidate-button',
111
+ 'index': str(token.id),
112
+ },
113
+ ),
114
+ ] if token.is_valid else []) + [
115
+ dbc.Button(
116
+ "Delete",
117
+ color='danger',
118
+ outline=True,
119
+ id={
120
+ 'type': 'tokens-delete-button',
121
+ 'index': str(token.id),
122
+ },
123
+ ),
127
124
  ]),
128
125
  ],
129
126
  body=True,
@@ -600,7 +597,7 @@ def build_tokens_register_output_modal(token: Token) -> List[Any]:
600
597
  dbc.Button(
601
598
  "Close",
602
599
  id='tokens-close-register-output-modal-button',
603
- disabled=True,
600
+ disabled=success,
604
601
  ),
605
602
  ]),
606
603
  ]
@@ -99,6 +99,7 @@ default_system_config = {
99
99
  'mssql': True,
100
100
  },
101
101
  'instance': {
102
+ 'create_metadata_cache_minutes': 14400,
102
103
  'stale_temporary_tables_minutes': 1440,
103
104
  'temporary_target': {
104
105
  'prefix': '_',
@@ -199,11 +200,11 @@ default_pipes_config = {
199
200
  },
200
201
  },
201
202
  'attributes': {
202
- 'local_cache_timeout_seconds': 60,
203
+ 'local_cache_timeout_seconds': 600.0,
203
204
  },
204
205
  'sync': {
205
206
  'filter_params_index_limit': 250,
206
- 'exists_cache_seconds': 5.0,
207
+ 'exists_cache_seconds': 60.0,
207
208
  },
208
209
  'verify': {
209
210
  'max_chunks_syncs': 3,
@@ -213,10 +214,10 @@ default_pipes_config = {
213
214
  },
214
215
  'dtypes': {
215
216
  'min_ratio_columns_changed_for_full_astype': 0.5,
216
- 'columns_types_cache_seconds': 5.0,
217
+ 'columns_types_cache_seconds': 60.0,
217
218
  },
218
219
  'static': {
219
- 'static_schema_cache_seconds': 60.0,
220
+ 'static_schema_cache_seconds': 3600.0,
220
221
  },
221
222
  }
222
223
  default_plugins_config = {}
@@ -149,6 +149,7 @@ paths = {
149
149
  'PIPES_CACHE_RESOURCES_PATH' : ('{CACHE_RESOURCES_PATH}', 'pipes'),
150
150
  'USERS_CACHE_RESOURCES_PATH' : ('{CACHE_RESOURCES_PATH}', 'users'),
151
151
  'VENVS_CACHE_RESOURCES_PATH' : ('{CACHE_RESOURCES_PATH}', 'venvs'),
152
+ 'SQL_CONN_CACHE_RESOURCES_PATH' : ('{CACHE_RESOURCES_PATH}', 'sql'),
152
153
 
153
154
  'PLUGINS_RESOURCES_PATH' : ('{INTERNAL_RESOURCES_PATH}', 'plugins'),
154
155
  'PLUGINS_INTERNAL_LOCK_PATH' : ('{INTERNAL_RESOURCES_PATH}', 'plugins.lock'),
@@ -2,4 +2,4 @@
2
2
  Specify the Meerschaum release version.
3
3
  """
4
4
 
5
- __version__ = "3.0.0rc2"
5
+ __version__ = "3.0.0rc3"
@@ -53,7 +53,11 @@ def get_tokens_pipe(self) -> mrsm.Pipe:
53
53
  )
54
54
 
55
55
 
56
- def register_token(self, token: Token, debug: bool = False) -> mrsm.SuccessTuple:
56
+ def register_token(
57
+ self,
58
+ token: Token,
59
+ debug: bool = False,
60
+ ) -> mrsm.SuccessTuple:
57
61
  """
58
62
  Register the new token to the tokens table.
59
63
  """
@@ -61,7 +65,7 @@ def register_token(self, token: Token, debug: bool = False) -> mrsm.SuccessTuple
61
65
  tokens_pipe = self.get_tokens_pipe()
62
66
  user_id = self.get_user_id(token.user) if token.user is not None else None
63
67
  if user_id is None:
64
- raise ValueError("Cannot register a token without a user.")
68
+ return False, "Cannot register a token without a user."
65
69
 
66
70
  doc = {
67
71
  'id': token_id,
@@ -7,6 +7,8 @@ Interface with SQL servers using sqlalchemy.
7
7
  """
8
8
 
9
9
  from __future__ import annotations
10
+
11
+ import pathlib
10
12
  import meerschaum as mrsm
11
13
  from meerschaum.utils.typing import Optional, Any, Union
12
14
 
@@ -376,6 +378,18 @@ class SQLConnector(InstanceConnector):
376
378
  self.__dict__['schema'] = _schema
377
379
  return _schema
378
380
 
381
+ def get_metadata_cache_path(self, kind: str = 'json') -> pathlib.Path:
382
+ """
383
+ Return the path to the file to which to write metadata cache.
384
+ """
385
+ from meerschaum.config.paths import SQL_CONN_CACHE_RESOURCES_PATH
386
+ filename = (
387
+ f'{self.label}-metadata.pkl'
388
+ if kind == 'pkl'
389
+ else f'{self.label}.json'
390
+ )
391
+ return SQL_CONN_CACHE_RESOURCES_PATH / filename
392
+
379
393
  def __getstate__(self):
380
394
  return self.__dict__
381
395
 
@@ -147,7 +147,7 @@ def fetch_pipes_keys(
147
147
  tags: Optional[List[str]] = None,
148
148
  params: Optional[Dict[str, Any]] = None,
149
149
  debug: bool = False
150
- ) -> Optional[List[Tuple[str, str, Optional[str]]]]:
150
+ ) -> List[Tuple[str, str, Optional[str]]]:
151
151
  """
152
152
  Return a list of tuples corresponding to the parameters provided.
153
153
 
@@ -162,16 +162,27 @@ def fetch_pipes_keys(
162
162
  location_keys: Optional[List[str]], default None
163
163
  List of location_keys to search by.
164
164
 
165
+ tags: Optional[List[str]], default None
166
+ List of pipes to search by.
167
+
165
168
  params: Optional[Dict[str, Any]], default None
166
169
  Dictionary of additional parameters to search by.
167
170
  E.g. `--params pipe_id:1`
168
171
 
169
172
  debug: bool, default False
170
173
  Verbosity toggle.
174
+
175
+ Returns
176
+ -------
177
+ A list of tuples of pipes' keys (connector_keys, metric_key, location_key).
171
178
  """
172
179
  from meerschaum.utils.packages import attempt_import
173
180
  from meerschaum.utils.misc import separate_negation_values
174
- from meerschaum.utils.sql import OMIT_NULLSFIRST_FLAVORS, table_exists
181
+ from meerschaum.utils.sql import (
182
+ OMIT_NULLSFIRST_FLAVORS,
183
+ table_exists,
184
+ json_flavors,
185
+ )
175
186
  from meerschaum._internal.static import STATIC_CONFIG
176
187
  import json
177
188
  from copy import deepcopy
@@ -259,25 +270,49 @@ def fetch_pipes_keys(
259
270
  in_ex_tag_groups = [separate_negation_values(tag_group) for tag_group in tag_groups]
260
271
 
261
272
  ors, nands = [], []
262
- for _in_tags, _ex_tags in in_ex_tag_groups:
263
- sub_ands = []
264
- for nt in _in_tags:
265
- sub_ands.append(
266
- sqlalchemy.cast(
267
- pipes_tbl.c['parameters'],
268
- sqlalchemy.String,
269
- ).like(f'%"tags":%"{nt}"%')
270
- )
271
- if sub_ands:
272
- ors.append(sqlalchemy.and_(*sub_ands))
273
-
274
- for xt in _ex_tags:
275
- nands.append(
276
- sqlalchemy.cast(
277
- pipes_tbl.c['parameters'],
278
- sqlalchemy.String,
279
- ).not_like(f'%"tags":%"{xt}"%')
280
- )
273
+ if self.flavor in json_flavors:
274
+ from sqlalchemy.dialects import postgresql
275
+ for _in_tags, _ex_tags in in_ex_tag_groups:
276
+ if _in_tags:
277
+ ors.append(
278
+ sqlalchemy.and_(
279
+ pipes_tbl.c['parameters'].cast(postgresql.JSONB).has_key('tags'),
280
+ pipes_tbl.c['parameters']['tags'].cast(
281
+ postgresql.JSONB
282
+ ).contains(_in_tags)
283
+ )
284
+ )
285
+ for xt in _ex_tags:
286
+ nands.append(
287
+ sqlalchemy.not_(
288
+ sqlalchemy.and_(
289
+ pipes_tbl.c['parameters'].cast(postgresql.JSONB).has_key('tags'),
290
+ pipes_tbl.c['parameters']['tags'].cast(
291
+ postgresql.JSONB
292
+ ).contains([xt])
293
+ )
294
+ )
295
+ )
296
+ else:
297
+ for _in_tags, _ex_tags in in_ex_tag_groups:
298
+ sub_ands = []
299
+ for nt in _in_tags:
300
+ sub_ands.append(
301
+ sqlalchemy.cast(
302
+ pipes_tbl.c['parameters'],
303
+ sqlalchemy.String,
304
+ ).like(f'%"tags":%"{nt}"%')
305
+ )
306
+ if sub_ands:
307
+ ors.append(sqlalchemy.and_(*sub_ands))
308
+
309
+ for xt in _ex_tags:
310
+ nands.append(
311
+ sqlalchemy.cast(
312
+ pipes_tbl.c['parameters'],
313
+ sqlalchemy.String,
314
+ ).not_like(f'%"tags":%"{xt}"%')
315
+ )
281
316
 
282
317
  q = q.where(sqlalchemy.and_(*nands)) if nands else q
283
318
  q = q.where(sqlalchemy.or_(*ors)) if ors else q
@@ -292,7 +327,7 @@ def fetch_pipes_keys(
292
327
 
293
328
  ### execute the query and return a list of tuples
294
329
  if debug:
295
- dprint(q.compile(compile_kwargs={'literal_binds': True}))
330
+ dprint(q)
296
331
  try:
297
332
  rows = (
298
333
  self.execute(q).fetchall()