meerschaum 3.0.0rc1__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 (66) hide show
  1. meerschaum/_internal/arguments/_parser.py +2 -1
  2. meerschaum/_internal/docs/index.py +49 -2
  3. meerschaum/_internal/shell/Shell.py +5 -4
  4. meerschaum/_internal/static.py +8 -24
  5. meerschaum/actions/bootstrap.py +1 -1
  6. meerschaum/actions/edit.py +6 -3
  7. meerschaum/actions/start.py +1 -1
  8. meerschaum/actions/verify.py +5 -8
  9. meerschaum/api/__init__.py +2 -1
  10. meerschaum/api/dash/__init__.py +0 -2
  11. meerschaum/api/dash/callbacks/__init__.py +1 -0
  12. meerschaum/api/dash/callbacks/dashboard.py +20 -19
  13. meerschaum/api/dash/callbacks/jobs.py +11 -5
  14. meerschaum/api/dash/callbacks/pipes.py +106 -5
  15. meerschaum/api/dash/callbacks/settings/__init__.py +0 -1
  16. meerschaum/api/dash/callbacks/{settings/tokens.py → tokens.py} +1 -1
  17. meerschaum/api/dash/jobs.py +1 -1
  18. meerschaum/api/dash/pages/__init__.py +2 -1
  19. meerschaum/api/dash/pages/{job.py → jobs.py} +10 -7
  20. meerschaum/api/dash/pages/pipes.py +4 -3
  21. meerschaum/api/dash/pages/settings/__init__.py +0 -1
  22. meerschaum/api/dash/pages/{settings/tokens.py → tokens.py} +6 -8
  23. meerschaum/api/dash/pipes.py +131 -0
  24. meerschaum/api/dash/tokens.py +28 -31
  25. meerschaum/api/routes/_pipes.py +47 -37
  26. meerschaum/config/_default.py +13 -2
  27. meerschaum/config/_paths.py +1 -0
  28. meerschaum/config/_version.py +1 -1
  29. meerschaum/config/stack/__init__.py +9 -8
  30. meerschaum/connectors/api/_pipes.py +2 -18
  31. meerschaum/connectors/api/_tokens.py +2 -2
  32. meerschaum/connectors/instance/_tokens.py +10 -6
  33. meerschaum/connectors/sql/_SQLConnector.py +14 -0
  34. meerschaum/connectors/sql/_create_engine.py +3 -14
  35. meerschaum/connectors/sql/_pipes.py +175 -185
  36. meerschaum/connectors/sql/_sql.py +38 -20
  37. meerschaum/connectors/sql/tables/__init__.py +237 -122
  38. meerschaum/connectors/valkey/_pipes.py +44 -16
  39. meerschaum/core/Pipe/__init__.py +28 -5
  40. meerschaum/core/Pipe/_attributes.py +273 -46
  41. meerschaum/core/Pipe/_data.py +55 -17
  42. meerschaum/core/Pipe/_dtypes.py +19 -4
  43. meerschaum/core/Pipe/_edit.py +2 -0
  44. meerschaum/core/Pipe/_fetch.py +1 -1
  45. meerschaum/core/Pipe/_sync.py +90 -160
  46. meerschaum/core/Pipe/_verify.py +3 -3
  47. meerschaum/core/Token/_Token.py +4 -5
  48. meerschaum/plugins/bootstrap.py +508 -3
  49. meerschaum/utils/_get_pipes.py +1 -1
  50. meerschaum/utils/dataframe.py +385 -68
  51. meerschaum/utils/debug.py +15 -15
  52. meerschaum/utils/dtypes/__init__.py +387 -22
  53. meerschaum/utils/dtypes/sql.py +327 -31
  54. meerschaum/utils/misc.py +9 -68
  55. meerschaum/utils/packages/__init__.py +7 -21
  56. meerschaum/utils/packages/_packages.py +7 -2
  57. meerschaum/utils/schedule.py +1 -1
  58. meerschaum/utils/sql.py +8 -8
  59. {meerschaum-3.0.0rc1.dist-info → meerschaum-3.0.0rc3.dist-info}/METADATA +5 -17
  60. {meerschaum-3.0.0rc1.dist-info → meerschaum-3.0.0rc3.dist-info}/RECORD +66 -65
  61. meerschaum-3.0.0rc3.dist-info/licenses/NOTICE +2 -0
  62. {meerschaum-3.0.0rc1.dist-info → meerschaum-3.0.0rc3.dist-info}/WHEEL +0 -0
  63. {meerschaum-3.0.0rc1.dist-info → meerschaum-3.0.0rc3.dist-info}/entry_points.txt +0 -0
  64. {meerschaum-3.0.0rc1.dist-info → meerschaum-3.0.0rc3.dist-info}/licenses/LICENSE +0 -0
  65. {meerschaum-3.0.0rc1.dist-info → meerschaum-3.0.0rc3.dist-info}/top_level.txt +0 -0
  66. {meerschaum-3.0.0rc1.dist-info → meerschaum-3.0.0rc3.dist-info}/zip-safe +0 -0
@@ -191,7 +191,7 @@ def sync_pipe(
191
191
  from meerschaum.utils.misc import items_str, interval_str
192
192
  from meerschaum.config import get_config
193
193
  from meerschaum.utils.packages import attempt_import
194
- from meerschaum.utils.dataframe import get_numeric_cols, to_json
194
+ from meerschaum.utils.dataframe import get_special_cols, to_json
195
195
  begin = time.perf_counter()
196
196
  more_itertools = attempt_import('more_itertools')
197
197
  if df is None:
@@ -223,22 +223,6 @@ def sync_pipe(
223
223
  else [partition.compute() for partition in df.partitions]
224
224
  )
225
225
 
226
- numeric_cols = get_numeric_cols(df)
227
- if numeric_cols:
228
- for col in numeric_cols:
229
- df[col] = df[col].apply(lambda x: f'{x:f}' if isinstance(x, Decimal) else x)
230
- pipe_dtypes = pipe.dtypes
231
- new_numeric_cols = [
232
- col
233
- for col in numeric_cols
234
- if pipe_dtypes.get(col, None) != 'numeric'
235
- ]
236
- edit_success, edit_msg = pipe.update_parameters({'dtypes': {col: 'numeric' for col in new_numeric_cols}})
237
- if not edit_success:
238
- warn(
239
- "Failed to update new numeric columns "
240
- + f"{items_str(new_numeric_cols)}:\n{edit_msg}"
241
- )
242
226
  elif isinstance(df, dict):
243
227
  ### `_chunks` is a dict of lists of dicts.
244
228
  ### e.g. {'a' : [ {'a':[1, 2]}, {'a':[3, 4]} ] }
@@ -325,7 +309,7 @@ def sync_pipe(
325
309
  def delete_pipe(
326
310
  self,
327
311
  pipe: Optional[mrsm.Pipe] = None,
328
- debug: bool = None,
312
+ debug: bool = False,
329
313
  ) -> SuccessTuple:
330
314
  """Delete a Pipe and drop its table."""
331
315
  if pipe is None:
@@ -12,7 +12,6 @@ from typing import Union, List, Optional
12
12
 
13
13
  import meerschaum as mrsm
14
14
  from meerschaum.core import Token
15
- from meerschaum.models import TokenModel
16
15
  from meerschaum._internal.static import STATIC_CONFIG
17
16
  tokens_endpoint = STATIC_CONFIG['api']['endpoints']['tokens']
18
17
 
@@ -45,10 +44,11 @@ def register_token(self, token: Token, debug: bool = False) -> mrsm.SuccessTuple
45
44
  return True, f"Registered token '{token.label}'."
46
45
 
47
46
 
48
- def get_token_model(self, token_id: uuid.UUID, debug: bool = False) -> Union[TokenModel, None]:
47
+ def get_token_model(self, token_id: uuid.UUID, debug: bool = False) -> 'Union[TokenModel, None]':
49
48
  """
50
49
  Return a token's model from the API instance.
51
50
  """
51
+ from meerschaum.models import TokenModel
52
52
  r_url = tokens_endpoint + f'/{token_id}'
53
53
  response = self.get(r_url, debug=debug)
54
54
  if not response:
@@ -14,7 +14,6 @@ from datetime import datetime, timezone
14
14
  import meerschaum as mrsm
15
15
  from meerschaum.core import Token, User
16
16
  from meerschaum.core.User import hash_password
17
- from meerschaum.models import TokenModel
18
17
  from meerschaum._internal.static import STATIC_CONFIG
19
18
 
20
19
 
@@ -43,8 +42,8 @@ def get_tokens_pipe(self) -> mrsm.Pipe:
43
42
  },
44
43
  dtypes={
45
44
  'id': 'uuid',
46
- 'creation': 'datetime64[ns, UTC]',
47
- 'expiration': 'datetime64[ns, UTC]',
45
+ 'creation': 'datetime',
46
+ 'expiration': 'datetime',
48
47
  'is_valid': 'bool',
49
48
  'label': 'string',
50
49
  'user_id': user_id_dtype,
@@ -54,7 +53,11 @@ def get_tokens_pipe(self) -> mrsm.Pipe:
54
53
  )
55
54
 
56
55
 
57
- 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:
58
61
  """
59
62
  Register the new token to the tokens table.
60
63
  """
@@ -62,7 +65,7 @@ def register_token(self, token: Token, debug: bool = False) -> mrsm.SuccessTuple
62
65
  tokens_pipe = self.get_tokens_pipe()
63
66
  user_id = self.get_user_id(token.user) if token.user is not None else None
64
67
  if user_id is None:
65
- raise ValueError("Cannot register a token without a user.")
68
+ return False, "Cannot register a token without a user."
66
69
 
67
70
  doc = {
68
71
  'id': token_id,
@@ -227,10 +230,11 @@ def get_token(self, token_id: Union[uuid.UUID, str], debug: bool = False) -> Uni
227
230
  return Token(**dict(token_model))
228
231
 
229
232
 
230
- def get_token_model(self, token_id: Union[uuid.UUID, Token], debug: bool = False) -> Union[TokenModel, None]:
233
+ def get_token_model(self, token_id: Union[uuid.UUID, Token], debug: bool = False) -> 'Union[TokenModel, None]':
231
234
  """
232
235
  Return a token's model from the instance.
233
236
  """
237
+ from meerschaum.models import TokenModel
234
238
  if isinstance(token_id, Token):
235
239
  token_id = Token.id
236
240
  if not 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
 
@@ -31,7 +31,6 @@ install_flavor_drivers = {
31
31
  'mssql': ['pyodbc'],
32
32
  'oracle': ['oracledb'],
33
33
  }
34
- require_patching_flavors = {'cockroachdb': [('sqlalchemy-cockroachdb', 'sqlalchemy_cockroachdb')]}
35
34
 
36
35
  flavor_dialects = {
37
36
  'cockroachdb': (
@@ -63,19 +62,6 @@ def create_engine(
63
62
  )
64
63
  if self.flavor == 'mssql':
65
64
  _init_mssql_sqlalchemy()
66
- if self.flavor in require_patching_flavors:
67
- from meerschaum.utils.packages import determine_version, _monkey_patch_get_distribution
68
- import pathlib
69
- for install_name, import_name in require_patching_flavors[self.flavor]:
70
- pkg = attempt_import(
71
- import_name,
72
- debug=debug,
73
- lazy=False,
74
- warn=False
75
- )
76
- _monkey_patch_get_distribution(
77
- install_name, determine_version(pathlib.Path(pkg.__file__), venv='mrsm')
78
- )
79
65
 
80
66
  ### supplement missing values with defaults (e.g. port number)
81
67
  for a, value in flavor_configs[self.flavor]['defaults'].items():
@@ -189,6 +175,9 @@ def _init_mssql_sqlalchemy():
189
175
  lazy=False,
190
176
  warn=False,
191
177
  )
178
+ if pyodbc is None:
179
+ raise EnvironmentError("Cannot import pyodbc. Is the MSSQL driver installed?")
180
+
192
181
  pyodbc.pooling = False
193
182
 
194
183
  MSDialect_pyodbc = sqlalchemy_dialects_mssql_pyodbc.MSDialect_pyodbc