meerschaum 2.3.6__py3-none-any.whl → 2.4.0.dev1__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 (53) hide show
  1. meerschaum/actions/bootstrap.py +36 -10
  2. meerschaum/actions/copy.py +3 -3
  3. meerschaum/actions/start.py +13 -14
  4. meerschaum/api/dash/__init__.py +7 -6
  5. meerschaum/api/dash/callbacks/__init__.py +1 -0
  6. meerschaum/api/dash/callbacks/dashboard.py +7 -5
  7. meerschaum/api/dash/callbacks/pipes.py +42 -0
  8. meerschaum/api/dash/pages/__init__.py +1 -0
  9. meerschaum/api/dash/pages/pipes.py +16 -0
  10. meerschaum/api/dash/pipes.py +79 -47
  11. meerschaum/api/dash/users.py +19 -6
  12. meerschaum/api/routes/_login.py +4 -4
  13. meerschaum/api/routes/_pipes.py +3 -3
  14. meerschaum/config/_default.py +9 -1
  15. meerschaum/config/_version.py +1 -1
  16. meerschaum/config/stack/__init__.py +59 -16
  17. meerschaum/connectors/Connector.py +19 -13
  18. meerschaum/connectors/__init__.py +9 -5
  19. meerschaum/connectors/poll.py +30 -24
  20. meerschaum/connectors/sql/_pipes.py +126 -154
  21. meerschaum/connectors/sql/_plugins.py +45 -43
  22. meerschaum/connectors/sql/_users.py +46 -38
  23. meerschaum/connectors/valkey/ValkeyConnector.py +535 -0
  24. meerschaum/connectors/valkey/__init__.py +8 -0
  25. meerschaum/connectors/valkey/_fetch.py +75 -0
  26. meerschaum/connectors/valkey/_pipes.py +839 -0
  27. meerschaum/connectors/valkey/_plugins.py +265 -0
  28. meerschaum/connectors/valkey/_users.py +305 -0
  29. meerschaum/core/Pipe/__init__.py +3 -0
  30. meerschaum/core/Pipe/_attributes.py +1 -2
  31. meerschaum/core/Pipe/_clear.py +16 -13
  32. meerschaum/core/Pipe/_copy.py +106 -0
  33. meerschaum/core/Pipe/_drop.py +4 -4
  34. meerschaum/core/Pipe/_dtypes.py +14 -14
  35. meerschaum/core/Pipe/_edit.py +15 -14
  36. meerschaum/core/Pipe/_sync.py +134 -51
  37. meerschaum/core/Pipe/_verify.py +11 -11
  38. meerschaum/core/User/_User.py +14 -12
  39. meerschaum/plugins/_Plugin.py +17 -13
  40. meerschaum/utils/_get_pipes.py +14 -20
  41. meerschaum/utils/dataframe.py +288 -101
  42. meerschaum/utils/dtypes/__init__.py +31 -6
  43. meerschaum/utils/dtypes/sql.py +4 -4
  44. meerschaum/utils/misc.py +3 -3
  45. meerschaum/utils/packages/_packages.py +1 -0
  46. {meerschaum-2.3.6.dist-info → meerschaum-2.4.0.dev1.dist-info}/METADATA +3 -1
  47. {meerschaum-2.3.6.dist-info → meerschaum-2.4.0.dev1.dist-info}/RECORD +53 -44
  48. {meerschaum-2.3.6.dist-info → meerschaum-2.4.0.dev1.dist-info}/WHEEL +1 -1
  49. {meerschaum-2.3.6.dist-info → meerschaum-2.4.0.dev1.dist-info}/LICENSE +0 -0
  50. {meerschaum-2.3.6.dist-info → meerschaum-2.4.0.dev1.dist-info}/NOTICE +0 -0
  51. {meerschaum-2.3.6.dist-info → meerschaum-2.4.0.dev1.dist-info}/entry_points.txt +0 -0
  52. {meerschaum-2.3.6.dist-info → meerschaum-2.4.0.dev1.dist-info}/top_level.txt +0 -0
  53. {meerschaum-2.3.6.dist-info → meerschaum-2.4.0.dev1.dist-info}/zip-safe +0 -0
@@ -15,10 +15,10 @@ from meerschaum.utils.warnings import warn, error, info
15
15
  from meerschaum.utils.debug import dprint
16
16
 
17
17
  def register_pipe(
18
- self,
19
- pipe: mrsm.Pipe,
20
- debug: bool = False,
21
- ) -> SuccessTuple:
18
+ self,
19
+ pipe: mrsm.Pipe,
20
+ debug: bool = False,
21
+ ) -> SuccessTuple:
22
22
  """
23
23
  Register a new pipe.
24
24
  A pipe's attributes must be set before registering.
@@ -140,14 +140,14 @@ def edit_pipe(
140
140
 
141
141
 
142
142
  def fetch_pipes_keys(
143
- self,
144
- connector_keys: Optional[List[str]] = None,
145
- metric_keys: Optional[List[str]] = None,
146
- location_keys: Optional[List[str]] = None,
147
- tags: Optional[List[str]] = None,
148
- params: Optional[Dict[str, Any]] = None,
149
- debug: bool = False
150
- ) -> Optional[List[Tuple[str, str, Optional[str]]]]:
143
+ self,
144
+ connector_keys: Optional[List[str]] = None,
145
+ metric_keys: Optional[List[str]] = None,
146
+ location_keys: Optional[List[str]] = None,
147
+ tags: Optional[List[str]] = None,
148
+ params: Optional[Dict[str, Any]] = None,
149
+ debug: bool = False
150
+ ) -> Optional[List[Tuple[str, str, Optional[str]]]]:
151
151
  """
152
152
  Return a list of tuples corresponding to the parameters provided.
153
153
 
@@ -634,20 +634,20 @@ def delete_pipe(
634
634
 
635
635
 
636
636
  def get_pipe_data(
637
- self,
638
- pipe: mrsm.Pipe,
639
- select_columns: Optional[List[str]] = None,
640
- omit_columns: Optional[List[str]] = None,
641
- begin: Union[datetime, str, None] = None,
642
- end: Union[datetime, str, None] = None,
643
- params: Optional[Dict[str, Any]] = None,
644
- order: str = 'asc',
645
- limit: Optional[int] = None,
646
- begin_add_minutes: int = 0,
647
- end_add_minutes: int = 0,
648
- debug: bool = False,
649
- **kw: Any
650
- ) -> Union[pd.DataFrame, None]:
637
+ self,
638
+ pipe: mrsm.Pipe,
639
+ select_columns: Optional[List[str]] = None,
640
+ omit_columns: Optional[List[str]] = None,
641
+ begin: Union[datetime, str, None] = None,
642
+ end: Union[datetime, str, None] = None,
643
+ params: Optional[Dict[str, Any]] = None,
644
+ order: str = 'asc',
645
+ limit: Optional[int] = None,
646
+ begin_add_minutes: int = 0,
647
+ end_add_minutes: int = 0,
648
+ debug: bool = False,
649
+ **kw: Any
650
+ ) -> Union[pd.DataFrame, None]:
651
651
  """
652
652
  Access a pipe's data from the SQL instance.
653
653
 
@@ -746,19 +746,19 @@ def get_pipe_data(
746
746
  }
747
747
  query = self.get_pipe_data_query(
748
748
  pipe,
749
- select_columns = select_columns,
750
- omit_columns = omit_columns,
751
- begin = begin,
752
- end = end,
753
- params = params,
754
- order = order,
755
- limit = limit,
756
- begin_add_minutes = begin_add_minutes,
757
- end_add_minutes = end_add_minutes,
758
- debug = debug,
749
+ select_columns=select_columns,
750
+ omit_columns=omit_columns,
751
+ begin=begin,
752
+ end=end,
753
+ params=params,
754
+ order=order,
755
+ limit=limit,
756
+ begin_add_minutes=begin_add_minutes,
757
+ end_add_minutes=end_add_minutes,
758
+ debug=debug,
759
759
  **kw
760
760
  )
761
-
761
+
762
762
  if is_dask:
763
763
  index_col = pipe.columns.get('datetime', None)
764
764
  kw['index_col'] = index_col
@@ -769,11 +769,11 @@ def get_pipe_data(
769
769
  if typ == 'numeric' and col in dtypes
770
770
  ]
771
771
  kw['coerce_float'] = kw.get('coerce_float', (len(numeric_columns) == 0))
772
-
772
+
773
773
  df = self.read(
774
774
  query,
775
- dtype = dtypes,
776
- debug = debug,
775
+ dtype=dtypes,
776
+ debug=debug,
777
777
  **kw
778
778
  )
779
779
  for col in numeric_columns:
@@ -782,28 +782,25 @@ def get_pipe_data(
782
782
  df[col] = df[col].apply(attempt_cast_to_numeric)
783
783
 
784
784
  if self.flavor == 'sqlite':
785
+ ignore_dt_cols = [
786
+ col
787
+ for col, dtype in pipe.dtypes.items()
788
+ if 'datetime' not in str(dtype)
789
+ ]
785
790
  ### NOTE: We have to consume the iterator here to ensure that datetimes are parsed correctly
786
791
  df = (
787
792
  parse_df_datetimes(
788
793
  df,
789
- ignore_cols = [
790
- col
791
- for col, dtype in pipe.dtypes.items()
792
- if 'datetime' not in str(dtype)
793
- ],
794
- chunksize = kw.get('chunksize', None),
795
- debug = debug,
794
+ ignore_cols=ignore_dt_cols,
795
+ chunksize=kw.get('chunksize', None),
796
+ debug=debug,
796
797
  ) if isinstance(df, pd.DataFrame) else (
797
798
  [
798
799
  parse_df_datetimes(
799
800
  c,
800
- ignore_cols = [
801
- col
802
- for col, dtype in pipe.dtypes.items()
803
- if 'datetime' not in str(dtype)
804
- ],
801
+ ignore_cols=ignore_dt_cols,
805
802
  chunksize = kw.get('chunksize', None),
806
- debug = debug,
803
+ debug=debug,
807
804
  )
808
805
  for c in df
809
806
  ]
@@ -817,21 +814,21 @@ def get_pipe_data(
817
814
 
818
815
 
819
816
  def get_pipe_data_query(
820
- self,
821
- pipe: mrsm.Pipe,
822
- select_columns: Optional[List[str]] = None,
823
- omit_columns: Optional[List[str]] = None,
824
- begin: Union[datetime, int, str, None] = None,
825
- end: Union[datetime, int, str, None] = None,
826
- params: Optional[Dict[str, Any]] = None,
827
- order: str = 'asc',
828
- limit: Optional[int] = None,
829
- begin_add_minutes: int = 0,
830
- end_add_minutes: int = 0,
831
- replace_nulls: Optional[str] = None,
832
- debug: bool = False,
833
- **kw: Any
834
- ) -> Union[str, None]:
817
+ self,
818
+ pipe: mrsm.Pipe,
819
+ select_columns: Optional[List[str]] = None,
820
+ omit_columns: Optional[List[str]] = None,
821
+ begin: Union[datetime, int, str, None] = None,
822
+ end: Union[datetime, int, str, None] = None,
823
+ params: Optional[Dict[str, Any]] = None,
824
+ order: str = 'asc',
825
+ limit: Optional[int] = None,
826
+ begin_add_minutes: int = 0,
827
+ end_add_minutes: int = 0,
828
+ replace_nulls: Optional[str] = None,
829
+ debug: bool = False,
830
+ **kw: Any
831
+ ) -> Union[str, None]:
835
832
  """
836
833
  Return the `SELECT` query for retrieving a pipe's data from its instance.
837
834
 
@@ -1107,18 +1104,18 @@ def get_pipe_attributes(
1107
1104
 
1108
1105
 
1109
1106
  def sync_pipe(
1110
- self,
1111
- pipe: mrsm.Pipe,
1112
- df: Union[pd.DataFrame, str, Dict[Any, Any], None] = None,
1113
- begin: Optional[datetime] = None,
1114
- end: Optional[datetime] = None,
1115
- chunksize: Optional[int] = -1,
1116
- check_existing: bool = True,
1117
- blocking: bool = True,
1118
- debug: bool = False,
1119
- _check_temporary_tables: bool = True,
1120
- **kw: Any
1121
- ) -> SuccessTuple:
1107
+ self,
1108
+ pipe: mrsm.Pipe,
1109
+ df: Union[pd.DataFrame, str, Dict[Any, Any], None] = None,
1110
+ begin: Optional[datetime] = None,
1111
+ end: Optional[datetime] = None,
1112
+ chunksize: Optional[int] = -1,
1113
+ check_existing: bool = True,
1114
+ blocking: bool = True,
1115
+ debug: bool = False,
1116
+ _check_temporary_tables: bool = True,
1117
+ **kw: Any
1118
+ ) -> SuccessTuple:
1122
1119
  """
1123
1120
  Sync a pipe using a database connection.
1124
1121
 
@@ -1191,9 +1188,9 @@ def sync_pipe(
1191
1188
  if not isinstance(df, pd.DataFrame):
1192
1189
  df = pipe.enforce_dtypes(
1193
1190
  df,
1194
- chunksize = chunksize,
1195
- safe_copy = kw.get('safe_copy', False),
1196
- debug = debug,
1191
+ chunksize=chunksize,
1192
+ safe_copy=kw.get('safe_copy', False),
1193
+ debug=debug,
1197
1194
  )
1198
1195
 
1199
1196
  ### if table does not exist, create it with indices
@@ -1243,8 +1240,8 @@ def sync_pipe(
1243
1240
  unseen_df, update_df, delta_df = (
1244
1241
  pipe.filter_existing(
1245
1242
  df,
1246
- chunksize = chunksize,
1247
- debug = debug,
1243
+ chunksize=chunksize,
1244
+ debug=debug,
1248
1245
  **kw
1249
1246
  ) if check_existing else (df, None, df)
1250
1247
  )
@@ -1263,31 +1260,6 @@ def sync_pipe(
1263
1260
  if 'name' in kw:
1264
1261
  kw.pop('name')
1265
1262
 
1266
- ### Account for first-time syncs of JSON columns.
1267
- unseen_json_cols = get_json_cols(unseen_df)
1268
- update_json_cols = get_json_cols(update_df) if update_df is not None else []
1269
- json_cols = list(set(unseen_json_cols + update_json_cols))
1270
- existing_json_cols = [col for col, typ in pipe.dtypes.items() if typ == 'json']
1271
- new_json_cols = [col for col in json_cols if col not in existing_json_cols]
1272
- if new_json_cols:
1273
- pipe.dtypes.update({col: 'json' for col in json_cols})
1274
- if not pipe.temporary:
1275
- edit_success, edit_msg = pipe.edit(interactive=False, debug=debug)
1276
- if not edit_success:
1277
- warn(f"Unable to update JSON dtypes for {pipe}:\n{edit_msg}")
1278
-
1279
- unseen_numeric_cols = get_numeric_cols(unseen_df)
1280
- update_numeric_cols = get_numeric_cols(update_df) if update_df is not None else []
1281
- numeric_cols = list(set(unseen_numeric_cols + update_numeric_cols))
1282
- existing_numeric_cols = [col for col, typ in pipe.dtypes.items() if typ == 'numeric']
1283
- new_numeric_cols = [col for col in numeric_cols if col not in existing_numeric_cols]
1284
- if new_numeric_cols:
1285
- pipe.dtypes.update({col: 'numeric' for col in numeric_cols})
1286
- if not pipe.temporary:
1287
- edit_success, edit_msg = pipe.edit(interactive=False, debug=debug)
1288
- if not edit_success:
1289
- warn(f"Unable to update NUMERIC dtypes for {pipe}:\n{edit_msg}")
1290
-
1291
1263
  ### Insert new data into Pipe's table.
1292
1264
  unseen_kw = copy.deepcopy(kw)
1293
1265
  unseen_kw.update({
@@ -1326,16 +1298,16 @@ def sync_pipe(
1326
1298
  self._log_temporary_tables_creation(temp_target, create=(not pipe.temporary), debug=debug)
1327
1299
  temp_pipe = Pipe(
1328
1300
  pipe.connector_keys.replace(':', '_') + '_', pipe.metric_key, pipe.location_key,
1329
- instance = pipe.instance_keys,
1330
- columns = {
1301
+ instance=pipe.instance_keys,
1302
+ columns={
1331
1303
  ix_key: ix
1332
1304
  for ix_key, ix in pipe.columns.items()
1333
1305
  if ix and ix in update_df.columns
1334
1306
  },
1335
- dtypes = pipe.dtypes,
1336
- target = temp_target,
1337
- temporary = True,
1338
- parameters = {
1307
+ dtypes=pipe.dtypes,
1308
+ target=temp_target,
1309
+ temporary=True,
1310
+ parameters={
1339
1311
  'schema': self.internal_schema,
1340
1312
  'hypertable': False,
1341
1313
  },
@@ -1352,20 +1324,20 @@ def sync_pipe(
1352
1324
  temp_target,
1353
1325
  self,
1354
1326
  join_cols,
1355
- upsert = upsert,
1356
- schema = self.get_pipe_schema(pipe),
1357
- patch_schema = self.internal_schema,
1358
- datetime_col = pipe.columns.get('datetime', None),
1359
- debug = debug,
1327
+ upsert=upsert,
1328
+ schema=self.get_pipe_schema(pipe),
1329
+ patch_schema=self.internal_schema,
1330
+ datetime_col=pipe.columns.get('datetime', None),
1331
+ debug=debug,
1360
1332
  )
1361
1333
  update_success = all(
1362
1334
  self.exec_queries(update_queries, break_on_error=True, rollback=True, debug=debug)
1363
1335
  )
1364
1336
  self._log_temporary_tables_creation(
1365
1337
  temp_target,
1366
- ready_to_drop = True,
1367
- create = (not pipe.temporary),
1368
- debug = debug,
1338
+ ready_to_drop=True,
1339
+ create=(not pipe.temporary),
1340
+ debug=debug,
1369
1341
  )
1370
1342
  if not update_success:
1371
1343
  warn(f"Failed to apply update to {pipe}.")
@@ -1406,16 +1378,16 @@ def sync_pipe(
1406
1378
 
1407
1379
 
1408
1380
  def sync_pipe_inplace(
1409
- self,
1410
- pipe: 'mrsm.Pipe',
1411
- params: Optional[Dict[str, Any]] = None,
1412
- begin: Optional[datetime] = None,
1413
- end: Optional[datetime] = None,
1414
- chunksize: Optional[int] = -1,
1415
- check_existing: bool = True,
1416
- debug: bool = False,
1417
- **kw: Any
1418
- ) -> SuccessTuple:
1381
+ self,
1382
+ pipe: 'mrsm.Pipe',
1383
+ params: Optional[Dict[str, Any]] = None,
1384
+ begin: Optional[datetime] = None,
1385
+ end: Optional[datetime] = None,
1386
+ chunksize: Optional[int] = -1,
1387
+ check_existing: bool = True,
1388
+ debug: bool = False,
1389
+ **kw: Any
1390
+ ) -> SuccessTuple:
1419
1391
  """
1420
1392
  If a pipe's connector is the same as its instance connector,
1421
1393
  it's more efficient to sync the pipe in-place rather than reading data into Pandas.
@@ -1455,13 +1427,13 @@ def sync_pipe_inplace(
1455
1427
  """
1456
1428
  if self.flavor == 'duckdb':
1457
1429
  return pipe.sync(
1458
- params = params,
1459
- begin = begin,
1460
- end = end,
1461
- chunksize = chunksize,
1462
- check_existing = check_existing,
1463
- debug = debug,
1464
- _inplace = False,
1430
+ params=params,
1431
+ begin=begin,
1432
+ end=end,
1433
+ chunksize=chunksize,
1434
+ check_existing=check_existing,
1435
+ debug=debug,
1436
+ _inplace=False,
1465
1437
  **kw
1466
1438
  )
1467
1439
  from meerschaum.utils.sql import (
@@ -2062,14 +2034,14 @@ def pipe_exists(
2062
2034
 
2063
2035
 
2064
2036
  def get_pipe_rowcount(
2065
- self,
2066
- pipe: mrsm.Pipe,
2067
- begin: Union[datetime, int, None] = None,
2068
- end: Union[datetime, int, None] = None,
2069
- params: Optional[Dict[str, Any]] = None,
2070
- remote: bool = False,
2071
- debug: bool = False
2072
- ) -> Union[int, None]:
2037
+ self,
2038
+ pipe: mrsm.Pipe,
2039
+ begin: Union[datetime, int, None] = None,
2040
+ end: Union[datetime, int, None] = None,
2041
+ params: Optional[Dict[str, Any]] = None,
2042
+ remote: bool = False,
2043
+ debug: bool = False
2044
+ ) -> Union[int, None]:
2073
2045
  """
2074
2046
  Get the rowcount for a pipe in accordance with given parameters.
2075
2047
 
@@ -2411,11 +2383,11 @@ def get_pipe_columns_types(
2411
2383
 
2412
2384
 
2413
2385
  def get_add_columns_queries(
2414
- self,
2415
- pipe: mrsm.Pipe,
2416
- df: Union[pd.DataFrame, Dict[str, str]],
2417
- debug: bool = False,
2418
- ) -> List[str]:
2386
+ self,
2387
+ pipe: mrsm.Pipe,
2388
+ df: Union[pd.DataFrame, Dict[str, str]],
2389
+ debug: bool = False,
2390
+ ) -> List[str]:
2419
2391
  """
2420
2392
  Add new null columns of the correct type to a table from a dataframe.
2421
2393
 
@@ -7,15 +7,19 @@ Functions for managing plugins registration via the SQL connector
7
7
  """
8
8
 
9
9
  from __future__ import annotations
10
+
11
+ import json
12
+
13
+ import meerschaum as mrsm
10
14
  from meerschaum.utils.typing import Optional, Any, List, SuccessTuple, Dict
11
15
 
12
16
  def register_plugin(
13
- self,
14
- plugin: 'meerschaum.core.Plugin',
15
- force: bool = False,
16
- debug: bool = False,
17
- **kw: Any
18
- ) -> SuccessTuple:
17
+ self,
18
+ plugin: 'mrsm.core.Plugin',
19
+ force: bool = False,
20
+ debug: bool = False,
21
+ **kw: Any
22
+ ) -> SuccessTuple:
19
23
  """Register a new plugin to the plugins table."""
20
24
  from meerschaum.utils.warnings import warn, error
21
25
  from meerschaum.utils.packages import attempt_import
@@ -46,14 +50,13 @@ def register_plugin(
46
50
  f"must be greater than existing version '{old_version}'."
47
51
  )
48
52
 
49
- import json
50
53
  bind_variables = {
51
- 'plugin_name' : plugin.name,
52
- 'version' : plugin.version,
53
- 'attributes' : (
54
+ 'plugin_name': plugin.name,
55
+ 'version': plugin.version,
56
+ 'attributes': (
54
57
  json.dumps(plugin.attributes) if self.flavor not in json_flavors else plugin.attributes
55
58
  ),
56
- 'user_id' : plugin.user_id,
59
+ 'user_id': plugin.user_id,
57
60
  }
58
61
 
59
62
  if old_id is None:
@@ -71,10 +74,10 @@ def register_plugin(
71
74
  return True, f"Successfully registered plugin '{plugin}'."
72
75
 
73
76
  def get_plugin_id(
74
- self,
75
- plugin: 'meerschaum.core.Plugin',
76
- debug: bool = False
77
- ) -> Optional[int]:
77
+ self,
78
+ plugin: 'mrsm.core.Plugin',
79
+ debug: bool = False
80
+ ) -> Optional[int]:
78
81
  """
79
82
  Return a plugin's ID.
80
83
  """
@@ -96,10 +99,10 @@ def get_plugin_id(
96
99
  return None
97
100
 
98
101
  def get_plugin_version(
99
- self,
100
- plugin: 'meerschaum.core.Plugin',
101
- debug: bool = False
102
- ) -> Optional[str]:
102
+ self,
103
+ plugin: 'mrsm.core.Plugin',
104
+ debug: bool = False
105
+ ) -> Optional[str]:
103
106
  """
104
107
  Return a plugin's version.
105
108
  """
@@ -112,10 +115,10 @@ def get_plugin_version(
112
115
  return self.value(query, debug=debug)
113
116
 
114
117
  def get_plugin_user_id(
115
- self,
116
- plugin: 'meerschaum.core.Plugin',
117
- debug: bool = False
118
- ) -> Optional[int]:
118
+ self,
119
+ plugin: 'mrsm.core.Plugin',
120
+ debug: bool = False
121
+ ) -> Optional[int]:
119
122
  """
120
123
  Return a plugin's user ID.
121
124
  """
@@ -137,10 +140,10 @@ def get_plugin_user_id(
137
140
  return None
138
141
 
139
142
  def get_plugin_username(
140
- self,
141
- plugin: 'meerschaum.core.Plugin',
142
- debug: bool = False
143
- ) -> Optional[str]:
143
+ self,
144
+ plugin: 'mrsm.core.Plugin',
145
+ debug: bool = False
146
+ ) -> Optional[str]:
144
147
  """
145
148
  Return the username of a plugin's owner.
146
149
  """
@@ -163,16 +166,15 @@ def get_plugin_username(
163
166
 
164
167
 
165
168
  def get_plugin_attributes(
166
- self,
167
- plugin: 'meerschaum.core.Plugin',
168
- debug: bool = False
169
- ) -> Dict[str, Any]:
169
+ self,
170
+ plugin: 'mrsm.core.Plugin',
171
+ debug: bool = False
172
+ ) -> Dict[str, Any]:
170
173
  """
171
174
  Return the attributes of a plugin.
172
175
  """
173
176
  ### ensure plugins table exists
174
177
  from meerschaum.connectors.sql.tables import get_tables
175
- import json
176
178
  plugins_tbl = get_tables(mrsm_instance=self, debug=debug)['plugins']
177
179
  from meerschaum.utils.packages import attempt_import
178
180
  sqlalchemy = attempt_import('sqlalchemy')
@@ -191,12 +193,12 @@ def get_plugin_attributes(
191
193
  return _attr
192
194
 
193
195
  def get_plugins(
194
- self,
195
- user_id: Optional[int] = None,
196
- search_term: Optional[str] = None,
197
- debug: bool = False,
198
- **kw: Any
199
- ) -> List[str]:
196
+ self,
197
+ user_id: Optional[int] = None,
198
+ search_term: Optional[str] = None,
199
+ debug: bool = False,
200
+ **kw: Any
201
+ ) -> List[str]:
200
202
  """
201
203
  Return a list of all registered plugins.
202
204
 
@@ -238,11 +240,11 @@ def get_plugins(
238
240
 
239
241
 
240
242
  def delete_plugin(
241
- self,
242
- plugin: 'meerschaum.core.Plugin',
243
- debug: bool = False,
244
- **kw: Any
245
- ) -> SuccessTuple:
243
+ self,
244
+ plugin: 'mrsm.core.Plugin',
245
+ debug: bool = False,
246
+ **kw: Any
247
+ ) -> SuccessTuple:
246
248
  """Delete a plugin from the plugins table."""
247
249
  from meerschaum.utils.warnings import warn, error
248
250
  from meerschaum.utils.packages import attempt_import