meerschaum 2.9.5__py3-none-any.whl → 3.0.0rc2__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 (158) hide show
  1. meerschaum/__init__.py +5 -2
  2. meerschaum/_internal/__init__.py +1 -0
  3. meerschaum/_internal/arguments/_parse_arguments.py +4 -4
  4. meerschaum/_internal/arguments/_parser.py +19 -2
  5. meerschaum/_internal/docs/index.py +49 -2
  6. meerschaum/_internal/entry.py +6 -6
  7. meerschaum/_internal/shell/Shell.py +1 -1
  8. meerschaum/_internal/static.py +356 -0
  9. meerschaum/actions/api.py +12 -2
  10. meerschaum/actions/bootstrap.py +7 -7
  11. meerschaum/actions/edit.py +142 -18
  12. meerschaum/actions/register.py +137 -6
  13. meerschaum/actions/show.py +117 -29
  14. meerschaum/actions/stop.py +4 -1
  15. meerschaum/actions/sync.py +1 -1
  16. meerschaum/actions/tag.py +9 -8
  17. meerschaum/actions/verify.py +5 -8
  18. meerschaum/api/__init__.py +11 -3
  19. meerschaum/api/_events.py +39 -2
  20. meerschaum/api/_oauth2.py +118 -8
  21. meerschaum/api/_tokens.py +102 -0
  22. meerschaum/api/dash/__init__.py +0 -3
  23. meerschaum/api/dash/callbacks/custom.py +2 -2
  24. meerschaum/api/dash/callbacks/dashboard.py +103 -19
  25. meerschaum/api/dash/callbacks/plugins.py +0 -1
  26. meerschaum/api/dash/callbacks/register.py +1 -1
  27. meerschaum/api/dash/callbacks/settings/__init__.py +1 -0
  28. meerschaum/api/dash/callbacks/settings/password_reset.py +2 -2
  29. meerschaum/api/dash/callbacks/settings/tokens.py +388 -0
  30. meerschaum/api/dash/components.py +30 -8
  31. meerschaum/api/dash/keys.py +19 -93
  32. meerschaum/api/dash/pages/dashboard.py +1 -20
  33. meerschaum/api/dash/pages/settings/__init__.py +1 -0
  34. meerschaum/api/dash/pages/settings/password_reset.py +1 -1
  35. meerschaum/api/dash/pages/settings/tokens.py +55 -0
  36. meerschaum/api/dash/pipes.py +94 -59
  37. meerschaum/api/dash/sessions.py +12 -0
  38. meerschaum/api/dash/tokens.py +606 -0
  39. meerschaum/api/dash/websockets.py +1 -1
  40. meerschaum/api/dash/webterm.py +4 -0
  41. meerschaum/api/models/__init__.py +23 -3
  42. meerschaum/api/models/_actions.py +22 -0
  43. meerschaum/api/models/_pipes.py +85 -7
  44. meerschaum/api/models/_tokens.py +81 -0
  45. meerschaum/api/resources/templates/termpage.html +12 -0
  46. meerschaum/api/routes/__init__.py +1 -0
  47. meerschaum/api/routes/_actions.py +3 -4
  48. meerschaum/api/routes/_connectors.py +3 -7
  49. meerschaum/api/routes/_jobs.py +14 -35
  50. meerschaum/api/routes/_login.py +49 -12
  51. meerschaum/api/routes/_misc.py +5 -10
  52. meerschaum/api/routes/_pipes.py +173 -140
  53. meerschaum/api/routes/_plugins.py +38 -28
  54. meerschaum/api/routes/_tokens.py +236 -0
  55. meerschaum/api/routes/_users.py +47 -35
  56. meerschaum/api/routes/_version.py +3 -3
  57. meerschaum/config/__init__.py +43 -20
  58. meerschaum/config/_default.py +43 -6
  59. meerschaum/config/_edit.py +28 -24
  60. meerschaum/config/_environment.py +1 -1
  61. meerschaum/config/_patch.py +6 -6
  62. meerschaum/config/_paths.py +5 -1
  63. meerschaum/config/_read_config.py +65 -34
  64. meerschaum/config/_sync.py +6 -3
  65. meerschaum/config/_version.py +1 -1
  66. meerschaum/config/stack/__init__.py +31 -11
  67. meerschaum/config/static.py +18 -0
  68. meerschaum/connectors/_Connector.py +10 -4
  69. meerschaum/connectors/__init__.py +4 -20
  70. meerschaum/connectors/api/_APIConnector.py +34 -6
  71. meerschaum/connectors/api/_actions.py +2 -2
  72. meerschaum/connectors/api/_jobs.py +1 -1
  73. meerschaum/connectors/api/_login.py +33 -7
  74. meerschaum/connectors/api/_misc.py +2 -2
  75. meerschaum/connectors/api/_pipes.py +16 -31
  76. meerschaum/connectors/api/_plugins.py +2 -2
  77. meerschaum/connectors/api/_request.py +1 -1
  78. meerschaum/connectors/api/_tokens.py +146 -0
  79. meerschaum/connectors/api/_users.py +70 -58
  80. meerschaum/connectors/instance/_InstanceConnector.py +83 -0
  81. meerschaum/connectors/instance/__init__.py +10 -0
  82. meerschaum/connectors/instance/_pipes.py +442 -0
  83. meerschaum/connectors/instance/_plugins.py +151 -0
  84. meerschaum/connectors/instance/_tokens.py +296 -0
  85. meerschaum/connectors/instance/_users.py +181 -0
  86. meerschaum/connectors/parse.py +4 -1
  87. meerschaum/connectors/sql/_SQLConnector.py +8 -5
  88. meerschaum/connectors/sql/_cli.py +12 -11
  89. meerschaum/connectors/sql/_create_engine.py +9 -168
  90. meerschaum/connectors/sql/_fetch.py +2 -18
  91. meerschaum/connectors/sql/_pipes.py +156 -190
  92. meerschaum/connectors/sql/_plugins.py +29 -0
  93. meerschaum/connectors/sql/_sql.py +46 -21
  94. meerschaum/connectors/sql/_users.py +29 -2
  95. meerschaum/connectors/sql/tables/__init__.py +1 -1
  96. meerschaum/connectors/valkey/_ValkeyConnector.py +2 -4
  97. meerschaum/connectors/valkey/_pipes.py +53 -26
  98. meerschaum/connectors/valkey/_plugins.py +2 -26
  99. meerschaum/core/Pipe/__init__.py +59 -19
  100. meerschaum/core/Pipe/_attributes.py +412 -90
  101. meerschaum/core/Pipe/_bootstrap.py +54 -24
  102. meerschaum/core/Pipe/_data.py +96 -18
  103. meerschaum/core/Pipe/_dtypes.py +48 -18
  104. meerschaum/core/Pipe/_edit.py +14 -4
  105. meerschaum/core/Pipe/_fetch.py +1 -1
  106. meerschaum/core/Pipe/_show.py +5 -5
  107. meerschaum/core/Pipe/_sync.py +118 -193
  108. meerschaum/core/Pipe/_verify.py +4 -4
  109. meerschaum/{plugins → core/Plugin}/_Plugin.py +9 -11
  110. meerschaum/core/Plugin/__init__.py +1 -1
  111. meerschaum/core/Token/_Token.py +220 -0
  112. meerschaum/core/Token/__init__.py +12 -0
  113. meerschaum/core/User/_User.py +34 -8
  114. meerschaum/core/User/__init__.py +9 -1
  115. meerschaum/core/__init__.py +1 -0
  116. meerschaum/jobs/_Job.py +3 -2
  117. meerschaum/jobs/__init__.py +3 -2
  118. meerschaum/jobs/systemd.py +1 -1
  119. meerschaum/models/__init__.py +35 -0
  120. meerschaum/models/pipes.py +247 -0
  121. meerschaum/models/tokens.py +38 -0
  122. meerschaum/models/users.py +26 -0
  123. meerschaum/plugins/__init__.py +22 -7
  124. meerschaum/plugins/bootstrap.py +2 -1
  125. meerschaum/utils/_get_pipes.py +68 -27
  126. meerschaum/utils/daemon/Daemon.py +2 -1
  127. meerschaum/utils/daemon/__init__.py +30 -2
  128. meerschaum/utils/dataframe.py +473 -81
  129. meerschaum/utils/debug.py +15 -15
  130. meerschaum/utils/dtypes/__init__.py +473 -34
  131. meerschaum/utils/dtypes/sql.py +368 -28
  132. meerschaum/utils/formatting/__init__.py +1 -1
  133. meerschaum/utils/formatting/_pipes.py +5 -4
  134. meerschaum/utils/formatting/_shell.py +11 -9
  135. meerschaum/utils/misc.py +246 -148
  136. meerschaum/utils/packages/__init__.py +10 -27
  137. meerschaum/utils/packages/_packages.py +41 -34
  138. meerschaum/utils/pipes.py +181 -0
  139. meerschaum/utils/process.py +1 -1
  140. meerschaum/utils/prompt.py +3 -1
  141. meerschaum/utils/schedule.py +2 -1
  142. meerschaum/utils/sql.py +121 -44
  143. meerschaum/utils/typing.py +1 -4
  144. meerschaum/utils/venv/_Venv.py +2 -2
  145. meerschaum/utils/venv/__init__.py +5 -7
  146. {meerschaum-2.9.5.dist-info → meerschaum-3.0.0rc2.dist-info}/METADATA +92 -96
  147. meerschaum-3.0.0rc2.dist-info/RECORD +283 -0
  148. {meerschaum-2.9.5.dist-info → meerschaum-3.0.0rc2.dist-info}/WHEEL +1 -1
  149. meerschaum-3.0.0rc2.dist-info/licenses/NOTICE +2 -0
  150. meerschaum/api/models/_interfaces.py +0 -15
  151. meerschaum/api/models/_locations.py +0 -15
  152. meerschaum/api/models/_metrics.py +0 -15
  153. meerschaum/config/static/__init__.py +0 -186
  154. meerschaum-2.9.5.dist-info/RECORD +0 -263
  155. {meerschaum-2.9.5.dist-info → meerschaum-3.0.0rc2.dist-info}/entry_points.txt +0 -0
  156. {meerschaum-2.9.5.dist-info → meerschaum-3.0.0rc2.dist-info}/licenses/LICENSE +0 -0
  157. {meerschaum-2.9.5.dist-info → meerschaum-3.0.0rc2.dist-info}/top_level.txt +0 -0
  158. {meerschaum-2.9.5.dist-info → meerschaum-3.0.0rc2.dist-info}/zip-safe +0 -0
meerschaum/utils/sql.py CHANGED
@@ -41,13 +41,33 @@ version_queries = {
41
41
  }
42
42
  SKIP_IF_EXISTS_FLAVORS = {'mssql', 'oracle'}
43
43
  DROP_IF_EXISTS_FLAVORS = {
44
- 'timescaledb', 'postgresql', 'postgis', 'citus', 'mssql', 'mysql', 'mariadb', 'sqlite',
44
+ 'timescaledb',
45
+ 'timescaledb-ha',
46
+ 'postgresql',
47
+ 'postgis',
48
+ 'citus',
49
+ 'mssql',
50
+ 'mysql',
51
+ 'mariadb',
52
+ 'sqlite',
45
53
  }
46
54
  DROP_INDEX_IF_EXISTS_FLAVORS = {
47
- 'mssql', 'timescaledb', 'postgresql', 'postgis', 'sqlite', 'citus',
55
+ 'mssql',
56
+ 'timescaledb',
57
+ 'timescaledb-ha',
58
+ 'postgresql',
59
+ 'postgis',
60
+ 'sqlite',
61
+ 'citus',
48
62
  }
49
63
  SKIP_AUTO_INCREMENT_FLAVORS = {'citus', 'duckdb'}
50
- COALESCE_UNIQUE_INDEX_FLAVORS = {'timescaledb', 'postgresql', 'postgis', 'citus'}
64
+ COALESCE_UNIQUE_INDEX_FLAVORS = {
65
+ 'timescaledb',
66
+ 'timescaledb-ha',
67
+ 'postgresql',
68
+ 'postgis',
69
+ 'citus',
70
+ }
51
71
  UPDATE_QUERIES = {
52
72
  'default': """
53
73
  UPDATE {target_table_name} AS f
@@ -67,6 +87,12 @@ UPDATE_QUERIES = {
67
87
  FROM {patch_table_name}
68
88
  ON CONFLICT ({join_cols_str}) DO {update_or_nothing} {sets_subquery_none_excluded}
69
89
  """,
90
+ 'timescaledb-ha-upsert': """
91
+ INSERT INTO {target_table_name} ({patch_cols_str})
92
+ SELECT {patch_cols_str}
93
+ FROM {patch_table_name}
94
+ ON CONFLICT ({join_cols_str}) DO {update_or_nothing} {sets_subquery_none_excluded}
95
+ """,
70
96
  'postgresql-upsert': """
71
97
  INSERT INTO {target_table_name} ({patch_cols_str})
72
98
  SELECT {patch_cols_str}
@@ -233,7 +259,7 @@ columns_types_queries = {
233
259
  DATA_TYPE AS [type],
234
260
  NUMERIC_PRECISION AS [numeric_precision],
235
261
  NUMERIC_SCALE AS [numeric_scale]
236
- FROM {db_prefix}INFORMATION_SCHEMA.COLUMNS
262
+ FROM {db_prefix}INFORMATION_SCHEMA.COLUMNS WITH (NOLOCK)
237
263
  WHERE TABLE_NAME IN (
238
264
  '{table}',
239
265
  '{table_trunc}'
@@ -286,6 +312,7 @@ columns_types_queries = {
286
312
  }
287
313
  hypertable_queries = {
288
314
  'timescaledb': 'SELECT hypertable_size(\'{table_name}\')',
315
+ 'timescaledb-ha': 'SELECT hypertable_size(\'{table_name}\')',
289
316
  'citus': 'SELECT citus_table_size(\'{table_name}\')',
290
317
  }
291
318
  columns_indices_queries = {
@@ -377,18 +404,18 @@ columns_indices_queries = {
377
404
  ELSE CAST(0 AS BIT)
378
405
  END AS [clustered]
379
406
  FROM
380
- sys.schemas s
381
- INNER JOIN sys.tables t
407
+ sys.schemas s WITH (NOLOCK)
408
+ INNER JOIN sys.tables t WITH (NOLOCK)
382
409
  ON s.schema_id = t.schema_id
383
- INNER JOIN sys.indexes i
410
+ INNER JOIN sys.indexes i WITH (NOLOCK)
384
411
  ON t.object_id = i.object_id
385
- INNER JOIN sys.index_columns ic
412
+ INNER JOIN sys.index_columns ic WITH (NOLOCK)
386
413
  ON i.object_id = ic.object_id
387
414
  AND i.index_id = ic.index_id
388
- INNER JOIN sys.columns c
415
+ INNER JOIN sys.columns c WITH (NOLOCK)
389
416
  ON ic.object_id = c.object_id
390
417
  AND ic.column_id = c.column_id
391
- LEFT JOIN sys.key_constraints kc
418
+ LEFT JOIN sys.key_constraints kc WITH (NOLOCK)
392
419
  ON kc.parent_object_id = i.object_id
393
420
  AND kc.type = 'PK'
394
421
  AND kc.name = i.name
@@ -483,49 +510,83 @@ reset_autoincrement_queries: Dict[str, Union[str, List[str]]] = {
483
510
  ),
484
511
  }
485
512
  table_wrappers = {
486
- 'default' : ('"', '"'),
487
- 'timescaledb': ('"', '"'),
488
- 'citus' : ('"', '"'),
489
- 'duckdb' : ('"', '"'),
490
- 'postgresql' : ('"', '"'),
491
- 'postgis' : ('"', '"'),
492
- 'sqlite' : ('"', '"'),
493
- 'mysql' : ('`', '`'),
494
- 'mariadb' : ('`', '`'),
495
- 'mssql' : ('[', ']'),
496
- 'cockroachdb': ('"', '"'),
497
- 'oracle' : ('"', '"'),
513
+ 'default' : ('"', '"'),
514
+ 'timescaledb' : ('"', '"'),
515
+ 'timescaledb-ha': ('"', '"'),
516
+ 'citus' : ('"', '"'),
517
+ 'duckdb' : ('"', '"'),
518
+ 'postgresql' : ('"', '"'),
519
+ 'postgis' : ('"', '"'),
520
+ 'sqlite' : ('"', '"'),
521
+ 'mysql' : ('`', '`'),
522
+ 'mariadb' : ('`', '`'),
523
+ 'mssql' : ('[', ']'),
524
+ 'cockroachdb' : ('"', '"'),
525
+ 'oracle' : ('"', '"'),
498
526
  }
499
527
  max_name_lens = {
500
- 'default' : 64,
501
- 'mssql' : 128,
502
- 'oracle' : 30,
503
- 'postgresql' : 64,
504
- 'postgis' : 64,
505
- 'timescaledb': 64,
506
- 'citus' : 64,
507
- 'cockroachdb': 64,
508
- 'sqlite' : 1024, ### Probably more, but 1024 seems more than reasonable.
509
- 'mysql' : 64,
510
- 'mariadb' : 64,
528
+ 'default' : 64,
529
+ 'mssql' : 128,
530
+ 'oracle' : 30,
531
+ 'postgresql' : 64,
532
+ 'postgis' : 64,
533
+ 'timescaledb' : 64,
534
+ 'timescaledb-ha': 64,
535
+ 'citus' : 64,
536
+ 'cockroachdb' : 64,
537
+ 'sqlite' : 1024, ### Probably more, but 1024 seems more than reasonable.
538
+ 'mysql' : 64,
539
+ 'mariadb' : 64,
540
+ }
541
+ json_flavors = {
542
+ 'postgresql',
543
+ 'postgis',
544
+ 'timescaledb',
545
+ 'timescaledb-ha',
546
+ 'citus',
547
+ 'cockroachdb',
548
+ }
549
+ NO_SCHEMA_FLAVORS = {
550
+ 'oracle',
551
+ 'sqlite',
552
+ 'mysql',
553
+ 'mariadb',
554
+ 'duckdb',
511
555
  }
512
- json_flavors = {'postgresql', 'postgis', 'timescaledb', 'citus', 'cockroachdb'}
513
- NO_SCHEMA_FLAVORS = {'oracle', 'sqlite', 'mysql', 'mariadb', 'duckdb'}
514
556
  DEFAULT_SCHEMA_FLAVORS = {
515
557
  'postgresql': 'public',
516
558
  'postgis': 'public',
517
559
  'timescaledb': 'public',
560
+ 'timescaledb-ha': 'public',
518
561
  'citus': 'public',
519
562
  'cockroachdb': 'public',
520
563
  'mysql': 'mysql',
521
564
  'mariadb': 'mysql',
522
565
  'mssql': 'dbo',
523
566
  }
524
- OMIT_NULLSFIRST_FLAVORS = {'mariadb', 'mysql', 'mssql'}
567
+ OMIT_NULLSFIRST_FLAVORS = {
568
+ 'mariadb',
569
+ 'mysql',
570
+ 'mssql',
571
+ }
525
572
 
526
- SINGLE_ALTER_TABLE_FLAVORS = {'duckdb', 'sqlite', 'mssql', 'oracle'}
527
- NO_CTE_FLAVORS = {'mysql', 'mariadb'}
528
- NO_SELECT_INTO_FLAVORS = {'sqlite', 'oracle', 'mysql', 'mariadb', 'duckdb'}
573
+ SINGLE_ALTER_TABLE_FLAVORS = {
574
+ 'duckdb',
575
+ 'sqlite',
576
+ 'mssql',
577
+ 'oracle',
578
+ }
579
+ NO_CTE_FLAVORS = {
580
+ 'mysql',
581
+ 'mariadb',
582
+ }
583
+ NO_SELECT_INTO_FLAVORS = {
584
+ 'sqlite',
585
+ 'oracle',
586
+ 'mysql',
587
+ 'mariadb',
588
+ 'duckdb',
589
+ }
529
590
 
530
591
 
531
592
  def clean(substring: str) -> None:
@@ -560,6 +621,7 @@ def dateadd_str(
560
621
  - `'postgresql'`
561
622
  - `'postgis'`
562
623
  - `'timescaledb'`
624
+ - `'timescaledb-ha'`
563
625
  - `'citus'`
564
626
  - `'cockroachdb'`
565
627
  - `'duckdb'`
@@ -663,7 +725,14 @@ def dateadd_str(
663
725
  )
664
726
 
665
727
  da = ""
666
- if flavor in ('postgresql', 'postgis', 'timescaledb', 'cockroachdb', 'citus'):
728
+ if flavor in (
729
+ 'postgresql',
730
+ 'postgis',
731
+ 'timescaledb',
732
+ 'timescaledb-ha',
733
+ 'cockroachdb',
734
+ 'citus',
735
+ ):
667
736
  begin = (
668
737
  f"CAST({begin} AS {db_type})" if begin != 'now'
669
738
  else f"CAST(NOW() AT TIME ZONE 'utc' AS {db_type})"
@@ -969,7 +1038,7 @@ def build_where(
969
1038
  ```
970
1039
  """
971
1040
  import json
972
- from meerschaum.config.static import STATIC_CONFIG
1041
+ from meerschaum._internal.static import STATIC_CONFIG
973
1042
  from meerschaum.utils.warnings import warn
974
1043
  from meerschaum.utils.dtypes import value_is_null, none_if_null
975
1044
  negation_prefix = STATIC_CONFIG['system']['fetch_pipes_keys']['negation_prefix']
@@ -2112,7 +2181,11 @@ def _get_create_table_query_from_dtypes(
2112
2181
  )
2113
2182
  elif flavor == 'oracle':
2114
2183
  query += f"\n {col_name} {col_db_type} {auto_increment_str} PRIMARY KEY,"
2115
- elif flavor == 'timescaledb' and datetime_column and datetime_column != primary_key:
2184
+ elif (
2185
+ flavor in ('timescaledb', 'timescaledb-ha')
2186
+ and datetime_column
2187
+ and datetime_column != primary_key
2188
+ ):
2116
2189
  query += f"\n {col_name} {col_db_type}{auto_increment_str} NOT NULL,"
2117
2190
  elif flavor == 'mssql':
2118
2191
  query += f"\n {col_name} {col_db_type}{auto_increment_str} NOT NULL,"
@@ -2125,7 +2198,7 @@ def _get_create_table_query_from_dtypes(
2125
2198
  col_name = sql_item_name(col, schema=None, flavor=flavor)
2126
2199
  query += f"\n {col_name} {db_type},"
2127
2200
  if (
2128
- flavor == 'timescaledb'
2201
+ flavor in ('timescaledb', 'timescaledb-ha')
2129
2202
  and datetime_column
2130
2203
  and primary_key
2131
2204
  and datetime_column != primary_key
@@ -2248,7 +2321,11 @@ def _get_create_table_query_from_cte(
2248
2321
  "ADD PRIMARY KEY ({primary_key_name})"
2249
2322
  ),
2250
2323
  ]
2251
- elif flavor == 'timescaledb' and datetime_column and datetime_column != primary_key:
2324
+ elif (
2325
+ flavor in ('timescaledb', 'timescaledb-ha')
2326
+ and datetime_column
2327
+ and datetime_column != primary_key
2328
+ ):
2252
2329
  create_table_queries = [
2253
2330
  (
2254
2331
  "SELECT *\n"
@@ -76,10 +76,7 @@ import collections.abc
76
76
  collections.Iterable = collections.abc.Iterable
77
77
 
78
78
  SuccessTuple = Tuple[bool, str]
79
- InstanceConnector = Union[
80
- 'meerschaum.connectors.sql.SQLConnector',
81
- 'meerschaum.connectors.api.APIConnector'
82
- ]
79
+ InstanceConnector = 'meerschaum.connectors.InstanceConnector'
83
80
  PipesDict = Dict[
84
81
  str, Dict[ ### connector_keys : metrics
85
82
  str, Dict[ ### metric_key : locations
@@ -35,13 +35,13 @@ class Venv:
35
35
 
36
36
  def __init__(
37
37
  self,
38
- venv: Union[str, 'meerschaum.plugins.Plugin', None] = 'mrsm',
38
+ venv: Union[str, 'meerschaum.core.Plugin', None] = 'mrsm',
39
39
  debug: bool = False,
40
40
  ) -> None:
41
41
  from meerschaum.utils.venv import activate_venv, deactivate_venv, active_venvs
42
42
  ### For some weird threading issue,
43
43
  ### we can't use `isinstance` here.
44
- if 'meerschaum.plugins._Plugin' in str(type(venv)):
44
+ if '_Plugin' in str(type(venv)):
45
45
  self._venv = venv.name
46
46
  self._activate = venv.activate_venv
47
47
  self._deactivate = venv.deactivate_venv
@@ -8,6 +8,8 @@ Manage virtual environments.
8
8
 
9
9
  from __future__ import annotations
10
10
 
11
+ import pathlib
12
+
11
13
  from meerschaum.utils.typing import Optional, Union, Dict, List, Tuple
12
14
  from meerschaum.utils.threading import RLock, get_ident
13
15
 
@@ -229,7 +231,6 @@ def verify_venv(
229
231
  """
230
232
  Verify that the virtual environment matches the expected state.
231
233
  """
232
- import pathlib
233
234
  import platform
234
235
  import os
235
236
  import shutil
@@ -382,11 +383,10 @@ def init_venv(
382
383
  import sys
383
384
  import platform
384
385
  import os
385
- import pathlib
386
386
  import shutil
387
387
  import time
388
388
 
389
- from meerschaum.config.static import STATIC_CONFIG
389
+ from meerschaum._internal.static import STATIC_CONFIG
390
390
  from meerschaum.config._paths import (
391
391
  VIRTENV_RESOURCES_PATH,
392
392
  VENVS_CACHE_RESOURCES_PATH,
@@ -682,7 +682,7 @@ def venv_target_path(
682
682
  venv: Union[str, None],
683
683
  allow_nonexistent: bool = False,
684
684
  debug: bool = False,
685
- ) -> 'pathlib.Path':
685
+ ) -> pathlib.Path:
686
686
  """
687
687
  Return a virtual environment's site-package path.
688
688
 
@@ -702,10 +702,9 @@ def venv_target_path(
702
702
  import os
703
703
  import sys
704
704
  import platform
705
- import pathlib
706
705
  import site
707
706
  from meerschaum.config._paths import VIRTENV_RESOURCES_PATH
708
- from meerschaum.config.static import STATIC_CONFIG
707
+ from meerschaum._internal.static import STATIC_CONFIG
709
708
 
710
709
  ### Check sys.path for a user-writable site-packages directory.
711
710
  if venv is None:
@@ -839,7 +838,6 @@ def get_module_venv(module) -> Union[str, None]:
839
838
  -------
840
839
  The name of a venv or `None`.
841
840
  """
842
- import pathlib
843
841
  from meerschaum.config.paths import VIRTENV_RESOURCES_PATH
844
842
  module_path = pathlib.Path(module.__file__).resolve()
845
843
  try:
@@ -1,12 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meerschaum
3
- Version: 2.9.5
3
+ Version: 3.0.0rc2
4
4
  Summary: Sync Time-Series Pipes with Meerschaum
5
- Home-page: https://meerschaum.io
6
- Author: Bennett Meares
7
- Author-email: bennett.meares@gmail.com
8
- Maintainer-email: bennett.meares@gmail.com
9
- License: Apache Software License 2.0
5
+ Author-email: Bennett Meares <bennett.meares@gmail.com>
6
+ Maintainer-email: Bennett Meares <bennett.meares@gmail.com>
7
+ License-Expression: Apache-2.0
10
8
  Project-URL: Documentation, https://docs.meerschaum.io
11
9
  Project-URL: Changelog, https://meerschaum.io/news/changelog
12
10
  Project-URL: GitHub, https://github.com/bmeares/Meerschaum
@@ -29,6 +27,7 @@ Classifier: Natural Language :: English
29
27
  Requires-Python: >=3.8
30
28
  Description-Content-Type: text/markdown
31
29
  License-File: LICENSE
30
+ License-File: NOTICE
32
31
  Provides-Extra: required
33
32
  Provides-Extra: minimal
34
33
  Provides-Extra: formatting
@@ -63,14 +62,16 @@ Requires-Dist: fasteners>=0.19.0; extra == "core"
63
62
  Requires-Dist: virtualenv>=20.1.0; extra == "core"
64
63
  Requires-Dist: attrs>=24.2.0; extra == "core"
65
64
  Requires-Dist: uv>=0.2.11; extra == "core"
65
+ Requires-Dist: pydantic>=2.11.7; extra == "core"
66
+ Requires-Dist: annotated-types>=0.7.0; extra == "core"
66
67
  Provides-Extra: jobs
67
- Requires-Dist: dill>=0.3.3; extra == "jobs"
68
- Requires-Dist: python-daemon>=0.2.3; extra == "jobs"
69
- Requires-Dist: watchfiles>=0.21.0; extra == "jobs"
70
- Requires-Dist: psutil>=5.8.0; extra == "jobs"
68
+ Requires-Dist: dill>=0.4.0; extra == "jobs"
69
+ Requires-Dist: python-daemon>=3.1.2; extra == "jobs"
70
+ Requires-Dist: watchfiles>=1.1.0; extra == "jobs"
71
+ Requires-Dist: psutil>=7.0.0; extra == "jobs"
71
72
  Provides-Extra: drivers
72
73
  Requires-Dist: cryptography>=38.0.1; extra == "drivers"
73
- Requires-Dist: psycopg[binary]>=3.2.1; extra == "drivers"
74
+ Requires-Dist: psycopg[binary]>=3.2.9; extra == "drivers"
74
75
  Requires-Dist: PyMySQL>=0.9.0; extra == "drivers"
75
76
  Requires-Dist: aiomysql>=0.0.21; extra == "drivers"
76
77
  Requires-Dist: sqlalchemy-cockroachdb>=2.0.0; extra == "drivers"
@@ -114,7 +115,7 @@ Requires-Dist: mkdocs-awesome-pages-plugin>=2.5.0; extra == "docs"
114
115
  Requires-Dist: mkdocs-section-index>=0.3.3; extra == "docs"
115
116
  Requires-Dist: mkdocs-linkcheck>=1.0.6; extra == "docs"
116
117
  Requires-Dist: mkdocs-redirects>=1.0.4; extra == "docs"
117
- Requires-Dist: jinja2==3.0.3; extra == "docs"
118
+ Requires-Dist: jinja2>=3.1.6; extra == "docs"
118
119
  Provides-Extra: gui
119
120
  Requires-Dist: pywebview>=3.6.3; extra == "gui"
120
121
  Requires-Dist: pycparser>=2.21.0; extra == "gui"
@@ -125,20 +126,20 @@ Requires-Dist: modin[ray]>=0.8.3; extra == "extras"
125
126
  Requires-Dist: nanoid>=2.0.0; extra == "extras"
126
127
  Requires-Dist: importlib-metadata>=4.12.0; extra == "extras"
127
128
  Provides-Extra: sql
128
- Requires-Dist: numpy>=1.18.5; extra == "sql"
129
- Requires-Dist: pandas[parquet]>=2.0.1; extra == "sql"
130
- Requires-Dist: pyarrow>=16.1.0; extra == "sql"
129
+ Requires-Dist: numpy>=2.3.1; extra == "sql"
130
+ Requires-Dist: pandas[parquet]>=2.3.1; extra == "sql"
131
+ Requires-Dist: pyarrow>=20.0.0; extra == "sql"
131
132
  Requires-Dist: dask[complete]>=2024.12.1; extra == "sql"
132
133
  Requires-Dist: partd>=1.4.2; extra == "sql"
133
134
  Requires-Dist: pytz; extra == "sql"
134
- Requires-Dist: joblib>=0.17.0; extra == "sql"
135
- Requires-Dist: SQLAlchemy>=2.0.5; extra == "sql"
135
+ Requires-Dist: joblib>=1.5.1; extra == "sql"
136
+ Requires-Dist: SQLAlchemy>=2.0.41; extra == "sql"
136
137
  Requires-Dist: GeoAlchemy2>=0.17.1; extra == "sql"
137
- Requires-Dist: databases>=0.4.0; extra == "sql"
138
- Requires-Dist: aiosqlite>=0.16.0; extra == "sql"
139
- Requires-Dist: asyncpg>=0.21.0; extra == "sql"
138
+ Requires-Dist: databases>=0.9.0; extra == "sql"
139
+ Requires-Dist: aiosqlite>=0.21.0; extra == "sql"
140
+ Requires-Dist: asyncpg>=0.30.0; extra == "sql"
140
141
  Requires-Dist: cryptography>=38.0.1; extra == "sql"
141
- Requires-Dist: psycopg[binary]>=3.2.1; extra == "sql"
142
+ Requires-Dist: psycopg[binary]>=3.2.9; extra == "sql"
142
143
  Requires-Dist: PyMySQL>=0.9.0; extra == "sql"
143
144
  Requires-Dist: aiomysql>=0.0.21; extra == "sql"
144
145
  Requires-Dist: sqlalchemy-cockroachdb>=2.0.0; extra == "sql"
@@ -166,43 +167,45 @@ Requires-Dist: fasteners>=0.19.0; extra == "sql"
166
167
  Requires-Dist: virtualenv>=20.1.0; extra == "sql"
167
168
  Requires-Dist: attrs>=24.2.0; extra == "sql"
168
169
  Requires-Dist: uv>=0.2.11; extra == "sql"
170
+ Requires-Dist: pydantic>=2.11.7; extra == "sql"
171
+ Requires-Dist: annotated-types>=0.7.0; extra == "sql"
169
172
  Requires-Dist: pyproj>=3.7.1; extra == "sql"
170
173
  Requires-Dist: geopandas>=1.0.1; extra == "sql"
171
174
  Requires-Dist: shapely>=2.0.7; extra == "sql"
172
175
  Provides-Extra: dash
173
- Requires-Dist: Flask-Compress>=1.10.1; extra == "dash"
174
- Requires-Dist: dash>=2.6.2; extra == "dash"
176
+ Requires-Dist: Flask-Compress>=1.17.0; extra == "dash"
177
+ Requires-Dist: dash>=3.1.1; extra == "dash"
175
178
  Requires-Dist: dash-bootstrap-components>=1.7.1; extra == "dash"
176
179
  Requires-Dist: dash-ace>=0.2.1; extra == "dash"
177
- Requires-Dist: dash-extensions>=1.0.4; extra == "dash"
178
- Requires-Dist: dash-daq>=0.5.0; extra == "dash"
179
- Requires-Dist: terminado>=0.12.1; extra == "dash"
180
- Requires-Dist: tornado>=6.1.0; extra == "dash"
180
+ Requires-Dist: dash-extensions>=2.0.4; extra == "dash"
181
+ Requires-Dist: dash-daq>=0.6.0; extra == "dash"
182
+ Requires-Dist: terminado>=0.18.1; extra == "dash"
183
+ Requires-Dist: tornado>=6.5.1; extra == "dash"
181
184
  Provides-Extra: api
182
- Requires-Dist: uvicorn[standard]>=0.29.0; extra == "api"
183
- Requires-Dist: gunicorn>=22.0.0; extra == "api"
184
- Requires-Dist: python-dotenv>=0.20.0; extra == "api"
185
- Requires-Dist: websockets>=11.0.3; extra == "api"
186
- Requires-Dist: fastapi>=0.111.0; extra == "api"
187
- Requires-Dist: fastapi-login>=1.7.2; extra == "api"
188
- Requires-Dist: python-multipart>=0.0.9; extra == "api"
189
- Requires-Dist: httpx>=0.27.2; extra == "api"
190
- Requires-Dist: httpcore>=1.0.6; extra == "api"
191
- Requires-Dist: valkey>=6.0.0; extra == "api"
192
- Requires-Dist: numpy>=1.18.5; extra == "api"
193
- Requires-Dist: pandas[parquet]>=2.0.1; extra == "api"
194
- Requires-Dist: pyarrow>=16.1.0; extra == "api"
185
+ Requires-Dist: uvicorn[standard]>=0.35.0; extra == "api"
186
+ Requires-Dist: gunicorn>=23.0.0; extra == "api"
187
+ Requires-Dist: python-dotenv>=1.1.1; extra == "api"
188
+ Requires-Dist: websockets>=15.0.1; extra == "api"
189
+ Requires-Dist: fastapi>=0.116.0; extra == "api"
190
+ Requires-Dist: fastapi-login>=1.10.3; extra == "api"
191
+ Requires-Dist: python-multipart>=0.0.20; extra == "api"
192
+ Requires-Dist: httpx>=0.28.1; extra == "api"
193
+ Requires-Dist: httpcore>=1.0.9; extra == "api"
194
+ Requires-Dist: valkey>=6.1.0; extra == "api"
195
+ Requires-Dist: numpy>=2.3.1; extra == "api"
196
+ Requires-Dist: pandas[parquet]>=2.3.1; extra == "api"
197
+ Requires-Dist: pyarrow>=20.0.0; extra == "api"
195
198
  Requires-Dist: dask[complete]>=2024.12.1; extra == "api"
196
199
  Requires-Dist: partd>=1.4.2; extra == "api"
197
200
  Requires-Dist: pytz; extra == "api"
198
- Requires-Dist: joblib>=0.17.0; extra == "api"
199
- Requires-Dist: SQLAlchemy>=2.0.5; extra == "api"
201
+ Requires-Dist: joblib>=1.5.1; extra == "api"
202
+ Requires-Dist: SQLAlchemy>=2.0.41; extra == "api"
200
203
  Requires-Dist: GeoAlchemy2>=0.17.1; extra == "api"
201
- Requires-Dist: databases>=0.4.0; extra == "api"
202
- Requires-Dist: aiosqlite>=0.16.0; extra == "api"
203
- Requires-Dist: asyncpg>=0.21.0; extra == "api"
204
+ Requires-Dist: databases>=0.9.0; extra == "api"
205
+ Requires-Dist: aiosqlite>=0.21.0; extra == "api"
206
+ Requires-Dist: asyncpg>=0.30.0; extra == "api"
204
207
  Requires-Dist: cryptography>=38.0.1; extra == "api"
205
- Requires-Dist: psycopg[binary]>=3.2.1; extra == "api"
208
+ Requires-Dist: psycopg[binary]>=3.2.9; extra == "api"
206
209
  Requires-Dist: PyMySQL>=0.9.0; extra == "api"
207
210
  Requires-Dist: aiomysql>=0.0.21; extra == "api"
208
211
  Requires-Dist: sqlalchemy-cockroachdb>=2.0.0; extra == "api"
@@ -230,6 +233,8 @@ Requires-Dist: fasteners>=0.19.0; extra == "api"
230
233
  Requires-Dist: virtualenv>=20.1.0; extra == "api"
231
234
  Requires-Dist: attrs>=24.2.0; extra == "api"
232
235
  Requires-Dist: uv>=0.2.11; extra == "api"
236
+ Requires-Dist: pydantic>=2.11.7; extra == "api"
237
+ Requires-Dist: annotated-types>=0.7.0; extra == "api"
233
238
  Requires-Dist: pyproj>=3.7.1; extra == "api"
234
239
  Requires-Dist: geopandas>=1.0.1; extra == "api"
235
240
  Requires-Dist: shapely>=2.0.7; extra == "api"
@@ -241,18 +246,18 @@ Requires-Dist: colorama>=0.4.3; extra == "api"
241
246
  Requires-Dist: rich>=13.4.2; extra == "api"
242
247
  Requires-Dist: more-termcolor>=1.1.3; extra == "api"
243
248
  Requires-Dist: humanfriendly>=10.0.0; extra == "api"
244
- Requires-Dist: Flask-Compress>=1.10.1; extra == "api"
245
- Requires-Dist: dash>=2.6.2; extra == "api"
249
+ Requires-Dist: Flask-Compress>=1.17.0; extra == "api"
250
+ Requires-Dist: dash>=3.1.1; extra == "api"
246
251
  Requires-Dist: dash-bootstrap-components>=1.7.1; extra == "api"
247
252
  Requires-Dist: dash-ace>=0.2.1; extra == "api"
248
- Requires-Dist: dash-extensions>=1.0.4; extra == "api"
249
- Requires-Dist: dash-daq>=0.5.0; extra == "api"
250
- Requires-Dist: terminado>=0.12.1; extra == "api"
251
- Requires-Dist: tornado>=6.1.0; extra == "api"
252
- Requires-Dist: dill>=0.3.3; extra == "api"
253
- Requires-Dist: python-daemon>=0.2.3; extra == "api"
254
- Requires-Dist: watchfiles>=0.21.0; extra == "api"
255
- Requires-Dist: psutil>=5.8.0; extra == "api"
253
+ Requires-Dist: dash-extensions>=2.0.4; extra == "api"
254
+ Requires-Dist: dash-daq>=0.6.0; extra == "api"
255
+ Requires-Dist: terminado>=0.18.1; extra == "api"
256
+ Requires-Dist: tornado>=6.5.1; extra == "api"
257
+ Requires-Dist: dill>=0.4.0; extra == "api"
258
+ Requires-Dist: python-daemon>=3.1.2; extra == "api"
259
+ Requires-Dist: watchfiles>=1.1.0; extra == "api"
260
+ Requires-Dist: psutil>=7.0.0; extra == "api"
256
261
  Provides-Extra: full
257
262
  Requires-Dist: pprintpp>=0.4.0; extra == "full"
258
263
  Requires-Dist: asciitree>=0.3.3; extra == "full"
@@ -284,12 +289,14 @@ Requires-Dist: fasteners>=0.19.0; extra == "full"
284
289
  Requires-Dist: virtualenv>=20.1.0; extra == "full"
285
290
  Requires-Dist: attrs>=24.2.0; extra == "full"
286
291
  Requires-Dist: uv>=0.2.11; extra == "full"
287
- Requires-Dist: dill>=0.3.3; extra == "full"
288
- Requires-Dist: python-daemon>=0.2.3; extra == "full"
289
- Requires-Dist: watchfiles>=0.21.0; extra == "full"
290
- Requires-Dist: psutil>=5.8.0; extra == "full"
292
+ Requires-Dist: pydantic>=2.11.7; extra == "full"
293
+ Requires-Dist: annotated-types>=0.7.0; extra == "full"
294
+ Requires-Dist: dill>=0.4.0; extra == "full"
295
+ Requires-Dist: python-daemon>=3.1.2; extra == "full"
296
+ Requires-Dist: watchfiles>=1.1.0; extra == "full"
297
+ Requires-Dist: psutil>=7.0.0; extra == "full"
291
298
  Requires-Dist: cryptography>=38.0.1; extra == "full"
292
- Requires-Dist: psycopg[binary]>=3.2.1; extra == "full"
299
+ Requires-Dist: psycopg[binary]>=3.2.9; extra == "full"
293
300
  Requires-Dist: PyMySQL>=0.9.0; extra == "full"
294
301
  Requires-Dist: aiomysql>=0.0.21; extra == "full"
295
302
  Requires-Dist: sqlalchemy-cockroachdb>=2.0.0; extra == "full"
@@ -300,49 +307,38 @@ Requires-Dist: geopandas>=1.0.1; extra == "full"
300
307
  Requires-Dist: shapely>=2.0.7; extra == "full"
301
308
  Requires-Dist: pywebview>=3.6.3; extra == "full"
302
309
  Requires-Dist: pycparser>=2.21.0; extra == "full"
303
- Requires-Dist: numpy>=1.18.5; extra == "full"
304
- Requires-Dist: pandas[parquet]>=2.0.1; extra == "full"
305
- Requires-Dist: pyarrow>=16.1.0; extra == "full"
310
+ Requires-Dist: numpy>=2.3.1; extra == "full"
311
+ Requires-Dist: pandas[parquet]>=2.3.1; extra == "full"
312
+ Requires-Dist: pyarrow>=20.0.0; extra == "full"
306
313
  Requires-Dist: dask[complete]>=2024.12.1; extra == "full"
307
314
  Requires-Dist: partd>=1.4.2; extra == "full"
308
315
  Requires-Dist: pytz; extra == "full"
309
- Requires-Dist: joblib>=0.17.0; extra == "full"
310
- Requires-Dist: SQLAlchemy>=2.0.5; extra == "full"
316
+ Requires-Dist: joblib>=1.5.1; extra == "full"
317
+ Requires-Dist: SQLAlchemy>=2.0.41; extra == "full"
311
318
  Requires-Dist: GeoAlchemy2>=0.17.1; extra == "full"
312
- Requires-Dist: databases>=0.4.0; extra == "full"
313
- Requires-Dist: aiosqlite>=0.16.0; extra == "full"
314
- Requires-Dist: asyncpg>=0.21.0; extra == "full"
315
- Requires-Dist: Flask-Compress>=1.10.1; extra == "full"
316
- Requires-Dist: dash>=2.6.2; extra == "full"
319
+ Requires-Dist: databases>=0.9.0; extra == "full"
320
+ Requires-Dist: aiosqlite>=0.21.0; extra == "full"
321
+ Requires-Dist: asyncpg>=0.30.0; extra == "full"
322
+ Requires-Dist: Flask-Compress>=1.17.0; extra == "full"
323
+ Requires-Dist: dash>=3.1.1; extra == "full"
317
324
  Requires-Dist: dash-bootstrap-components>=1.7.1; extra == "full"
318
325
  Requires-Dist: dash-ace>=0.2.1; extra == "full"
319
- Requires-Dist: dash-extensions>=1.0.4; extra == "full"
320
- Requires-Dist: dash-daq>=0.5.0; extra == "full"
321
- Requires-Dist: terminado>=0.12.1; extra == "full"
322
- Requires-Dist: tornado>=6.1.0; extra == "full"
323
- Requires-Dist: uvicorn[standard]>=0.29.0; extra == "full"
324
- Requires-Dist: gunicorn>=22.0.0; extra == "full"
325
- Requires-Dist: python-dotenv>=0.20.0; extra == "full"
326
- Requires-Dist: websockets>=11.0.3; extra == "full"
327
- Requires-Dist: fastapi>=0.111.0; extra == "full"
328
- Requires-Dist: fastapi-login>=1.7.2; extra == "full"
329
- Requires-Dist: python-multipart>=0.0.9; extra == "full"
330
- Requires-Dist: httpx>=0.27.2; extra == "full"
331
- Requires-Dist: httpcore>=1.0.6; extra == "full"
332
- Requires-Dist: valkey>=6.0.0; extra == "full"
333
- Dynamic: author
334
- Dynamic: author-email
335
- Dynamic: classifier
336
- Dynamic: description
337
- Dynamic: description-content-type
338
- Dynamic: home-page
339
- Dynamic: license
326
+ Requires-Dist: dash-extensions>=2.0.4; extra == "full"
327
+ Requires-Dist: dash-daq>=0.6.0; extra == "full"
328
+ Requires-Dist: terminado>=0.18.1; extra == "full"
329
+ Requires-Dist: tornado>=6.5.1; extra == "full"
330
+ Requires-Dist: uvicorn[standard]>=0.35.0; extra == "full"
331
+ Requires-Dist: gunicorn>=23.0.0; extra == "full"
332
+ Requires-Dist: python-dotenv>=1.1.1; extra == "full"
333
+ Requires-Dist: websockets>=15.0.1; extra == "full"
334
+ Requires-Dist: fastapi>=0.116.0; extra == "full"
335
+ Requires-Dist: fastapi-login>=1.10.3; extra == "full"
336
+ Requires-Dist: python-multipart>=0.0.20; extra == "full"
337
+ Requires-Dist: httpx>=0.28.1; extra == "full"
338
+ Requires-Dist: httpcore>=1.0.9; extra == "full"
339
+ Requires-Dist: valkey>=6.1.0; extra == "full"
340
340
  Dynamic: license-file
341
- Dynamic: maintainer-email
342
- Dynamic: project-url
343
341
  Dynamic: provides-extra
344
- Dynamic: requires-python
345
- Dynamic: summary
346
342
 
347
343
  <img src="https://meerschaum.io/assets/banner_1920x320.png" alt="Meerschaum banner" style="width: 100%"/>
348
344