meerschaum 2.7.5__py3-none-any.whl → 2.7.6__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/_internal/shell/Shell.py +4 -6
- meerschaum/_internal/shell/ShellCompleter.py +6 -5
- meerschaum/actions/clear.py +6 -3
- meerschaum/actions/copy.py +33 -27
- meerschaum/actions/sync.py +22 -18
- meerschaum/api/dash/pipes.py +2 -3
- meerschaum/config/_default.py +5 -0
- meerschaum/config/_version.py +1 -1
- meerschaum/connectors/api/_misc.py +3 -2
- meerschaum/connectors/api/_pipes.py +8 -9
- meerschaum/connectors/sql/_SQLConnector.py +1 -0
- meerschaum/connectors/sql/_pipes.py +37 -10
- meerschaum/connectors/sql/_sql.py +9 -1
- meerschaum/jobs/_Job.py +1 -0
- meerschaum/plugins/__init__.py +7 -3
- meerschaum/utils/daemon/Daemon.py +5 -1
- meerschaum/utils/daemon/__init__.py +2 -2
- meerschaum/utils/misc.py +7 -6
- meerschaum/utils/packages/__init__.py +31 -27
- meerschaum/utils/packages/_packages.py +1 -1
- meerschaum/utils/prompt.py +54 -36
- meerschaum/utils/venv/__init__.py +12 -3
- {meerschaum-2.7.5.dist-info → meerschaum-2.7.6.dist-info}/METADATA +4 -4
- {meerschaum-2.7.5.dist-info → meerschaum-2.7.6.dist-info}/RECORD +30 -30
- {meerschaum-2.7.5.dist-info → meerschaum-2.7.6.dist-info}/WHEEL +1 -1
- {meerschaum-2.7.5.dist-info → meerschaum-2.7.6.dist-info}/LICENSE +0 -0
- {meerschaum-2.7.5.dist-info → meerschaum-2.7.6.dist-info}/NOTICE +0 -0
- {meerschaum-2.7.5.dist-info → meerschaum-2.7.6.dist-info}/entry_points.txt +0 -0
- {meerschaum-2.7.5.dist-info → meerschaum-2.7.6.dist-info}/top_level.txt +0 -0
- {meerschaum-2.7.5.dist-info → meerschaum-2.7.6.dist-info}/zip-safe +0 -0
@@ -742,8 +742,7 @@ class Shell(cmd.Cmd):
|
|
742
742
|
"""
|
743
743
|
from meerschaum import get_connector
|
744
744
|
from meerschaum.connectors.parse import parse_instance_keys
|
745
|
-
from meerschaum.utils.warnings import
|
746
|
-
from meerschaum.utils.misc import remove_ansi
|
745
|
+
from meerschaum.utils.warnings import info
|
747
746
|
|
748
747
|
if action is None:
|
749
748
|
action = []
|
@@ -829,7 +828,7 @@ class Shell(cmd.Cmd):
|
|
829
828
|
"""
|
830
829
|
from meerschaum import get_connector
|
831
830
|
from meerschaum.connectors.parse import parse_repo_keys
|
832
|
-
from meerschaum.utils.warnings import
|
831
|
+
from meerschaum.utils.warnings import info
|
833
832
|
|
834
833
|
if action is None:
|
835
834
|
action = []
|
@@ -878,7 +877,6 @@ class Shell(cmd.Cmd):
|
|
878
877
|
|
879
878
|
Note that executors are API instances.
|
880
879
|
"""
|
881
|
-
from meerschaum import get_connector
|
882
880
|
from meerschaum.connectors.parse import parse_executor_keys
|
883
881
|
from meerschaum.utils.warnings import warn, info
|
884
882
|
from meerschaum.jobs import get_executor_keys_from_context
|
@@ -894,7 +892,7 @@ class Shell(cmd.Cmd):
|
|
894
892
|
executor_keys = get_executor_keys_from_context()
|
895
893
|
|
896
894
|
if executor_keys == 'systemd' and get_executor_keys_from_context() != 'systemd':
|
897
|
-
warn(
|
895
|
+
warn("Cannot execute via `systemd`, falling back to `local`...", stack=False)
|
898
896
|
executor_keys = 'local'
|
899
897
|
|
900
898
|
conn = parse_executor_keys(executor_keys, debug=debug)
|
@@ -935,7 +933,7 @@ class Shell(cmd.Cmd):
|
|
935
933
|
if args['action'][0] not in shell_attrs['_actions']:
|
936
934
|
try:
|
937
935
|
print(textwrap.dedent(getattr(self, f"do_{args['action'][0]}").__doc__))
|
938
|
-
except Exception
|
936
|
+
except Exception:
|
939
937
|
print(f"No help on '{args['action'][0]}'.")
|
940
938
|
return ""
|
941
939
|
parse_help(args)
|
@@ -7,13 +7,15 @@ Implement the prompt_toolkit Completer base class.
|
|
7
7
|
"""
|
8
8
|
|
9
9
|
from __future__ import annotations
|
10
|
-
from
|
11
|
-
from meerschaum.utils.typing import Optional
|
12
|
-
from meerschaum.actions import get_shell, get_completer, get_main_action_name, get_action
|
10
|
+
from meerschaum.actions import get_shell, get_main_action_name, get_action
|
13
11
|
from meerschaum._internal.arguments import parse_line
|
14
12
|
|
15
13
|
from meerschaum.utils.packages import attempt_import, ensure_readline
|
16
|
-
|
14
|
+
|
15
|
+
prompt_toolkit_completion = attempt_import('prompt_toolkit.completion', lazy=False, install=True)
|
16
|
+
Completer = prompt_toolkit_completion.Completer
|
17
|
+
Completion = prompt_toolkit_completion.Completion
|
18
|
+
|
17
19
|
|
18
20
|
class ShellCompleter(Completer):
|
19
21
|
"""
|
@@ -30,7 +32,6 @@ class ShellCompleter(Completer):
|
|
30
32
|
yielded = []
|
31
33
|
ensure_readline()
|
32
34
|
parts = document.text.split('-')
|
33
|
-
ends_with_space = parts[0].endswith(' ')
|
34
35
|
last_action_line = parts[0].split('+')[-1]
|
35
36
|
part_0_subbed_spaces = last_action_line.replace(' ', '_')
|
36
37
|
parsed_text = (part_0_subbed_spaces + '-'.join(parts[1:]))
|
meerschaum/actions/clear.py
CHANGED
@@ -130,12 +130,15 @@ def _ask_with_rowcounts(
|
|
130
130
|
)
|
131
131
|
|
132
132
|
|
133
|
-
pipes_rowcounts = {
|
133
|
+
pipes_rowcounts = {
|
134
|
+
pipe: pipe.get_rowcount(begin=begin, end=end, debug=debug)
|
135
|
+
for pipe in pipes
|
136
|
+
}
|
134
137
|
print_options(
|
135
|
-
[str(
|
138
|
+
[str(pipe) + f'\n{rowcount:,}\n' for pipe, rowcount in pipes_rowcounts.items()],
|
136
139
|
header='Number of Rows to be Deleted'
|
137
140
|
)
|
138
|
-
total_num_rows = sum([
|
141
|
+
total_num_rows = sum([rowcount for rowcount in pipes_rowcounts.values()])
|
139
142
|
question = (
|
140
143
|
f"Are you sure you want to delete {total_num_rows:,} rows across {len(pipes)} pipe"
|
141
144
|
+ ('s' if len(pipes) != 1 else '')
|
meerschaum/actions/copy.py
CHANGED
@@ -7,7 +7,7 @@ Functions for copying elements.
|
|
7
7
|
"""
|
8
8
|
|
9
9
|
from __future__ import annotations
|
10
|
-
from meerschaum.utils.typing import
|
10
|
+
from meerschaum.utils.typing import Any, SuccessTuple, Optional, List
|
11
11
|
|
12
12
|
def copy(
|
13
13
|
action: Optional[List[str]] = None,
|
@@ -69,44 +69,53 @@ def _copy_pipes(
|
|
69
69
|
Copy pipes' attributes and make new pipes.
|
70
70
|
"""
|
71
71
|
from meerschaum import get_pipes, Pipe
|
72
|
-
from meerschaum.utils.prompt import prompt, yes_no
|
72
|
+
from meerschaum.utils.prompt import prompt, yes_no, get_connectors_completer
|
73
73
|
from meerschaum.utils.warnings import warn
|
74
74
|
from meerschaum.utils.formatting import print_tuple
|
75
75
|
from meerschaum.utils.formatting._shell import clear_screen
|
76
76
|
pipes = get_pipes(as_list=True, **kw)
|
77
77
|
successes = 0
|
78
|
-
for
|
79
|
-
ck = prompt(
|
80
|
-
|
81
|
-
|
78
|
+
for pipe in pipes:
|
79
|
+
ck = prompt(
|
80
|
+
f"Connector keys for copy of {pipe}:",
|
81
|
+
default=pipe.connector_keys,
|
82
|
+
completer=get_connectors_completer(),
|
83
|
+
)
|
84
|
+
mk = prompt(f"Metric key for copy of {pipe}:", default=pipe.metric_key)
|
85
|
+
lk = prompt(
|
86
|
+
f"Location key for copy of {pipe} ('None' to omit):",
|
87
|
+
default=str(pipe.location_key),
|
88
|
+
)
|
82
89
|
if lk in ('', 'None', '[None]'):
|
83
90
|
lk = None
|
84
|
-
|
85
|
-
ck, mk, lk,
|
86
|
-
parameters=p.parameters.copy(),
|
87
|
-
)
|
91
|
+
|
88
92
|
instance_keys = prompt(
|
89
|
-
f"Meerschaum instance
|
90
|
-
default=
|
93
|
+
f"Meerschaum instance for copy of {pipe}:",
|
94
|
+
default=pipe.instance_keys
|
91
95
|
)
|
92
|
-
|
93
|
-
|
94
|
-
|
96
|
+
new_pipe = Pipe(
|
97
|
+
ck, mk, lk,
|
98
|
+
instance=instance_keys,
|
99
|
+
parameters=pipe.parameters.copy(),
|
100
|
+
)
|
101
|
+
|
102
|
+
if new_pipe.get_id(debug=debug) is not None:
|
103
|
+
warn(f"{new_pipe} already exists. Skipping...", stack=False)
|
95
104
|
continue
|
96
|
-
_register_success_tuple =
|
105
|
+
_register_success_tuple = new_pipe.register(debug=debug)
|
97
106
|
if not _register_success_tuple[0]:
|
98
|
-
warn(f"Failed to register new {
|
107
|
+
warn(f"Failed to register new {new_pipe}.", stack=False)
|
99
108
|
continue
|
100
109
|
|
101
110
|
clear_screen(debug=debug)
|
102
111
|
successes += 1
|
103
112
|
print_tuple(
|
104
|
-
(True, f"Successfully copied attributes of {
|
113
|
+
(True, f"Successfully copied attributes of {pipe} " + f" into {new_pipe}.")
|
105
114
|
)
|
106
115
|
if (
|
107
116
|
force or yes_no(
|
108
117
|
(
|
109
|
-
f"Do you want to copy data from {
|
118
|
+
f"Do you want to copy data from {pipe} into {new_pipe}?\n\n"
|
110
119
|
+ "If you specified `--begin`, `--end` or `--params`, data will be filtered."
|
111
120
|
),
|
112
121
|
noask=noask,
|
@@ -114,8 +123,8 @@ def _copy_pipes(
|
|
114
123
|
default='n',
|
115
124
|
)
|
116
125
|
):
|
117
|
-
|
118
|
-
|
126
|
+
new_pipe.sync(
|
127
|
+
pipe.get_data(
|
119
128
|
debug=debug,
|
120
129
|
as_iterator=True,
|
121
130
|
**kw
|
@@ -142,17 +151,14 @@ def _copy_connectors(
|
|
142
151
|
) -> SuccessTuple:
|
143
152
|
"""
|
144
153
|
Create a new connector from an existing one.
|
145
|
-
|
146
154
|
"""
|
147
|
-
import os, pathlib
|
148
155
|
from meerschaum.utils.prompt import yes_no, prompt
|
149
156
|
from meerschaum.connectors.parse import parse_connector_keys
|
150
157
|
from meerschaum.config import _config, get_config
|
151
|
-
from meerschaum.
|
152
|
-
from meerschaum.utils.warnings import info, warn
|
158
|
+
from meerschaum.utils.warnings import info
|
153
159
|
from meerschaum.utils.formatting import pprint
|
154
160
|
from meerschaum.actions import get_action
|
155
|
-
|
161
|
+
_ = _config()
|
156
162
|
if action is None:
|
157
163
|
action = []
|
158
164
|
if connector_keys is None:
|
@@ -170,7 +176,7 @@ def _copy_connectors(
|
|
170
176
|
|
171
177
|
try:
|
172
178
|
conn = parse_connector_keys(ck)
|
173
|
-
except Exception
|
179
|
+
except Exception:
|
174
180
|
return False, f"Unable to parse connector '{ck}'."
|
175
181
|
|
176
182
|
if len(_keys) == 2:
|
meerschaum/actions/sync.py
CHANGED
@@ -275,12 +275,14 @@ def _sync_pipes(
|
|
275
275
|
import time
|
276
276
|
import os
|
277
277
|
import contextlib
|
278
|
+
from datetime import timedelta
|
278
279
|
|
279
280
|
from meerschaum.utils.warnings import warn, info
|
280
281
|
from meerschaum.utils.formatting._shell import progress
|
281
282
|
from meerschaum.utils.formatting._shell import clear_screen
|
282
283
|
from meerschaum.utils.formatting import print_pipes_results
|
283
284
|
from meerschaum.config.static import STATIC_CONFIG
|
285
|
+
from meerschaum.utils.misc import interval_str
|
284
286
|
|
285
287
|
noninteractive_val = os.environ.get(STATIC_CONFIG['environment']['noninteractive'], None)
|
286
288
|
noninteractive = str(noninteractive_val).lower() in ('1', 'true', 'yes')
|
@@ -321,7 +323,7 @@ def _sync_pipes(
|
|
321
323
|
for pipe, (_success, _msg) in results_dict.items()
|
322
324
|
if not _success
|
323
325
|
]
|
324
|
-
except Exception
|
326
|
+
except Exception:
|
325
327
|
import traceback
|
326
328
|
traceback.print_exc()
|
327
329
|
warn(
|
@@ -351,9 +353,9 @@ def _sync_pipes(
|
|
351
353
|
success_msg = (
|
352
354
|
"Successfully spawned threads for pipes:"
|
353
355
|
if unblock
|
354
|
-
else
|
356
|
+
else "Successfully synced pipes:"
|
355
357
|
)
|
356
|
-
fail_msg =
|
358
|
+
fail_msg = "Failed to sync pipes:"
|
357
359
|
if results_dict:
|
358
360
|
print_pipes_results(
|
359
361
|
results_dict,
|
@@ -362,8 +364,10 @@ def _sync_pipes(
|
|
362
364
|
nopretty = nopretty,
|
363
365
|
)
|
364
366
|
|
367
|
+
lap_duration_text = interval_str(timedelta(seconds=(lap_end - lap_begin)))
|
368
|
+
|
365
369
|
msg = (
|
366
|
-
f"It took {
|
370
|
+
f"It took {lap_duration_text} to sync " +
|
367
371
|
f"{len(success_pipes) + len(failure_pipes)} pipe" +
|
368
372
|
("s" if (len(success_pipes) + len(failure_pipes)) != 1 else "") + "\n" +
|
369
373
|
f" ({len(success_pipes)} succeeded, {len(failure_pipes)} failed)."
|
@@ -385,26 +389,26 @@ def _sync_pipes(
|
|
385
389
|
|
386
390
|
|
387
391
|
def _wrap_pipe(
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
392
|
+
pipe,
|
393
|
+
unblock: bool = False,
|
394
|
+
force: bool = False,
|
395
|
+
debug: bool = False,
|
396
|
+
min_seconds: int = 1,
|
397
|
+
workers = None,
|
398
|
+
verify: bool = False,
|
399
|
+
deduplicate: bool = False,
|
400
|
+
bounded: Optional[bool] = None,
|
401
|
+
chunk_interval: Union[timedelta, int, None] = None,
|
402
|
+
**kw
|
403
|
+
):
|
400
404
|
"""
|
401
405
|
Wrapper function for handling exceptions.
|
402
406
|
"""
|
403
407
|
import time
|
404
408
|
import traceback
|
405
|
-
from datetime import datetime,
|
409
|
+
from datetime import datetime, timezone
|
406
410
|
import meerschaum as mrsm
|
407
|
-
from meerschaum.utils.typing import is_success_tuple
|
411
|
+
from meerschaum.utils.typing import is_success_tuple
|
408
412
|
from meerschaum.connectors import get_connector_plugin
|
409
413
|
from meerschaum.utils.venv import Venv
|
410
414
|
from meerschaum.plugins import _pre_sync_hooks, _post_sync_hooks
|
meerschaum/api/dash/pipes.py
CHANGED
@@ -12,7 +12,6 @@ import shlex
|
|
12
12
|
from textwrap import dedent
|
13
13
|
from urllib.parse import urlencode
|
14
14
|
|
15
|
-
from dash.dependencies import Input, Output, State
|
16
15
|
from meerschaum.utils.typing import List, Optional, Dict, Any, Tuple, Union
|
17
16
|
from meerschaum.utils.misc import string_to_dict
|
18
17
|
from meerschaum.utils.packages import attempt_import, import_dcc, import_html, import_pandas
|
@@ -76,7 +75,7 @@ def keys_from_state(
|
|
76
75
|
try:
|
77
76
|
# params = string_to_dict(state['params-textarea.value'])
|
78
77
|
params = string_to_dict(state['search-parameters-editor.value'])
|
79
|
-
except Exception
|
78
|
+
except Exception:
|
80
79
|
params = None
|
81
80
|
else:
|
82
81
|
params = None
|
@@ -506,7 +505,7 @@ def accordion_items_from_pipe(
|
|
506
505
|
|
507
506
|
stats_rows = []
|
508
507
|
if rowcount is not None:
|
509
|
-
stats_rows.append(html.Tr([html.Td("Row
|
508
|
+
stats_rows.append(html.Tr([html.Td("Row Count"), html.Td(f"{rowcount:,}")]))
|
510
509
|
if interval is not None:
|
511
510
|
stats_rows.append(
|
512
511
|
html.Tr([html.Td("Timespan"), html.Td(humanfriendly.format_timespan(interval))])
|
meerschaum/config/_default.py
CHANGED
@@ -76,6 +76,11 @@ default_system_config = {
|
|
76
76
|
},
|
77
77
|
'instance': {
|
78
78
|
'stale_temporary_tables_minutes': 1440,
|
79
|
+
'temporary_target': {
|
80
|
+
'prefix': '_',
|
81
|
+
'transaction_id_length': 4,
|
82
|
+
'separator': '_',
|
83
|
+
},
|
79
84
|
},
|
80
85
|
'chunksize': 100_000,
|
81
86
|
'poolclass': 'sqlalchemy.pool.QueuePool',
|
meerschaum/config/_version.py
CHANGED
@@ -20,12 +20,13 @@ def get_mrsm_version(self, **kw) -> Optional[str]:
|
|
20
20
|
use_token=False,
|
21
21
|
**kw
|
22
22
|
).json()
|
23
|
-
except Exception
|
23
|
+
except Exception:
|
24
24
|
return None
|
25
25
|
if isinstance(j, dict) and 'detail' in j:
|
26
26
|
return None
|
27
27
|
return j
|
28
28
|
|
29
|
+
|
29
30
|
def get_chaining_status(self, **kw) -> Optional[bool]:
|
30
31
|
"""
|
31
32
|
Fetch the chaining status of the API instance.
|
@@ -39,7 +40,7 @@ def get_chaining_status(self, **kw) -> Optional[bool]:
|
|
39
40
|
)
|
40
41
|
if not response:
|
41
42
|
return None
|
42
|
-
except Exception
|
43
|
+
except Exception:
|
43
44
|
return None
|
44
45
|
|
45
46
|
return response.json()
|
@@ -9,8 +9,7 @@ Register or fetch Pipes from the API
|
|
9
9
|
from __future__ import annotations
|
10
10
|
import time
|
11
11
|
import json
|
12
|
-
from
|
13
|
-
from datetime import datetime
|
12
|
+
from datetime import datetime, timedelta
|
14
13
|
|
15
14
|
import meerschaum as mrsm
|
16
15
|
from meerschaum.utils.debug import dprint
|
@@ -178,11 +177,11 @@ def sync_pipe(
|
|
178
177
|
"""Sync a DataFrame into a Pipe."""
|
179
178
|
from decimal import Decimal
|
180
179
|
from meerschaum.utils.debug import dprint
|
181
|
-
from meerschaum.utils.misc import json_serialize_datetime, items_str
|
180
|
+
from meerschaum.utils.misc import json_serialize_datetime, items_str, interval_str
|
182
181
|
from meerschaum.config import get_config
|
183
182
|
from meerschaum.utils.packages import attempt_import
|
184
|
-
from meerschaum.utils.dataframe import get_numeric_cols, to_json
|
185
|
-
begin = time.
|
183
|
+
from meerschaum.utils.dataframe import get_numeric_cols, to_json
|
184
|
+
begin = time.perf_counter()
|
186
185
|
more_itertools = attempt_import('more_itertools')
|
187
186
|
if df is None:
|
188
187
|
msg = f"DataFrame is `None`. Cannot sync {pipe}."
|
@@ -304,9 +303,10 @@ def sync_pipe(
|
|
304
303
|
num_success_chunks += 1
|
305
304
|
|
306
305
|
success_tuple = True, (
|
307
|
-
f"It took {
|
306
|
+
f"It took {interval_str(timedelta(seconds=(time.perf_counter() - begin)))} "
|
307
|
+
+ "to sync {rowcount:,} row"
|
308
308
|
+ ('s' if rowcount != 1 else '')
|
309
|
-
+ f" across {num_success_chunks} chunk" + ('s' if num_success_chunks != 1 else '') +
|
309
|
+
+ f" across {num_success_chunks:,} chunk" + ('s' if num_success_chunks != 1 else '') +
|
310
310
|
f" to {pipe}."
|
311
311
|
)
|
312
312
|
return success_tuple
|
@@ -549,10 +549,9 @@ def create_metadata(
|
|
549
549
|
if debug:
|
550
550
|
dprint("Create metadata response: {response.text}")
|
551
551
|
try:
|
552
|
-
|
552
|
+
_ = json.loads(response.text)
|
553
553
|
except Exception as e:
|
554
554
|
warn(f"Failed to create metadata on {self}:\n{e}")
|
555
|
-
metadata_response = False
|
556
555
|
return False
|
557
556
|
|
558
557
|
|
@@ -1505,7 +1505,6 @@ def sync_pipe(
|
|
1505
1505
|
UPDATE_QUERIES,
|
1506
1506
|
get_reset_autoincrement_queries,
|
1507
1507
|
)
|
1508
|
-
from meerschaum.utils.misc import generate_password
|
1509
1508
|
from meerschaum.utils.dtypes import are_dtypes_equal
|
1510
1509
|
from meerschaum.utils.dtypes.sql import get_db_type_from_pd_type
|
1511
1510
|
from meerschaum import Pipe
|
@@ -1720,9 +1719,7 @@ def sync_pipe(
|
|
1720
1719
|
warn(f"Could not reset auto-incrementing primary key for {pipe}.", stack=False)
|
1721
1720
|
|
1722
1721
|
if update_df is not None and len(update_df) > 0:
|
1723
|
-
|
1724
|
-
temp_prefix = '##' if self.flavor != 'oracle' else '_'
|
1725
|
-
temp_target = temp_prefix + transact_id + '_' + pipe.target
|
1722
|
+
temp_target = self.get_temporary_target(pipe.target, label='update')
|
1726
1723
|
self._log_temporary_tables_creation(temp_target, create=(not pipe.temporary), debug=debug)
|
1727
1724
|
temp_pipe = Pipe(
|
1728
1725
|
pipe.connector_keys.replace(':', '_') + '_', pipe.metric_key, pipe.location_key,
|
@@ -1743,7 +1740,7 @@ def sync_pipe(
|
|
1743
1740
|
static=True,
|
1744
1741
|
autoincrement=False,
|
1745
1742
|
parameters={
|
1746
|
-
'schema':
|
1743
|
+
'schema': self.internal_schema,
|
1747
1744
|
'hypertable': False,
|
1748
1745
|
},
|
1749
1746
|
)
|
@@ -1910,15 +1907,18 @@ def sync_pipe_inplace(
|
|
1910
1907
|
)
|
1911
1908
|
from meerschaum.utils.misc import generate_password
|
1912
1909
|
|
1913
|
-
|
1914
|
-
|
1915
|
-
|
1916
|
-
|
1910
|
+
transaction_id_length = (
|
1911
|
+
mrsm.get_config(
|
1912
|
+
'system', 'connectors', 'sql', 'instance', 'temporary_target', 'transaction_id_length'
|
1913
|
+
)
|
1914
|
+
)
|
1915
|
+
transact_id = generate_password(transaction_id_length)
|
1917
1916
|
|
1918
1917
|
internal_schema = self.internal_schema
|
1918
|
+
target = pipe.target
|
1919
1919
|
temp_table_roots = ['backtrack', 'new', 'delta', 'joined', 'unseen', 'update']
|
1920
1920
|
temp_tables = {
|
1921
|
-
table_root:
|
1921
|
+
table_root: self.get_temporary_target(target, transact_id=transact_id, label=table_root)
|
1922
1922
|
for table_root in temp_table_roots
|
1923
1923
|
}
|
1924
1924
|
temp_table_names = {
|
@@ -3626,3 +3626,30 @@ def get_pipe_schema(self, pipe: mrsm.Pipe) -> Union[str, None]:
|
|
3626
3626
|
A schema string or `None` if nothing is configured.
|
3627
3627
|
"""
|
3628
3628
|
return pipe.parameters.get('schema', self.schema)
|
3629
|
+
|
3630
|
+
|
3631
|
+
@staticmethod
|
3632
|
+
def get_temporary_target(
|
3633
|
+
target: str,
|
3634
|
+
transact_id: Optional[str, None] = None,
|
3635
|
+
label: Optional[str] = None,
|
3636
|
+
separator: Optional[str] = None,
|
3637
|
+
) -> str:
|
3638
|
+
"""
|
3639
|
+
Return a unique(ish) temporary target for a pipe.
|
3640
|
+
"""
|
3641
|
+
from meerschaum.utils.misc import generate_password
|
3642
|
+
temp_target_cf = (
|
3643
|
+
mrsm.get_config('system', 'connectors', 'sql', 'instance', 'temporary_target') or {}
|
3644
|
+
)
|
3645
|
+
transaction_id_len = temp_target_cf.get('transaction_id_length', 3)
|
3646
|
+
transact_id = transact_id or generate_password(transaction_id_len)
|
3647
|
+
temp_prefix = temp_target_cf.get('prefix', '_')
|
3648
|
+
separator = separator or temp_target_cf.get('separator', '_')
|
3649
|
+
return (
|
3650
|
+
temp_prefix
|
3651
|
+
+ target
|
3652
|
+
+ separator
|
3653
|
+
+ transact_id
|
3654
|
+
+ ((separator + label) if label else '')
|
3655
|
+
)
|
@@ -778,6 +778,7 @@ def to_sql(
|
|
778
778
|
import time
|
779
779
|
import json
|
780
780
|
from decimal import Decimal
|
781
|
+
from datetime import timedelta
|
781
782
|
from meerschaum.utils.warnings import error, warn
|
782
783
|
import warnings
|
783
784
|
import functools
|
@@ -816,6 +817,7 @@ def to_sql(
|
|
816
817
|
PD_TO_SQLALCHEMY_DTYPES_FLAVORS,
|
817
818
|
get_db_type_from_pd_type,
|
818
819
|
)
|
820
|
+
from meerschaum.utils.misc import interval_str
|
819
821
|
from meerschaum.connectors.sql._create_engine import flavor_configs
|
820
822
|
from meerschaum.utils.packages import attempt_import, import_pandas
|
821
823
|
sqlalchemy = attempt_import('sqlalchemy', debug=debug)
|
@@ -998,7 +1000,13 @@ def to_sql(
|
|
998
1000
|
|
999
1001
|
end = time.perf_counter()
|
1000
1002
|
if success:
|
1001
|
-
|
1003
|
+
num_rows = len(df)
|
1004
|
+
msg = (
|
1005
|
+
f"It took {interval_str(timedelta(seconds=(end - start)))} "
|
1006
|
+
+ f"to sync {num_rows:,} row"
|
1007
|
+
+ ('s' if num_rows != 1 else '')
|
1008
|
+
+ f" to {name}."
|
1009
|
+
)
|
1002
1010
|
stats['start'] = start
|
1003
1011
|
stats['end'] = end
|
1004
1012
|
stats['duration'] = end - start
|
meerschaum/jobs/_Job.py
CHANGED
meerschaum/plugins/__init__.py
CHANGED
@@ -126,8 +126,8 @@ def pre_sync_hook(
|
|
126
126
|
|
127
127
|
|
128
128
|
def post_sync_hook(
|
129
|
-
|
130
|
-
|
129
|
+
function: Callable[[Any], Any],
|
130
|
+
) -> Callable[[Any], Any]:
|
131
131
|
"""
|
132
132
|
Register a function as a sync hook to be executed upon completion of a sync.
|
133
133
|
|
@@ -143,10 +143,14 @@ def post_sync_hook(
|
|
143
143
|
Examples
|
144
144
|
--------
|
145
145
|
>>> from meerschaum.plugins import post_sync_hook
|
146
|
+
>>> from meerschaum.utils.misc import interval_str
|
147
|
+
>>> from datetime import timedelta
|
146
148
|
>>>
|
147
149
|
>>> @post_sync_hook
|
148
150
|
... def log_sync(pipe, success_tuple, duration=None, **kwargs):
|
149
|
-
...
|
151
|
+
... duration_delta = timedelta(seconds=duration)
|
152
|
+
... duration_text = interval_str(duration_delta)
|
153
|
+
... print(f"It took {duration_text} to sync {pipe}.")
|
150
154
|
>>>
|
151
155
|
"""
|
152
156
|
with _locks['_post_sync_hooks']:
|
@@ -1017,7 +1017,8 @@ class Daemon:
|
|
1017
1017
|
|
1018
1018
|
def read_pickle(self) -> Daemon:
|
1019
1019
|
"""Read a Daemon's pickle file and return the `Daemon`."""
|
1020
|
-
import pickle
|
1020
|
+
import pickle
|
1021
|
+
import traceback
|
1021
1022
|
if not self.pickle_path.exists():
|
1022
1023
|
error(f"Pickle file does not exist for daemon '{self.daemon_id}'.")
|
1023
1024
|
|
@@ -1053,6 +1054,9 @@ class Daemon:
|
|
1053
1054
|
if self._properties is None:
|
1054
1055
|
self._properties = {}
|
1055
1056
|
|
1057
|
+
if self._properties.get('result', None) is None:
|
1058
|
+
_ = self._properties.pop('result', None)
|
1059
|
+
|
1056
1060
|
if _file_properties is not None:
|
1057
1061
|
self._properties = apply_patch_to_config(
|
1058
1062
|
_file_properties,
|
@@ -37,7 +37,7 @@ def daemon_entry(sysargs: Optional[List[str]] = None) -> SuccessTuple:
|
|
37
37
|
filtered_sysargs = [arg for arg in sysargs if arg not in ('-d', '--daemon')]
|
38
38
|
try:
|
39
39
|
label = shlex.join(filtered_sysargs) if sysargs else None
|
40
|
-
except Exception
|
40
|
+
except Exception:
|
41
41
|
label = ' '.join(filtered_sysargs) if sysargs else None
|
42
42
|
|
43
43
|
name = _args.get('name', None)
|
@@ -45,7 +45,7 @@ def daemon_entry(sysargs: Optional[List[str]] = None) -> SuccessTuple:
|
|
45
45
|
if name:
|
46
46
|
try:
|
47
47
|
daemon = Daemon(daemon_id=name)
|
48
|
-
except Exception
|
48
|
+
except Exception:
|
49
49
|
daemon = None
|
50
50
|
|
51
51
|
if daemon is not None:
|
meerschaum/utils/misc.py
CHANGED
@@ -90,20 +90,21 @@ def add_method_to_class(
|
|
90
90
|
|
91
91
|
|
92
92
|
def generate_password(length: int = 12) -> str:
|
93
|
-
"""
|
93
|
+
"""
|
94
|
+
Generate a secure password of given length.
|
94
95
|
|
95
96
|
Parameters
|
96
97
|
----------
|
97
|
-
length
|
98
|
+
length: int, default 12
|
98
99
|
The length of the password.
|
99
100
|
|
100
101
|
Returns
|
101
102
|
-------
|
102
103
|
A random password string.
|
103
|
-
|
104
104
|
"""
|
105
|
-
import secrets
|
106
|
-
|
105
|
+
import secrets
|
106
|
+
import string
|
107
|
+
return ''.join((secrets.choice(string.ascii_letters + string.digits) for i in range(length)))
|
107
108
|
|
108
109
|
def is_int(s : str) -> bool:
|
109
110
|
"""
|
@@ -121,7 +122,7 @@ def is_int(s : str) -> bool:
|
|
121
122
|
"""
|
122
123
|
try:
|
123
124
|
float(s)
|
124
|
-
except Exception
|
125
|
+
except Exception:
|
125
126
|
return False
|
126
127
|
|
127
128
|
return float(s).is_integer()
|
@@ -337,14 +337,14 @@ def get_install_no_version(install_name: str) -> str:
|
|
337
337
|
|
338
338
|
import_versions = {}
|
339
339
|
def determine_version(
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
340
|
+
path: pathlib.Path,
|
341
|
+
import_name: Optional[str] = None,
|
342
|
+
venv: Optional[str] = 'mrsm',
|
343
|
+
search_for_metadata: bool = True,
|
344
|
+
split: bool = True,
|
345
|
+
warn: bool = False,
|
346
|
+
debug: bool = False,
|
347
|
+
) -> Union[str, None]:
|
348
348
|
"""
|
349
349
|
Determine a module's `__version__` string from its filepath.
|
350
350
|
|
@@ -381,11 +381,8 @@ def determine_version(
|
|
381
381
|
with _locks['import_versions']:
|
382
382
|
if venv not in import_versions:
|
383
383
|
import_versions[venv] = {}
|
384
|
-
import
|
385
|
-
import re, os
|
384
|
+
import os
|
386
385
|
old_cwd = os.getcwd()
|
387
|
-
if debug:
|
388
|
-
from meerschaum.utils.debug import dprint
|
389
386
|
from meerschaum.utils.warnings import warn as warn_function
|
390
387
|
if import_name is None:
|
391
388
|
import_name = path.parent.stem if path.stem == '__init__' else path.stem
|
@@ -395,7 +392,10 @@ def determine_version(
|
|
395
392
|
_version = None
|
396
393
|
module_parent_dir = (
|
397
394
|
path.parent.parent if path.stem == '__init__' else path.parent
|
398
|
-
) if path is not None else venv_target_path(venv, debug=debug)
|
395
|
+
) if path is not None else venv_target_path(venv, allow_nonexistent=True, debug=debug)
|
396
|
+
|
397
|
+
if not module_parent_dir.exists():
|
398
|
+
return None
|
399
399
|
|
400
400
|
installed_dir_name = _import_to_dir_name(import_name)
|
401
401
|
clean_installed_dir_name = installed_dir_name.lower().replace('-', '_')
|
@@ -403,7 +403,11 @@ def determine_version(
|
|
403
403
|
### First, check if a dist-info directory exists.
|
404
404
|
_found_versions = []
|
405
405
|
if search_for_metadata:
|
406
|
-
|
406
|
+
try:
|
407
|
+
filenames = os.listdir(module_parent_dir)
|
408
|
+
except FileNotFoundError:
|
409
|
+
filenames = []
|
410
|
+
for filename in filenames:
|
407
411
|
if not filename.endswith('.dist-info'):
|
408
412
|
continue
|
409
413
|
filename_lower = filename.lower()
|
@@ -430,7 +434,7 @@ def determine_version(
|
|
430
434
|
try:
|
431
435
|
os.chdir(module_parent_dir)
|
432
436
|
_version = importlib_metadata.metadata(import_name)['Version']
|
433
|
-
except Exception
|
437
|
+
except Exception:
|
434
438
|
_version = None
|
435
439
|
finally:
|
436
440
|
os.chdir(old_cwd)
|
@@ -698,7 +702,7 @@ def need_update(
|
|
698
702
|
(not semver.Version.parse(version).match(required_version))
|
699
703
|
if required_version else False
|
700
704
|
)
|
701
|
-
except AttributeError
|
705
|
+
except AttributeError:
|
702
706
|
pip_install(_import_to_install_name('semver'), venv='mrsm', debug=debug)
|
703
707
|
semver = manually_import_module('semver', venv='mrsm', debug=debug)
|
704
708
|
return (
|
@@ -724,10 +728,10 @@ def need_update(
|
|
724
728
|
|
725
729
|
|
726
730
|
def get_pip(
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
+
venv: Optional[str] = 'mrsm',
|
732
|
+
color: bool = True,
|
733
|
+
debug: bool = False,
|
734
|
+
) -> bool:
|
731
735
|
"""
|
732
736
|
Download and run the get-pip.py script.
|
733
737
|
|
@@ -747,7 +751,8 @@ def get_pip(
|
|
747
751
|
A bool indicating success.
|
748
752
|
|
749
753
|
"""
|
750
|
-
import sys
|
754
|
+
import sys
|
755
|
+
import subprocess
|
751
756
|
from meerschaum.utils.misc import wget
|
752
757
|
from meerschaum.config._paths import CACHE_RESOURCES_PATH
|
753
758
|
from meerschaum.config.static import STATIC_CONFIG
|
@@ -755,7 +760,7 @@ def get_pip(
|
|
755
760
|
dest = CACHE_RESOURCES_PATH / 'get-pip.py'
|
756
761
|
try:
|
757
762
|
wget(url, dest, color=False, debug=debug)
|
758
|
-
except Exception
|
763
|
+
except Exception:
|
759
764
|
print(f"Failed to fetch pip from '{url}'. Please install pip and restart Meerschaum.")
|
760
765
|
sys.exit(1)
|
761
766
|
if venv is not None:
|
@@ -776,6 +781,7 @@ def pip_install(
|
|
776
781
|
_uninstall: bool = False,
|
777
782
|
_from_completely_uninstall: bool = False,
|
778
783
|
_install_uv_pip: bool = True,
|
784
|
+
_use_uv_pip: bool = True,
|
779
785
|
color: bool = True,
|
780
786
|
silent: bool = False,
|
781
787
|
debug: bool = False,
|
@@ -835,10 +841,7 @@ def pip_install(
|
|
835
841
|
from meerschaum.utils.warnings import warn
|
836
842
|
if args is None:
|
837
843
|
args = ['--upgrade'] if not _uninstall else []
|
838
|
-
if color
|
839
|
-
ANSI, UNICODE = True, True
|
840
|
-
else:
|
841
|
-
ANSI, UNICODE = False, False
|
844
|
+
ANSI = True if color else False
|
842
845
|
if check_wheel:
|
843
846
|
have_wheel = venv_contains_package('wheel', venv=venv, debug=debug)
|
844
847
|
|
@@ -877,7 +880,8 @@ def pip_install(
|
|
877
880
|
)
|
878
881
|
|
879
882
|
use_uv_pip = (
|
880
|
-
|
883
|
+
_use_uv_pip
|
884
|
+
and venv_contains_package('uv', venv=None, debug=debug)
|
881
885
|
and uv_bin is not None
|
882
886
|
and venv is not None
|
883
887
|
and is_uv_enabled()
|
@@ -136,7 +136,7 @@ packages['sql'] = {
|
|
136
136
|
'numpy' : 'numpy>=1.18.5',
|
137
137
|
'pandas' : 'pandas[parquet]>=2.0.1',
|
138
138
|
'pyarrow' : 'pyarrow>=16.1.0',
|
139
|
-
'dask' : 'dask[complete]>=2024.
|
139
|
+
'dask' : 'dask[complete]>=2024.12.1',
|
140
140
|
'partd' : 'partd>=1.4.2',
|
141
141
|
'pytz' : 'pytz',
|
142
142
|
'joblib' : 'joblib>=0.17.0',
|
meerschaum/utils/prompt.py
CHANGED
@@ -7,7 +7,9 @@ Functions for interacting with the user.
|
|
7
7
|
"""
|
8
8
|
|
9
9
|
from __future__ import annotations
|
10
|
+
|
10
11
|
import os
|
12
|
+
import meerschaum as mrsm
|
11
13
|
from meerschaum.utils.typing import Any, Union, Optional, Tuple, List
|
12
14
|
|
13
15
|
|
@@ -63,9 +65,8 @@ def prompt(
|
|
63
65
|
|
64
66
|
"""
|
65
67
|
from meerschaum.utils.packages import attempt_import
|
66
|
-
from meerschaum.utils.formatting import
|
68
|
+
from meerschaum.utils.formatting import ANSI, CHARSET, highlight_pipes, fill_ansi
|
67
69
|
from meerschaum.config import get_config
|
68
|
-
from meerschaum.config.static import _static_config
|
69
70
|
from meerschaum.utils.misc import filter_keywords
|
70
71
|
from meerschaum.utils.daemon import running_in_daemon
|
71
72
|
noask = check_noask(noask)
|
@@ -175,8 +176,6 @@ def yes_no(
|
|
175
176
|
```
|
176
177
|
"""
|
177
178
|
from meerschaum.utils.warnings import error, warn
|
178
|
-
from meerschaum.utils.formatting import ANSI, UNICODE
|
179
|
-
from meerschaum.utils.packages import attempt_import
|
180
179
|
|
181
180
|
default = options[0] if yes else default
|
182
181
|
noask = yes or check_noask(noask)
|
@@ -195,7 +194,7 @@ def yes_no(
|
|
195
194
|
success = False
|
196
195
|
|
197
196
|
if not success:
|
198
|
-
error(
|
197
|
+
error("Error getting response. Aborting...", stack=False)
|
199
198
|
if answer == "":
|
200
199
|
answer = default
|
201
200
|
|
@@ -205,19 +204,20 @@ def yes_no(
|
|
205
204
|
|
206
205
|
return answer.lower() == options[0].lower()
|
207
206
|
|
207
|
+
|
208
208
|
def choose(
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
209
|
+
question: str,
|
210
|
+
choices: List[Union[str, Tuple[str, str]]],
|
211
|
+
default: Union[str, List[str], None] = None,
|
212
|
+
numeric: bool = True,
|
213
|
+
multiple: bool = False,
|
214
|
+
as_indices: bool = False,
|
215
|
+
delimiter: str = ',',
|
216
|
+
icon: bool = True,
|
217
|
+
warn: bool = True,
|
218
|
+
noask: bool = False,
|
219
|
+
**kw
|
220
|
+
) -> Union[str, Tuple[str], None]:
|
221
221
|
"""
|
222
222
|
Present a list of options and return the user's choice.
|
223
223
|
|
@@ -418,8 +418,8 @@ def choose(
|
|
418
418
|
valid = (len(answers) > 1 or not (len(answers) == 1 and answers[0] is None))
|
419
419
|
for a in answers:
|
420
420
|
if (
|
421
|
-
not
|
422
|
-
and not
|
421
|
+
a not in {_original for _new, _original in altered_choices.items()}
|
422
|
+
and a not in _choices
|
423
423
|
and a != default
|
424
424
|
and not noask
|
425
425
|
):
|
@@ -428,21 +428,22 @@ def choose(
|
|
428
428
|
if valid:
|
429
429
|
break
|
430
430
|
if warn:
|
431
|
-
_warn(
|
431
|
+
_warn("Please pick a valid choice.", stack=False)
|
432
432
|
|
433
433
|
if not multiple:
|
434
434
|
if not numeric:
|
435
435
|
return answer
|
436
436
|
try:
|
437
437
|
_answer = choices[int(answer) - 1]
|
438
|
-
if as_indices and isinstance(
|
438
|
+
if as_indices and isinstance(_answer, tuple):
|
439
439
|
return _answer[0]
|
440
440
|
return _answer
|
441
|
-
except Exception
|
441
|
+
except Exception:
|
442
442
|
_warn(f"Could not cast answer '{answer}' to an integer.", stacklevel=3)
|
443
443
|
|
444
444
|
if not numeric:
|
445
445
|
return answers
|
446
|
+
|
446
447
|
_answers = []
|
447
448
|
for a in answers:
|
448
449
|
try:
|
@@ -451,17 +452,17 @@ def choose(
|
|
451
452
|
if isinstance(_answer_to_return, tuple) and as_indices:
|
452
453
|
_answer_to_return = _answer_to_return[0]
|
453
454
|
_answers.append(_answer_to_return)
|
454
|
-
except Exception
|
455
|
+
except Exception:
|
455
456
|
_warn(f"Could not cast answer '{a}' to an integer.", stacklevel=3)
|
456
457
|
return _answers
|
457
458
|
|
458
459
|
|
459
460
|
def get_password(
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
461
|
+
username: Optional[str] = None,
|
462
|
+
minimum_length: Optional[int] = None,
|
463
|
+
confirm: bool = True,
|
464
|
+
**kw: Any
|
465
|
+
) -> str:
|
465
466
|
"""
|
466
467
|
Prompt the user for a password.
|
467
468
|
|
@@ -493,15 +494,15 @@ def get_password(
|
|
493
494
|
from meerschaum.utils.warnings import warn
|
494
495
|
while True:
|
495
496
|
password = prompt(
|
496
|
-
|
497
|
-
is_password
|
497
|
+
"Password" + (f" for user '{username}':" if username is not None else ":"),
|
498
|
+
is_password=True,
|
498
499
|
**kw
|
499
500
|
)
|
500
501
|
if minimum_length is not None and len(password) < minimum_length:
|
501
502
|
warn(
|
502
503
|
"Password is too short. " +
|
503
504
|
f"Please enter a password that is at least {minimum_length} characters.",
|
504
|
-
stack
|
505
|
+
stack=False
|
505
506
|
)
|
506
507
|
continue
|
507
508
|
|
@@ -509,12 +510,12 @@ def get_password(
|
|
509
510
|
return password
|
510
511
|
|
511
512
|
_password = prompt(
|
512
|
-
|
513
|
-
is_password
|
513
|
+
"Confirm password" + (f" for user '{username}':" if username is not None else ":"),
|
514
|
+
is_password=True,
|
514
515
|
**kw
|
515
516
|
)
|
516
517
|
if password != _password:
|
517
|
-
warn(
|
518
|
+
warn("Passwords do not match! Please try again.", stack=False)
|
518
519
|
continue
|
519
520
|
else:
|
520
521
|
return password
|
@@ -550,13 +551,13 @@ def get_email(username: Optional[str] = None, allow_omit: bool = True, **kw: Any
|
|
550
551
|
from meerschaum.utils.misc import is_valid_email
|
551
552
|
while True:
|
552
553
|
email = prompt(
|
553
|
-
|
554
|
+
"Email" + (f" for user '{username}'" if username is not None else "") +
|
554
555
|
(" (empty to omit):" if allow_omit else ": "),
|
555
556
|
**kw
|
556
557
|
)
|
557
558
|
if (allow_omit and email == '') or is_valid_email(email):
|
558
559
|
return email
|
559
|
-
warn(
|
560
|
+
warn("Invalid email! Please try again.", stack=False)
|
560
561
|
|
561
562
|
|
562
563
|
def check_noask(noask: bool = False) -> bool:
|
@@ -571,3 +572,20 @@ def check_noask(noask: bool = False) -> bool:
|
|
571
572
|
os.environ.get(NOASK, 'false').lower()
|
572
573
|
in ('1', 'true')
|
573
574
|
)
|
575
|
+
|
576
|
+
|
577
|
+
def get_connectors_completer(*types: str):
|
578
|
+
"""
|
579
|
+
Return a prompt-toolkit Completer object to pass into `prompt()`.
|
580
|
+
"""
|
581
|
+
from meerschaum.utils.misc import get_connector_labels
|
582
|
+
prompt_toolkit_completion = mrsm.attempt_import('prompt_toolkit.completion', lazy=False)
|
583
|
+
Completer = prompt_toolkit_completion.Completer
|
584
|
+
Completion = prompt_toolkit_completion.Completion
|
585
|
+
|
586
|
+
class ConnectorCompleter(Completer):
|
587
|
+
def get_completions(self, document, complete_event):
|
588
|
+
for label in get_connector_labels(*types):
|
589
|
+
yield Completion(label, start_position=(-1 * len(document.text)))
|
590
|
+
|
591
|
+
return ConnectorCompleter()
|
@@ -410,7 +410,7 @@ def init_venv(
|
|
410
410
|
pass
|
411
411
|
|
412
412
|
def wait_for_lock():
|
413
|
-
max_lock_seconds =
|
413
|
+
max_lock_seconds = 2.0
|
414
414
|
step_sleep_seconds = 0.1
|
415
415
|
init_venv_check_start = time.perf_counter()
|
416
416
|
while ((time.perf_counter() - init_venv_check_start) < max_lock_seconds):
|
@@ -450,13 +450,22 @@ def init_venv(
|
|
450
450
|
temp_vtp = VENVS_CACHE_RESOURCES_PATH / str(venv)
|
451
451
|
rename_vtp = vtp.exists() and not temp_vtp.exists()
|
452
452
|
|
453
|
+
wait_for_lock()
|
454
|
+
update_lock(True)
|
455
|
+
|
453
456
|
if rename_vtp:
|
454
457
|
if debug:
|
455
458
|
print(f"Moving '{vtp}' to '{temp_vtp}'...")
|
456
459
|
shutil.move(vtp, temp_vtp)
|
457
460
|
|
458
|
-
|
459
|
-
|
461
|
+
if venv_path.exists():
|
462
|
+
if debug:
|
463
|
+
print(f"Removing '{venv_path}'...")
|
464
|
+
try:
|
465
|
+
shutil.rmtree(venv_path)
|
466
|
+
except Exception as e:
|
467
|
+
if debug:
|
468
|
+
print(f"Failed to remove '{venv_path}' ({e}). Continuing...")
|
460
469
|
|
461
470
|
if uv is not None:
|
462
471
|
_venv_success = run_python_package(
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: meerschaum
|
3
|
-
Version: 2.7.
|
3
|
+
Version: 2.7.6
|
4
4
|
Summary: Sync Time-Series Pipes with Meerschaum
|
5
5
|
Home-page: https://meerschaum.io
|
6
6
|
Author: Bennett Meares
|
@@ -127,7 +127,7 @@ Provides-Extra: sql
|
|
127
127
|
Requires-Dist: numpy>=1.18.5; extra == "sql"
|
128
128
|
Requires-Dist: pandas[parquet]>=2.0.1; extra == "sql"
|
129
129
|
Requires-Dist: pyarrow>=16.1.0; extra == "sql"
|
130
|
-
Requires-Dist: dask[complete]>=2024.
|
130
|
+
Requires-Dist: dask[complete]>=2024.12.1; extra == "sql"
|
131
131
|
Requires-Dist: partd>=1.4.2; extra == "sql"
|
132
132
|
Requires-Dist: pytz; extra == "sql"
|
133
133
|
Requires-Dist: joblib>=0.17.0; extra == "sql"
|
@@ -187,7 +187,7 @@ Requires-Dist: valkey>=6.0.0; extra == "api"
|
|
187
187
|
Requires-Dist: numpy>=1.18.5; extra == "api"
|
188
188
|
Requires-Dist: pandas[parquet]>=2.0.1; extra == "api"
|
189
189
|
Requires-Dist: pyarrow>=16.1.0; extra == "api"
|
190
|
-
Requires-Dist: dask[complete]>=2024.
|
190
|
+
Requires-Dist: dask[complete]>=2024.12.1; extra == "api"
|
191
191
|
Requires-Dist: partd>=1.4.2; extra == "api"
|
192
192
|
Requires-Dist: pytz; extra == "api"
|
193
193
|
Requires-Dist: joblib>=0.17.0; extra == "api"
|
@@ -292,7 +292,7 @@ Requires-Dist: pycparser>=2.21.0; extra == "full"
|
|
292
292
|
Requires-Dist: numpy>=1.18.5; extra == "full"
|
293
293
|
Requires-Dist: pandas[parquet]>=2.0.1; extra == "full"
|
294
294
|
Requires-Dist: pyarrow>=16.1.0; extra == "full"
|
295
|
-
Requires-Dist: dask[complete]>=2024.
|
295
|
+
Requires-Dist: dask[complete]>=2024.12.1; extra == "full"
|
296
296
|
Requires-Dist: partd>=1.4.2; extra == "full"
|
297
297
|
Requires-Dist: pytz; extra == "full"
|
298
298
|
Requires-Dist: joblib>=0.17.0; extra == "full"
|
@@ -12,8 +12,8 @@ meerschaum/_internal/gui/app/__init__.py,sha256=rKUa8hHk6Fai-PDF61tQcpT1myxKcfmv
|
|
12
12
|
meerschaum/_internal/gui/app/_windows.py,sha256=-VHdjTzA3V596fVqnbmTxemONSp_80-sTNJ0CTB8FwU,2632
|
13
13
|
meerschaum/_internal/gui/app/actions.py,sha256=rx37qXf3uoa7Ou0n1cISqNFZNL0nr4wO7vSUmWO8f2E,935
|
14
14
|
meerschaum/_internal/gui/app/pipes.py,sha256=4nAQ0rrHb_2bNgDF0Ru2YlbPaCDDzAl5beOGU4Af-4A,1596
|
15
|
-
meerschaum/_internal/shell/Shell.py,sha256
|
16
|
-
meerschaum/_internal/shell/ShellCompleter.py,sha256=
|
15
|
+
meerschaum/_internal/shell/Shell.py,sha256=R6xW-D9gVuxJxQzf4Bf6E9V8exE40aCdrDJ_snUpoxA,39982
|
16
|
+
meerschaum/_internal/shell/ShellCompleter.py,sha256=Ex6mPv83RUNdC3ufRJCcaoOmQ8q8z6tCHDVzXQmWIpY,3293
|
17
17
|
meerschaum/_internal/shell/ValidAutoSuggest.py,sha256=bARjOWMidz0dvMelLUe6yRPto5l3gcEHYHqFDjoh22I,1280
|
18
18
|
meerschaum/_internal/shell/__init__.py,sha256=vXQoQPEVlYiUYai1b5AwQAlTnja6A2cSABnqXhzlS7I,281
|
19
19
|
meerschaum/_internal/shell/updates.py,sha256=FmKu1NsIE7AI1zq8zNeKneZzORv6BeURQeX0lRR81Ag,5040
|
@@ -25,8 +25,8 @@ meerschaum/actions/__init__.py,sha256=MHPs8aRBhbZQXnqd_6tVtisTrNCgPAPgnNcXYbn0zP
|
|
25
25
|
meerschaum/actions/api.py,sha256=41r3fBh3vAPyNaOrvbh2oh6WUJTR2I-zaOEZN60A66E,12538
|
26
26
|
meerschaum/actions/attach.py,sha256=UV19d9W_2WYcrf7BRz7k3mriDoX1V4rA4AKvbLdor0o,3106
|
27
27
|
meerschaum/actions/bootstrap.py,sha256=08o3PchrJ_Rv8IP30ZBH1Ovk-b8qFBGPedCjF7jRzSo,18084
|
28
|
-
meerschaum/actions/clear.py,sha256=
|
29
|
-
meerschaum/actions/copy.py,sha256=
|
28
|
+
meerschaum/actions/clear.py,sha256=v_xHn7-Pu7iwFNJ07q9eJt2hqPV7OwNZHUYa9dvixs4,4976
|
29
|
+
meerschaum/actions/copy.py,sha256=z_51zEQCKDXnAGfICIGKS3klZ2OTPdiZPJACvpuheDY,6861
|
30
30
|
meerschaum/actions/deduplicate.py,sha256=puYyxeFYEUy1Sd2IOcZB2e6MrNxAZl2bTLmNzFDkCiw,1167
|
31
31
|
meerschaum/actions/delete.py,sha256=H5oP0nE7qIWnFvkuFhZQZQYBVC0IbUevpaQ_2YQKXRA,18559
|
32
32
|
meerschaum/actions/drop.py,sha256=Hd5h4rrWd7qL2rTqglsTonUsEoH7qQlsfqNFSHGeqr0,2453
|
@@ -46,7 +46,7 @@ meerschaum/actions/sql.py,sha256=zG-KydYR654RHaF-O4Id3ACCDWeogk2B1R-OFLwFbG0,451
|
|
46
46
|
meerschaum/actions/stack.py,sha256=ZwrCTGJ0x3jjZkRieWcvqasQHYCqNtB1HYvTX-r3Z3g,5996
|
47
47
|
meerschaum/actions/start.py,sha256=NtdVzeB00PQBnDSUSu8ypHmMrZT8_Idmw5BfVZ--Zic,21296
|
48
48
|
meerschaum/actions/stop.py,sha256=5fdUw70YN-yuUWrC-NhA88cxr9FZ5NbssbQ8xXO8nFU,4632
|
49
|
-
meerschaum/actions/sync.py,sha256=
|
49
|
+
meerschaum/actions/sync.py,sha256=br87b8uqpv7GW18f_O7Zg7QioPh0t377J082yfmuSak,17223
|
50
50
|
meerschaum/actions/tag.py,sha256=SJf5qFW0ccLXjqlTdkK_0MCcrCMdg6xhYrhKdco0hdA,3053
|
51
51
|
meerschaum/actions/uninstall.py,sha256=tBXhdXggSieGEQe4EPGxpgMK0MZTJCweNvAJ9-59El0,5776
|
52
52
|
meerschaum/actions/upgrade.py,sha256=AjuC93Te-I_GWwIfuNkFJ2q1zVHDQ2Oco34S4JgK2iA,6485
|
@@ -62,7 +62,7 @@ meerschaum/api/dash/connectors.py,sha256=-Wd40ieYJI2nOASXi4V1C4bvLekjnN_tj6zp7Hg
|
|
62
62
|
meerschaum/api/dash/graphs.py,sha256=wJUDWzcLN8-C3xko6rj0F2v7Rt8YDkSXoVkkXJjYGIk,2046
|
63
63
|
meerschaum/api/dash/jobs.py,sha256=mj9STE6AaQY4fwkjD1JcYRG0iW3VEcP04bO1SlKgiXw,7681
|
64
64
|
meerschaum/api/dash/keys.py,sha256=hzEVeN60SAfVTVSO5lajGaykxRIKGhj9Ph00HRJnNoE,12598
|
65
|
-
meerschaum/api/dash/pipes.py,sha256=
|
65
|
+
meerschaum/api/dash/pipes.py,sha256=Zm2UKovwz6K8Mt6dTCY2LgDyUyFhEZ5D8nWw4ecPUXI,26210
|
66
66
|
meerschaum/api/dash/plugins.py,sha256=KdfG04f6SsUpBg-nm7MUJegFGuElOj-GAkxDX98hi60,3768
|
67
67
|
meerschaum/api/dash/sessions.py,sha256=-y5p4MYKh1eFzppkBfMsd6T7-rJs1nYS2-4fbVRAeRA,5029
|
68
68
|
meerschaum/api/dash/sync.py,sha256=9lt7IRdG-fe9gf_ZO_viPiGlerX7ic6r_VFocv3I51A,504
|
@@ -132,7 +132,7 @@ meerschaum/api/routes/_webterm.py,sha256=MenDvWXnZ8CWEmryB46pKohMf0PN6o1xJGZ3LFj
|
|
132
132
|
meerschaum/api/tables/__init__.py,sha256=e2aNC0CdlWICTUMx1i9RauF8Pm426J0RZJbsJWv4SWo,482
|
133
133
|
meerschaum/config/__init__.py,sha256=5ZBq71P9t3nb74r5CGvMfNuauPscfegBX-nkaAUi5C4,11541
|
134
134
|
meerschaum/config/_dash.py,sha256=BJHl4xMrQB-YHUEU7ldEW8q_nOPoIRSOqLrfGElc6Dw,187
|
135
|
-
meerschaum/config/_default.py,sha256=
|
135
|
+
meerschaum/config/_default.py,sha256=6SC7MOkU_2oJ7RtFXQCz9w1Qqg2_8w5UdOaR_HL3lzI,6009
|
136
136
|
meerschaum/config/_edit.py,sha256=M9yX_SDD24gV5kWITZpy7p9AWTizJsIAGWAs3WZx-Ws,9087
|
137
137
|
meerschaum/config/_environment.py,sha256=Vv4DLDfc2vKLbCLsMvkQDj77K4kEvHKEBmUBo-wCrgo,4419
|
138
138
|
meerschaum/config/_formatting.py,sha256=OMuqS1EWOsj_34wSs2tOqGIWci3bTMIZ5l-uelZgsIM,6672
|
@@ -143,7 +143,7 @@ meerschaum/config/_preprocess.py,sha256=-AEA8m_--KivZwTQ1sWN6LTn5sio_fUr2XZ51BO6
|
|
143
143
|
meerschaum/config/_read_config.py,sha256=RLC3HHi_1ndj7ITVDKLD9_uULY3caGRwSz3ATYE-ixA,15014
|
144
144
|
meerschaum/config/_shell.py,sha256=46_m49Txc5q1rGfCgO49ca48BODx45DQJi8D0zz1R18,4245
|
145
145
|
meerschaum/config/_sync.py,sha256=jHcWRkxd82_BgX8Xo8agsWvf7BSbv3qHLWmYl6ehp_0,4242
|
146
|
-
meerschaum/config/_version.py,sha256=
|
146
|
+
meerschaum/config/_version.py,sha256=EePnAdxzJgKO-MgeMY2aPKqoD0YcmJBjbRii3glP9Q4,71
|
147
147
|
meerschaum/config/paths.py,sha256=JjibeGN3YAdSNceRwsd42aNmeUrIgM6ndzC8qZAmNI0,621
|
148
148
|
meerschaum/config/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
149
149
|
meerschaum/config/stack/__init__.py,sha256=2UukC0Lmk-aVL1o1qXzumqmuIrw3vu9fD7iCuz4XD4I,10544
|
@@ -162,23 +162,23 @@ meerschaum/connectors/api/_actions.py,sha256=gd3F8i5BvN8XRvMcPvPVR8sc1DeLzgoBHdD
|
|
162
162
|
meerschaum/connectors/api/_fetch.py,sha256=Khq9AFr1nk8Dsmcedb77aWhAuHw0JGgVeahDG95Q5MQ,2072
|
163
163
|
meerschaum/connectors/api/_jobs.py,sha256=N5lpHFGG10jlVgaJeWAOTuLBQw3AdgjXsEPpp1YwZQE,11270
|
164
164
|
meerschaum/connectors/api/_login.py,sha256=5GsD-B214vr5EYfM3XrTUs1sTFApxZA-9dNxq8oNSyg,2050
|
165
|
-
meerschaum/connectors/api/_misc.py,sha256=
|
166
|
-
meerschaum/connectors/api/_pipes.py,sha256=
|
165
|
+
meerschaum/connectors/api/_misc.py,sha256=XK0LLexNUEKZjAAqoJ-9oOgwLlMdwxSOvcpqO5NuOas,1083
|
166
|
+
meerschaum/connectors/api/_pipes.py,sha256=hk6Qj3tgog8naxl0Y2l6TfJsG4AZmel3bFIaLxuy0XY,21248
|
167
167
|
meerschaum/connectors/api/_plugins.py,sha256=z04tPjfZZWwa7T60mogZH3X3wDmeLdnoN5Oh8m_YsU8,5217
|
168
168
|
meerschaum/connectors/api/_request.py,sha256=Wc4Y70t0VxEj3_ch5fAeeoSAeFMuRnyNLOV-aUFInjY,6996
|
169
169
|
meerschaum/connectors/api/_uri.py,sha256=HWxqGx4R1cHZ3ywy9Ro9ePbFxxusw4RLaC3hpGt9Z6I,1469
|
170
170
|
meerschaum/connectors/api/_users.py,sha256=kzb7ENgXwQ19OJYKOuuWzx2rwVuUZCly9dTnyvVuT2Q,5275
|
171
171
|
meerschaum/connectors/plugin/PluginConnector.py,sha256=aQ1QaB7MordCFimZqoGLb0R12PfDUN_nWks2J5mzeAs,2084
|
172
172
|
meerschaum/connectors/plugin/__init__.py,sha256=pwF7TGY4WNz2_HaVdmK4rPQ9ZwTOEuPHgzOqsGcoXJw,198
|
173
|
-
meerschaum/connectors/sql/_SQLConnector.py,sha256=
|
173
|
+
meerschaum/connectors/sql/_SQLConnector.py,sha256=uyGoCshgL-u6j3VbCDiBJn8LkVuveLeE62y8MWxSo24,12015
|
174
174
|
meerschaum/connectors/sql/__init__.py,sha256=3cqYiDkVasn7zWdtOTAZbT4bo95AuvGOmDD2TkaAxtw,205
|
175
175
|
meerschaum/connectors/sql/_cli.py,sha256=VqAHkdXC0HVXuHaZik2q-cTVmIsuS4DWMcPMJPP_g-Q,4514
|
176
176
|
meerschaum/connectors/sql/_create_engine.py,sha256=RzJz4Qc43P4JS6tkgVvAhbdjEejIepWbxymIfVZ44Nk,10555
|
177
177
|
meerschaum/connectors/sql/_fetch.py,sha256=GOU1JnPOBgaI3dDr0JdAmfTMPLIMM0EFHrsqDgDIO74,14070
|
178
178
|
meerschaum/connectors/sql/_instance.py,sha256=mmZnodccuCqmZN-UnznnFZ7JodxtT47kwjDDaDKgwUg,6274
|
179
|
-
meerschaum/connectors/sql/_pipes.py,sha256=
|
179
|
+
meerschaum/connectors/sql/_pipes.py,sha256=M0VQqkwd9sSyyttyKxonjoGi61guVc-oa1KiuWS7sd8,122315
|
180
180
|
meerschaum/connectors/sql/_plugins.py,sha256=wbxcNxqTtjfDsxPvdVGTllasYf6NHHzODaQ72hEUSBQ,8135
|
181
|
-
meerschaum/connectors/sql/_sql.py,sha256=
|
181
|
+
meerschaum/connectors/sql/_sql.py,sha256=brYLHJFt6BYlFYUhK--4okkll7UTkRR_PnvjjIJvXNY,41289
|
182
182
|
meerschaum/connectors/sql/_uri.py,sha256=0BrhQtqQdzg9mR04gWBZINs_BbPFtSlTECXT_TCUwik,3460
|
183
183
|
meerschaum/connectors/sql/_users.py,sha256=FJjYeJGhr-TDHziNc6p_5mupGRtGjezKPIYgHFEVSnY,9956
|
184
184
|
meerschaum/connectors/sql/tools.py,sha256=jz8huOaRCwGlYdtGfAqAh7SoK8uydYBrasKQba9FT38,187
|
@@ -211,33 +211,33 @@ meerschaum/core/Plugin/__init__.py,sha256=UXg64EvJPgI1PCxkY_KM02-ZmBm4FZpLPIQR_u
|
|
211
211
|
meerschaum/core/User/_User.py,sha256=qbI0GIkr3G0PI4d9S49uatbJQ2kH_-z5-GoVJ0fuEtA,6624
|
212
212
|
meerschaum/core/User/__init__.py,sha256=9qNy-Gobui4x6GiaE8U7-WOggsdniOM3_wegLN3SVKs,988
|
213
213
|
meerschaum/jobs/_Executor.py,sha256=qM62BhFTM4tyJ7p90KOM0y3qyeRY9k3ZV_aTDJMHnO8,1682
|
214
|
-
meerschaum/jobs/_Job.py,sha256=
|
214
|
+
meerschaum/jobs/_Job.py,sha256=m_OzHG1zdV3jBS1CS6idT-sc5XBx-sMz4CJZbWKeKqI,32217
|
215
215
|
meerschaum/jobs/__init__.py,sha256=YjwB6t8HCT593ckrOlImgk0kLX-1NgAYzNXVwS-uvyY,12173
|
216
216
|
meerschaum/jobs/systemd.py,sha256=Rq-tsDPslG17ZhpKMrVJ5r8Z0IPr6DEc9APObfIoXCg,24614
|
217
217
|
meerschaum/plugins/_Plugin.py,sha256=bIo4HX8TTWIcwIHROwMt4VK6OoEUhY_3Qc8q-2dp-ZA,33895
|
218
|
-
meerschaum/plugins/__init__.py,sha256=
|
218
|
+
meerschaum/plugins/__init__.py,sha256=Kl7Dz0CwUUxyjRC5RWnYo6WMLsOvdX2eQ38Rh3BjdzY,26465
|
219
219
|
meerschaum/plugins/bootstrap.py,sha256=VwjpZAuYdqPJW0YoVgAoM_taHkdQHqP902-8T7OWWCI,11339
|
220
220
|
meerschaum/utils/__init__.py,sha256=QrK1K9hIbPCRCM5k2nZGFqGnrqhA0Eh-iSmCU7FG6Cs,612
|
221
221
|
meerschaum/utils/_get_pipes.py,sha256=tu4xKPoDn79Dz2kWM13cXTP4DSCkn-3G9M8KiLftopw,11073
|
222
222
|
meerschaum/utils/dataframe.py,sha256=fM8_DxnMTMhXDUqWIVXR-bOOwzBGO-cRcjarOIN3jdQ,47990
|
223
223
|
meerschaum/utils/debug.py,sha256=GyIzJmunkoPnOcZNYVQdT4Sgd-aOb5MI2VbIgATOjIQ,3695
|
224
224
|
meerschaum/utils/interactive.py,sha256=t-6jWozXSqL7lYGDHuwiOjTgr-UKhdcg61q_eR5mikI,3196
|
225
|
-
meerschaum/utils/misc.py,sha256=
|
225
|
+
meerschaum/utils/misc.py,sha256=Ut__DxYXuu-WtF9Mg2Z1CrnQMBmhPuqGsjOgiZMhAww,47079
|
226
226
|
meerschaum/utils/networking.py,sha256=Sr_eYUGW8_UV9-k9LqRFf7xLtbUcsDucODyLCRsFRUc,1006
|
227
227
|
meerschaum/utils/pool.py,sha256=vkE42af4fjrTEJTxf6Ek3xGucm1MtEkpsSEiaVzNKHs,2655
|
228
228
|
meerschaum/utils/process.py,sha256=9O8PPPJjY9Q5W2f39I3B3lFU6TlSiRiI3bgrzdOOyOw,7843
|
229
|
-
meerschaum/utils/prompt.py,sha256=
|
229
|
+
meerschaum/utils/prompt.py,sha256=qbS8l0DfD6eRB9_RRbfkKLPs3m-Hw2zXSeQCf0TDJgU,19370
|
230
230
|
meerschaum/utils/schedule.py,sha256=bUsaCO9CGn2vJO5UvoISScHDDGIiMdCPHxpTFmu7vwE,11531
|
231
231
|
meerschaum/utils/sql.py,sha256=JqOfWCHWAlm1fr7mtZMquoGCOnPyIlX5LDshcRFDgdo,77993
|
232
232
|
meerschaum/utils/threading.py,sha256=awjbVL_QR6G-o_9Qk85utac9cSdqkiC8tQSdERCdrG8,2814
|
233
233
|
meerschaum/utils/typing.py,sha256=U3MC347sh1umpa3Xr1k71eADyDmk4LB6TnVCpq8dVzI,2830
|
234
234
|
meerschaum/utils/warnings.py,sha256=n-phr3BftNNgyPnvnXC_VMSjtCvjiCZ-ewmVfcROhkc,6611
|
235
235
|
meerschaum/utils/yaml.py,sha256=PoC1du0pn2hLwTHwL-zuOf_EBWZSbCGOz-P-AZ4BWN0,3901
|
236
|
-
meerschaum/utils/daemon/Daemon.py,sha256=
|
236
|
+
meerschaum/utils/daemon/Daemon.py,sha256=jNhzpkcR-kXgIQKBqr--cFx6ZhAb0a0sdjnCOUkLEL0,42885
|
237
237
|
meerschaum/utils/daemon/FileDescriptorInterceptor.py,sha256=MJKMO0Syf3d8yWUs6xXcQzg8Ptsuvh2aCRRoglOjusA,5257
|
238
238
|
meerschaum/utils/daemon/RotatingFile.py,sha256=ePm_svjwyFDWh6V1k-bp1RHXCSWlyxDtlFu4SU4XvPU,24369
|
239
239
|
meerschaum/utils/daemon/StdinFile.py,sha256=qdZ8E_RSOkURypwnS50mWeyWyRig1bAY9tKWMTVKajc,3307
|
240
|
-
meerschaum/utils/daemon/__init__.py,sha256=
|
240
|
+
meerschaum/utils/daemon/__init__.py,sha256=ziRPyu_IM3l7Xd58y3Uvt0fZLoirJ9nuboFIxxult6c,8741
|
241
241
|
meerschaum/utils/daemon/_names.py,sha256=d2ZwTxBoTAqXZkCfZ5LuX2XrkQmLNUq1OTlUqfoH5dA,4515
|
242
242
|
meerschaum/utils/dtypes/__init__.py,sha256=c6DoYyCbWvMdRapBRKP5UJYLRUWtkTIlC_8HRzXFh2s,12166
|
243
243
|
meerschaum/utils/dtypes/sql.py,sha256=Ew-ULDAJipzWpq_W-3fGGgTORhtoIqRZzZcS7k0L4B4,19582
|
@@ -246,16 +246,16 @@ meerschaum/utils/formatting/_jobs.py,sha256=izsqPJhTtUkXUUtWnbXtReYsUYwulXtci3pB
|
|
246
246
|
meerschaum/utils/formatting/_pipes.py,sha256=OISJmmFiilaDbZxkiXck_g39MnnTfk_fJJyJ-YInvXA,19559
|
247
247
|
meerschaum/utils/formatting/_pprint.py,sha256=tgrT3FyGyu5CWJYysqK3kX1xdZYorlbOk9fcU_vt9Qg,3096
|
248
248
|
meerschaum/utils/formatting/_shell.py,sha256=XH7VFLteNv7NGtWhJl7FdIGt80sKeTiDoJokGSDAwBM,3761
|
249
|
-
meerschaum/utils/packages/__init__.py,sha256=
|
250
|
-
meerschaum/utils/packages/_packages.py,sha256=
|
249
|
+
meerschaum/utils/packages/__init__.py,sha256=TdKaj2tmN4bFwzusOfMv24P5ET7Zv73vyoOf9GOIr5E,64427
|
250
|
+
meerschaum/utils/packages/_packages.py,sha256=_xODMSz1FAcx3XHrn9RXUhGJ1zg-QKsVu9zYZV2UJeY,8868
|
251
251
|
meerschaum/utils/packages/lazy_loader.py,sha256=VHnph3VozH29R4JnSSBfwtA5WKZYZQFT_GeQSShCnuc,2540
|
252
252
|
meerschaum/utils/venv/_Venv.py,sha256=gc1TCeAj-kTZbQFAT9xl1bi4HXFV5ApT0dPOJfxwr78,3748
|
253
|
-
meerschaum/utils/venv/__init__.py,sha256=
|
254
|
-
meerschaum-2.7.
|
255
|
-
meerschaum-2.7.
|
256
|
-
meerschaum-2.7.
|
257
|
-
meerschaum-2.7.
|
258
|
-
meerschaum-2.7.
|
259
|
-
meerschaum-2.7.
|
260
|
-
meerschaum-2.7.
|
261
|
-
meerschaum-2.7.
|
253
|
+
meerschaum/utils/venv/__init__.py,sha256=vVU9vj7t-HTiRU--ReQZ9kRLesVqcHnSJDbmcfC-Dzg,27030
|
254
|
+
meerschaum-2.7.6.dist-info/LICENSE,sha256=jG2zQEdRNt88EgHUWPpXVWmOrOduUQRx7MnYV9YIPaw,11359
|
255
|
+
meerschaum-2.7.6.dist-info/METADATA,sha256=fWChi6YW7sc_kNoXq7H3ryE-RdPH0fSR5UsFWQfMhps,24227
|
256
|
+
meerschaum-2.7.6.dist-info/NOTICE,sha256=OTA9Fcthjf5BRvWDDIcBC_xfLpeDV-RPZh3M-HQBRtQ,114
|
257
|
+
meerschaum-2.7.6.dist-info/WHEEL,sha256=A3WOREP4zgxI0fKrHUG8DC8013e3dK3n7a6HDbcEIwE,91
|
258
|
+
meerschaum-2.7.6.dist-info/entry_points.txt,sha256=5YBVzibw-0rNA_1VjB16z5GABsOGf-CDhW4yqH8C7Gc,88
|
259
|
+
meerschaum-2.7.6.dist-info/top_level.txt,sha256=bNoSiDj0El6buocix-FRoAtJOeq1qOF5rRm2u9i7Q6A,11
|
260
|
+
meerschaum-2.7.6.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
261
|
+
meerschaum-2.7.6.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|