meerschaum 2.9.4__py3-none-any.whl → 3.0.0__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.
- meerschaum/__init__.py +5 -2
- meerschaum/_internal/__init__.py +1 -0
- meerschaum/_internal/arguments/_parse_arguments.py +4 -4
- meerschaum/_internal/arguments/_parser.py +33 -4
- meerschaum/_internal/cli/__init__.py +6 -0
- meerschaum/_internal/cli/daemons.py +103 -0
- meerschaum/_internal/cli/entry.py +220 -0
- meerschaum/_internal/cli/workers.py +435 -0
- meerschaum/_internal/docs/index.py +48 -2
- meerschaum/_internal/entry.py +50 -14
- meerschaum/_internal/shell/Shell.py +121 -29
- meerschaum/_internal/shell/__init__.py +4 -1
- meerschaum/_internal/static.py +359 -0
- meerschaum/_internal/term/TermPageHandler.py +1 -2
- meerschaum/_internal/term/__init__.py +40 -6
- meerschaum/_internal/term/tools.py +33 -8
- meerschaum/actions/__init__.py +6 -4
- meerschaum/actions/api.py +53 -13
- meerschaum/actions/attach.py +1 -0
- meerschaum/actions/bootstrap.py +8 -8
- meerschaum/actions/delete.py +4 -2
- meerschaum/actions/edit.py +171 -25
- meerschaum/actions/login.py +8 -8
- meerschaum/actions/register.py +143 -6
- meerschaum/actions/reload.py +22 -5
- meerschaum/actions/restart.py +14 -0
- meerschaum/actions/show.py +184 -31
- meerschaum/actions/start.py +166 -17
- meerschaum/actions/stop.py +38 -2
- meerschaum/actions/sync.py +7 -2
- meerschaum/actions/tag.py +9 -8
- meerschaum/actions/verify.py +5 -8
- meerschaum/api/__init__.py +45 -15
- meerschaum/api/_events.py +46 -4
- meerschaum/api/_oauth2.py +162 -9
- meerschaum/api/_tokens.py +102 -0
- meerschaum/api/dash/__init__.py +0 -3
- meerschaum/api/dash/callbacks/__init__.py +1 -0
- meerschaum/api/dash/callbacks/custom.py +4 -3
- meerschaum/api/dash/callbacks/dashboard.py +228 -117
- meerschaum/api/dash/callbacks/jobs.py +14 -7
- meerschaum/api/dash/callbacks/login.py +10 -1
- meerschaum/api/dash/callbacks/pipes.py +194 -14
- meerschaum/api/dash/callbacks/plugins.py +0 -1
- meerschaum/api/dash/callbacks/register.py +10 -3
- meerschaum/api/dash/callbacks/settings/password_reset.py +2 -2
- meerschaum/api/dash/callbacks/tokens.py +389 -0
- meerschaum/api/dash/components.py +36 -15
- meerschaum/api/dash/jobs.py +1 -1
- meerschaum/api/dash/keys.py +35 -93
- meerschaum/api/dash/pages/__init__.py +2 -1
- meerschaum/api/dash/pages/dashboard.py +1 -20
- meerschaum/api/dash/pages/{job.py → jobs.py} +10 -7
- meerschaum/api/dash/pages/login.py +2 -2
- meerschaum/api/dash/pages/pipes.py +16 -5
- meerschaum/api/dash/pages/settings/password_reset.py +1 -1
- meerschaum/api/dash/pages/tokens.py +53 -0
- meerschaum/api/dash/pipes.py +438 -88
- meerschaum/api/dash/sessions.py +12 -0
- meerschaum/api/dash/tokens.py +603 -0
- meerschaum/api/dash/websockets.py +1 -1
- meerschaum/api/dash/webterm.py +18 -6
- meerschaum/api/models/__init__.py +23 -3
- meerschaum/api/models/_actions.py +22 -0
- meerschaum/api/models/_pipes.py +91 -7
- meerschaum/api/models/_tokens.py +81 -0
- meerschaum/api/resources/static/css/dash.css +16 -0
- meerschaum/api/resources/static/js/terminado.js +3 -0
- meerschaum/api/resources/static/js/xterm-addon-unicode11.js +2 -0
- meerschaum/api/resources/templates/termpage.html +13 -0
- meerschaum/api/routes/__init__.py +1 -0
- meerschaum/api/routes/_actions.py +3 -4
- meerschaum/api/routes/_connectors.py +3 -7
- meerschaum/api/routes/_jobs.py +26 -35
- meerschaum/api/routes/_login.py +120 -15
- meerschaum/api/routes/_misc.py +5 -10
- meerschaum/api/routes/_pipes.py +178 -143
- meerschaum/api/routes/_plugins.py +38 -28
- meerschaum/api/routes/_tokens.py +236 -0
- meerschaum/api/routes/_users.py +47 -35
- meerschaum/api/routes/_version.py +3 -3
- meerschaum/api/routes/_webterm.py +3 -3
- meerschaum/config/__init__.py +100 -30
- meerschaum/config/_default.py +132 -64
- meerschaum/config/_edit.py +38 -32
- meerschaum/config/_formatting.py +2 -0
- meerschaum/config/_patch.py +10 -8
- meerschaum/config/_paths.py +133 -13
- meerschaum/config/_read_config.py +87 -36
- meerschaum/config/_sync.py +6 -3
- meerschaum/config/_version.py +1 -1
- meerschaum/config/environment.py +262 -0
- meerschaum/config/stack/__init__.py +37 -15
- meerschaum/config/static.py +18 -0
- meerschaum/connectors/_Connector.py +11 -6
- meerschaum/connectors/__init__.py +41 -22
- meerschaum/connectors/api/_APIConnector.py +34 -6
- meerschaum/connectors/api/_actions.py +2 -2
- meerschaum/connectors/api/_jobs.py +12 -1
- meerschaum/connectors/api/_login.py +33 -7
- meerschaum/connectors/api/_misc.py +2 -2
- meerschaum/connectors/api/_pipes.py +23 -32
- meerschaum/connectors/api/_plugins.py +2 -2
- meerschaum/connectors/api/_request.py +1 -1
- meerschaum/connectors/api/_tokens.py +146 -0
- meerschaum/connectors/api/_users.py +70 -58
- meerschaum/connectors/instance/_InstanceConnector.py +83 -0
- meerschaum/connectors/instance/__init__.py +10 -0
- meerschaum/connectors/instance/_pipes.py +442 -0
- meerschaum/connectors/instance/_plugins.py +159 -0
- meerschaum/connectors/instance/_tokens.py +317 -0
- meerschaum/connectors/instance/_users.py +188 -0
- meerschaum/connectors/parse.py +5 -2
- meerschaum/connectors/sql/_SQLConnector.py +22 -5
- meerschaum/connectors/sql/_cli.py +12 -11
- meerschaum/connectors/sql/_create_engine.py +12 -168
- meerschaum/connectors/sql/_fetch.py +2 -18
- meerschaum/connectors/sql/_pipes.py +295 -278
- meerschaum/connectors/sql/_plugins.py +29 -0
- meerschaum/connectors/sql/_sql.py +47 -22
- meerschaum/connectors/sql/_users.py +36 -2
- meerschaum/connectors/sql/tables/__init__.py +254 -122
- meerschaum/connectors/valkey/_ValkeyConnector.py +5 -7
- meerschaum/connectors/valkey/_pipes.py +60 -31
- meerschaum/connectors/valkey/_plugins.py +2 -26
- meerschaum/core/Pipe/__init__.py +115 -85
- meerschaum/core/Pipe/_attributes.py +425 -124
- meerschaum/core/Pipe/_bootstrap.py +54 -24
- meerschaum/core/Pipe/_cache.py +555 -0
- meerschaum/core/Pipe/_clear.py +0 -11
- meerschaum/core/Pipe/_data.py +96 -68
- meerschaum/core/Pipe/_deduplicate.py +0 -13
- meerschaum/core/Pipe/_delete.py +12 -21
- meerschaum/core/Pipe/_drop.py +11 -23
- meerschaum/core/Pipe/_dtypes.py +49 -19
- meerschaum/core/Pipe/_edit.py +14 -4
- meerschaum/core/Pipe/_fetch.py +1 -1
- meerschaum/core/Pipe/_index.py +8 -14
- meerschaum/core/Pipe/_show.py +5 -5
- meerschaum/core/Pipe/_sync.py +123 -204
- meerschaum/core/Pipe/_verify.py +4 -4
- meerschaum/{plugins → core/Plugin}/_Plugin.py +16 -12
- meerschaum/core/Plugin/__init__.py +1 -1
- meerschaum/core/Token/_Token.py +220 -0
- meerschaum/core/Token/__init__.py +12 -0
- meerschaum/core/User/_User.py +35 -10
- meerschaum/core/User/__init__.py +9 -1
- meerschaum/core/__init__.py +1 -0
- meerschaum/jobs/_Executor.py +88 -4
- meerschaum/jobs/_Job.py +149 -38
- meerschaum/jobs/__init__.py +3 -2
- meerschaum/jobs/systemd.py +8 -3
- meerschaum/models/__init__.py +35 -0
- meerschaum/models/pipes.py +247 -0
- meerschaum/models/tokens.py +38 -0
- meerschaum/models/users.py +26 -0
- meerschaum/plugins/__init__.py +301 -88
- meerschaum/plugins/bootstrap.py +510 -4
- meerschaum/utils/_get_pipes.py +97 -30
- meerschaum/utils/daemon/Daemon.py +199 -43
- meerschaum/utils/daemon/FileDescriptorInterceptor.py +0 -1
- meerschaum/utils/daemon/RotatingFile.py +63 -36
- meerschaum/utils/daemon/StdinFile.py +53 -13
- meerschaum/utils/daemon/__init__.py +47 -6
- meerschaum/utils/daemon/_names.py +6 -3
- meerschaum/utils/dataframe.py +480 -82
- meerschaum/utils/debug.py +49 -19
- meerschaum/utils/dtypes/__init__.py +478 -37
- meerschaum/utils/dtypes/sql.py +369 -29
- meerschaum/utils/formatting/__init__.py +5 -2
- meerschaum/utils/formatting/_jobs.py +1 -1
- meerschaum/utils/formatting/_pipes.py +52 -50
- meerschaum/utils/formatting/_pprint.py +1 -0
- meerschaum/utils/formatting/_shell.py +44 -18
- meerschaum/utils/misc.py +268 -186
- meerschaum/utils/packages/__init__.py +25 -40
- meerschaum/utils/packages/_packages.py +42 -34
- meerschaum/utils/pipes.py +213 -0
- meerschaum/utils/process.py +2 -2
- meerschaum/utils/prompt.py +175 -144
- meerschaum/utils/schedule.py +2 -1
- meerschaum/utils/sql.py +135 -49
- meerschaum/utils/threading.py +42 -0
- meerschaum/utils/typing.py +1 -4
- meerschaum/utils/venv/_Venv.py +2 -2
- meerschaum/utils/venv/__init__.py +7 -7
- meerschaum/utils/warnings.py +19 -13
- {meerschaum-2.9.4.dist-info → meerschaum-3.0.0.dist-info}/METADATA +94 -96
- meerschaum-3.0.0.dist-info/RECORD +289 -0
- {meerschaum-2.9.4.dist-info → meerschaum-3.0.0.dist-info}/WHEEL +1 -1
- meerschaum-3.0.0.dist-info/licenses/NOTICE +2 -0
- meerschaum/api/models/_interfaces.py +0 -15
- meerschaum/api/models/_locations.py +0 -15
- meerschaum/api/models/_metrics.py +0 -15
- meerschaum/config/_environment.py +0 -145
- meerschaum/config/static/__init__.py +0 -186
- meerschaum-2.9.4.dist-info/RECORD +0 -263
- {meerschaum-2.9.4.dist-info → meerschaum-3.0.0.dist-info}/entry_points.txt +0 -0
- {meerschaum-2.9.4.dist-info → meerschaum-3.0.0.dist-info}/licenses/LICENSE +0 -0
- {meerschaum-2.9.4.dist-info → meerschaum-3.0.0.dist-info}/top_level.txt +0 -0
- {meerschaum-2.9.4.dist-info → meerschaum-3.0.0.dist-info}/zip-safe +0 -0
meerschaum/config/_formatting.py
CHANGED
meerschaum/config/_patch.py
CHANGED
@@ -9,12 +9,13 @@ Functions for patching the configuration dictionary
|
|
9
9
|
import sys
|
10
10
|
import copy
|
11
11
|
from meerschaum.utils.typing import Dict, Any
|
12
|
-
from meerschaum.utils.warnings import warn
|
12
|
+
from meerschaum.utils.warnings import warn as _warn
|
13
13
|
|
14
14
|
def apply_patch_to_config(
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
config: Dict[str, Any],
|
16
|
+
patch: Dict[str, Any],
|
17
|
+
warn: bool = False,
|
18
|
+
) -> Dict[str, Any]:
|
18
19
|
"""Patch the config dict with a new dict (cascade patching)."""
|
19
20
|
_base = copy.deepcopy(config) if isinstance(config, dict) else {}
|
20
21
|
if not isinstance(patch, dict):
|
@@ -24,7 +25,8 @@ def apply_patch_to_config(
|
|
24
25
|
if base is None:
|
25
26
|
return {}
|
26
27
|
if not isinstance(base, dict):
|
27
|
-
warn
|
28
|
+
if warn:
|
29
|
+
_warn(f"Overwriting the value {base} with a dictionary:\n{patch}")
|
28
30
|
base = {}
|
29
31
|
for key, value in patch.items():
|
30
32
|
if isinstance(value, dict):
|
@@ -37,9 +39,9 @@ def apply_patch_to_config(
|
|
37
39
|
|
38
40
|
|
39
41
|
def write_patch(
|
40
|
-
|
41
|
-
|
42
|
-
|
42
|
+
patch: Dict[str, Any],
|
43
|
+
debug: bool = False
|
44
|
+
) -> None:
|
43
45
|
"""Write patch dict to yaml."""
|
44
46
|
from meerschaum.utils.debug import dprint
|
45
47
|
from meerschaum.config._paths import PATCH_DIR_PATH
|
meerschaum/config/_paths.py
CHANGED
@@ -9,9 +9,16 @@ Define file paths
|
|
9
9
|
from __future__ import annotations
|
10
10
|
|
11
11
|
from pathlib import Path
|
12
|
-
import
|
13
|
-
|
14
|
-
|
12
|
+
import contextlib
|
13
|
+
import os
|
14
|
+
import platform
|
15
|
+
import sys
|
16
|
+
import json
|
17
|
+
|
18
|
+
from typing import Union, List
|
19
|
+
|
20
|
+
from meerschaum._internal.static import STATIC_CONFIG
|
21
|
+
|
15
22
|
|
16
23
|
DOT_CONFIG_DIR_PATH = Path(
|
17
24
|
os.environ.get('XDG_CONFIG_HOME', Path.home() / '.config')
|
@@ -71,7 +78,7 @@ if ENVIRONMENT_PLUGINS_DIR in os.environ:
|
|
71
78
|
if path_str
|
72
79
|
]
|
73
80
|
)
|
74
|
-
except Exception
|
81
|
+
except Exception:
|
75
82
|
PLUGINS_DIR_PATHS = []
|
76
83
|
|
77
84
|
if not PLUGINS_DIR_PATHS:
|
@@ -82,20 +89,23 @@ if ENVIRONMENT_PLUGINS_DIR in os.environ:
|
|
82
89
|
f"`export {ENVIRONMENT_PLUGINS_DIR}=./plugins:/another/path/to/plugins`\n\n"
|
83
90
|
"or a JSON-encoded path list:\n\n"
|
84
91
|
f"`export {ENVIRONMENT_PLUGINS_DIR}=" + "'[\"./plugins\", \"/another/path/to/plugins\"]'`"
|
85
|
-
|
92
|
+
"",
|
86
93
|
)
|
87
94
|
sys.exit(1)
|
88
95
|
else:
|
89
96
|
PLUGINS_DIR_PATHS = [_ROOT_DIR_PATH / 'plugins']
|
90
97
|
|
91
98
|
### Remove duplicate plugins paths.
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
+
def _process_plugins_dir_paths(plugins_dir_paths: List[Path]):
|
100
|
+
_seen_plugins_paths, _plugins_paths_to_remove = set(), set()
|
101
|
+
for _plugin_path in plugins_dir_paths:
|
102
|
+
if _plugin_path in _seen_plugins_paths:
|
103
|
+
_plugins_paths_to_remove.add(_plugin_path)
|
104
|
+
_seen_plugins_paths.add(_plugin_path)
|
105
|
+
for _plugin_path in _plugins_paths_to_remove:
|
106
|
+
plugins_dir_paths.remove(_plugin_path)
|
107
|
+
_process_plugins_dir_paths(PLUGINS_DIR_PATHS)
|
108
|
+
|
99
109
|
|
100
110
|
ENVIRONMENT_VENVS_DIR = STATIC_CONFIG['environment']['venvs']
|
101
111
|
if ENVIRONMENT_VENVS_DIR in os.environ:
|
@@ -144,11 +154,17 @@ paths = {
|
|
144
154
|
'API_SECRET_KEY_PATH' : ('{API_CONFIG_RESOURCES_PATH}', '.api_secret_key'),
|
145
155
|
'API_UVICORN_RESOURCES_PATH' : ('{API_CONFIG_RESOURCES_PATH}', 'uvicorn'),
|
146
156
|
'API_UVICORN_CONFIG_PATH' : ('{API_UVICORN_RESOURCES_PATH}', '.thread_config.json'),
|
157
|
+
|
158
|
+
'WEBTERM_INTERNAL_RESOURCES_PATH': ('{INTERNAL_RESOURCES_PATH}', 'webterm'),
|
147
159
|
|
148
160
|
'CACHE_RESOURCES_PATH' : ('{ROOT_DIR_PATH}', '.cache'),
|
149
161
|
'PIPES_CACHE_RESOURCES_PATH' : ('{CACHE_RESOURCES_PATH}', 'pipes'),
|
150
162
|
'USERS_CACHE_RESOURCES_PATH' : ('{CACHE_RESOURCES_PATH}', 'users'),
|
151
163
|
'VENVS_CACHE_RESOURCES_PATH' : ('{CACHE_RESOURCES_PATH}', 'venvs'),
|
164
|
+
'SQL_CONN_CACHE_RESOURCES_PATH' : ('{CACHE_RESOURCES_PATH}', 'sql'),
|
165
|
+
|
166
|
+
'CLI_RESOURCES_PATH' : ('{INTERNAL_RESOURCES_PATH}', 'cli'),
|
167
|
+
'CLI_LOGS_RESOURCES_PATH' : ('{CLI_RESOURCES_PATH}', 'logs'),
|
152
168
|
|
153
169
|
'PLUGINS_RESOURCES_PATH' : ('{INTERNAL_RESOURCES_PATH}', 'plugins'),
|
154
170
|
'PLUGINS_INTERNAL_LOCK_PATH' : ('{INTERNAL_RESOURCES_PATH}', 'plugins.lock'),
|
@@ -156,6 +172,11 @@ paths = {
|
|
156
172
|
'PLUGINS_ARCHIVES_RESOURCES_PATH': ('{PLUGINS_RESOURCES_PATH}', '.archives'),
|
157
173
|
'PLUGINS_TEMP_RESOURCES_PATH' : ('{PLUGINS_RESOURCES_PATH}', '.tmp'),
|
158
174
|
'PLUGINS_INIT_PATH' : ('{PLUGINS_RESOURCES_PATH}', '__init__.py'),
|
175
|
+
'PLUGINS_INJECTED_RESOURCES_PATH': ('{PLUGINS_RESOURCES_PATH}', '.injected'),
|
176
|
+
|
177
|
+
'DB_RESOURCES_PATH' : ('{ROOT_DIR_PATH}', 'db'),
|
178
|
+
'DB_INIT_RESOURCES_PATH' : ('{DB_RESOURCES_PATH}', 'initdb'),
|
179
|
+
'DB_CREATE_EXTENSIONS_PATH' : ('{DB_INIT_RESOURCES_PATH}', 'create-extensions.sql'),
|
159
180
|
|
160
181
|
'SQLITE_RESOURCES_PATH' : ('{ROOT_DIR_PATH}', 'sqlite'),
|
161
182
|
'SQLITE_DB_PATH' : ('{SQLITE_RESOURCES_PATH}', 'mrsm_local.db'),
|
@@ -192,11 +213,110 @@ paths = {
|
|
192
213
|
|
193
214
|
def set_root(root: Union[Path, str]):
|
194
215
|
"""Modify the value of `ROOT_DIR_PATH`."""
|
195
|
-
paths['ROOT_DIR_PATH'] = Path(root).resolve()
|
216
|
+
paths['ROOT_DIR_PATH'] = Path(root).resolve().as_posix()
|
196
217
|
for path_name, path_parts in paths.items():
|
197
218
|
if isinstance(path_parts, tuple) and path_parts[0] == '{ROOT_DIR_PATH}':
|
198
219
|
globals()[path_name] = __getattr__(path_name)
|
199
220
|
|
221
|
+
def set_plugins_dir_paths(plugins_dir_paths: Union[List[Path], Path, str]):
|
222
|
+
"""Modify the value of `PLUGINS_DIR_PATHS`."""
|
223
|
+
global PLUGINS_DIR_PATHS
|
224
|
+
if isinstance(plugins_dir_paths, str):
|
225
|
+
if plugins_dir_paths.strip() and plugins_dir_paths.lstrip()[0] == '[':
|
226
|
+
plugins_dir_paths = json.loads(plugins_dir_paths)
|
227
|
+
else:
|
228
|
+
plugins_dir_paths = plugins_dir_paths.split(':')
|
229
|
+
plugins_dir_paths = [Path(_path).resolve() for _path in plugins_dir_paths]
|
230
|
+
if isinstance(plugins_dir_paths, Path):
|
231
|
+
plugins_dir_paths = [plugins_dir_paths.resolve()]
|
232
|
+
|
233
|
+
PLUGINS_DIR_PATHS = plugins_dir_paths
|
234
|
+
_process_plugins_dir_paths(plugins_dir_paths)
|
235
|
+
|
236
|
+
def set_venvs_dir_path(venvs_dir_path: Union[str, Path]):
|
237
|
+
"""Modify the value of `VIRTENV_RESOURCES_PATH`."""
|
238
|
+
paths['VIRTENV_RESOURCES_PATH'] = Path(venvs_dir_path).resolve().as_posix()
|
239
|
+
|
240
|
+
def set_config_dir_path(config_dir_path: Union[str, Path]):
|
241
|
+
paths['CONFIG_DIR_PATH'] = Path(config_dir_path).resolve().as_posix()
|
242
|
+
|
243
|
+
|
244
|
+
@contextlib.contextmanager
|
245
|
+
def replace_root_dir(root_dir_path: Union[str, Path, None]):
|
246
|
+
"""
|
247
|
+
Temporarily replace the root directory path.
|
248
|
+
"""
|
249
|
+
if root_dir_path is None:
|
250
|
+
try:
|
251
|
+
yield
|
252
|
+
finally:
|
253
|
+
return
|
254
|
+
|
255
|
+
old_root = paths.get('ROOT_DIR_PATH', _ROOT_DIR_PATH)
|
256
|
+
set_root(root_dir_path)
|
257
|
+
|
258
|
+
try:
|
259
|
+
yield
|
260
|
+
finally:
|
261
|
+
set_root(old_root)
|
262
|
+
|
263
|
+
@contextlib.contextmanager
|
264
|
+
def replace_plugins_dir_paths(plugins_dir_paths: Union[List[Path], None]):
|
265
|
+
"""
|
266
|
+
Temporarily replace the plugins directory paths.
|
267
|
+
"""
|
268
|
+
if plugins_dir_paths is None:
|
269
|
+
try:
|
270
|
+
yield
|
271
|
+
finally:
|
272
|
+
return
|
273
|
+
|
274
|
+
old_plugins_dir_paths = PLUGINS_DIR_PATHS
|
275
|
+
set_plugins_dir_paths(plugins_dir_paths)
|
276
|
+
|
277
|
+
try:
|
278
|
+
yield
|
279
|
+
finally:
|
280
|
+
set_plugins_dir_paths(old_plugins_dir_paths)
|
281
|
+
|
282
|
+
@contextlib.contextmanager
|
283
|
+
def replace_venvs_dir_path(venvs_dir_path: Union[Path, None]):
|
284
|
+
"""
|
285
|
+
Temporarily replace the virtual environments directory path.
|
286
|
+
"""
|
287
|
+
if venvs_dir_path is None:
|
288
|
+
try:
|
289
|
+
yield
|
290
|
+
finally:
|
291
|
+
return
|
292
|
+
|
293
|
+
old_venvs_dir_path = paths.get('VIRTENV_RESOURCES_PATH', _VENVS_DIR_PATH)
|
294
|
+
set_venvs_dir_path(venvs_dir_path)
|
295
|
+
|
296
|
+
try:
|
297
|
+
yield
|
298
|
+
finally:
|
299
|
+
set_venvs_dir_path(old_venvs_dir_path)
|
300
|
+
|
301
|
+
@contextlib.contextmanager
|
302
|
+
def replace_config_dir_path(config_dir_path: Union[Path, None]):
|
303
|
+
"""
|
304
|
+
Temporarily replace the config directory path.
|
305
|
+
"""
|
306
|
+
if config_dir_path is None:
|
307
|
+
try:
|
308
|
+
yield
|
309
|
+
finally:
|
310
|
+
return
|
311
|
+
|
312
|
+
old_config_dir_path = paths.get('CONFIG_DIR_PATH', _CONFIG_DIR_PATH)
|
313
|
+
set_config_dir_path(config_dir_path)
|
314
|
+
|
315
|
+
try:
|
316
|
+
yield
|
317
|
+
finally:
|
318
|
+
set_config_dir_path(old_config_dir_path)
|
319
|
+
|
200
320
|
|
201
321
|
def __getattr__(name: str) -> Path:
|
202
322
|
if name not in paths:
|
@@ -8,8 +8,9 @@ Import the config yaml file
|
|
8
8
|
from __future__ import annotations
|
9
9
|
import pathlib
|
10
10
|
|
11
|
+
import meerschaum as mrsm
|
11
12
|
from meerschaum.utils.typing import Optional, Dict, Any, List, Tuple, Union
|
12
|
-
from meerschaum.
|
13
|
+
from meerschaum._internal.static import STATIC_CONFIG
|
13
14
|
|
14
15
|
|
15
16
|
def read_config(
|
@@ -49,11 +50,11 @@ def read_config(
|
|
49
50
|
>>> read_config(keys=['meerschaum'], with_filename=True)
|
50
51
|
>>> ({...}, ['meerschaum.yaml'])
|
51
52
|
"""
|
52
|
-
import
|
53
|
-
|
53
|
+
import os
|
54
|
+
import json
|
55
|
+
import itertools
|
54
56
|
from meerschaum.utils.yaml import yaml, _yaml
|
55
57
|
from meerschaum.config._paths import CONFIG_DIR_PATH
|
56
|
-
from meerschaum.config.static import STATIC_CONFIG
|
57
58
|
from meerschaum.config._patch import apply_patch_to_config
|
58
59
|
if directory is None:
|
59
60
|
directory = CONFIG_DIR_PATH
|
@@ -106,20 +107,25 @@ def read_config(
|
|
106
107
|
### If default config contains symlinks, add them to the config to write.
|
107
108
|
try:
|
108
109
|
_default_symlinks = _default_dict[symlinks_key][mk]
|
109
|
-
except
|
110
|
+
except KeyError:
|
110
111
|
_default_symlinks = {}
|
112
|
+
|
111
113
|
config[mk] = _default_dict[mk]
|
112
114
|
if _default_symlinks:
|
113
115
|
if symlinks_key not in config:
|
114
116
|
config[symlinks_key] = {}
|
117
|
+
if symlinks_key not in config_to_write:
|
118
|
+
config_to_write[symlinks_key] = {}
|
119
|
+
|
115
120
|
if mk not in config[symlinks_key]:
|
116
121
|
config[symlinks_key][mk] = {}
|
122
|
+
if mk not in config_to_write[symlinks_key]:
|
123
|
+
config_to_write[symlinks_key][mk] = {}
|
124
|
+
|
117
125
|
config[symlinks_key][mk] = apply_patch_to_config(
|
118
126
|
config[symlinks_key][mk],
|
119
127
|
_default_symlinks
|
120
128
|
)
|
121
|
-
if symlinks_key not in config_to_write:
|
122
|
-
config_to_write[symlinks_key] = {}
|
123
129
|
config_to_write[symlinks_key][mk] = config[symlinks_key][mk]
|
124
130
|
|
125
131
|
### Write the default key.
|
@@ -179,6 +185,7 @@ def read_config(
|
|
179
185
|
import traceback
|
180
186
|
traceback.print_exc()
|
181
187
|
_config_key = {}
|
188
|
+
substitute = False
|
182
189
|
_single_key_config = (
|
183
190
|
search_and_substitute_config({key: _config_key}) if substitute
|
184
191
|
else {key: _config_key}
|
@@ -208,15 +215,16 @@ def read_config(
|
|
208
215
|
|
209
216
|
|
210
217
|
def search_and_substitute_config(
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
"""
|
218
|
+
config: Dict[str, Any],
|
219
|
+
leading_key: str = "MRSM",
|
220
|
+
delimiter: str = ":",
|
221
|
+
begin_key: str = "{",
|
222
|
+
end_key: str = "}",
|
223
|
+
literal_key: str = '!',
|
224
|
+
keep_symlinks: bool = True,
|
225
|
+
) -> Dict[str, Any]:
|
226
|
+
"""
|
227
|
+
Search the config for Meerschaum substitution syntax and substite with value of keys.
|
220
228
|
|
221
229
|
Parameters
|
222
230
|
----------
|
@@ -242,7 +250,7 @@ def search_and_substitute_config(
|
|
242
250
|
- ' MRSM{a:b:c} ' => ' "{\'d\': 1}"' : not isolated
|
243
251
|
- ' MRSM{!a:b:c} ' => ' {"d": 1}' : literal
|
244
252
|
|
245
|
-
keep_symlinks
|
253
|
+
keep_symlinks: bool, default True
|
246
254
|
If True, include the symlinks under the top-level key '_symlinks' (never written to a file).
|
247
255
|
Defaults to True.
|
248
256
|
|
@@ -251,7 +259,13 @@ def search_and_substitute_config(
|
|
251
259
|
```
|
252
260
|
MRSM{meerschaum:connectors:main:host} => cf['meerschaum']['connectors']['main']['host']
|
253
261
|
```
|
262
|
+
|
263
|
+
Returns
|
264
|
+
-------
|
265
|
+
The configuration dictionary with `MRSM{}` symlinks replaced with
|
266
|
+
the values from the current configuration.
|
254
267
|
"""
|
268
|
+
from meerschaum.config import get_config
|
255
269
|
|
256
270
|
_links = []
|
257
271
|
def _find_symlinks(d, _keys: Optional[List[str]] = None):
|
@@ -270,9 +284,6 @@ def search_and_substitute_config(
|
|
270
284
|
import json
|
271
285
|
needle = leading_key + begin_key
|
272
286
|
haystack = json.dumps(config, separators=(',', ':'))
|
273
|
-
mod_haystack = list(str(haystack))
|
274
|
-
buff = str(needle)
|
275
|
-
max_index = len(haystack) - len(buff)
|
276
287
|
|
277
288
|
patterns = {}
|
278
289
|
isolated_patterns = {}
|
@@ -329,7 +340,7 @@ def search_and_substitute_config(
|
|
329
340
|
write_missing=False,
|
330
341
|
sync_files=False,
|
331
342
|
)
|
332
|
-
except Exception
|
343
|
+
except Exception:
|
333
344
|
import traceback
|
334
345
|
traceback.print_exc()
|
335
346
|
valid = False
|
@@ -382,15 +393,55 @@ def search_and_substitute_config(
|
|
382
393
|
s[_keys[-1]] = _pattern
|
383
394
|
|
384
395
|
from meerschaum.config._patch import apply_patch_to_config
|
385
|
-
from meerschaum.config.static import STATIC_CONFIG
|
386
396
|
symlinks_key = STATIC_CONFIG['config']['symlinks_key']
|
387
|
-
if
|
388
|
-
|
389
|
-
|
397
|
+
if symlinks:
|
398
|
+
if symlinks_key not in parsed_config:
|
399
|
+
parsed_config[symlinks_key] = symlinks
|
400
|
+
else:
|
401
|
+
parsed_config[symlinks_key] = apply_patch_to_config(
|
402
|
+
parsed_config[symlinks_key],
|
403
|
+
symlinks,
|
404
|
+
warn=False,
|
405
|
+
)
|
390
406
|
|
391
407
|
return parsed_config
|
392
408
|
|
393
409
|
|
410
|
+
def revert_symlinks_config(config: Dict[str, Any]) -> Dict[str, Any]:
|
411
|
+
"""
|
412
|
+
Given a configuration dictionary, re-apply the values from the
|
413
|
+
accompanying `_symlinks` dictionary.
|
414
|
+
|
415
|
+
Parameters
|
416
|
+
----------
|
417
|
+
config: Dict[str, Any]
|
418
|
+
The configuration dictionary containing a `_symlinks` dictionary.
|
419
|
+
|
420
|
+
Returns
|
421
|
+
-------
|
422
|
+
A configuration dictionary with `_symlinks` re-applied.
|
423
|
+
"""
|
424
|
+
import copy
|
425
|
+
from meerschaum._internal.static import STATIC_CONFIG
|
426
|
+
|
427
|
+
symlinks_key = STATIC_CONFIG['config']['symlinks_key']
|
428
|
+
if symlinks_key not in config:
|
429
|
+
return config
|
430
|
+
|
431
|
+
reverted_config = copy.deepcopy(config)
|
432
|
+
symlinks_config = reverted_config.pop(symlinks_key)
|
433
|
+
|
434
|
+
def deep_patch(target_dict, patch_dict):
|
435
|
+
for key, value in patch_dict.items():
|
436
|
+
if isinstance(value, dict) and key in target_dict and isinstance(target_dict[key], dict):
|
437
|
+
deep_patch(target_dict[key], value)
|
438
|
+
else:
|
439
|
+
target_dict[key] = value
|
440
|
+
|
441
|
+
deep_patch(reverted_config, symlinks_config)
|
442
|
+
return reverted_config
|
443
|
+
|
444
|
+
|
394
445
|
def get_possible_keys() -> List[str]:
|
395
446
|
"""
|
396
447
|
Return a list of possible top-level keys.
|
@@ -407,12 +458,13 @@ def get_possible_keys() -> List[str]:
|
|
407
458
|
|
408
459
|
|
409
460
|
def get_keyfile_path(
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
461
|
+
key: str,
|
462
|
+
create_new: bool = False,
|
463
|
+
directory: Union[pathlib.Path, str, None] = None,
|
464
|
+
) -> Union[pathlib.Path, None]:
|
414
465
|
"""Determine a key's file path."""
|
415
|
-
import os
|
466
|
+
import os
|
467
|
+
import pathlib
|
416
468
|
if directory is None:
|
417
469
|
from meerschaum.config._paths import CONFIG_DIR_PATH
|
418
470
|
directory = CONFIG_DIR_PATH
|
@@ -422,16 +474,15 @@ def get_keyfile_path(
|
|
422
474
|
os.path.join(
|
423
475
|
directory,
|
424
476
|
read_config(
|
425
|
-
keys
|
426
|
-
with_filenames
|
427
|
-
write_missing
|
428
|
-
substitute
|
477
|
+
keys=[key],
|
478
|
+
with_filenames=True,
|
479
|
+
write_missing=False,
|
480
|
+
substitute=False,
|
429
481
|
)[1][0]
|
430
482
|
)
|
431
483
|
)
|
432
|
-
except IndexError
|
484
|
+
except IndexError:
|
433
485
|
if create_new:
|
434
|
-
from meerschaum.config.static import STATIC_CONFIG
|
435
486
|
default_filetype = STATIC_CONFIG['config']['default_filetype']
|
436
487
|
return pathlib.Path(os.path.join(directory, key + '.' + default_filetype))
|
437
488
|
return None
|
meerschaum/config/_sync.py
CHANGED
@@ -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
|
43
|
+
import os
|
44
|
+
import sys
|
44
45
|
try:
|
45
46
|
from meerschaum.utils.yaml import yaml, _yaml
|
46
|
-
except Exception
|
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.
|
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,
|
meerschaum/config/_version.py
CHANGED