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.
Files changed (201) 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 +33 -4
  5. meerschaum/_internal/cli/__init__.py +6 -0
  6. meerschaum/_internal/cli/daemons.py +103 -0
  7. meerschaum/_internal/cli/entry.py +220 -0
  8. meerschaum/_internal/cli/workers.py +435 -0
  9. meerschaum/_internal/docs/index.py +48 -2
  10. meerschaum/_internal/entry.py +50 -14
  11. meerschaum/_internal/shell/Shell.py +121 -29
  12. meerschaum/_internal/shell/__init__.py +4 -1
  13. meerschaum/_internal/static.py +359 -0
  14. meerschaum/_internal/term/TermPageHandler.py +1 -2
  15. meerschaum/_internal/term/__init__.py +40 -6
  16. meerschaum/_internal/term/tools.py +33 -8
  17. meerschaum/actions/__init__.py +6 -4
  18. meerschaum/actions/api.py +53 -13
  19. meerschaum/actions/attach.py +1 -0
  20. meerschaum/actions/bootstrap.py +8 -8
  21. meerschaum/actions/delete.py +4 -2
  22. meerschaum/actions/edit.py +171 -25
  23. meerschaum/actions/login.py +8 -8
  24. meerschaum/actions/register.py +143 -6
  25. meerschaum/actions/reload.py +22 -5
  26. meerschaum/actions/restart.py +14 -0
  27. meerschaum/actions/show.py +184 -31
  28. meerschaum/actions/start.py +166 -17
  29. meerschaum/actions/stop.py +38 -2
  30. meerschaum/actions/sync.py +7 -2
  31. meerschaum/actions/tag.py +9 -8
  32. meerschaum/actions/verify.py +5 -8
  33. meerschaum/api/__init__.py +45 -15
  34. meerschaum/api/_events.py +46 -4
  35. meerschaum/api/_oauth2.py +162 -9
  36. meerschaum/api/_tokens.py +102 -0
  37. meerschaum/api/dash/__init__.py +0 -3
  38. meerschaum/api/dash/callbacks/__init__.py +1 -0
  39. meerschaum/api/dash/callbacks/custom.py +4 -3
  40. meerschaum/api/dash/callbacks/dashboard.py +228 -117
  41. meerschaum/api/dash/callbacks/jobs.py +14 -7
  42. meerschaum/api/dash/callbacks/login.py +10 -1
  43. meerschaum/api/dash/callbacks/pipes.py +194 -14
  44. meerschaum/api/dash/callbacks/plugins.py +0 -1
  45. meerschaum/api/dash/callbacks/register.py +10 -3
  46. meerschaum/api/dash/callbacks/settings/password_reset.py +2 -2
  47. meerschaum/api/dash/callbacks/tokens.py +389 -0
  48. meerschaum/api/dash/components.py +36 -15
  49. meerschaum/api/dash/jobs.py +1 -1
  50. meerschaum/api/dash/keys.py +35 -93
  51. meerschaum/api/dash/pages/__init__.py +2 -1
  52. meerschaum/api/dash/pages/dashboard.py +1 -20
  53. meerschaum/api/dash/pages/{job.py → jobs.py} +10 -7
  54. meerschaum/api/dash/pages/login.py +2 -2
  55. meerschaum/api/dash/pages/pipes.py +16 -5
  56. meerschaum/api/dash/pages/settings/password_reset.py +1 -1
  57. meerschaum/api/dash/pages/tokens.py +53 -0
  58. meerschaum/api/dash/pipes.py +438 -88
  59. meerschaum/api/dash/sessions.py +12 -0
  60. meerschaum/api/dash/tokens.py +603 -0
  61. meerschaum/api/dash/websockets.py +1 -1
  62. meerschaum/api/dash/webterm.py +18 -6
  63. meerschaum/api/models/__init__.py +23 -3
  64. meerschaum/api/models/_actions.py +22 -0
  65. meerschaum/api/models/_pipes.py +91 -7
  66. meerschaum/api/models/_tokens.py +81 -0
  67. meerschaum/api/resources/static/css/dash.css +16 -0
  68. meerschaum/api/resources/static/js/terminado.js +3 -0
  69. meerschaum/api/resources/static/js/xterm-addon-unicode11.js +2 -0
  70. meerschaum/api/resources/templates/termpage.html +13 -0
  71. meerschaum/api/routes/__init__.py +1 -0
  72. meerschaum/api/routes/_actions.py +3 -4
  73. meerschaum/api/routes/_connectors.py +3 -7
  74. meerschaum/api/routes/_jobs.py +26 -35
  75. meerschaum/api/routes/_login.py +120 -15
  76. meerschaum/api/routes/_misc.py +5 -10
  77. meerschaum/api/routes/_pipes.py +178 -143
  78. meerschaum/api/routes/_plugins.py +38 -28
  79. meerschaum/api/routes/_tokens.py +236 -0
  80. meerschaum/api/routes/_users.py +47 -35
  81. meerschaum/api/routes/_version.py +3 -3
  82. meerschaum/api/routes/_webterm.py +3 -3
  83. meerschaum/config/__init__.py +100 -30
  84. meerschaum/config/_default.py +132 -64
  85. meerschaum/config/_edit.py +38 -32
  86. meerschaum/config/_formatting.py +2 -0
  87. meerschaum/config/_patch.py +10 -8
  88. meerschaum/config/_paths.py +133 -13
  89. meerschaum/config/_read_config.py +87 -36
  90. meerschaum/config/_sync.py +6 -3
  91. meerschaum/config/_version.py +1 -1
  92. meerschaum/config/environment.py +262 -0
  93. meerschaum/config/stack/__init__.py +37 -15
  94. meerschaum/config/static.py +18 -0
  95. meerschaum/connectors/_Connector.py +11 -6
  96. meerschaum/connectors/__init__.py +41 -22
  97. meerschaum/connectors/api/_APIConnector.py +34 -6
  98. meerschaum/connectors/api/_actions.py +2 -2
  99. meerschaum/connectors/api/_jobs.py +12 -1
  100. meerschaum/connectors/api/_login.py +33 -7
  101. meerschaum/connectors/api/_misc.py +2 -2
  102. meerschaum/connectors/api/_pipes.py +23 -32
  103. meerschaum/connectors/api/_plugins.py +2 -2
  104. meerschaum/connectors/api/_request.py +1 -1
  105. meerschaum/connectors/api/_tokens.py +146 -0
  106. meerschaum/connectors/api/_users.py +70 -58
  107. meerschaum/connectors/instance/_InstanceConnector.py +83 -0
  108. meerschaum/connectors/instance/__init__.py +10 -0
  109. meerschaum/connectors/instance/_pipes.py +442 -0
  110. meerschaum/connectors/instance/_plugins.py +159 -0
  111. meerschaum/connectors/instance/_tokens.py +317 -0
  112. meerschaum/connectors/instance/_users.py +188 -0
  113. meerschaum/connectors/parse.py +5 -2
  114. meerschaum/connectors/sql/_SQLConnector.py +22 -5
  115. meerschaum/connectors/sql/_cli.py +12 -11
  116. meerschaum/connectors/sql/_create_engine.py +12 -168
  117. meerschaum/connectors/sql/_fetch.py +2 -18
  118. meerschaum/connectors/sql/_pipes.py +295 -278
  119. meerschaum/connectors/sql/_plugins.py +29 -0
  120. meerschaum/connectors/sql/_sql.py +47 -22
  121. meerschaum/connectors/sql/_users.py +36 -2
  122. meerschaum/connectors/sql/tables/__init__.py +254 -122
  123. meerschaum/connectors/valkey/_ValkeyConnector.py +5 -7
  124. meerschaum/connectors/valkey/_pipes.py +60 -31
  125. meerschaum/connectors/valkey/_plugins.py +2 -26
  126. meerschaum/core/Pipe/__init__.py +115 -85
  127. meerschaum/core/Pipe/_attributes.py +425 -124
  128. meerschaum/core/Pipe/_bootstrap.py +54 -24
  129. meerschaum/core/Pipe/_cache.py +555 -0
  130. meerschaum/core/Pipe/_clear.py +0 -11
  131. meerschaum/core/Pipe/_data.py +96 -68
  132. meerschaum/core/Pipe/_deduplicate.py +0 -13
  133. meerschaum/core/Pipe/_delete.py +12 -21
  134. meerschaum/core/Pipe/_drop.py +11 -23
  135. meerschaum/core/Pipe/_dtypes.py +49 -19
  136. meerschaum/core/Pipe/_edit.py +14 -4
  137. meerschaum/core/Pipe/_fetch.py +1 -1
  138. meerschaum/core/Pipe/_index.py +8 -14
  139. meerschaum/core/Pipe/_show.py +5 -5
  140. meerschaum/core/Pipe/_sync.py +123 -204
  141. meerschaum/core/Pipe/_verify.py +4 -4
  142. meerschaum/{plugins → core/Plugin}/_Plugin.py +16 -12
  143. meerschaum/core/Plugin/__init__.py +1 -1
  144. meerschaum/core/Token/_Token.py +220 -0
  145. meerschaum/core/Token/__init__.py +12 -0
  146. meerschaum/core/User/_User.py +35 -10
  147. meerschaum/core/User/__init__.py +9 -1
  148. meerschaum/core/__init__.py +1 -0
  149. meerschaum/jobs/_Executor.py +88 -4
  150. meerschaum/jobs/_Job.py +149 -38
  151. meerschaum/jobs/__init__.py +3 -2
  152. meerschaum/jobs/systemd.py +8 -3
  153. meerschaum/models/__init__.py +35 -0
  154. meerschaum/models/pipes.py +247 -0
  155. meerschaum/models/tokens.py +38 -0
  156. meerschaum/models/users.py +26 -0
  157. meerschaum/plugins/__init__.py +301 -88
  158. meerschaum/plugins/bootstrap.py +510 -4
  159. meerschaum/utils/_get_pipes.py +97 -30
  160. meerschaum/utils/daemon/Daemon.py +199 -43
  161. meerschaum/utils/daemon/FileDescriptorInterceptor.py +0 -1
  162. meerschaum/utils/daemon/RotatingFile.py +63 -36
  163. meerschaum/utils/daemon/StdinFile.py +53 -13
  164. meerschaum/utils/daemon/__init__.py +47 -6
  165. meerschaum/utils/daemon/_names.py +6 -3
  166. meerschaum/utils/dataframe.py +480 -82
  167. meerschaum/utils/debug.py +49 -19
  168. meerschaum/utils/dtypes/__init__.py +478 -37
  169. meerschaum/utils/dtypes/sql.py +369 -29
  170. meerschaum/utils/formatting/__init__.py +5 -2
  171. meerschaum/utils/formatting/_jobs.py +1 -1
  172. meerschaum/utils/formatting/_pipes.py +52 -50
  173. meerschaum/utils/formatting/_pprint.py +1 -0
  174. meerschaum/utils/formatting/_shell.py +44 -18
  175. meerschaum/utils/misc.py +268 -186
  176. meerschaum/utils/packages/__init__.py +25 -40
  177. meerschaum/utils/packages/_packages.py +42 -34
  178. meerschaum/utils/pipes.py +213 -0
  179. meerschaum/utils/process.py +2 -2
  180. meerschaum/utils/prompt.py +175 -144
  181. meerschaum/utils/schedule.py +2 -1
  182. meerschaum/utils/sql.py +135 -49
  183. meerschaum/utils/threading.py +42 -0
  184. meerschaum/utils/typing.py +1 -4
  185. meerschaum/utils/venv/_Venv.py +2 -2
  186. meerschaum/utils/venv/__init__.py +7 -7
  187. meerschaum/utils/warnings.py +19 -13
  188. {meerschaum-2.9.4.dist-info → meerschaum-3.0.0.dist-info}/METADATA +94 -96
  189. meerschaum-3.0.0.dist-info/RECORD +289 -0
  190. {meerschaum-2.9.4.dist-info → meerschaum-3.0.0.dist-info}/WHEEL +1 -1
  191. meerschaum-3.0.0.dist-info/licenses/NOTICE +2 -0
  192. meerschaum/api/models/_interfaces.py +0 -15
  193. meerschaum/api/models/_locations.py +0 -15
  194. meerschaum/api/models/_metrics.py +0 -15
  195. meerschaum/config/_environment.py +0 -145
  196. meerschaum/config/static/__init__.py +0 -186
  197. meerschaum-2.9.4.dist-info/RECORD +0 -263
  198. {meerschaum-2.9.4.dist-info → meerschaum-3.0.0.dist-info}/entry_points.txt +0 -0
  199. {meerschaum-2.9.4.dist-info → meerschaum-3.0.0.dist-info}/licenses/LICENSE +0 -0
  200. {meerschaum-2.9.4.dist-info → meerschaum-3.0.0.dist-info}/top_level.txt +0 -0
  201. {meerschaum-2.9.4.dist-info → meerschaum-3.0.0.dist-info}/zip-safe +0 -0
@@ -10,11 +10,21 @@ from __future__ import annotations
10
10
 
11
11
  import meerschaum as mrsm
12
12
  from meerschaum.utils.typing import (
13
- Sequence, Optional, Union, Mapping, Any, InstanceConnector, PipesDict, List, Dict, Tuple
13
+ Sequence,
14
+ Optional,
15
+ Union,
16
+ Mapping,
17
+ Any,
18
+ PipesDict,
19
+ List,
20
+ Dict,
21
+ Tuple,
22
+ InstanceConnector,
14
23
  )
15
24
 
16
25
  __pdoc__ = {'get_pipes': True, 'fetch_pipes_keys': True}
17
26
 
27
+
18
28
  def get_pipes(
19
29
  connector_keys: Union[str, List[str], None] = None,
20
30
  metric_keys: Union[str, List[str], None] = None,
@@ -24,10 +34,12 @@ def get_pipes(
24
34
  mrsm_instance: Union[str, InstanceConnector, None] = None,
25
35
  instance: Union[str, InstanceConnector, None] = None,
26
36
  as_list: bool = False,
37
+ as_tags_dict: bool = False,
27
38
  method: str = 'registered',
39
+ workers: Optional[int] = None,
28
40
  debug: bool = False,
29
41
  **kw: Any
30
- ) -> Union[PipesDict, List[mrsm.Pipe]]:
42
+ ) -> Union[PipesDict, List[mrsm.Pipe], Dict[str, mrsm.Pipe]]:
31
43
  """
32
44
  Return a dictionary or list of `meerschaum.Pipe` objects.
33
45
 
@@ -62,6 +74,10 @@ def get_pipes(
62
74
  `False` : `{connector_keys: {metric_key: {location_key: Pipe}}}`
63
75
  `True` : `[Pipe]`
64
76
 
77
+ as_tags_dict: bool, default False
78
+ If `True`, return a dictionary mapping tags to pipes.
79
+ Pipes with multiple tags will be repeated.
80
+
65
81
  method: str, default 'registered'
66
82
  Available options: `['registered', 'explicit', 'all']`
67
83
  If `'registered'` (default), create pipes based on registered keys in the connector's pipes table
@@ -71,6 +87,11 @@ def get_pipes(
71
87
  If `'all'`, create pipes from predefined metrics and locations. Required `connector_keys`.
72
88
  **NOTE:** Method `'all'` is not implemented!
73
89
 
90
+ workers: Optional[int], default None
91
+ If provided (and `as_tags_dict` is `True`), set the number of workers for the pool
92
+ to fetch tags.
93
+ Only takes effect if the instance connector supports multi-threading
94
+
74
95
  **kw: Any:
75
96
  Keyword arguments to pass to the `meerschaum.Pipe` constructor.
76
97
 
@@ -80,6 +101,7 @@ def get_pipes(
80
101
  A dictionary of dictionaries and `meerschaum.Pipe` objects
81
102
  in the connector, metric, location hierarchy.
82
103
  If `as_list` is `True`, return a list of `meerschaum.Pipe` objects.
104
+ If `as_tags_dict` is `True`, return a dictionary mapping tags to pipes.
83
105
 
84
106
  Examples
85
107
  --------
@@ -100,14 +122,18 @@ def get_pipes(
100
122
  >>> pipes['sql:main']['weather'][None]
101
123
  >>> ### Return a list instead:
102
124
  >>> get_pipes(as_list=True)
103
- [sql_main_weather]
104
- >>>
125
+ [Pipe('sql:main', 'weather')]
126
+ >>> get_pipes(as_tags_dict=True)
127
+ {'gvl': Pipe('sql:main', 'weather')}
105
128
  ```
106
129
  """
107
130
 
131
+ import json
132
+ from collections import defaultdict
108
133
  from meerschaum.config import get_config
109
134
  from meerschaum.utils.warnings import error
110
135
  from meerschaum.utils.misc import filter_keywords
136
+ from meerschaum.utils.pool import get_pool
111
137
 
112
138
  if connector_keys is None:
113
139
  connector_keys = []
@@ -159,40 +185,81 @@ def get_pipes(
159
185
  location_keys = location_keys,
160
186
  tags = tags,
161
187
  params = params,
188
+ workers = workers,
162
189
  debug = debug
163
190
  )
164
191
  if result is None:
165
- error(f"Unable to build pipes!")
192
+ error("Unable to build pipes!")
166
193
 
167
194
  ### Populate the `pipes` dictionary with Pipes based on the keys
168
195
  ### obtained from the chosen `method`.
169
196
  from meerschaum import Pipe
170
197
  pipes = {}
171
- for ck, mk, lk in result:
198
+ for keys_tuple in result:
199
+ ck, mk, lk = keys_tuple[0], keys_tuple[1], keys_tuple[2]
200
+ pipe_tags_or_parameters = keys_tuple[3] if len(keys_tuple) == 4 else None
201
+ pipe_parameters = (
202
+ pipe_tags_or_parameters
203
+ if isinstance(pipe_tags_or_parameters, (dict, str))
204
+ else None
205
+ )
206
+ if isinstance(pipe_parameters, str):
207
+ pipe_parameters = json.loads(pipe_parameters)
208
+ pipe_tags = (
209
+ pipe_tags_or_parameters
210
+ if isinstance(pipe_tags_or_parameters, list)
211
+ else (
212
+ pipe_tags_or_parameters.get('tags', None)
213
+ if isinstance(pipe_tags_or_parameters, dict)
214
+ else None
215
+ )
216
+ )
217
+
172
218
  if ck not in pipes:
173
219
  pipes[ck] = {}
174
220
 
175
221
  if mk not in pipes[ck]:
176
222
  pipes[ck][mk] = {}
177
223
 
178
- pipes[ck][mk][lk] = Pipe(
224
+ pipe = Pipe(
179
225
  ck, mk, lk,
180
226
  mrsm_instance = connector,
227
+ parameters = pipe_parameters,
228
+ tags = pipe_tags,
181
229
  debug = debug,
182
230
  **filter_keywords(Pipe, **kw)
183
231
  )
232
+ pipe.__dict__['_tags'] = pipe_tags
233
+ pipes[ck][mk][lk] = pipe
184
234
 
185
- if not as_list:
235
+ if not as_list and not as_tags_dict:
186
236
  return pipes
237
+
187
238
  from meerschaum.utils.misc import flatten_pipes_dict
188
- return flatten_pipes_dict(pipes)
239
+ pipes_list = flatten_pipes_dict(pipes)
240
+ if as_list:
241
+ return pipes_list
242
+
243
+ pool = get_pool(workers=(workers if connector.IS_THREAD_SAFE else 1))
244
+ def gather_pipe_tags(pipe: mrsm.Pipe) -> Tuple[mrsm.Pipe, List[str]]:
245
+ _tags = pipe.__dict__.get('_tags', None)
246
+ gathered_tags = _tags if _tags is not None else pipe.tags
247
+ return pipe, (gathered_tags or [])
248
+
249
+ tags_pipes = defaultdict(lambda: [])
250
+ pipes_tags = dict(pool.map(gather_pipe_tags, pipes_list))
251
+ for pipe, tags in pipes_tags.items():
252
+ for tag in (tags or []):
253
+ tags_pipes[tag].append(pipe)
254
+
255
+ return dict(tags_pipes)
189
256
 
190
257
 
191
258
  def fetch_pipes_keys(
192
- method: str,
193
- connector: 'meerschaum.connectors.Connector',
194
- **kw: Any
195
- ) -> List[Tuple[str, str, str]]:
259
+ method: str,
260
+ connector: 'mrsm.connectors.InstanceConnector',
261
+ **kw: Any
262
+ ) -> List[Tuple[str, str, str]]:
196
263
  """
197
264
  Fetch keys for pipes according to a method.
198
265
 
@@ -201,7 +268,7 @@ def fetch_pipes_keys(
201
268
  method: str
202
269
  The method by which to fetch the keys. See `get_pipes()` above.
203
270
 
204
- connector: meerschaum.connectors.Connector
271
+ connector: meerschaum.connectors.InstanceConnector
205
272
  The connector to use to fetch the keys.
206
273
  Must be of type `meerschaum.connectors.sql.SQLConnector.SQLConnector`
207
274
  or `meerschaum.connectors.api.APIConnector.APIConnector`.
@@ -234,14 +301,14 @@ def fetch_pipes_keys(
234
301
  from meerschaum.utils.warnings import error
235
302
 
236
303
  def _registered(
237
- connector_keys: Optional[List[str]] = None,
238
- metric_keys: Optional[List[str]] = None,
239
- location_keys: Optional[List[str]] = None,
240
- tags: Optional[List[str]] = None,
241
- params: Optional[Dict[str, Any]] = None,
242
- debug: bool = False,
243
- **kw
244
- ) -> List[Tuple[str, str, str]]:
304
+ connector_keys: Optional[List[str]] = None,
305
+ metric_keys: Optional[List[str]] = None,
306
+ location_keys: Optional[List[str]] = None,
307
+ tags: Optional[List[str]] = None,
308
+ params: Optional[Dict[str, Any]] = None,
309
+ debug: bool = False,
310
+ **kw
311
+ ) -> List[Tuple[str, str, str]]:
245
312
  """
246
313
  Get keys from the pipes table or the API directly.
247
314
  Builds query or URL based on provided keys and parameters.
@@ -269,14 +336,14 @@ def fetch_pipes_keys(
269
336
  )
270
337
 
271
338
  def _explicit(
272
- connector_keys: Optional[List[str]] = None,
273
- metric_keys: Optional[List[str]] = None,
274
- location_keys: Optional[List[str]] = None,
275
- params: Optional[Dict[str, Any]] = None,
276
- tags: Optional[List[str]] = None,
277
- debug: bool = False,
278
- **kw
279
- ) -> List[Tuple[str, str, str]]:
339
+ connector_keys: Optional[List[str]] = None,
340
+ metric_keys: Optional[List[str]] = None,
341
+ location_keys: Optional[List[str]] = None,
342
+ params: Optional[Dict[str, Any]] = None,
343
+ tags: Optional[List[str]] = None,
344
+ debug: bool = False,
345
+ **kw
346
+ ) -> List[Tuple[str, str, str]]:
280
347
  """
281
348
  Explicitly build Pipes based on provided keys.
282
349
  Raises an error if `connector_keys` or `metric_keys` is empty,