meerschaum 2.9.4__py3-none-any.whl → 3.0.0rc1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- meerschaum/__init__.py +5 -2
- meerschaum/_internal/__init__.py +1 -0
- meerschaum/_internal/arguments/_parse_arguments.py +4 -4
- meerschaum/_internal/arguments/_parser.py +17 -1
- meerschaum/_internal/entry.py +6 -6
- meerschaum/_internal/shell/Shell.py +1 -1
- meerschaum/_internal/static.py +372 -0
- meerschaum/actions/api.py +12 -2
- meerschaum/actions/bootstrap.py +7 -7
- meerschaum/actions/edit.py +142 -18
- meerschaum/actions/register.py +137 -6
- meerschaum/actions/show.py +117 -29
- meerschaum/actions/stop.py +4 -1
- meerschaum/actions/sync.py +1 -1
- meerschaum/actions/tag.py +9 -8
- meerschaum/api/__init__.py +9 -2
- meerschaum/api/_events.py +39 -2
- meerschaum/api/_oauth2.py +118 -8
- meerschaum/api/_tokens.py +102 -0
- meerschaum/api/dash/__init__.py +0 -1
- meerschaum/api/dash/callbacks/custom.py +2 -2
- meerschaum/api/dash/callbacks/dashboard.py +133 -18
- meerschaum/api/dash/callbacks/plugins.py +0 -1
- meerschaum/api/dash/callbacks/register.py +1 -1
- meerschaum/api/dash/callbacks/settings/__init__.py +1 -0
- meerschaum/api/dash/callbacks/settings/password_reset.py +2 -2
- meerschaum/api/dash/callbacks/settings/tokens.py +388 -0
- meerschaum/api/dash/components.py +30 -8
- meerschaum/api/dash/keys.py +19 -93
- meerschaum/api/dash/pages/dashboard.py +1 -20
- meerschaum/api/dash/pages/settings/__init__.py +1 -0
- meerschaum/api/dash/pages/settings/password_reset.py +1 -1
- meerschaum/api/dash/pages/settings/tokens.py +55 -0
- meerschaum/api/dash/pipes.py +156 -58
- meerschaum/api/dash/sessions.py +12 -0
- meerschaum/api/dash/tokens.py +606 -0
- meerschaum/api/dash/websockets.py +1 -1
- meerschaum/api/dash/webterm.py +4 -0
- meerschaum/api/models/__init__.py +23 -3
- meerschaum/api/models/_actions.py +22 -0
- meerschaum/api/models/_pipes.py +85 -7
- meerschaum/api/models/_tokens.py +81 -0
- meerschaum/api/resources/static/css/dash.css +16 -0
- meerschaum/api/resources/templates/termpage.html +12 -0
- meerschaum/api/routes/__init__.py +1 -0
- meerschaum/api/routes/_actions.py +3 -4
- meerschaum/api/routes/_connectors.py +3 -7
- meerschaum/api/routes/_jobs.py +14 -35
- meerschaum/api/routes/_login.py +49 -12
- meerschaum/api/routes/_misc.py +5 -10
- meerschaum/api/routes/_pipes.py +134 -111
- meerschaum/api/routes/_plugins.py +38 -28
- meerschaum/api/routes/_tokens.py +236 -0
- meerschaum/api/routes/_users.py +47 -35
- meerschaum/api/routes/_version.py +3 -3
- meerschaum/config/__init__.py +43 -20
- meerschaum/config/_default.py +32 -5
- meerschaum/config/_edit.py +28 -24
- meerschaum/config/_environment.py +1 -1
- meerschaum/config/_patch.py +6 -6
- meerschaum/config/_paths.py +5 -1
- meerschaum/config/_read_config.py +65 -34
- meerschaum/config/_sync.py +6 -3
- meerschaum/config/_version.py +1 -1
- meerschaum/config/stack/__init__.py +24 -5
- meerschaum/config/static.py +18 -0
- meerschaum/connectors/_Connector.py +10 -4
- meerschaum/connectors/__init__.py +4 -20
- meerschaum/connectors/api/_APIConnector.py +34 -6
- meerschaum/connectors/api/_actions.py +2 -2
- meerschaum/connectors/api/_jobs.py +1 -1
- meerschaum/connectors/api/_login.py +33 -7
- meerschaum/connectors/api/_misc.py +2 -2
- meerschaum/connectors/api/_pipes.py +15 -14
- meerschaum/connectors/api/_plugins.py +2 -2
- meerschaum/connectors/api/_request.py +1 -1
- meerschaum/connectors/api/_tokens.py +146 -0
- meerschaum/connectors/api/_users.py +70 -58
- meerschaum/connectors/instance/_InstanceConnector.py +83 -0
- meerschaum/connectors/instance/__init__.py +10 -0
- meerschaum/connectors/instance/_pipes.py +442 -0
- meerschaum/connectors/instance/_plugins.py +151 -0
- meerschaum/connectors/instance/_tokens.py +296 -0
- meerschaum/connectors/instance/_users.py +181 -0
- meerschaum/connectors/parse.py +4 -1
- meerschaum/connectors/sql/_SQLConnector.py +8 -5
- meerschaum/connectors/sql/_cli.py +12 -11
- meerschaum/connectors/sql/_create_engine.py +6 -154
- meerschaum/connectors/sql/_fetch.py +2 -18
- meerschaum/connectors/sql/_pipes.py +42 -31
- meerschaum/connectors/sql/_plugins.py +29 -0
- meerschaum/connectors/sql/_sql.py +9 -2
- meerschaum/connectors/sql/_users.py +29 -2
- meerschaum/connectors/sql/tables/__init__.py +1 -1
- meerschaum/connectors/valkey/_ValkeyConnector.py +2 -4
- meerschaum/connectors/valkey/_pipes.py +9 -10
- meerschaum/connectors/valkey/_plugins.py +2 -26
- meerschaum/core/Pipe/__init__.py +31 -14
- meerschaum/core/Pipe/_attributes.py +156 -58
- meerschaum/core/Pipe/_bootstrap.py +54 -24
- meerschaum/core/Pipe/_data.py +41 -1
- meerschaum/core/Pipe/_dtypes.py +29 -14
- meerschaum/core/Pipe/_edit.py +12 -4
- meerschaum/core/Pipe/_show.py +5 -5
- meerschaum/core/Pipe/_sync.py +48 -53
- meerschaum/core/Pipe/_verify.py +1 -1
- meerschaum/{plugins → core/Plugin}/_Plugin.py +9 -11
- meerschaum/core/Plugin/__init__.py +1 -1
- meerschaum/core/Token/_Token.py +221 -0
- meerschaum/core/Token/__init__.py +12 -0
- meerschaum/core/User/_User.py +34 -8
- meerschaum/core/User/__init__.py +9 -1
- meerschaum/core/__init__.py +1 -0
- meerschaum/jobs/_Job.py +3 -2
- meerschaum/jobs/__init__.py +3 -2
- meerschaum/jobs/systemd.py +1 -1
- meerschaum/models/__init__.py +35 -0
- meerschaum/models/pipes.py +247 -0
- meerschaum/models/tokens.py +38 -0
- meerschaum/models/users.py +26 -0
- meerschaum/plugins/__init__.py +22 -7
- meerschaum/plugins/bootstrap.py +2 -1
- meerschaum/utils/_get_pipes.py +68 -27
- meerschaum/utils/daemon/Daemon.py +2 -1
- meerschaum/utils/daemon/__init__.py +30 -2
- meerschaum/utils/dataframe.py +96 -15
- meerschaum/utils/dtypes/__init__.py +93 -21
- meerschaum/utils/dtypes/sql.py +44 -0
- meerschaum/utils/formatting/__init__.py +1 -1
- meerschaum/utils/formatting/_pipes.py +5 -4
- meerschaum/utils/formatting/_shell.py +11 -9
- meerschaum/utils/misc.py +237 -80
- meerschaum/utils/packages/__init__.py +3 -6
- meerschaum/utils/packages/_packages.py +34 -32
- meerschaum/utils/pipes.py +181 -0
- meerschaum/utils/process.py +1 -1
- meerschaum/utils/prompt.py +3 -1
- meerschaum/utils/schedule.py +1 -0
- meerschaum/utils/sql.py +115 -39
- meerschaum/utils/typing.py +1 -4
- meerschaum/utils/venv/_Venv.py +2 -2
- meerschaum/utils/venv/__init__.py +5 -7
- {meerschaum-2.9.4.dist-info → meerschaum-3.0.0rc1.dist-info}/METADATA +88 -80
- meerschaum-3.0.0rc1.dist-info/RECORD +282 -0
- {meerschaum-2.9.4.dist-info → meerschaum-3.0.0rc1.dist-info}/WHEEL +1 -1
- meerschaum/api/models/_interfaces.py +0 -15
- meerschaum/api/models/_locations.py +0 -15
- meerschaum/api/models/_metrics.py +0 -15
- meerschaum/config/static/__init__.py +0 -186
- meerschaum-2.9.4.dist-info/RECORD +0 -263
- {meerschaum-2.9.4.dist-info → meerschaum-3.0.0rc1.dist-info}/entry_points.txt +0 -0
- {meerschaum-2.9.4.dist-info → meerschaum-3.0.0rc1.dist-info}/licenses/LICENSE +0 -0
- {meerschaum-2.9.4.dist-info → meerschaum-3.0.0rc1.dist-info}/top_level.txt +0 -0
- {meerschaum-2.9.4.dist-info → meerschaum-3.0.0rc1.dist-info}/zip-safe +0 -0
meerschaum/core/Pipe/_data.py
CHANGED
@@ -109,7 +109,6 @@ def get_data(
|
|
109
109
|
from meerschaum.utils.packages import attempt_import
|
110
110
|
dd = attempt_import('dask.dataframe') if as_dask else None
|
111
111
|
dask = attempt_import('dask') if as_dask else None
|
112
|
-
dateutil_parser = attempt_import('dateutil.parser')
|
113
112
|
|
114
113
|
if select_columns == '*':
|
115
114
|
select_columns = None
|
@@ -833,3 +832,44 @@ def parse_date_bounds(self, *dt_vals: Union[datetime, int, None]) -> Union[
|
|
833
832
|
if len(bounds) == 1:
|
834
833
|
return bounds[0]
|
835
834
|
return bounds
|
835
|
+
|
836
|
+
|
837
|
+
def get_doc(self, **kwargs) -> Union[Dict[str, Any], None]:
|
838
|
+
"""
|
839
|
+
Convenience function to return a single row as a dictionary (or `None`) from `Pipe.get_data().
|
840
|
+
Keywords arguments are passed to `Pipe.get_data()`.
|
841
|
+
"""
|
842
|
+
from meerschaum.utils.warnings import warn
|
843
|
+
kwargs['limit'] = 1
|
844
|
+
try:
|
845
|
+
result_df = self.get_data(**kwargs)
|
846
|
+
if result_df is None or len(result_df) == 0:
|
847
|
+
return None
|
848
|
+
return result_df.reset_index(drop=True).iloc[0].to_dict()
|
849
|
+
except Exception as e:
|
850
|
+
warn(f"Failed to read value from {self}:\n{e}", stack=False)
|
851
|
+
return None
|
852
|
+
|
853
|
+
def get_value(
|
854
|
+
self,
|
855
|
+
column: str,
|
856
|
+
params: Optional[Dict[str, Any]] = None,
|
857
|
+
**kwargs: Any
|
858
|
+
) -> Any:
|
859
|
+
"""
|
860
|
+
Convenience function to return a single value (or `None`) from `Pipe.get_data()`.
|
861
|
+
Keywords arguments are passed to `Pipe.get_data()`.
|
862
|
+
"""
|
863
|
+
from meerschaum.utils.warnings import warn
|
864
|
+
kwargs['select_columns'] = [column]
|
865
|
+
kwargs['limit'] = 1
|
866
|
+
try:
|
867
|
+
result_df = self.get_data(params=params, **kwargs)
|
868
|
+
if result_df is None or len(result_df) == 0:
|
869
|
+
return None
|
870
|
+
if column not in result_df.columns:
|
871
|
+
raise ValueError(f"Column '{column}' was not included in the result set.")
|
872
|
+
return result_df[column][0]
|
873
|
+
except Exception as e:
|
874
|
+
warn(f"Failed to read value from {self}:\n{e}", stack=False)
|
875
|
+
return None
|
meerschaum/core/Pipe/_dtypes.py
CHANGED
@@ -31,7 +31,11 @@ def enforce_dtypes(
|
|
31
31
|
import traceback
|
32
32
|
from meerschaum.utils.warnings import warn
|
33
33
|
from meerschaum.utils.debug import dprint
|
34
|
-
from meerschaum.utils.dataframe import
|
34
|
+
from meerschaum.utils.dataframe import (
|
35
|
+
parse_df_datetimes,
|
36
|
+
enforce_dtypes as _enforce_dtypes,
|
37
|
+
parse_simple_lines,
|
38
|
+
)
|
35
39
|
from meerschaum.utils.dtypes import are_dtypes_equal
|
36
40
|
from meerschaum.utils.packages import import_pandas
|
37
41
|
pd = import_pandas(debug=debug)
|
@@ -45,23 +49,34 @@ def enforce_dtypes(
|
|
45
49
|
|
46
50
|
if not self.enforce:
|
47
51
|
enforce = False
|
52
|
+
|
48
53
|
pipe_dtypes = self.dtypes if enforce else {}
|
49
54
|
|
50
55
|
try:
|
51
56
|
if isinstance(df, str):
|
52
|
-
df
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
57
|
+
if df.strip() and df.strip()[0] not in ('{', '['):
|
58
|
+
df = parse_df_datetimes(
|
59
|
+
parse_simple_lines(df),
|
60
|
+
ignore_cols=[
|
61
|
+
col
|
62
|
+
for col, dtype in pipe_dtypes.items()
|
63
|
+
if (not enforce or not are_dtypes_equal(dtype, 'datetime'))
|
64
|
+
],
|
65
|
+
)
|
66
|
+
else:
|
67
|
+
df = parse_df_datetimes(
|
68
|
+
pd.read_json(StringIO(df)),
|
69
|
+
ignore_cols=[
|
70
|
+
col
|
71
|
+
for col, dtype in pipe_dtypes.items()
|
72
|
+
if (not enforce or not are_dtypes_equal(dtype, 'datetime'))
|
73
|
+
],
|
74
|
+
ignore_all=(not enforce),
|
75
|
+
strip_timezone=(self.tzinfo is None),
|
76
|
+
chunksize=chunksize,
|
77
|
+
debug=debug,
|
78
|
+
)
|
79
|
+
elif isinstance(df, (dict, list, tuple)):
|
65
80
|
df = parse_df_datetimes(
|
66
81
|
df,
|
67
82
|
ignore_cols=[
|
meerschaum/core/Pipe/_edit.py
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# vim:fenc=utf-8
|
4
4
|
|
5
5
|
"""
|
6
|
-
Edit a Pipe's parameters
|
6
|
+
Edit a Pipe's parameters.
|
7
7
|
"""
|
8
8
|
|
9
9
|
from __future__ import annotations
|
@@ -47,6 +47,13 @@ def edit(
|
|
47
47
|
if self.temporary:
|
48
48
|
return False, "Cannot edit pipes created with `temporary=True` (read-only)."
|
49
49
|
|
50
|
+
if hasattr(self, '_symlinks'):
|
51
|
+
from meerschaum.utils.misc import get_val_from_dict_path, set_val_in_dict_path
|
52
|
+
for path, vals in self._symlinks.items():
|
53
|
+
current_val = get_val_from_dict_path(self.parameters, path)
|
54
|
+
if current_val == vals['substituted']:
|
55
|
+
set_val_in_dict_path(self.parameters, path, vals['original'])
|
56
|
+
|
50
57
|
if not interactive:
|
51
58
|
with Venv(get_connector_plugin(self.instance_connector)):
|
52
59
|
return self.instance_connector.edit_pipe(self, patch=patch, debug=debug, **kw)
|
@@ -65,7 +72,8 @@ def edit(
|
|
65
72
|
from meerschaum.config import get_config
|
66
73
|
parameters = dict(get_config('pipes', 'parameters', patch=True))
|
67
74
|
from meerschaum.config._patch import apply_patch_to_config
|
68
|
-
|
75
|
+
raw_parameters = self.attributes.get('parameters', {})
|
76
|
+
parameters = apply_patch_to_config(parameters, raw_parameters)
|
69
77
|
|
70
78
|
### write parameters to yaml file
|
71
79
|
with open(parameters_path, 'w+') as f:
|
@@ -194,7 +202,7 @@ def edit_definition(
|
|
194
202
|
return True, "Success"
|
195
203
|
|
196
204
|
def _edit_sql():
|
197
|
-
import
|
205
|
+
import textwrap
|
198
206
|
from meerschaum.config._paths import PIPES_CACHE_RESOURCES_PATH
|
199
207
|
from meerschaum.utils.misc import edit_file
|
200
208
|
definition_filename = str(self) + '.sql'
|
@@ -214,7 +222,7 @@ def edit_definition(
|
|
214
222
|
|
215
223
|
edit_file(definition_path)
|
216
224
|
try:
|
217
|
-
with open(definition_path, 'r') as f:
|
225
|
+
with open(definition_path, 'r', encoding='utf-8') as f:
|
218
226
|
file_definition = f.read()
|
219
227
|
except Exception as e:
|
220
228
|
return False, f"Failed reading file '{definition_path}':\n" + str(e)
|
meerschaum/core/Pipe/_show.py
CHANGED
@@ -9,11 +9,11 @@ Show information about a Pipe
|
|
9
9
|
from meerschaum.utils.typing import SuccessTuple
|
10
10
|
|
11
11
|
def show(
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
self,
|
13
|
+
nopretty: bool = False,
|
14
|
+
debug: bool = False,
|
15
|
+
**kw
|
16
|
+
) -> SuccessTuple:
|
17
17
|
"""
|
18
18
|
Show attributes of a Pipe.
|
19
19
|
|
meerschaum/core/Pipe/_sync.py
CHANGED
@@ -13,7 +13,7 @@ import time
|
|
13
13
|
import threading
|
14
14
|
import multiprocessing
|
15
15
|
import functools
|
16
|
-
from datetime import datetime, timedelta
|
16
|
+
from datetime import datetime, timedelta, timezone
|
17
17
|
from typing import TYPE_CHECKING
|
18
18
|
|
19
19
|
import meerschaum as mrsm
|
@@ -42,6 +42,7 @@ def sync(
|
|
42
42
|
pd.DataFrame,
|
43
43
|
Dict[str, List[Any]],
|
44
44
|
List[Dict[str, Any]],
|
45
|
+
str,
|
45
46
|
InferFetch
|
46
47
|
] = InferFetch,
|
47
48
|
begin: Union[datetime, int, str, None] = '',
|
@@ -71,6 +72,7 @@ def sync(
|
|
71
72
|
----------
|
72
73
|
df: Union[None, pd.DataFrame, Dict[str, List[Any]]], default None
|
73
74
|
An optional DataFrame to sync into the pipe. Defaults to `None`.
|
75
|
+
If `df` is a string, it will be parsed via `meerschaum.utils.dataframe.parse_simple_lines()`.
|
74
76
|
|
75
77
|
begin: Union[datetime, int, str, None], default ''
|
76
78
|
Optionally specify the earliest datetime to search for data.
|
@@ -134,6 +136,7 @@ def sync(
|
|
134
136
|
from meerschaum.utils.misc import df_is_chunk_generator, filter_keywords, filter_arguments
|
135
137
|
from meerschaum.utils.pool import get_pool
|
136
138
|
from meerschaum.config import get_config
|
139
|
+
from meerschaum.utils.dtypes import are_dtypes_equal
|
137
140
|
|
138
141
|
if (callback is not None or error_callback is not None) and blocking:
|
139
142
|
warn("Callback functions are only executed when blocking = False. Ignoring...")
|
@@ -170,6 +173,7 @@ def sync(
|
|
170
173
|
'pd.DataFrame',
|
171
174
|
Dict[str, List[Any]],
|
172
175
|
List[Dict[str, Any]],
|
176
|
+
str,
|
173
177
|
InferFetch
|
174
178
|
] = InferFetch,
|
175
179
|
) -> SuccessTuple:
|
@@ -189,6 +193,10 @@ def sync(
|
|
189
193
|
p._exists = None
|
190
194
|
return register_success, register_msg
|
191
195
|
|
196
|
+
if isinstance(df, str):
|
197
|
+
from meerschaum.utils.dataframe import parse_simple_lines
|
198
|
+
df = parse_simple_lines(df)
|
199
|
+
|
192
200
|
### If connector is a plugin with a `sync()` method, return that instead.
|
193
201
|
### If the plugin does not have a `sync()` method but does have a `fetch()` method,
|
194
202
|
### use that instead.
|
@@ -209,7 +217,7 @@ def sync(
|
|
209
217
|
p._exists = None
|
210
218
|
return False, f"Unable to create the connector for {p}."
|
211
219
|
|
212
|
-
### Sync in place if
|
220
|
+
### Sync in place if possible.
|
213
221
|
if (
|
214
222
|
str(self.connector) == str(self.instance_connector)
|
215
223
|
and
|
@@ -398,6 +406,21 @@ def sync(
|
|
398
406
|
enforce=enforce_dtypes,
|
399
407
|
debug=debug,
|
400
408
|
)
|
409
|
+
if p.autotime:
|
410
|
+
dt_col = p.columns.get('datetime', 'ts')
|
411
|
+
dt_typ = p.dtypes.get(dt_col, 'datetime') if dt_col else 'datetime'
|
412
|
+
if dt_col and hasattr(df, 'columns') and dt_col not in df.columns:
|
413
|
+
now = datetime.now(timezone.utc)
|
414
|
+
now_val = (
|
415
|
+
int(now.timestamp() * 1000)
|
416
|
+
if are_dtypes_equal(dt_typ, 'int')
|
417
|
+
else now
|
418
|
+
)
|
419
|
+
if debug:
|
420
|
+
dprint(f"Adding current timestamp to dataframe synced to {p}: {now_val}")
|
421
|
+
|
422
|
+
df[dt_col] = now_val
|
423
|
+
kw['check_existing'] = False
|
401
424
|
|
402
425
|
### Capture `numeric`, `uuid`, `json`, and `bytes` columns.
|
403
426
|
self._persist_new_json_columns(df, debug=debug)
|
@@ -447,9 +470,9 @@ def sync(
|
|
447
470
|
if self.cache_pipe is not None:
|
448
471
|
if debug:
|
449
472
|
dprint("Caching retrieved dataframe.", **kw)
|
450
|
-
|
451
|
-
|
452
|
-
|
473
|
+
_sync_cache_tuple = self.cache_pipe.sync(df, debug=debug, **kw)
|
474
|
+
if not _sync_cache_tuple[0]:
|
475
|
+
warn(f"Failed to sync local cache for {self}.")
|
453
476
|
|
454
477
|
self._exists = None
|
455
478
|
return return_tuple
|
@@ -691,7 +714,9 @@ def filter_existing(
|
|
691
714
|
NA = pd.NA
|
692
715
|
|
693
716
|
primary_key = self.columns.get('primary', None)
|
717
|
+
dt_col = self.columns.get('datetime', None)
|
694
718
|
autoincrement = self.parameters.get('autoincrement', False)
|
719
|
+
autotime = self.parameters.get('autotime', False)
|
695
720
|
pipe_columns = self.columns.copy()
|
696
721
|
|
697
722
|
if primary_key and autoincrement and df is not None and primary_key in df.columns:
|
@@ -702,6 +727,14 @@ def filter_existing(
|
|
702
727
|
del df[primary_key]
|
703
728
|
_ = self.columns.pop(primary_key, None)
|
704
729
|
|
730
|
+
if dt_col and autotime and df is not None and dt_col in df.columns:
|
731
|
+
if safe_copy:
|
732
|
+
df = df.copy()
|
733
|
+
safe_copy = False
|
734
|
+
if df[dt_col].isnull().all():
|
735
|
+
del df[dt_col]
|
736
|
+
_ = self.columns.pop(dt_col, None)
|
737
|
+
|
705
738
|
def get_empty_df():
|
706
739
|
empty_df = pd.DataFrame([])
|
707
740
|
dtypes = dict(df.dtypes) if df is not None else {}
|
@@ -730,6 +763,11 @@ def filter_existing(
|
|
730
763
|
df = self.enforce_dtypes(df, chunksize=chunksize, debug=debug)
|
731
764
|
return df, get_empty_df(), df
|
732
765
|
|
766
|
+
if autotime and dt_col and dt_col not in df.columns:
|
767
|
+
if enforce_dtypes:
|
768
|
+
df = self.enforce_dtypes(df, chunksize=chunksize, debug=debug)
|
769
|
+
return df, get_empty_df(), df
|
770
|
+
|
733
771
|
try:
|
734
772
|
min_dt_val = df[dt_col].min(skipna=True) if dt_col and dt_col in df.columns else None
|
735
773
|
if is_dask and min_dt_val is not None:
|
@@ -1013,15 +1051,7 @@ def _persist_new_numeric_columns(self, df, debug: bool = False) -> SuccessTuple:
|
|
1013
1051
|
self._attributes_sync_time = None
|
1014
1052
|
dtypes = self.parameters.get('dtypes', {})
|
1015
1053
|
dtypes.update({col: 'numeric' for col in new_numeric_cols})
|
1016
|
-
self.
|
1017
|
-
if not self.temporary:
|
1018
|
-
edit_success, edit_msg = self.edit(interactive=False, debug=debug)
|
1019
|
-
if not edit_success:
|
1020
|
-
warn(f"Unable to update NUMERIC dtypes for {self}:\n{edit_msg}")
|
1021
|
-
|
1022
|
-
return edit_success, edit_msg
|
1023
|
-
|
1024
|
-
return True, "Success"
|
1054
|
+
return self.update_parameters({'dtypes': dtypes}, debug=debug)
|
1025
1055
|
|
1026
1056
|
|
1027
1057
|
def _persist_new_uuid_columns(self, df, debug: bool = False) -> SuccessTuple:
|
@@ -1038,15 +1068,7 @@ def _persist_new_uuid_columns(self, df, debug: bool = False) -> SuccessTuple:
|
|
1038
1068
|
self._attributes_sync_time = None
|
1039
1069
|
dtypes = self.parameters.get('dtypes', {})
|
1040
1070
|
dtypes.update({col: 'uuid' for col in new_uuid_cols})
|
1041
|
-
self.
|
1042
|
-
if not self.temporary:
|
1043
|
-
edit_success, edit_msg = self.edit(interactive=False, debug=debug)
|
1044
|
-
if not edit_success:
|
1045
|
-
warn(f"Unable to update UUID dtypes for {self}:\n{edit_msg}")
|
1046
|
-
|
1047
|
-
return edit_success, edit_msg
|
1048
|
-
|
1049
|
-
return True, "Success"
|
1071
|
+
return self.update_parameters({'dtypes': dtypes}, debug=debug)
|
1050
1072
|
|
1051
1073
|
|
1052
1074
|
def _persist_new_json_columns(self, df, debug: bool = False) -> SuccessTuple:
|
@@ -1063,16 +1085,7 @@ def _persist_new_json_columns(self, df, debug: bool = False) -> SuccessTuple:
|
|
1063
1085
|
self._attributes_sync_time = None
|
1064
1086
|
dtypes = self.parameters.get('dtypes', {})
|
1065
1087
|
dtypes.update({col: 'json' for col in new_json_cols})
|
1066
|
-
self.
|
1067
|
-
|
1068
|
-
if not self.temporary:
|
1069
|
-
edit_success, edit_msg = self.edit(interactive=False, debug=debug)
|
1070
|
-
if not edit_success:
|
1071
|
-
warn(f"Unable to update JSON dtypes for {self}:\n{edit_msg}")
|
1072
|
-
|
1073
|
-
return edit_success, edit_msg
|
1074
|
-
|
1075
|
-
return True, "Success"
|
1088
|
+
return self.update_parameters({'dtypes': dtypes}, debug=debug)
|
1076
1089
|
|
1077
1090
|
|
1078
1091
|
def _persist_new_bytes_columns(self, df, debug: bool = False) -> SuccessTuple:
|
@@ -1089,16 +1102,7 @@ def _persist_new_bytes_columns(self, df, debug: bool = False) -> SuccessTuple:
|
|
1089
1102
|
self._attributes_sync_time = None
|
1090
1103
|
dtypes = self.parameters.get('dtypes', {})
|
1091
1104
|
dtypes.update({col: 'bytes' for col in new_bytes_cols})
|
1092
|
-
self.
|
1093
|
-
|
1094
|
-
if not self.temporary:
|
1095
|
-
edit_success, edit_msg = self.edit(interactive=False, debug=debug)
|
1096
|
-
if not edit_success:
|
1097
|
-
warn(f"Unable to update bytes dtypes for {self}:\n{edit_msg}")
|
1098
|
-
|
1099
|
-
return edit_success, edit_msg
|
1100
|
-
|
1101
|
-
return True, "Success"
|
1105
|
+
return self.update_parameters({'dtypes': dtypes}, debug=debug)
|
1102
1106
|
|
1103
1107
|
|
1104
1108
|
def _persist_new_geometry_columns(self, df, debug: bool = False) -> SuccessTuple:
|
@@ -1146,13 +1150,4 @@ def _persist_new_geometry_columns(self, df, debug: bool = False) -> SuccessTuple
|
|
1146
1150
|
new_cols_types[col] = f"{new_dtype}{modifier}"
|
1147
1151
|
|
1148
1152
|
dtypes.update(new_cols_types)
|
1149
|
-
self.
|
1150
|
-
|
1151
|
-
if not self.temporary:
|
1152
|
-
edit_success, edit_msg = self.edit(interactive=False, debug=debug)
|
1153
|
-
if not edit_success:
|
1154
|
-
warn(f"Unable to update bytes dtypes for {self}:\n{edit_msg}")
|
1155
|
-
|
1156
|
-
return edit_success, edit_msg
|
1157
|
-
|
1158
|
-
return True, "Success"
|
1153
|
+
return self.update_parameters({'dtypes': dtypes})
|
meerschaum/core/Pipe/_verify.py
CHANGED
@@ -12,7 +12,7 @@ import time
|
|
12
12
|
import meerschaum as mrsm
|
13
13
|
from meerschaum.utils.typing import SuccessTuple, Any, Optional, Union, Tuple, Dict
|
14
14
|
from meerschaum.utils.warnings import warn, info
|
15
|
-
from meerschaum.
|
15
|
+
from meerschaum._internal.static import STATIC_CONFIG
|
16
16
|
|
17
17
|
|
18
18
|
def verify(
|
@@ -22,19 +22,13 @@ from meerschaum.utils.typing import (
|
|
22
22
|
Union,
|
23
23
|
)
|
24
24
|
from meerschaum.utils.warnings import error, warn
|
25
|
-
from meerschaum.config import get_config
|
26
|
-
from meerschaum.config._paths import (
|
27
|
-
PLUGINS_RESOURCES_PATH,
|
28
|
-
PLUGINS_ARCHIVES_RESOURCES_PATH,
|
29
|
-
PLUGINS_TEMP_RESOURCES_PATH,
|
30
|
-
VIRTENV_RESOURCES_PATH,
|
31
|
-
PLUGINS_DIR_PATHS,
|
32
|
-
)
|
33
25
|
_tmpversion = None
|
34
26
|
_ongoing_installations = set()
|
35
27
|
|
28
|
+
|
36
29
|
class Plugin:
|
37
30
|
"""Handle packaging of Meerschaum plugins."""
|
31
|
+
|
38
32
|
def __init__(
|
39
33
|
self,
|
40
34
|
name: str,
|
@@ -47,7 +41,8 @@ class Plugin:
|
|
47
41
|
repo_connector: Optional['mrsm.connectors.api.APIConnector'] = None,
|
48
42
|
repo: Union['mrsm.connectors.api.APIConnector', str, None] = None,
|
49
43
|
):
|
50
|
-
from meerschaum.
|
44
|
+
from meerschaum._internal.static import STATIC_CONFIG
|
45
|
+
from meerschaum.config.paths import PLUGINS_ARCHIVES_RESOURCES_PATH, VIRTENV_RESOURCES_PATH
|
51
46
|
sep = STATIC_CONFIG['plugins']['repo_separator']
|
52
47
|
_repo = None
|
53
48
|
if sep in name:
|
@@ -130,6 +125,8 @@ class Plugin:
|
|
130
125
|
if self.__dict__.get('_module', None) is not None:
|
131
126
|
return self.module.__file__
|
132
127
|
|
128
|
+
from meerschaum.config.paths import PLUGINS_RESOURCES_PATH
|
129
|
+
|
133
130
|
potential_dir = PLUGINS_RESOURCES_PATH / self.name
|
134
131
|
if (
|
135
132
|
potential_dir.exists()
|
@@ -295,6 +292,7 @@ class Plugin:
|
|
295
292
|
from meerschaum.utils.packages import attempt_import, determine_version, reload_meerschaum
|
296
293
|
from meerschaum.utils.venv import init_venv
|
297
294
|
from meerschaum.utils.misc import safely_extract_tar
|
295
|
+
from meerschaum.config.paths import PLUGINS_TEMP_RESOURCES_PATH, PLUGINS_DIR_PATHS
|
298
296
|
old_cwd = os.getcwd()
|
299
297
|
old_version = ''
|
300
298
|
new_version = ''
|
@@ -722,7 +720,7 @@ class Plugin:
|
|
722
720
|
"""
|
723
721
|
from meerschaum.utils.warnings import warn
|
724
722
|
from meerschaum.config import get_config
|
725
|
-
from meerschaum.
|
723
|
+
from meerschaum._internal.static import STATIC_CONFIG
|
726
724
|
from meerschaum.connectors.parse import is_valid_connector_keys
|
727
725
|
plugins = []
|
728
726
|
_deps = self.get_dependencies(debug=debug)
|
@@ -953,7 +951,7 @@ class Plugin:
|
|
953
951
|
"""
|
954
952
|
Include the repo keys with the plugin's name.
|
955
953
|
"""
|
956
|
-
from meerschaum.
|
954
|
+
from meerschaum._internal.static import STATIC_CONFIG
|
957
955
|
sep = STATIC_CONFIG['plugins']['repo_separator']
|
958
956
|
return self.name + sep + str(self.repo_connector)
|
959
957
|
|