meerschaum 2.3.0.dev1__py3-none-any.whl → 2.3.0.dev3__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 CHANGED
@@ -30,6 +30,7 @@ from meerschaum.utils import get_pipes
30
30
  from meerschaum.utils.formatting import pprint
31
31
  from meerschaum._internal.docs import index as __doc__
32
32
  from meerschaum.config import __version__, get_config
33
+ from meerschaum._internal.entry import entry
33
34
  from meerschaum.__main__ import _close_pools
34
35
 
35
36
  atexit.register(_close_pools)
@@ -55,4 +56,5 @@ __all__ = (
55
56
  "SuccessTuple",
56
57
  "Connector",
57
58
  "make_connector",
59
+ "entry",
58
60
  )
@@ -288,9 +288,6 @@ def remove_leading_action(
288
288
  for a in action:
289
289
  _action.append(a.replace('_', UNDERSCORE_STANDIN))
290
290
 
291
- ### e.g. 'show_pipes_baz'
292
- action_str = '_'.join(_action)
293
-
294
291
  ### e.g. 'show_pipes'
295
292
  action_name = action_function.__name__.lstrip('_')
296
293
 
@@ -300,6 +297,16 @@ def remove_leading_action(
300
297
  ### Strip away any leading prefices.
301
298
  action_name = action_name[main_action_index:]
302
299
 
300
+ subaction_parts = action_name.replace(main_action_name, '').lstrip('_').split('_')
301
+ subaction_name = subaction_parts[0] if subaction_parts else None
302
+
303
+ ### e.g. 'pipe' -> 'pipes'
304
+ if subaction_name and subaction_name.endswith('s') and not action[1].endswith('s'):
305
+ _action[1] += 's'
306
+
307
+ ### e.g. 'show_pipes_baz'
308
+ action_str = '_'.join(_action)
309
+
303
310
  if not action_str.replace(UNDERSCORE_STANDIN, '_').startswith(action_name):
304
311
  warn(f"Unable to parse '{action_str}' for action '{action_name}'.")
305
312
  return action
@@ -12,9 +12,9 @@ from meerschaum.utils.packages import get_modules_from_package
12
12
  _custom_actions = []
13
13
 
14
14
  def get_subactions(
15
- action: Union[str, List[str]],
16
- _actions: Optional[Dict[str, Callable[[Any], Any]]] = None,
17
- ) -> Dict[str, Callable[[Any], Any]]:
15
+ action: Union[str, List[str]],
16
+ _actions: Optional[Dict[str, Callable[[Any], Any]]] = None,
17
+ ) -> Dict[str, Callable[[Any], Any]]:
18
18
  """
19
19
  Return a dictionary of an action's sub-action functions.
20
20
 
@@ -52,9 +52,9 @@ def get_subactions(
52
52
 
53
53
 
54
54
  def get_action(
55
- action: Union[str, List[str]],
56
- _actions: Optional[Dict[str, Callable[[Any], Any]]] = None,
57
- ) -> Union[Callable[[Any], Any], None]:
55
+ action: Union[str, List[str]],
56
+ _actions: Optional[Dict[str, Callable[[Any], Any]]] = None,
57
+ ) -> Union[Callable[[Any], Any], None]:
58
58
  """
59
59
  Return a function corresponding to the given action list.
60
60
  This may be a custom action with an underscore, in which case, allow for underscores.
@@ -92,6 +92,8 @@ def get_action(
92
92
  if action[0] in _actions:
93
93
  subactions = get_subactions([action[0]], _actions=_actions)
94
94
  if action[1] not in subactions:
95
+ if (action[1] + 's') in subactions:
96
+ return subactions[action[1] + 's']
95
97
  return _actions[action[0]]
96
98
  return subactions[action[1]]
97
99
 
@@ -11,6 +11,7 @@ from meerschaum.utils.typing import Optional, List, Any, SuccessTuple
11
11
 
12
12
  def attach(
13
13
  action: Optional[List[str]] = None,
14
+ executor_keys: Optional[str] = None,
14
15
  **kwargs: Any
15
16
  ) -> SuccessTuple:
16
17
  """
@@ -21,7 +22,7 @@ def attach(
21
22
  'jobs': _attach_jobs,
22
23
  'logs': _attach_logs,
23
24
  }
24
- return choose_subaction(action, attach_options, **kwargs)
25
+ return choose_subaction(action, attach_options, executor_keys=executor_keys, **kwargs)
25
26
 
26
27
 
27
28
  def _complete_attach(
@@ -64,6 +65,7 @@ def _attach_jobs(
64
65
  """
65
66
  Attach to a job, and prompt the user when blocking on input.
66
67
  """
68
+ action = action or []
67
69
  if not action and not name:
68
70
  return False, "Provide the name of the job to attach to."
69
71
 
@@ -72,12 +74,23 @@ def _attach_jobs(
72
74
  if not job.exists():
73
75
  return False, f"Job '{job.name}' does not exist."
74
76
 
75
- job.monitor_logs(
76
- stop_on_exit=True,
77
- strip_timestamps=True,
78
- )
77
+ success, message = True, "Success"
78
+
79
+ def _capture_result(result: SuccessTuple):
80
+ nonlocal success, message
81
+ success, message = result
82
+
83
+ try:
84
+ job.monitor_logs(
85
+ stop_callback_function=_capture_result,
86
+ accept_input=True,
87
+ stop_on_exit=True,
88
+ strip_timestamps=True,
89
+ )
90
+ except KeyboardInterrupt:
91
+ pass
79
92
 
80
- return True, "Success"
93
+ return success, message
81
94
 
82
95
 
83
96
  def _attach_logs(*args, **kwargs) -> SuccessTuple:
@@ -232,7 +232,7 @@ def _start_jobs(
232
232
  stop_success_tuple = actions['stop'](
233
233
  action=['jobs'] + [_name for _name in _filtered_running_jobs],
234
234
  force=True,
235
- mrsm_instance=mrsm_instance,
235
+ executor_keys=executor_keys,
236
236
  debug=debug,
237
237
  )
238
238
  if not stop_success_tuple[0]:
@@ -34,6 +34,7 @@ from meerschaum.api import (
34
34
  from meerschaum.config.static import STATIC_CONFIG
35
35
 
36
36
  JOBS_STDIN_MESSAGE: str = STATIC_CONFIG['api']['jobs']['stdin_message']
37
+ JOBS_STOP_MESSAGE: str = STATIC_CONFIG['api']['jobs']['stop_message']
37
38
 
38
39
 
39
40
  @app.get(endpoints['jobs'], tags=['Jobs'])
@@ -245,13 +246,10 @@ def get_is_blocking_on_stdin(
245
246
 
246
247
  _job_clients = defaultdict(lambda: [])
247
248
  _job_stop_events = defaultdict(lambda: asyncio.Event())
248
- async def notify_clients(name: str, content: str):
249
+ async def notify_clients(name: str, websocket: WebSocket, content: str):
249
250
  """
250
251
  Write the given content to all connected clients.
251
252
  """
252
- if not _job_clients[name]:
253
- _job_stop_events[name].set()
254
-
255
253
  async def _notify_client(client):
256
254
  try:
257
255
  await client.send_text(content)
@@ -261,20 +259,14 @@ async def notify_clients(name: str, content: str):
261
259
  except Exception:
262
260
  pass
263
261
 
264
- notify_tasks = [
265
- asyncio.create_task(_notify_client(client))
266
- for client in _job_clients[name]
267
- ]
268
- await asyncio.wait(notify_tasks)
262
+ await _notify_client(websocket)
269
263
 
270
264
 
271
- async def get_input_from_clients(name):
265
+ async def get_input_from_clients(name: str, websocket: WebSocket) -> str:
272
266
  """
273
267
  When a job is blocking on input, return input from the first client which provides it.
274
268
  """
275
- print('GET INPUT FROM CLIENTS')
276
269
  if not _job_clients[name]:
277
- print('NO CLIENTS')
278
270
  return ''
279
271
 
280
272
  async def _read_client(client):
@@ -299,6 +291,23 @@ async def get_input_from_clients(name):
299
291
  return task.result()
300
292
 
301
293
 
294
+ async def send_stop_message(name: str, client: WebSocket, result: SuccessTuple):
295
+ """
296
+ Send a stop message to clients when the job stops.
297
+ """
298
+ try:
299
+ await client.send_text(JOBS_STOP_MESSAGE)
300
+ await client.send_json(result)
301
+ except WebSocketDisconnect:
302
+ _job_stop_events[name].set()
303
+ if client in _job_clients[name]:
304
+ _job_clients[name].remove(client)
305
+ except RuntimeError:
306
+ pass
307
+ except Exception:
308
+ warn(traceback.format_exc())
309
+
310
+
302
311
  @app.websocket(endpoints['logs'] + '/{name}/ws')
303
312
  async def logs_websocket(name: str, websocket: WebSocket):
304
313
  """
@@ -309,11 +318,32 @@ async def logs_websocket(name: str, websocket: WebSocket):
309
318
  _job_clients[name].append(websocket)
310
319
 
311
320
  async def monitor_logs():
312
- await job.monitor_logs_async(
313
- partial(notify_clients, name),
314
- input_callback_function=partial(get_input_from_clients, name),
315
- stop_event=_job_stop_events[name],
316
- )
321
+ try:
322
+ callback_function = partial(
323
+ notify_clients,
324
+ name,
325
+ websocket,
326
+ )
327
+ input_callback_function = partial(
328
+ get_input_from_clients,
329
+ name,
330
+ websocket,
331
+ )
332
+ stop_callback_function = partial(
333
+ send_stop_message,
334
+ name,
335
+ websocket,
336
+ )
337
+ await job.monitor_logs_async(
338
+ callback_function=callback_function,
339
+ input_callback_function=input_callback_function,
340
+ stop_callback_function=stop_callback_function,
341
+ stop_event=_job_stop_events[name],
342
+ stop_on_exit=True,
343
+ accept_input=True,
344
+ )
345
+ except Exception:
346
+ warn(traceback.format_exc())
317
347
 
318
348
  try:
319
349
  token = await websocket.receive_text()
@@ -329,7 +359,8 @@ async def logs_websocket(name: str, websocket: WebSocket):
329
359
  await websocket.send_text("Invalid credentials.")
330
360
  await websocket.close()
331
361
  except WebSocketDisconnect:
332
- pass
362
+ _job_stop_events[name].set()
363
+ monitor_task.cancel()
333
364
  except asyncio.CancelledError:
334
365
  pass
335
366
  except Exception:
@@ -78,7 +78,7 @@ default_shell_config = {
78
78
  },
79
79
  'executor' : {
80
80
  'rich' : {
81
- 'style' : 'gold1',
81
+ 'style' : 'yellow',
82
82
  },
83
83
  },
84
84
  'username' : {
@@ -2,4 +2,4 @@
2
2
  Specify the Meerschaum release version.
3
3
  """
4
4
 
5
- __version__ = "2.3.0.dev1"
5
+ __version__ = "2.3.0.dev3"
@@ -43,7 +43,9 @@ STATIC_CONFIG: Dict[str, Any] = {
43
43
  'webterm_job_name': '_webterm',
44
44
  'default_timeout': 600,
45
45
  'jobs': {
46
- 'stdin_message': 'MRSM_STDIN'
46
+ 'stdin_message': 'MRSM_STDIN',
47
+ 'stop_message': 'MRSM_STOP',
48
+ 'metadata_cache_seconds': 5,
47
49
  },
48
50
  },
49
51
  'sql': {
@@ -7,17 +7,21 @@ Manage jobs via the Meerschaum API.
7
7
  """
8
8
 
9
9
  import asyncio
10
+ import time
11
+ import json
10
12
  from datetime import datetime
11
13
 
12
14
  import meerschaum as mrsm
13
15
  from meerschaum.utils.typing import Dict, Any, SuccessTuple, List, Union, Callable
14
16
  from meerschaum.utils.jobs import Job
15
17
  from meerschaum.config.static import STATIC_CONFIG
16
- from meerschaum.utils.warnings import warn
18
+ from meerschaum.utils.warnings import warn, dprint
17
19
 
18
20
  JOBS_ENDPOINT: str = STATIC_CONFIG['api']['endpoints']['jobs']
19
21
  LOGS_ENDPOINT: str = STATIC_CONFIG['api']['endpoints']['logs']
20
22
  JOBS_STDIN_MESSAGE: str = STATIC_CONFIG['api']['jobs']['stdin_message']
23
+ JOBS_STOP_MESSAGE: str = STATIC_CONFIG['api']['jobs']['stop_message']
24
+ JOB_METADATA_CACHE_SECONDS: int = STATIC_CONFIG['api']['jobs']['metadata_cache_seconds']
21
25
 
22
26
 
23
27
  def get_jobs(self, debug: bool = False) -> Dict[str, Job]:
@@ -59,6 +63,20 @@ def get_job_metadata(self, name: str, debug: bool = False) -> Dict[str, Any]:
59
63
  """
60
64
  Return the metadata for a single job.
61
65
  """
66
+ now = time.perf_counter()
67
+ _job_metadata_cache = self.__dict__.get('_job_metadata_cache', None)
68
+ _job_metadata_timestamp = (
69
+ _job_metadata_cache.get(name, {}).get('timestamp', None)
70
+ ) if _job_metadata_cache is not None else None
71
+
72
+ if (
73
+ _job_metadata_timestamp is not None
74
+ and (now - _job_metadata_timestamp) < JOB_METADATA_CACHE_SECONDS
75
+ ):
76
+ if debug:
77
+ dprint(f"Returning cached metadata for job '{name}'.")
78
+ return _job_metadata_cache[name]['metadata']
79
+
62
80
  response = self.get(JOBS_ENDPOINT + f"/{name}", debug=debug)
63
81
  if not response:
64
82
  if debug:
@@ -70,7 +88,15 @@ def get_job_metadata(self, name: str, debug: bool = False) -> Dict[str, Any]:
70
88
  warn(f"Failed to get metadata for job '{name}':\n{msg}")
71
89
  return {}
72
90
 
73
- return response.json()
91
+ metadata = response.json()
92
+ if _job_metadata_cache is None:
93
+ self._job_metadata_cache = {}
94
+
95
+ self._job_metadata_cache[name] = {
96
+ 'timestamp': now,
97
+ 'metadata': metadata,
98
+ }
99
+ return metadata
74
100
 
75
101
 
76
102
  def get_job_properties(self, name: str, debug: bool = False) -> Dict[str, Any]:
@@ -191,17 +217,55 @@ async def monitor_logs_async(
191
217
  name: str,
192
218
  callback_function: Callable[[Any], Any],
193
219
  input_callback_function: Callable[[], str],
220
+ stop_callback_function: Callable[[SuccessTuple], str],
221
+ stop_on_exit: bool = False,
222
+ strip_timestamps: bool = False,
194
223
  accept_input: bool = True,
195
224
  debug: bool = False,
196
225
  ):
197
226
  """
198
227
  Monitor a job's log files and await a callback with the changes.
199
228
  """
229
+ from meerschaum.utils.jobs import StopMonitoringLogs
230
+ from meerschaum.utils.formatting._jobs import strip_timestamp_from_line
231
+
200
232
  websockets, websockets_exceptions = mrsm.attempt_import('websockets', 'websockets.exceptions')
201
233
  protocol = 'ws' if self.URI.startswith('http://') else 'wss'
202
234
  port = self.port if 'port' in self.__dict__ else ''
203
235
  uri = f"{protocol}://{self.host}:{port}{LOGS_ENDPOINT}/{name}/ws"
204
236
 
237
+ async def _stdin_callback(client):
238
+ if input_callback_function is None:
239
+ return
240
+
241
+ if asyncio.iscoroutinefunction(input_callback_function):
242
+ data = await input_callback_function()
243
+ else:
244
+ data = input_callback_function()
245
+
246
+ await client.send(data)
247
+
248
+ async def _stop_callback(client):
249
+ try:
250
+ result = tuple(json.loads(await client.recv()))
251
+ except Exception as e:
252
+ warn(traceback.format_exc())
253
+ result = False, str(e)
254
+
255
+ if stop_callback_function is not None:
256
+ if asyncio.iscoroutinefunction(stop_callback_function):
257
+ await stop_callback_function(result)
258
+ else:
259
+ stop_callback_function(result)
260
+
261
+ if stop_on_exit:
262
+ raise StopMonitoringLogs
263
+
264
+ message_callbacks = {
265
+ JOBS_STDIN_MESSAGE: _stdin_callback,
266
+ JOBS_STOP_MESSAGE: _stop_callback,
267
+ }
268
+
205
269
  async with websockets.connect(uri) as websocket:
206
270
  try:
207
271
  await websocket.send(self.token or 'no-login')
@@ -211,28 +275,31 @@ async def monitor_logs_async(
211
275
  while True:
212
276
  try:
213
277
  response = await websocket.recv()
214
- if response == JOBS_STDIN_MESSAGE:
215
- if asyncio.iscoroutinefunction(input_callback_function):
216
- data = await input_callback_function()
217
- else:
218
- data = input_callback_function()
219
-
220
- await websocket.send(data)
278
+ callback = message_callbacks.get(response, None)
279
+ if callback is not None:
280
+ await callback(websocket)
221
281
  continue
222
282
 
283
+ if strip_timestamps:
284
+ response = strip_timestamp_from_line(response)
285
+
223
286
  if asyncio.iscoroutinefunction(callback_function):
224
287
  await callback_function(response)
225
288
  else:
226
289
  callback_function(response)
227
- except KeyboardInterrupt:
290
+ except (KeyboardInterrupt, StopMonitoringLogs):
228
291
  await websocket.close()
229
292
  break
230
293
 
294
+
231
295
  def monitor_logs(
232
296
  self,
233
297
  name: str,
234
298
  callback_function: Callable[[Any], Any],
235
299
  input_callback_function: Callable[[None], str],
300
+ stop_callback_function: Callable[[None], str],
301
+ stop_on_exit: bool = False,
302
+ strip_timestamps: bool = False,
236
303
  accept_input: bool = True,
237
304
  debug: bool = False,
238
305
  ):
@@ -244,6 +311,9 @@ def monitor_logs(
244
311
  name,
245
312
  callback_function,
246
313
  input_callback_function=input_callback_function,
314
+ stop_callback_function=stop_callback_function,
315
+ stop_on_exit=stop_on_exit,
316
+ strip_timestamps=strip_timestamps,
247
317
  accept_input=accept_input,
248
318
  debug=debug
249
319
  )
@@ -218,7 +218,8 @@ class Job:
218
218
  self,
219
219
  callback_function: Callable[[str], None] = partial(print, end=''),
220
220
  input_callback_function: Optional[Callable[[], str]] = None,
221
- stop_event: Optional[threading.Event] = None,
221
+ stop_callback_function: Optional[Callable[[SuccessTuple], None]] = None,
222
+ stop_event: Optional[asyncio.Event] = None,
222
223
  stop_on_exit: bool = False,
223
224
  strip_timestamps: bool = False,
224
225
  accept_input: bool = True,
@@ -237,6 +238,10 @@ class Job:
237
238
  If provided, execute this callback when the daemon is blocking on stdin.
238
239
  Defaults to `sys.stdin.readline()`.
239
240
 
241
+ stop_callback_function: Optional[Callable[[SuccessTuple]], str], default None
242
+ If provided, execute this callback when the daemon stops.
243
+ The job's SuccessTuple will be passed to the callback.
244
+
240
245
  stop_event: Optional[asyncio.Event], default None
241
246
  If provided, stop monitoring when this event is set.
242
247
  You may instead raise `meerschaum.utils.jobs.StopMonitoringLogs`
@@ -251,13 +256,29 @@ class Job:
251
256
  accept_input: bool, default True
252
257
  If `True`, accept input when the daemon blocks on stdin.
253
258
  """
259
+ def default_input_callback_function():
260
+ return sys.stdin.readline()
261
+
262
+ if input_callback_function is None:
263
+ input_callback_function = default_input_callback_function
264
+
254
265
  if self.executor is not None:
255
- self.executor.monitor_logs(self.name, callback_function)
266
+ self.executor.monitor_logs(
267
+ self.name,
268
+ callback_function,
269
+ input_callback_function=input_callback_function,
270
+ stop_callback_function=stop_callback_function,
271
+ stop_on_exit=stop_on_exit,
272
+ accept_input=accept_input,
273
+ strip_timestamps=strip_timestamps,
274
+ debug=debug,
275
+ )
256
276
  return
257
277
 
258
278
  monitor_logs_coroutine = self.monitor_logs_async(
259
279
  callback_function=callback_function,
260
280
  input_callback_function=input_callback_function,
281
+ stop_callback_function=stop_callback_function,
261
282
  stop_event=stop_event,
262
283
  stop_on_exit=stop_on_exit,
263
284
  strip_timestamps=strip_timestamps,
@@ -270,6 +291,7 @@ class Job:
270
291
  self,
271
292
  callback_function: Callable[[str], None] = partial(print, end='', flush=True),
272
293
  input_callback_function: Optional[Callable[[], str]] = None,
294
+ stop_callback_function: Optional[Callable[[SuccessTuple], None]] = None,
273
295
  stop_event: Optional[asyncio.Event] = None,
274
296
  stop_on_exit: bool = False,
275
297
  strip_timestamps: bool = False,
@@ -289,6 +311,10 @@ class Job:
289
311
  If provided, execute this callback when the daemon is blocking on stdin.
290
312
  Defaults to `sys.stdin.readline()`.
291
313
 
314
+ stop_callback_function: Optional[Callable[[SuccessTuple]], str], default None
315
+ If provided, execute this callback when the daemon stops.
316
+ The job's SuccessTuple will be passed to the callback.
317
+
292
318
  stop_event: Optional[asyncio.Event], default None
293
319
  If provided, stop monitoring when this event is set.
294
320
  You may instead raise `meerschaum.utils.jobs.StopMonitoringLogs`
@@ -314,6 +340,8 @@ class Job:
314
340
  self.name,
315
341
  callback_function,
316
342
  input_callback_function=input_callback_function,
343
+ stop_callback_function=stop_callback_function,
344
+ stop_on_exit=stop_on_exit,
317
345
  accept_input=accept_input,
318
346
  debug=debug,
319
347
  )
@@ -323,7 +351,7 @@ class Job:
323
351
 
324
352
  events = {
325
353
  'user': stop_event,
326
- 'stopped': (asyncio.Event() if stop_on_exit else None),
354
+ 'stopped': asyncio.Event(),
327
355
  }
328
356
  combined_event = asyncio.Event()
329
357
  emitted_text = False
@@ -340,7 +368,19 @@ class Job:
340
368
  await asyncio.sleep(sleep_time)
341
369
  sleep_time = round(sleep_time * 1.1, 2)
342
370
  continue
343
- events['stopped'].set()
371
+
372
+ if stop_callback_function is not None:
373
+ try:
374
+ if asyncio.iscoroutinefunction(stop_callback_function):
375
+ await stop_callback_function(self.result)
376
+ else:
377
+ stop_callback_function(self.result)
378
+ except Exception:
379
+ warn(traceback.format_exc())
380
+
381
+ if stop_on_exit:
382
+ events['stopped'].set()
383
+
344
384
  break
345
385
  await asyncio.sleep(0.1)
346
386
 
@@ -360,7 +400,7 @@ class Job:
360
400
 
361
401
  try:
362
402
  print('', end='', flush=True)
363
- if asyncio.iscoroutinefunction(callback_function):
403
+ if asyncio.iscoroutinefunction(input_callback_function):
364
404
  data = await input_callback_function()
365
405
  else:
366
406
  data = input_callback_function()
@@ -444,23 +484,8 @@ class Job:
444
484
  if latest_subfile_path != file_path:
445
485
  continue
446
486
 
447
- lines = log.readlines()
448
- for line in lines:
449
- if strip_timestamps:
450
- line = strip_timestamp_from_line(line)
451
- try:
452
- if asyncio.iscoroutinefunction(callback_function):
453
- await callback_function(line)
454
- else:
455
- callback_function(line)
456
- emitted_text = True
457
- except RuntimeError:
458
- return
459
- except StopMonitoringLogs:
460
- return
461
- except Exception:
462
- warn(f"Error in logs callback:\n{traceback.format_exc()}")
463
- return
487
+ await emit_latest_lines()
488
+ await emit_latest_lines()
464
489
 
465
490
  await emit_latest_lines()
466
491
 
@@ -477,6 +502,7 @@ class Job:
477
502
  """
478
503
  Write to a job's daemon's `stdin`.
479
504
  """
505
+ ### TODO implement remote method?
480
506
  if self.executor is not None:
481
507
  pass
482
508
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: meerschaum
3
- Version: 2.3.0.dev1
3
+ Version: 2.3.0.dev3
4
4
  Summary: Sync Time-Series Pipes with Meerschaum
5
5
  Home-page: https://meerschaum.io
6
6
  Author: Bennett Meares
@@ -1,9 +1,9 @@
1
- meerschaum/__init__.py,sha256=wx5DF7gMpBt7zjDNsj8IxJ2PmhRGI5EdwjziOiGbWew,1636
1
+ meerschaum/__init__.py,sha256=XhFLXXw1EmoFxiTMDXuNYLb6Bpzg3-V3CmvjSHDLQPk,1694
2
2
  meerschaum/__main__.py,sha256=-xIXokhJ5vV784zDBF4engE3J1nj3LDHlLIRYMQ5nXY,2883
3
3
  meerschaum/_internal/__init__.py,sha256=ilC7utfKtin7GAvuN34fKyUQYfPyqH0Mm3MJF5iyEf4,169
4
4
  meerschaum/_internal/entry.py,sha256=4zHxcNFffxNUVVwYCjWMupG9CFeY78rKKsRfbmCPRVc,6228
5
5
  meerschaum/_internal/arguments/__init__.py,sha256=HFciFQgo2ZOT19Mo6CpLhPYlpLYh2sNn1C9Lo7NMADc,519
6
- meerschaum/_internal/arguments/_parse_arguments.py,sha256=ZPkJamB6noJAEpG_cyZGVYu6hXxtQ7H7c-j7gq3Csi8,10405
6
+ meerschaum/_internal/arguments/_parse_arguments.py,sha256=EJfxtQJcoc0DBTTUHLTbC1cwe_K_WAiNOXMLEXGQ7vE,10708
7
7
  meerschaum/_internal/arguments/_parser.py,sha256=vRqs7NuDSC0EDkmaDLwyTi4XDjAQOhon1lIEZjjtiEQ,14842
8
8
  meerschaum/_internal/docs/__init__.py,sha256=ZQYHWo6n0kfLLkyG36YXqTYvv2Pc7it5HZHMylT6cBA,126
9
9
  meerschaum/_internal/docs/index.py,sha256=Qovl1fI-KqCz7KtxCIWklqUGUcJ8Sbx4UKAEarrUn_A,18056
@@ -21,9 +21,9 @@ meerschaum/_internal/shell/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeu
21
21
  meerschaum/_internal/term/TermPageHandler.py,sha256=Rt5S47Pr_3HLJc8xIXpZUczYE_Dw2qT8qwf1jZFtUHQ,520
22
22
  meerschaum/_internal/term/__init__.py,sha256=eXjfRzpnASWomB4xpY2AfzC_CLenkInNnVWSLZEexlg,1638
23
23
  meerschaum/_internal/term/tools.py,sha256=dXVAimKD-Yv2fg2WOTr0YGBY7XDKjQqw-RizcS65YVI,727
24
- meerschaum/actions/__init__.py,sha256=ZUdQk6FvuMqyEvLCP-RiDDlIK4NwkqLRgFZSKq04qq4,11440
24
+ meerschaum/actions/__init__.py,sha256=A-xwztWrq9xL_FbiBcoNB9-WKfwzYlFerh4XFl-Ao5c,11515
25
25
  meerschaum/actions/api.py,sha256=8wjREHNRkl8WBgtz1KfWmAVjeFR_J2j7ghXjSyYUW3g,12603
26
- meerschaum/actions/attach.py,sha256=sMR7CZbvCadnOBJtxx1CklqUXChRCvuChTxTe0rS5Ew,2433
26
+ meerschaum/actions/attach.py,sha256=oH0OLCMe0ki00VM7l6fPuDzRRbRSYKlnT2NJ-w0jJ-M,2837
27
27
  meerschaum/actions/bootstrap.py,sha256=9D3cBHzgZbZyWy-Y7iQgk9bpTbKEhumFKbIIThZgPXI,14058
28
28
  meerschaum/actions/clear.py,sha256=OoFZE0bK5m8s3GLNZcixuVT0DMj1izXVxGCATcmUGbI,4851
29
29
  meerschaum/actions/copy.py,sha256=8g3ANXfVdvuyaoXcZjgTg3BxHTOhHGrzVDOOsTBrpSU,6213
@@ -43,7 +43,7 @@ meerschaum/actions/sh.py,sha256=fLfTJaacKu4sjLTRqEzzYlT2WbbdZBEczsKb6F-qAek,2026
43
43
  meerschaum/actions/show.py,sha256=kPKKKvfM_orc9wqkIDU3Nq9Hy-vOYnu3Nne7XuyigGg,28165
44
44
  meerschaum/actions/sql.py,sha256=wYofwk1vGO96U2ncigGEfMtYMZeprz2FR1PRRZhkAPI,4311
45
45
  meerschaum/actions/stack.py,sha256=7ODAxzmCx8i9AHxvkbr5ZtzUNPpY-iqlSVo4rZHMOw4,5900
46
- meerschaum/actions/start.py,sha256=osQtYyhGM4vk2RwDzel5WXNVWBJqgVYSXNisRLY9YUM,18105
46
+ meerschaum/actions/start.py,sha256=CHOQRkhUEDW65Vlr6wlzUZOkHhAOX0g5-YIwl1vRod8,18105
47
47
  meerschaum/actions/stop.py,sha256=HM_oCMlQWARXa3kh60SdxvUHWTJV42R9B8VBUmXCE9U,4472
48
48
  meerschaum/actions/sync.py,sha256=AkH-1O5bkUC-UElQGr0lRhrX-z18ZY2nBPSy9EsW1Kc,17506
49
49
  meerschaum/actions/tag.py,sha256=SJf5qFW0ccLXjqlTdkK_0MCcrCMdg6xhYrhKdco0hdA,3053
@@ -117,7 +117,7 @@ meerschaum/api/routes/__init__.py,sha256=jbkeFNl51Tg8aT5gWe560ZLZLojFJsLMe5IENRj
117
117
  meerschaum/api/routes/_actions.py,sha256=uZCf6HdSxixEJ2S2YJhzU8zx1E5mmKXPsVHN8xJW-z4,4400
118
118
  meerschaum/api/routes/_connectors.py,sha256=NNbcn5xWhKqw2PqueSEaqRaZ95hFGDKazG5lE7gsssc,1849
119
119
  meerschaum/api/routes/_index.py,sha256=QI6CBo6pI2Zi0a6fJHDjZfiLa9f4okb0BGe3A_JD0kM,578
120
- meerschaum/api/routes/_jobs.py,sha256=4dVbzu_3d9m5Di9fjQ-2m6qn9KuN-UwY0BhPD8D_8jM,8459
120
+ meerschaum/api/routes/_jobs.py,sha256=rh20XU6JTE0OUpHSmzO8G6eqETW10QSnWvKNW07nyvs,9545
121
121
  meerschaum/api/routes/_login.py,sha256=psPKmFkXgYVX83NepqwIhaLsQ5uWgOc4F2QZtPGxY1A,2482
122
122
  meerschaum/api/routes/_misc.py,sha256=05--9ZVFeaCgZrHER2kA3SYdK4TyfkEXOCjLvPbum-w,2469
123
123
  meerschaum/api/routes/_pipes.py,sha256=1gBuE4E-QvIK_kmbmiw7uLcXjnIobFI1t4tb2skpp6E,21592
@@ -137,9 +137,9 @@ meerschaum/config/_patch.py,sha256=21N30q1ANmWMDQ-2RUjpMx7KafWfPQ3lKx9rrMqg1s4,1
137
137
  meerschaum/config/_paths.py,sha256=Tfet05CY4OsIwumZO98h-L1Jy8_DH_OQ-0M1UBp83tk,9365
138
138
  meerschaum/config/_preprocess.py,sha256=-AEA8m_--KivZwTQ1sWN6LTn5sio_fUr2XZ51BO6wLs,1220
139
139
  meerschaum/config/_read_config.py,sha256=WFZKIXZMDe_ca0ES7ivgM_mnwShvFxLdoeisT_X5-h0,14720
140
- meerschaum/config/_shell.py,sha256=FXml2CqtvjY0wVTS4B2VqMKaGlWJHPK-_PT_Nr48ys4,4244
140
+ meerschaum/config/_shell.py,sha256=46_m49Txc5q1rGfCgO49ca48BODx45DQJi8D0zz1R18,4245
141
141
  meerschaum/config/_sync.py,sha256=oK2ZujO2T1he08BXCFyiniBUevNGWSQKXLcS_jRv_7Y,4155
142
- meerschaum/config/_version.py,sha256=qr-fEo2FFI5Xvih81aaNY1pLvQj86Jj6DjKkA6RJsG4,76
142
+ meerschaum/config/_version.py,sha256=RWnwyq5Sie04gEBTdVX8F09ia8uQfTEBjVp7fIsT_1c,76
143
143
  meerschaum/config/paths.py,sha256=JjibeGN3YAdSNceRwsd42aNmeUrIgM6ndzC8qZAmNI0,621
144
144
  meerschaum/config/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
145
145
  meerschaum/config/stack/__init__.py,sha256=Yt7GNzC_hz7iUDZ4gVho_lugJO2DnXgnMtsMG_ReoRg,9114
@@ -147,7 +147,7 @@ meerschaum/config/stack/grafana/__init__.py,sha256=LNXQw2FvHKrD68RDhqDmi2wJjAHaK
147
147
  meerschaum/config/stack/mosquitto/__init__.py,sha256=-OwOjq8KiBoSH_pmgCAAF3Dp3CRD4KgAEdimZSadROs,186
148
148
  meerschaum/config/stack/mosquitto/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
149
149
  meerschaum/config/stack/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
150
- meerschaum/config/static/__init__.py,sha256=8bNRKw7nDI9EojtvPydM3UPHVbZKeiffbPxxrMxamsM,4735
150
+ meerschaum/config/static/__init__.py,sha256=ckRqGYD6xnIzWqSyPeKGVPgNCnNAIOvUGRlQLYnBpc0,4818
151
151
  meerschaum/connectors/Connector.py,sha256=sa95S2upqaMpwZoVm3SwDovUoMM5JiWD6qg6QT4jxdA,6476
152
152
  meerschaum/connectors/__init__.py,sha256=jo6X4AdhB2BXKIsoqHOqWtNqMaqLa_EqwopPNVE4vkc,12147
153
153
  meerschaum/connectors/parse.py,sha256=F2RLb6U7lW0BGDxSHcXdCDf5g4RibKFjX8jOAcfYvFU,4451
@@ -156,7 +156,7 @@ meerschaum/connectors/api/APIConnector.py,sha256=CRPrlarB3QccY2sm7D1J-tZTfLcvP3B
156
156
  meerschaum/connectors/api/__init__.py,sha256=JwKrGtuE5aOd2VnsRwudFBYyBf5IxczOwPVdNvCUgSQ,205
157
157
  meerschaum/connectors/api/_actions.py,sha256=KS2Ib5_yHuN0Fw86wyg0bXORV2xY4m3DQrBtcqIIjnY,2343
158
158
  meerschaum/connectors/api/_fetch.py,sha256=Khq9AFr1nk8Dsmcedb77aWhAuHw0JGgVeahDG95Q5MQ,2072
159
- meerschaum/connectors/api/_jobs.py,sha256=iPEVy331-zQVQ37hlWI1ddFQTHbJGxLuxi_3RTdWC08,7501
159
+ meerschaum/connectors/api/_jobs.py,sha256=-8m-MRfpuldLmo4_ZSaJx-F5ok1kdYMq4c_QkubMaUc,9848
160
160
  meerschaum/connectors/api/_login.py,sha256=5GsD-B214vr5EYfM3XrTUs1sTFApxZA-9dNxq8oNSyg,2050
161
161
  meerschaum/connectors/api/_misc.py,sha256=OZRZBYOokKIEjmQaR8jUYgu6ZRn9VzXBChzR8CfDv_w,1092
162
162
  meerschaum/connectors/api/_pipes.py,sha256=wf-_jqFBiTNw2s2msp0Ye6IyTl5JWiyC9aLBI0PQuPs,20962
@@ -231,18 +231,18 @@ meerschaum/utils/formatting/_jobs.py,sha256=m3dVGRS3zRNAbu7zWPdpEuou6GEOe7hHWrTz
231
231
  meerschaum/utils/formatting/_pipes.py,sha256=wy0iWJFsFl3X2VloaiA_gp9Yx9w6tD3FQZvAQAqef4A,19492
232
232
  meerschaum/utils/formatting/_pprint.py,sha256=tgrT3FyGyu5CWJYysqK3kX1xdZYorlbOk9fcU_vt9Qg,3096
233
233
  meerschaum/utils/formatting/_shell.py,sha256=jsjf_GMXBpGNBbpT7skTUZrHZl5HooFzffRDc4hz5Tc,3786
234
- meerschaum/utils/jobs/_Job.py,sha256=id0VMZw6mNsmhjCpu2VptYQlcwH7oNg0-NtdRbc41Uw,22155
234
+ meerschaum/utils/jobs/_Job.py,sha256=1glG_n8r6CuC2Al3NVYogwFMKjSxiM4GCT9o6WDtkGg,23322
235
235
  meerschaum/utils/jobs/__init__.py,sha256=NfO43tpGgPBikoFV98w2cFag0aQd7Z7FOpb5NCJZ0lg,6088
236
236
  meerschaum/utils/packages/__init__.py,sha256=zBy3cUy60Eht90PhgWzL_VjTjJSFpt5sA-DvrLch47A,63179
237
237
  meerschaum/utils/packages/_packages.py,sha256=pWSVUEQ0XXEmnRbVUOH-c17O0VGdxuGAixuE2-XJP0I,7976
238
238
  meerschaum/utils/packages/lazy_loader.py,sha256=VHnph3VozH29R4JnSSBfwtA5WKZYZQFT_GeQSShCnuc,2540
239
239
  meerschaum/utils/venv/_Venv.py,sha256=sBnlmxHdAh2bx8btfVoD79-H9-cYsv5lP02IIXkyECs,3553
240
240
  meerschaum/utils/venv/__init__.py,sha256=7TjSHKbUAACqteNFkqp3CS8vxm9lMo8sJJ7q_oaCMd0,24365
241
- meerschaum-2.3.0.dev1.dist-info/LICENSE,sha256=jG2zQEdRNt88EgHUWPpXVWmOrOduUQRx7MnYV9YIPaw,11359
242
- meerschaum-2.3.0.dev1.dist-info/METADATA,sha256=_1wseADvLgHCK8nwyxtXe9IiVFE2pEA3ZAW8fJQb9vE,24188
243
- meerschaum-2.3.0.dev1.dist-info/NOTICE,sha256=OTA9Fcthjf5BRvWDDIcBC_xfLpeDV-RPZh3M-HQBRtQ,114
244
- meerschaum-2.3.0.dev1.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
245
- meerschaum-2.3.0.dev1.dist-info/entry_points.txt,sha256=5YBVzibw-0rNA_1VjB16z5GABsOGf-CDhW4yqH8C7Gc,88
246
- meerschaum-2.3.0.dev1.dist-info/top_level.txt,sha256=bNoSiDj0El6buocix-FRoAtJOeq1qOF5rRm2u9i7Q6A,11
247
- meerschaum-2.3.0.dev1.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
248
- meerschaum-2.3.0.dev1.dist-info/RECORD,,
241
+ meerschaum-2.3.0.dev3.dist-info/LICENSE,sha256=jG2zQEdRNt88EgHUWPpXVWmOrOduUQRx7MnYV9YIPaw,11359
242
+ meerschaum-2.3.0.dev3.dist-info/METADATA,sha256=EqHz-2EqQQmaoX6ptL-7G8tJHNbfH1CzICUberopzDc,24188
243
+ meerschaum-2.3.0.dev3.dist-info/NOTICE,sha256=OTA9Fcthjf5BRvWDDIcBC_xfLpeDV-RPZh3M-HQBRtQ,114
244
+ meerschaum-2.3.0.dev3.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
245
+ meerschaum-2.3.0.dev3.dist-info/entry_points.txt,sha256=5YBVzibw-0rNA_1VjB16z5GABsOGf-CDhW4yqH8C7Gc,88
246
+ meerschaum-2.3.0.dev3.dist-info/top_level.txt,sha256=bNoSiDj0El6buocix-FRoAtJOeq1qOF5rRm2u9i7Q6A,11
247
+ meerschaum-2.3.0.dev3.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
248
+ meerschaum-2.3.0.dev3.dist-info/RECORD,,