meerschaum 2.9.4__py3-none-any.whl → 3.0.0rc1__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 (154) 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 +17 -1
  5. meerschaum/_internal/entry.py +6 -6
  6. meerschaum/_internal/shell/Shell.py +1 -1
  7. meerschaum/_internal/static.py +372 -0
  8. meerschaum/actions/api.py +12 -2
  9. meerschaum/actions/bootstrap.py +7 -7
  10. meerschaum/actions/edit.py +142 -18
  11. meerschaum/actions/register.py +137 -6
  12. meerschaum/actions/show.py +117 -29
  13. meerschaum/actions/stop.py +4 -1
  14. meerschaum/actions/sync.py +1 -1
  15. meerschaum/actions/tag.py +9 -8
  16. meerschaum/api/__init__.py +9 -2
  17. meerschaum/api/_events.py +39 -2
  18. meerschaum/api/_oauth2.py +118 -8
  19. meerschaum/api/_tokens.py +102 -0
  20. meerschaum/api/dash/__init__.py +0 -1
  21. meerschaum/api/dash/callbacks/custom.py +2 -2
  22. meerschaum/api/dash/callbacks/dashboard.py +133 -18
  23. meerschaum/api/dash/callbacks/plugins.py +0 -1
  24. meerschaum/api/dash/callbacks/register.py +1 -1
  25. meerschaum/api/dash/callbacks/settings/__init__.py +1 -0
  26. meerschaum/api/dash/callbacks/settings/password_reset.py +2 -2
  27. meerschaum/api/dash/callbacks/settings/tokens.py +388 -0
  28. meerschaum/api/dash/components.py +30 -8
  29. meerschaum/api/dash/keys.py +19 -93
  30. meerschaum/api/dash/pages/dashboard.py +1 -20
  31. meerschaum/api/dash/pages/settings/__init__.py +1 -0
  32. meerschaum/api/dash/pages/settings/password_reset.py +1 -1
  33. meerschaum/api/dash/pages/settings/tokens.py +55 -0
  34. meerschaum/api/dash/pipes.py +156 -58
  35. meerschaum/api/dash/sessions.py +12 -0
  36. meerschaum/api/dash/tokens.py +606 -0
  37. meerschaum/api/dash/websockets.py +1 -1
  38. meerschaum/api/dash/webterm.py +4 -0
  39. meerschaum/api/models/__init__.py +23 -3
  40. meerschaum/api/models/_actions.py +22 -0
  41. meerschaum/api/models/_pipes.py +85 -7
  42. meerschaum/api/models/_tokens.py +81 -0
  43. meerschaum/api/resources/static/css/dash.css +16 -0
  44. meerschaum/api/resources/templates/termpage.html +12 -0
  45. meerschaum/api/routes/__init__.py +1 -0
  46. meerschaum/api/routes/_actions.py +3 -4
  47. meerschaum/api/routes/_connectors.py +3 -7
  48. meerschaum/api/routes/_jobs.py +14 -35
  49. meerschaum/api/routes/_login.py +49 -12
  50. meerschaum/api/routes/_misc.py +5 -10
  51. meerschaum/api/routes/_pipes.py +134 -111
  52. meerschaum/api/routes/_plugins.py +38 -28
  53. meerschaum/api/routes/_tokens.py +236 -0
  54. meerschaum/api/routes/_users.py +47 -35
  55. meerschaum/api/routes/_version.py +3 -3
  56. meerschaum/config/__init__.py +43 -20
  57. meerschaum/config/_default.py +32 -5
  58. meerschaum/config/_edit.py +28 -24
  59. meerschaum/config/_environment.py +1 -1
  60. meerschaum/config/_patch.py +6 -6
  61. meerschaum/config/_paths.py +5 -1
  62. meerschaum/config/_read_config.py +65 -34
  63. meerschaum/config/_sync.py +6 -3
  64. meerschaum/config/_version.py +1 -1
  65. meerschaum/config/stack/__init__.py +24 -5
  66. meerschaum/config/static.py +18 -0
  67. meerschaum/connectors/_Connector.py +10 -4
  68. meerschaum/connectors/__init__.py +4 -20
  69. meerschaum/connectors/api/_APIConnector.py +34 -6
  70. meerschaum/connectors/api/_actions.py +2 -2
  71. meerschaum/connectors/api/_jobs.py +1 -1
  72. meerschaum/connectors/api/_login.py +33 -7
  73. meerschaum/connectors/api/_misc.py +2 -2
  74. meerschaum/connectors/api/_pipes.py +15 -14
  75. meerschaum/connectors/api/_plugins.py +2 -2
  76. meerschaum/connectors/api/_request.py +1 -1
  77. meerschaum/connectors/api/_tokens.py +146 -0
  78. meerschaum/connectors/api/_users.py +70 -58
  79. meerschaum/connectors/instance/_InstanceConnector.py +83 -0
  80. meerschaum/connectors/instance/__init__.py +10 -0
  81. meerschaum/connectors/instance/_pipes.py +442 -0
  82. meerschaum/connectors/instance/_plugins.py +151 -0
  83. meerschaum/connectors/instance/_tokens.py +296 -0
  84. meerschaum/connectors/instance/_users.py +181 -0
  85. meerschaum/connectors/parse.py +4 -1
  86. meerschaum/connectors/sql/_SQLConnector.py +8 -5
  87. meerschaum/connectors/sql/_cli.py +12 -11
  88. meerschaum/connectors/sql/_create_engine.py +6 -154
  89. meerschaum/connectors/sql/_fetch.py +2 -18
  90. meerschaum/connectors/sql/_pipes.py +42 -31
  91. meerschaum/connectors/sql/_plugins.py +29 -0
  92. meerschaum/connectors/sql/_sql.py +9 -2
  93. meerschaum/connectors/sql/_users.py +29 -2
  94. meerschaum/connectors/sql/tables/__init__.py +1 -1
  95. meerschaum/connectors/valkey/_ValkeyConnector.py +2 -4
  96. meerschaum/connectors/valkey/_pipes.py +9 -10
  97. meerschaum/connectors/valkey/_plugins.py +2 -26
  98. meerschaum/core/Pipe/__init__.py +31 -14
  99. meerschaum/core/Pipe/_attributes.py +156 -58
  100. meerschaum/core/Pipe/_bootstrap.py +54 -24
  101. meerschaum/core/Pipe/_data.py +41 -1
  102. meerschaum/core/Pipe/_dtypes.py +29 -14
  103. meerschaum/core/Pipe/_edit.py +12 -4
  104. meerschaum/core/Pipe/_show.py +5 -5
  105. meerschaum/core/Pipe/_sync.py +48 -53
  106. meerschaum/core/Pipe/_verify.py +1 -1
  107. meerschaum/{plugins → core/Plugin}/_Plugin.py +9 -11
  108. meerschaum/core/Plugin/__init__.py +1 -1
  109. meerschaum/core/Token/_Token.py +221 -0
  110. meerschaum/core/Token/__init__.py +12 -0
  111. meerschaum/core/User/_User.py +34 -8
  112. meerschaum/core/User/__init__.py +9 -1
  113. meerschaum/core/__init__.py +1 -0
  114. meerschaum/jobs/_Job.py +3 -2
  115. meerschaum/jobs/__init__.py +3 -2
  116. meerschaum/jobs/systemd.py +1 -1
  117. meerschaum/models/__init__.py +35 -0
  118. meerschaum/models/pipes.py +247 -0
  119. meerschaum/models/tokens.py +38 -0
  120. meerschaum/models/users.py +26 -0
  121. meerschaum/plugins/__init__.py +22 -7
  122. meerschaum/plugins/bootstrap.py +2 -1
  123. meerschaum/utils/_get_pipes.py +68 -27
  124. meerschaum/utils/daemon/Daemon.py +2 -1
  125. meerschaum/utils/daemon/__init__.py +30 -2
  126. meerschaum/utils/dataframe.py +96 -15
  127. meerschaum/utils/dtypes/__init__.py +93 -21
  128. meerschaum/utils/dtypes/sql.py +44 -0
  129. meerschaum/utils/formatting/__init__.py +1 -1
  130. meerschaum/utils/formatting/_pipes.py +5 -4
  131. meerschaum/utils/formatting/_shell.py +11 -9
  132. meerschaum/utils/misc.py +237 -80
  133. meerschaum/utils/packages/__init__.py +3 -6
  134. meerschaum/utils/packages/_packages.py +34 -32
  135. meerschaum/utils/pipes.py +181 -0
  136. meerschaum/utils/process.py +1 -1
  137. meerschaum/utils/prompt.py +3 -1
  138. meerschaum/utils/schedule.py +1 -0
  139. meerschaum/utils/sql.py +115 -39
  140. meerschaum/utils/typing.py +1 -4
  141. meerschaum/utils/venv/_Venv.py +2 -2
  142. meerschaum/utils/venv/__init__.py +5 -7
  143. {meerschaum-2.9.4.dist-info → meerschaum-3.0.0rc1.dist-info}/METADATA +88 -80
  144. meerschaum-3.0.0rc1.dist-info/RECORD +282 -0
  145. {meerschaum-2.9.4.dist-info → meerschaum-3.0.0rc1.dist-info}/WHEEL +1 -1
  146. meerschaum/api/models/_interfaces.py +0 -15
  147. meerschaum/api/models/_locations.py +0 -15
  148. meerschaum/api/models/_metrics.py +0 -15
  149. meerschaum/config/static/__init__.py +0 -186
  150. meerschaum-2.9.4.dist-info/RECORD +0 -263
  151. {meerschaum-2.9.4.dist-info → meerschaum-3.0.0rc1.dist-info}/entry_points.txt +0 -0
  152. {meerschaum-2.9.4.dist-info → meerschaum-3.0.0rc1.dist-info}/licenses/LICENSE +0 -0
  153. {meerschaum-2.9.4.dist-info → meerschaum-3.0.0rc1.dist-info}/top_level.txt +0 -0
  154. {meerschaum-2.9.4.dist-info → meerschaum-3.0.0rc1.dist-info}/zip-safe +0 -0
@@ -9,14 +9,24 @@ and if interactive, print the welcome message.
9
9
 
10
10
  from __future__ import annotations
11
11
 
12
- import os, shutil, sys, pathlib, copy
13
- from meerschaum.utils.typing import Any, Dict, Optional, Union
12
+ import os
13
+ import shutil
14
+ import sys
15
+ import copy
16
+
17
+ from meerschaum.utils.typing import Any, Dict, Optional
14
18
  from meerschaum.utils.threading import RLock
15
- from meerschaum.utils.warnings import warn, error
16
19
 
17
20
  from meerschaum.config._version import __version__
18
21
  from meerschaum.config._edit import edit_config, write_config
19
- from meerschaum.config.static import STATIC_CONFIG
22
+ from meerschaum.config._read_config import (
23
+ search_and_substitute_config,
24
+ revert_symlinks_config,
25
+ get_possible_keys,
26
+ get_keyfile_path,
27
+ read_config,
28
+ )
29
+ from meerschaum._internal.static import STATIC_CONFIG
20
30
 
21
31
  from meerschaum.config._paths import (
22
32
  PERMANENT_PATCH_DIR_PATH,
@@ -31,8 +41,16 @@ __all__ = (
31
41
  'write_plugin_config',
32
42
  'get_config',
33
43
  'write_config',
44
+ 'edit_config',
34
45
  'set_config',
46
+ 'search_and_substitute_config',
47
+ 'revert_symlinks_config',
48
+ 'get_possible_keys',
49
+ 'get_keyfile_path',
50
+ 'apply_patch_to_config',
51
+ 'read_config',
35
52
  'paths',
53
+ 'STATIC_CONFIG',
36
54
  )
37
55
  __pdoc__ = {'static': False, 'resources': False, 'stack': False, }
38
56
  _locks = {'config': RLock()}
@@ -40,9 +58,12 @@ _locks = {'config': RLock()}
40
58
  ### apply config preprocessing (e.g. main to meta)
41
59
  config = {}
42
60
  def _config(
43
- *keys: str, reload: bool = False, substitute: bool = True,
44
- sync_files: bool = True, write_missing: bool = True,
45
- ) -> Dict[str, Any]:
61
+ *keys: str,
62
+ reload: bool = False,
63
+ substitute: bool = True,
64
+ sync_files: bool = True,
65
+ write_missing: bool = True,
66
+ ) -> Dict[str, Any]:
46
67
  """
47
68
  Read and process the configuration file.
48
69
  """
@@ -153,7 +174,7 @@ def get_config(
153
174
  ):
154
175
  try:
155
176
  _subbed = search_and_substitute_config({keys[0]: config[keys[0]]})
156
- except Exception as e:
177
+ except Exception:
157
178
  import traceback
158
179
  traceback.print_exc()
159
180
  config[keys[0]] = _subbed[keys[0]]
@@ -164,7 +185,7 @@ def get_config(
164
185
  config[symlinks_key][keys[0]] = {}
165
186
  config[symlinks_key][keys[0]] = apply_patch_to_config(
166
187
  _subbed,
167
- config[symlinks_key][keys[0]]
188
+ {symlinks_key: config[symlinks_key][keys[0]]}
168
189
  )
169
190
 
170
191
  from meerschaum.config._sync import sync_files as _sync_files
@@ -193,7 +214,7 @@ def get_config(
193
214
  for k in keys:
194
215
  try:
195
216
  c = c[k]
196
- except Exception as e:
217
+ except Exception:
197
218
  invalid_keys = True
198
219
  break
199
220
  if invalid_keys:
@@ -208,7 +229,7 @@ def get_config(
208
229
  for k in keys:
209
230
  try:
210
231
  _c = _c[k]
211
- except Exception as e:
232
+ except Exception:
212
233
  in_default = False
213
234
  if in_default:
214
235
  c = _c
@@ -219,7 +240,7 @@ def get_config(
219
240
  if warn:
220
241
  from meerschaum.utils.warnings import warn as _warn
221
242
  _warn(warning_msg, stacklevel=3, color=False)
222
- except Exception as e:
243
+ except Exception:
223
244
  if warn:
224
245
  print(warning_msg)
225
246
  if as_tuple:
@@ -247,14 +268,15 @@ def get_config(
247
268
 
248
269
 
249
270
  def get_plugin_config(
250
- *keys: str,
251
- warn: bool = False,
252
- **kw: Any
253
- ) -> Optional[Any]:
271
+ *keys: str,
272
+ warn: bool = False,
273
+ **kw: Any
274
+ ) -> Optional[Any]:
254
275
  """
255
276
  This may only be called from within a Meerschaum plugin.
256
277
  See `meerschaum.config.get_config` for arguments.
257
278
  """
279
+ from meerschaum.utils.warnings import error
258
280
  from meerschaum.plugins import _get_parent_plugin
259
281
  parent_plugin_name = _get_parent_plugin(2)
260
282
  if parent_plugin_name is None:
@@ -271,16 +293,17 @@ def get_plugin_config(
271
293
 
272
294
 
273
295
  def write_plugin_config(
274
- config_dict: Dict[str, Any],
275
- **kw : Any
276
- ):
296
+ config_dict: Dict[str, Any],
297
+ **kw: Any
298
+ ):
277
299
  """
278
300
  Write a plugin's configuration dictionary.
279
301
  """
302
+ from meerschaum.utils.warnings import error
280
303
  from meerschaum.plugins import _get_parent_plugin
281
304
  parent_plugin_name = _get_parent_plugin(2)
282
305
  if parent_plugin_name is None:
283
- error(f"You may only call `get_plugin_config()` from within a Meerschaum plugin.")
306
+ error("You may only call `get_plugin_config()` from within a Meerschaum plugin.")
284
307
  plugins_cf = get_config('plugins', warn=False)
285
308
  if plugins_cf is None:
286
309
  plugins_cf = {}
@@ -6,11 +6,33 @@
6
6
  The default configuration values to write to config.yaml.
7
7
  """
8
8
 
9
- import sys, os, multiprocessing
9
+ import multiprocessing
10
+ from typing import Dict, Any
10
11
 
11
- from meerschaum.connectors import attributes as connector_attributes
12
12
  from meerschaum.config._paths import SQLITE_DB_PATH
13
+ from meerschaum._internal.static import STATIC_CONFIG
13
14
 
15
+ CONNECTOR_ATTRIBUTES: Dict[str, Dict[str, Any]] = {
16
+ 'api': {
17
+ 'required': [
18
+ 'host',
19
+ ],
20
+ 'optional': [
21
+ 'port',
22
+ 'username',
23
+ 'password',
24
+ 'client_id',
25
+ 'client_secret',
26
+ 'api_key',
27
+ ],
28
+ 'default': {
29
+ 'protocol': 'http',
30
+ },
31
+ },
32
+ 'sql': {
33
+ 'flavors': STATIC_CONFIG['sql']['create_engine_flavors'],
34
+ },
35
+ }
14
36
  default_meerschaum_config = {
15
37
  'instance': 'sql:main',
16
38
  'api_instance': 'MRSM{meerschaum:instance}',
@@ -22,14 +44,14 @@ default_meerschaum_config = {
22
44
  'main': {
23
45
  'username': 'mrsm',
24
46
  'password': 'mrsm',
25
- 'flavor': 'timescaledb',
47
+ 'flavor': 'timescaledb-ha',
26
48
  'host': 'localhost',
27
49
  'database': 'meerschaum',
28
50
  'port': 5432,
29
51
  },
30
52
  'local': {
31
53
  'flavor': 'sqlite',
32
- 'database': str(SQLITE_DB_PATH),
54
+ 'database': SQLITE_DB_PATH.as_posix(),
33
55
  },
34
56
  'memory': {
35
57
  'flavor': 'sqlite',
@@ -37,7 +59,7 @@ default_meerschaum_config = {
37
59
  },
38
60
  },
39
61
  'api': {
40
- 'default': connector_attributes['api']['default'],
62
+ 'default': CONNECTOR_ATTRIBUTES['api']['default'],
41
63
  'main': {
42
64
  'host': 'localhost',
43
65
  'port': 8000,
@@ -73,6 +95,7 @@ default_system_config = {
73
95
  'postgis': True,
74
96
  'citus': True,
75
97
  'timescaledb': True,
98
+ 'timescaledb-ha': True,
76
99
  'mssql': True,
77
100
  },
78
101
  'instance': {
@@ -121,6 +144,10 @@ default_system_config = {
121
144
  'endpoints': {
122
145
  'docs_in_production': True,
123
146
  },
147
+ 'tokens': {
148
+ 'valid_refresh_minutes': 60,
149
+ 'default_expiration_days': 366,
150
+ },
124
151
  'permissions': {
125
152
  'registration': {
126
153
  'users': True,
@@ -7,8 +7,9 @@ Functions for editing the configuration file
7
7
  """
8
8
 
9
9
  from __future__ import annotations
10
+
10
11
  import pathlib
11
- from meerschaum.utils.typing import Optional, Any, SuccessTuple, Mapping, Dict, List, Union
12
+ from meerschaum.utils.typing import Optional, Any, SuccessTuple, Dict, List, Union
12
13
 
13
14
 
14
15
  def edit_config(
@@ -19,20 +20,27 @@ def edit_config(
19
20
  ) -> SuccessTuple:
20
21
  """Edit the configuration files."""
21
22
  from meerschaum.config import get_config, config
22
- from meerschaum.config._read_config import get_keyfile_path, read_config
23
+ from meerschaum.config._read_config import get_keyfile_path, read_config, revert_symlinks_config
23
24
  from meerschaum.config._paths import CONFIG_DIR_PATH
25
+ from meerschaum._internal.static import STATIC_CONFIG
24
26
  from meerschaum.utils.packages import reload_meerschaum
25
27
  from meerschaum.utils.misc import edit_file
26
- from meerschaum.utils.warnings import warn, dprint
28
+ from meerschaum.utils.warnings import warn
27
29
  from meerschaum.utils.prompt import prompt
28
30
 
29
31
  if keys is None:
30
32
  keys = []
31
33
 
34
+ symlinks_key = STATIC_CONFIG['config']['symlinks_key']
32
35
  def _edit_key(key: str):
36
+ new_key_config = None
33
37
  while True:
34
38
  ### If defined in default, create the config file.
35
- key_config = config.pop(key, None)
39
+ symlinks_key_config = config.get(symlinks_key, {}).get(key, {})
40
+ key_config = revert_symlinks_config({
41
+ key: config.pop(key, {}),
42
+ symlinks_key: {key: symlinks_key_config},
43
+ })
36
44
  keyfile_path = get_keyfile_path(key, create_new=True)
37
45
  get_config(key, write_missing=True, warn=False)
38
46
 
@@ -60,7 +68,7 @@ def edit_config(
60
68
  for k in keys:
61
69
  _edit_key(k)
62
70
  except KeyboardInterrupt:
63
- return False, f""
71
+ return False, ""
64
72
 
65
73
  reload_meerschaum(debug=debug)
66
74
  return (True, "Success")
@@ -95,7 +103,7 @@ def write_config(
95
103
  if directory is None:
96
104
  from meerschaum.config._paths import CONFIG_DIR_PATH
97
105
  directory = CONFIG_DIR_PATH
98
- from meerschaum.config.static import STATIC_CONFIG
106
+ from meerschaum._internal.static import STATIC_CONFIG
99
107
  from meerschaum.config._default import default_header_comment
100
108
  from meerschaum.config._patch import apply_patch_to_config
101
109
  from meerschaum.config._read_config import get_keyfile_path
@@ -153,7 +161,7 @@ def write_config(
153
161
  success = True
154
162
  except Exception as e:
155
163
  success = False
156
- print(f"FAILED TO WRITE!")
164
+ print("FAILED TO WRITE!")
157
165
  print(e)
158
166
  print(filter_keywords(
159
167
  filetype_dumpers[filetype],
@@ -165,16 +173,16 @@ def write_config(
165
173
  try:
166
174
  if os.path.exists(filepath):
167
175
  os.remove(filepath)
168
- except Exception as e:
176
+ except Exception:
169
177
  print(f"Failed to write '{k}'")
170
178
  return False
171
179
 
172
180
  return True
173
181
 
174
182
  def general_write_yaml_config(
175
- files: Optional[Dict[pathlib.Path, Dict[str, Any]]] = None,
176
- debug: bool = False
177
- ):
183
+ files: Optional[Dict[pathlib.Path, Dict[str, Any]]] = None,
184
+ debug: bool = False
185
+ ):
178
186
  """
179
187
  Write configuration dictionaries to file paths with optional headers.
180
188
 
@@ -216,18 +224,15 @@ def general_write_yaml_config(
216
224
  return True
217
225
 
218
226
  def general_edit_config(
219
- action: Optional[List[str]] = None,
220
- files: Optional[Dict[str, Union[str, pathlib.Path]]] = None,
221
- default: Optional[str] = None,
222
- debug: bool = False
223
- ):
227
+ action: Optional[List[str]] = None,
228
+ files: Optional[Dict[str, Union[str, pathlib.Path]]] = None,
229
+ default: Optional[str] = None,
230
+ debug: bool = False
231
+ ) -> SuccessTuple:
224
232
  """Prompt the user to edit any config files."""
225
233
  if default is None:
226
234
  raise Exception("Provide a default choice for which file to edit")
227
- import os
228
- from subprocess import call
229
235
  from meerschaum.utils.misc import edit_file
230
- from meerschaum.utils.debug import dprint
231
236
 
232
237
  if files is None:
233
238
  files = {}
@@ -257,11 +262,10 @@ def copy_default_to_config(debug : bool = False):
257
262
  return True
258
263
 
259
264
  def write_default_config(
260
- debug : bool = False,
261
- **kw
262
- ):
265
+ debug: bool = False,
266
+ **kw
267
+ ):
263
268
  """Write the default configuration files."""
264
- import os
265
269
  from meerschaum.config._paths import DEFAULT_CONFIG_DIR_PATH
266
- from meerschaum.config._default import default_config, default_header_comment
270
+ from meerschaum.config._default import default_config
267
271
  return write_config(default_config, directory=DEFAULT_CONFIG_DIR_PATH)
@@ -10,7 +10,7 @@ import os
10
10
  import re
11
11
  import json
12
12
  from meerschaum.utils.typing import List, Union, Dict, Any
13
- from meerschaum.config.static import STATIC_CONFIG
13
+ from meerschaum._internal.static import STATIC_CONFIG
14
14
 
15
15
  def apply_environment_patches() -> None:
16
16
  """
@@ -12,9 +12,9 @@ from meerschaum.utils.typing import Dict, Any
12
12
  from meerschaum.utils.warnings import warn
13
13
 
14
14
  def apply_patch_to_config(
15
- config: Dict[str, Any],
16
- patch: Dict[str, Any],
17
- ) -> Dict[str, Any]:
15
+ config: Dict[str, Any],
16
+ patch: Dict[str, Any],
17
+ ) -> Dict[str, Any]:
18
18
  """Patch the config dict with a new dict (cascade patching)."""
19
19
  _base = copy.deepcopy(config) if isinstance(config, dict) else {}
20
20
  if not isinstance(patch, dict):
@@ -37,9 +37,9 @@ def apply_patch_to_config(
37
37
 
38
38
 
39
39
  def write_patch(
40
- patch: Dict[str, Any],
41
- debug: bool = False
42
- ):
40
+ patch: Dict[str, Any],
41
+ debug: bool = False
42
+ ) -> None:
43
43
  """Write patch dict to yaml."""
44
44
  from meerschaum.utils.debug import dprint
45
45
  from meerschaum.config._paths import PATCH_DIR_PATH
@@ -11,7 +11,7 @@ from __future__ import annotations
11
11
  from pathlib import Path
12
12
  import os, platform, sys, json
13
13
  from meerschaum.utils.typing import Union
14
- from meerschaum.config.static import STATIC_CONFIG
14
+ from meerschaum._internal.static import STATIC_CONFIG
15
15
 
16
16
  DOT_CONFIG_DIR_PATH = Path(
17
17
  os.environ.get('XDG_CONFIG_HOME', Path.home() / '.config')
@@ -157,6 +157,10 @@ paths = {
157
157
  'PLUGINS_TEMP_RESOURCES_PATH' : ('{PLUGINS_RESOURCES_PATH}', '.tmp'),
158
158
  'PLUGINS_INIT_PATH' : ('{PLUGINS_RESOURCES_PATH}', '__init__.py'),
159
159
 
160
+ 'DB_RESOURCES_PATH' : ('{ROOT_DIR_PATH}', 'db'),
161
+ 'DB_INIT_RESOURCES_PATH' : ('{DB_RESOURCES_PATH}', 'initdb'),
162
+ 'DB_CREATE_EXTENSIONS_PATH' : ('{DB_INIT_RESOURCES_PATH}', 'create-extensions.sql'),
163
+
160
164
  'SQLITE_RESOURCES_PATH' : ('{ROOT_DIR_PATH}', 'sqlite'),
161
165
  'SQLITE_DB_PATH' : ('{SQLITE_RESOURCES_PATH}', 'mrsm_local.db'),
162
166
 
@@ -9,7 +9,6 @@ from __future__ import annotations
9
9
  import pathlib
10
10
 
11
11
  from meerschaum.utils.typing import Optional, Dict, Any, List, Tuple, Union
12
- from meerschaum.config import get_config
13
12
 
14
13
 
15
14
  def read_config(
@@ -49,11 +48,12 @@ def read_config(
49
48
  >>> read_config(keys=['meerschaum'], with_filename=True)
50
49
  >>> ({...}, ['meerschaum.yaml'])
51
50
  """
52
- import sys, shutil, os, json, itertools
53
- from meerschaum.utils.packages import attempt_import
51
+ import os
52
+ import json
53
+ import itertools
54
54
  from meerschaum.utils.yaml import yaml, _yaml
55
55
  from meerschaum.config._paths import CONFIG_DIR_PATH
56
- from meerschaum.config.static import STATIC_CONFIG
56
+ from meerschaum._internal.static import STATIC_CONFIG
57
57
  from meerschaum.config._patch import apply_patch_to_config
58
58
  if directory is None:
59
59
  directory = CONFIG_DIR_PATH
@@ -106,7 +106,7 @@ def read_config(
106
106
  ### If default config contains symlinks, add them to the config to write.
107
107
  try:
108
108
  _default_symlinks = _default_dict[symlinks_key][mk]
109
- except Exception as e:
109
+ except Exception:
110
110
  _default_symlinks = {}
111
111
  config[mk] = _default_dict[mk]
112
112
  if _default_symlinks:
@@ -179,6 +179,7 @@ def read_config(
179
179
  import traceback
180
180
  traceback.print_exc()
181
181
  _config_key = {}
182
+ substitute = False
182
183
  _single_key_config = (
183
184
  search_and_substitute_config({key: _config_key}) if substitute
184
185
  else {key: _config_key}
@@ -208,15 +209,16 @@ def read_config(
208
209
 
209
210
 
210
211
  def search_and_substitute_config(
211
- config: Dict[str, Any],
212
- leading_key: str = "MRSM",
213
- delimiter: str = ":",
214
- begin_key: str = "{",
215
- end_key: str = "}",
216
- literal_key: str = '!',
217
- keep_symlinks: bool = True,
218
- ) -> Dict[str, Any]:
219
- """Search the config for Meerschaum substitution syntax and substite with value of keys.
212
+ config: Dict[str, Any],
213
+ leading_key: str = "MRSM",
214
+ delimiter: str = ":",
215
+ begin_key: str = "{",
216
+ end_key: str = "}",
217
+ literal_key: str = '!',
218
+ keep_symlinks: bool = True,
219
+ ) -> Dict[str, Any]:
220
+ """
221
+ Search the config for Meerschaum substitution syntax and substite with value of keys.
220
222
 
221
223
  Parameters
222
224
  ----------
@@ -242,7 +244,7 @@ def search_and_substitute_config(
242
244
  - ' MRSM{a:b:c} ' => ' "{\'d\': 1}"' : not isolated
243
245
  - ' MRSM{!a:b:c} ' => ' {"d": 1}' : literal
244
246
 
245
- keep_symlinks :
247
+ keep_symlinks: bool, default True
246
248
  If True, include the symlinks under the top-level key '_symlinks' (never written to a file).
247
249
  Defaults to True.
248
250
 
@@ -251,7 +253,13 @@ def search_and_substitute_config(
251
253
  ```
252
254
  MRSM{meerschaum:connectors:main:host} => cf['meerschaum']['connectors']['main']['host']
253
255
  ```
256
+
257
+ Returns
258
+ -------
259
+ The configuration dictionary with `MRSM{}` symlinks replaced with
260
+ the values from the current configuration.
254
261
  """
262
+ from meerschaum.config import get_config
255
263
 
256
264
  _links = []
257
265
  def _find_symlinks(d, _keys: Optional[List[str]] = None):
@@ -270,9 +278,6 @@ def search_and_substitute_config(
270
278
  import json
271
279
  needle = leading_key + begin_key
272
280
  haystack = json.dumps(config, separators=(',', ':'))
273
- mod_haystack = list(str(haystack))
274
- buff = str(needle)
275
- max_index = len(haystack) - len(buff)
276
281
 
277
282
  patterns = {}
278
283
  isolated_patterns = {}
@@ -329,7 +334,7 @@ def search_and_substitute_config(
329
334
  write_missing=False,
330
335
  sync_files=False,
331
336
  )
332
- except Exception as e:
337
+ except Exception:
333
338
  import traceback
334
339
  traceback.print_exc()
335
340
  valid = False
@@ -382,15 +387,40 @@ def search_and_substitute_config(
382
387
  s[_keys[-1]] = _pattern
383
388
 
384
389
  from meerschaum.config._patch import apply_patch_to_config
385
- from meerschaum.config.static import STATIC_CONFIG
390
+ from meerschaum._internal.static import STATIC_CONFIG
386
391
  symlinks_key = STATIC_CONFIG['config']['symlinks_key']
387
- if symlinks_key not in parsed_config:
388
- parsed_config[symlinks_key] = {}
389
- parsed_config[symlinks_key] = apply_patch_to_config(parsed_config[symlinks_key], symlinks)
392
+ if symlinks_key in parsed_config:
393
+ parsed_config[symlinks_key] = apply_patch_to_config(parsed_config[symlinks_key], symlinks)
390
394
 
391
395
  return parsed_config
392
396
 
393
397
 
398
+ def revert_symlinks_config(config: Dict[str, Any]) -> Dict[str, Any]:
399
+ """
400
+ Given a configuration dictionary, re-apply the values from the
401
+ accompanying `_symlinks` dictionary.
402
+
403
+ Parameters
404
+ ----------
405
+ config: Dict[str, Any]
406
+ The configuration dictionary containing a `_symlinks` dictionary.
407
+
408
+ Returns
409
+ -------
410
+ A configuration dictionary with `_symlinks` re-applied.
411
+ """
412
+ from meerschaum.config import apply_patch_to_config
413
+ from meerschaum._internal.static import STATIC_CONFIG
414
+ symlinks_key = STATIC_CONFIG['config']['symlinks_key']
415
+ if symlinks_key not in config:
416
+ return config
417
+
418
+ symlinks_config = config[symlinks_key]
419
+ reverted_config = apply_patch_to_config(config, symlinks_config)
420
+ _ = reverted_config.pop(symlinks_key, None)
421
+ return reverted_config
422
+
423
+
394
424
  def get_possible_keys() -> List[str]:
395
425
  """
396
426
  Return a list of possible top-level keys.
@@ -407,12 +437,13 @@ def get_possible_keys() -> List[str]:
407
437
 
408
438
 
409
439
  def get_keyfile_path(
410
- key: str,
411
- create_new: bool = False,
412
- directory: Union[pathlib.Path, str, None] = None,
413
- ) -> Union[pathlib.Path, None]:
440
+ key: str,
441
+ create_new: bool = False,
442
+ directory: Union[pathlib.Path, str, None] = None,
443
+ ) -> Union[pathlib.Path, None]:
414
444
  """Determine a key's file path."""
415
- import os, pathlib
445
+ import os
446
+ import pathlib
416
447
  if directory is None:
417
448
  from meerschaum.config._paths import CONFIG_DIR_PATH
418
449
  directory = CONFIG_DIR_PATH
@@ -422,16 +453,16 @@ def get_keyfile_path(
422
453
  os.path.join(
423
454
  directory,
424
455
  read_config(
425
- keys = [key],
426
- with_filenames = True,
427
- write_missing = False,
428
- substitute = False,
456
+ keys=[key],
457
+ with_filenames=True,
458
+ write_missing=False,
459
+ substitute=False,
429
460
  )[1][0]
430
461
  )
431
462
  )
432
- except IndexError as e:
463
+ except IndexError:
433
464
  if create_new:
434
- from meerschaum.config.static import STATIC_CONFIG
465
+ from meerschaum._internal.static import STATIC_CONFIG
435
466
  default_filetype = STATIC_CONFIG['config']['default_filetype']
436
467
  return pathlib.Path(os.path.join(directory, key + '.' + default_filetype))
437
468
  return None
@@ -40,10 +40,11 @@ def sync_yaml_configs(
40
40
  If provided, iterate through a list of tuples,
41
41
  replacing the old string (index 0) with the new string (index 1).
42
42
  """
43
- import os, sys
43
+ import os
44
+ import sys
44
45
  try:
45
46
  from meerschaum.utils.yaml import yaml, _yaml
46
- except Exception as e:
47
+ except Exception:
47
48
  return
48
49
  from meerschaum.config._patch import apply_patch_to_config
49
50
  import meerschaum.config
@@ -110,7 +111,8 @@ def sync_files(keys: Optional[List[str]] = None):
110
111
  GRAFANA_DATASOURCE_PATH,
111
112
  GRAFANA_DASHBOARD_PATH,
112
113
  )
113
- from meerschaum.config.static import STATIC_CONFIG
114
+ from meerschaum._internal.static import STATIC_CONFIG
115
+ from meerschaum.config.stack import _write_initdb
114
116
 
115
117
  sync_yaml_configs(
116
118
  ['stack', STACK_COMPOSE_FILENAME],
@@ -131,6 +133,7 @@ def sync_files(keys: Optional[List[str]] = None):
131
133
  GRAFANA_DASHBOARD_PATH,
132
134
  substitute=True,
133
135
  )
136
+ _write_initdb()
134
137
 
135
138
  key_functions = {
136
139
  'stack': _stack,
@@ -2,4 +2,4 @@
2
2
  Specify the Meerschaum release version.
3
3
  """
4
4
 
5
- __version__ = "2.9.4"
5
+ __version__ = "3.0.0rc1"