meerschaum 2.3.6__py3-none-any.whl → 2.4.0.dev1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. meerschaum/actions/bootstrap.py +36 -10
  2. meerschaum/actions/copy.py +3 -3
  3. meerschaum/actions/start.py +13 -14
  4. meerschaum/api/dash/__init__.py +7 -6
  5. meerschaum/api/dash/callbacks/__init__.py +1 -0
  6. meerschaum/api/dash/callbacks/dashboard.py +7 -5
  7. meerschaum/api/dash/callbacks/pipes.py +42 -0
  8. meerschaum/api/dash/pages/__init__.py +1 -0
  9. meerschaum/api/dash/pages/pipes.py +16 -0
  10. meerschaum/api/dash/pipes.py +79 -47
  11. meerschaum/api/dash/users.py +19 -6
  12. meerschaum/api/routes/_login.py +4 -4
  13. meerschaum/api/routes/_pipes.py +3 -3
  14. meerschaum/config/_default.py +9 -1
  15. meerschaum/config/_version.py +1 -1
  16. meerschaum/config/stack/__init__.py +59 -16
  17. meerschaum/connectors/Connector.py +19 -13
  18. meerschaum/connectors/__init__.py +9 -5
  19. meerschaum/connectors/poll.py +30 -24
  20. meerschaum/connectors/sql/_pipes.py +126 -154
  21. meerschaum/connectors/sql/_plugins.py +45 -43
  22. meerschaum/connectors/sql/_users.py +46 -38
  23. meerschaum/connectors/valkey/ValkeyConnector.py +535 -0
  24. meerschaum/connectors/valkey/__init__.py +8 -0
  25. meerschaum/connectors/valkey/_fetch.py +75 -0
  26. meerschaum/connectors/valkey/_pipes.py +839 -0
  27. meerschaum/connectors/valkey/_plugins.py +265 -0
  28. meerschaum/connectors/valkey/_users.py +305 -0
  29. meerschaum/core/Pipe/__init__.py +3 -0
  30. meerschaum/core/Pipe/_attributes.py +1 -2
  31. meerschaum/core/Pipe/_clear.py +16 -13
  32. meerschaum/core/Pipe/_copy.py +106 -0
  33. meerschaum/core/Pipe/_drop.py +4 -4
  34. meerschaum/core/Pipe/_dtypes.py +14 -14
  35. meerschaum/core/Pipe/_edit.py +15 -14
  36. meerschaum/core/Pipe/_sync.py +134 -51
  37. meerschaum/core/Pipe/_verify.py +11 -11
  38. meerschaum/core/User/_User.py +14 -12
  39. meerschaum/plugins/_Plugin.py +17 -13
  40. meerschaum/utils/_get_pipes.py +14 -20
  41. meerschaum/utils/dataframe.py +288 -101
  42. meerschaum/utils/dtypes/__init__.py +31 -6
  43. meerschaum/utils/dtypes/sql.py +4 -4
  44. meerschaum/utils/misc.py +3 -3
  45. meerschaum/utils/packages/_packages.py +1 -0
  46. {meerschaum-2.3.6.dist-info → meerschaum-2.4.0.dev1.dist-info}/METADATA +3 -1
  47. {meerschaum-2.3.6.dist-info → meerschaum-2.4.0.dev1.dist-info}/RECORD +53 -44
  48. {meerschaum-2.3.6.dist-info → meerschaum-2.4.0.dev1.dist-info}/WHEEL +1 -1
  49. {meerschaum-2.3.6.dist-info → meerschaum-2.4.0.dev1.dist-info}/LICENSE +0 -0
  50. {meerschaum-2.3.6.dist-info → meerschaum-2.4.0.dev1.dist-info}/NOTICE +0 -0
  51. {meerschaum-2.3.6.dist-info → meerschaum-2.4.0.dev1.dist-info}/entry_points.txt +0 -0
  52. {meerschaum-2.3.6.dist-info → meerschaum-2.4.0.dev1.dist-info}/top_level.txt +0 -0
  53. {meerschaum-2.3.6.dist-info → meerschaum-2.4.0.dev1.dist-info}/zip-safe +0 -0
@@ -0,0 +1,265 @@
1
+ #! /usr/bin/env python3
2
+ # vim:fenc=utf-8
3
+
4
+ """
5
+ Define methods for registering plugins.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import json
11
+
12
+ import meerschaum as mrsm
13
+ from meerschaum.utils.typing import Optional, Any, List, SuccessTuple, Dict, Union
14
+
15
+ PLUGINS_TABLE: str = "mrsm_plugins"
16
+ PLUGIN_PREFIX: str = "mrsm_plugin"
17
+
18
+
19
+ def get_plugins_pipe(self) -> mrsm.Pipe:
20
+ """
21
+ Return the pipe to store the plugins.
22
+ """
23
+ return mrsm.Pipe(
24
+ 'mrsm', 'plugins',
25
+ columns=['plugin_name'],
26
+ temporary=True,
27
+ target=PLUGINS_TABLE,
28
+ instance=self,
29
+ )
30
+
31
+
32
+ @classmethod
33
+ def get_plugin_key(cls, plugin_name: str, sub_key: str) -> str:
34
+ """
35
+ Return the key for a plugin's attribute.
36
+ """
37
+ return cls.get_entity_key(PLUGIN_PREFIX, plugin_name, sub_key)
38
+
39
+
40
+ @classmethod
41
+ def get_plugin_keys_vals(
42
+ cls,
43
+ plugin: 'mrsm.core.Plugin',
44
+ mutable_only: bool = False,
45
+ ) -> Dict[str, str]:
46
+ """
47
+ Return a dictionary containing keys and values to set for the plugin.
48
+
49
+ Parameters
50
+ ----------
51
+ plugin: mrsm.core.Plugin
52
+ The plugin for which to generate the keys.
53
+
54
+ mutable_only: bool, default False
55
+ If `True`, only return keys which may be edited.
56
+
57
+ Returns
58
+ -------
59
+ A dictionary mapping a plugins's keys to values.
60
+ """
61
+ plugin_attributes_str = json.dumps(plugin.attributes, separators=(',', ':'))
62
+ mutable_keys_vals = {
63
+ cls.get_plugin_key(plugin.name, 'attributes'): plugin_attributes_str,
64
+ cls.get_plugin_key(plugin.name, 'version'): plugin.version,
65
+ }
66
+ if mutable_only:
67
+ return mutable_keys_vals
68
+
69
+ immutable_keys_vals = {
70
+ cls.get_plugin_key(plugin.name, 'user_id'): plugin.user_id,
71
+ }
72
+
73
+ return {**immutable_keys_vals, **mutable_keys_vals}
74
+
75
+
76
+ def register_plugin(
77
+ self,
78
+ plugin: 'mrsm.core.Plugin',
79
+ force: bool = False,
80
+ debug: bool = False,
81
+ **kw: Any
82
+ ) -> SuccessTuple:
83
+ """Register a new plugin to the `mrsm_plugins` "table"."""
84
+ from meerschaum.utils.misc import generate_password
85
+
86
+ plugins_pipe = self.get_plugins_pipe()
87
+ keys_vals = self.get_plugin_keys_vals(plugin)
88
+
89
+ try:
90
+ sync_success, sync_msg = plugins_pipe.sync(
91
+ [
92
+ {
93
+ 'plugin_name': plugin.name,
94
+ 'user_id': plugin.user_id,
95
+ },
96
+ ],
97
+ check_existing=False,
98
+ debug=debug,
99
+ )
100
+ if not sync_success:
101
+ return sync_success, sync_msg
102
+
103
+ for key, val in keys_vals.items():
104
+ if val is not None:
105
+ self.set(key, val)
106
+
107
+ success, msg = True, "Success"
108
+ except Exception as e:
109
+ success = False
110
+ msg = f"Failed to register plugin '{plugin.name}':\n{e}"
111
+
112
+ if not success:
113
+ for key in keys_vals:
114
+ try:
115
+ self.client.delete(key)
116
+ except Exception:
117
+ pass
118
+
119
+ return success, msg
120
+
121
+
122
+ def get_plugin_id(
123
+ self,
124
+ plugin: 'mrsm.core.Plugin',
125
+ debug: bool = False
126
+ ) -> Union[str, None]:
127
+ """
128
+ Return a plugin's ID.
129
+ """
130
+ return plugin.name
131
+
132
+
133
+ def get_plugin_version(
134
+ self,
135
+ plugin: 'mrsm.core.Plugin',
136
+ debug: bool = False,
137
+ ) -> Union[str, None]:
138
+ """
139
+ Return a plugin's version.
140
+ """
141
+ version_key = self.get_plugin_key(plugin.name, 'version')
142
+
143
+ try:
144
+ return self.get(version_key)
145
+ except Exception:
146
+ return None
147
+
148
+
149
+ def get_plugin_user_id(
150
+ self,
151
+ plugin: 'mrsm.core.Plugin',
152
+ debug: bool = False
153
+ ) -> Union[str, None]:
154
+ """
155
+ Return a plugin's user ID.
156
+ """
157
+ user_id_key = self.get_plugin_key(plugin.name, 'user_id')
158
+
159
+ try:
160
+ return self.get(user_id_key)
161
+ except Exception:
162
+ return None
163
+
164
+
165
+ def get_plugin_username(
166
+ self,
167
+ plugin: 'mrsm.core.Plugin',
168
+ debug: bool = False
169
+ ) -> Union[str]:
170
+ """
171
+ Return the username of a plugin's owner.
172
+ """
173
+ user_id = self.get_plugin_user_id(plugin, debug=debug)
174
+ if user_id is None:
175
+ return None
176
+
177
+ username_key = self.get_user_key(user_id, 'username')
178
+ try:
179
+ return self.get(username_key)
180
+ except Exception:
181
+ return None
182
+
183
+
184
+ def get_plugin_attributes(
185
+ self,
186
+ plugin: 'mrsm.core.Plugin',
187
+ debug: bool = False
188
+ ) -> Dict[str, Any]:
189
+ """
190
+ Return the attributes of a plugin.
191
+ """
192
+ attributes_key = self.get_plugin_key(plugin.name, 'attributes')
193
+ try:
194
+ attributes_str = self.get(attributes_key)
195
+ if not attributes_str:
196
+ return {}
197
+ return json.loads(attributes_str)
198
+ except Exception:
199
+ return {}
200
+
201
+
202
+ def get_plugins(
203
+ self,
204
+ user_id: Optional[int] = None,
205
+ search_term: Optional[str] = None,
206
+ debug: bool = False,
207
+ **kw: Any
208
+ ) -> List[str]:
209
+ """
210
+ Return a list of plugin names.
211
+ """
212
+ plugins_pipe = self.get_plugins_pipe()
213
+ params = {}
214
+ if user_id:
215
+ params['user_id'] = user_id
216
+
217
+ df = plugins_pipe.get_data(['plugin_name'], params=params, debug=debug)
218
+ docs = df.to_dict(orient='records')
219
+
220
+ return [
221
+ doc['plugin_name']
222
+ for doc in docs
223
+ if (plugin_name := doc['plugin_name']).startswith(search_term or '')
224
+ ]
225
+
226
+
227
+ def delete_plugin(
228
+ self,
229
+ plugin: 'mrsm.core.Plugin',
230
+ debug: bool = False,
231
+ **kw: Any
232
+ ) -> SuccessTuple:
233
+ """
234
+ Delete a plugin from the plugins table.
235
+ """
236
+ plugins_pipe = self.get_plugins_pipe()
237
+ clear_success, clear_msg = plugins_pipe.clear(params={'plugin_name': plugin.name}, debug=debug)
238
+ if not clear_success:
239
+ return clear_success, clear_msg
240
+
241
+ keys_vals = self.get_plugin_keys_vals(plugin)
242
+ try:
243
+ old_keys_vals = {
244
+ key: self.get(key)
245
+ for key in keys_vals
246
+ }
247
+ except Exception as e:
248
+ return False, f"Failed to delete plugin '{plugin.name}':\n{e}"
249
+
250
+ try:
251
+ for key in keys_vals:
252
+ self.client.delete(key)
253
+ success, msg = True, "Success"
254
+ except Exception as e:
255
+ success = False
256
+ msg = f"Failed to delete plugin '{plugin.name}':\n{e}"
257
+
258
+ if not success:
259
+ try:
260
+ for key, old_val in old_keys_vals.items():
261
+ self.set(key, old_val)
262
+ except Exception:
263
+ pass
264
+
265
+ return success, msg
@@ -0,0 +1,305 @@
1
+ #! /usr/bin/env python3
2
+ # vim:fenc=utf-8
3
+
4
+ """
5
+ Define methods for managing users.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import json
11
+
12
+ import meerschaum as mrsm
13
+ from meerschaum.utils.typing import Any, Union, SuccessTuple, Dict, List
14
+
15
+ USERS_TABLE: str = 'mrsm_users'
16
+ USER_PREFIX: str = 'mrsm_user'
17
+
18
+
19
+ def get_users_pipe(self):
20
+ """
21
+ Return the pipe which stores the registered users.
22
+ """
23
+ return mrsm.Pipe(
24
+ 'mrsm', 'users',
25
+ columns=['user_id'],
26
+ temporary=True,
27
+ target=USERS_TABLE,
28
+ instance=self,
29
+ )
30
+
31
+
32
+ @classmethod
33
+ def get_user_key(cls, user_id_or_username: str, sub_key: str, by_username: bool = False) -> str:
34
+ """
35
+ Return the key to store metadata about a user.
36
+
37
+ Parameters
38
+ ----------
39
+ user_id_or_username: str
40
+ The user ID or username of the given user.
41
+ If `by_username` is `True`, then provide the username.
42
+
43
+ sub_key: str
44
+ The key suffix, e.g. `'attributes'`.
45
+
46
+ by_username: bool, default False
47
+ If `True`, then treat `user_id_or_username` as a username.
48
+
49
+ Returns
50
+ -------
51
+ A key to store information about a user.
52
+
53
+ Examples
54
+ --------
55
+ >>> get_user_key('deadbeef', 'attributes')
56
+ 'mrsm_user:user_id:deadbeef:attributes'
57
+ >>> get_user_key('foo', 'user_id', by_username=True)
58
+ 'mrsm_user:username:foo:user_id'
59
+ """
60
+ key_type = 'user_id' if not by_username else 'username'
61
+ return cls.get_entity_key(USER_PREFIX, key_type, user_id_or_username, sub_key)
62
+
63
+
64
+ @classmethod
65
+ def get_user_keys_vals(
66
+ cls,
67
+ user: 'mrsm.core.User',
68
+ mutable_only: bool = False,
69
+ ) -> Dict[str, str]:
70
+ """
71
+ Return a dictionary containing keys and values to set for the user.
72
+
73
+ Parameters
74
+ ----------
75
+ user: mrsm.core.User
76
+ The user for which to generate the keys.
77
+
78
+ mutable_only: bool, default False
79
+ If `True`, only return keys which may be edited.
80
+
81
+ Returns
82
+ -------
83
+ A dictionary mapping a user's keys to values.
84
+ """
85
+ user_attributes_str = json.dumps(user.attributes, separators=(',', ':'))
86
+ mutable_keys_vals = {
87
+ cls.get_user_key(user.user_id, 'attributes'): user_attributes_str,
88
+ cls.get_user_key(user.user_id, 'email'): user.email,
89
+ cls.get_user_key(user.user_id, 'type'): user.type,
90
+ cls.get_user_key(user.user_id, 'password_hash'): user.password_hash,
91
+ }
92
+ if mutable_only:
93
+ return mutable_keys_vals
94
+
95
+ immutable_keys_vals = {
96
+ cls.get_user_key(user.user_id, 'username'): user.username,
97
+ cls.get_user_key(user.username, 'user_id', by_username=True): user.user_id,
98
+ }
99
+
100
+ return {**immutable_keys_vals, **mutable_keys_vals}
101
+
102
+
103
+ def register_user(
104
+ self,
105
+ user: 'mrsm.core.User',
106
+ debug: bool = False,
107
+ **kwargs: Any
108
+ ) -> SuccessTuple:
109
+ """
110
+ Register a new user.
111
+ """
112
+ from meerschaum.utils.misc import generate_password
113
+
114
+ user.user_id = generate_password(12)
115
+ users_pipe = self.get_users_pipe()
116
+ keys_vals = self.get_user_keys_vals(user)
117
+
118
+ try:
119
+ sync_success, sync_msg = users_pipe.sync(
120
+ [
121
+ {
122
+ 'user_id': user.user_id,
123
+ 'username': user.username,
124
+ },
125
+ ],
126
+ check_existing=False,
127
+ debug=debug,
128
+ )
129
+ if not sync_success:
130
+ return sync_success, sync_msg
131
+
132
+ for key, val in keys_vals.items():
133
+ if val is not None:
134
+ self.set(key, val)
135
+
136
+ success, msg = True, "Success"
137
+ except Exception as e:
138
+ success = False
139
+ import traceback
140
+ traceback.print_exc()
141
+ msg = f"Failed to register '{user.username}':\n{e}"
142
+
143
+ if not success:
144
+ for key in keys_vals:
145
+ try:
146
+ self.client.delete(key)
147
+ except Exception:
148
+ pass
149
+
150
+ return success, msg
151
+
152
+
153
+ def get_user_id(self, user: 'mrsm.core.User', debug: bool = False) -> Union[str, None]:
154
+ """
155
+ Return the ID for a user, or `None`.
156
+ """
157
+ username_user_id_key = self.get_user_key(user.username, 'user_id', by_username=True)
158
+ try:
159
+ user_id = self.get(username_user_id_key)
160
+ except Exception:
161
+ user_id = None
162
+ return user_id
163
+
164
+
165
+ def edit_user(
166
+ self,
167
+ user: 'mrsm.core.User',
168
+ debug: bool = False,
169
+ **kw: Any
170
+ ) -> SuccessTuple:
171
+ """
172
+ Edit the attributes for an existing user.
173
+ """
174
+ keys_vals = self.get_user_keys_vals(user, mutable_only=True)
175
+ try:
176
+ old_keys_vals = {
177
+ key: self.get(key)
178
+ for key in keys_vals
179
+ }
180
+ except Exception as e:
181
+ return False, f"Failed to edit user:\n{e}"
182
+
183
+ try:
184
+ for key, val in keys_vals.items():
185
+ self.set(key, val)
186
+ success, msg = True, "Success"
187
+ except Exception as e:
188
+ success = False
189
+ msg = f"Failed to edit user:\n{e}"
190
+
191
+ if not success:
192
+ try:
193
+ for key, old_val in old_keys_vals.items():
194
+ self.set(key, old_val)
195
+ except Exception:
196
+ pass
197
+
198
+ return success, msg
199
+
200
+
201
+ def get_user_attributes(
202
+ self,
203
+ user: 'mrsm.core.User',
204
+ debug: bool = False
205
+ ) -> Union[Dict[str, Any], None]:
206
+ """
207
+ Return the user's attributes.
208
+ """
209
+ user_id = user.user_id if user.user_id is not None else self.get_user_id(user, debug=debug)
210
+ user_id_attributes_key = self.get_user_key(user_id, 'attributes')
211
+ try:
212
+ return json.loads(self.get(user_id_attributes_key))
213
+ except Exception:
214
+ return None
215
+
216
+
217
+ def delete_user(
218
+ self,
219
+ user: 'mrsm.core.User',
220
+ debug: bool = False
221
+ ) -> SuccessTuple:
222
+ """
223
+ Delete a user's keys.
224
+ """
225
+ user_id = user.user_id if user.user_id is not None else self.get_user_id(user, debug=debug)
226
+ users_pipe = self.get_users_pipe()
227
+ keys_vals = self.get_user_keys_vals(user)
228
+ try:
229
+ old_keys_vals = {
230
+ key: self.get(key)
231
+ for key in keys_vals
232
+ }
233
+ except Exception as e:
234
+ return False, f"Failed to delete user:\n{e}"
235
+
236
+ clear_success, clear_msg = users_pipe.clear(params={'user_id': user_id})
237
+ if not clear_success:
238
+ return clear_success, clear_msg
239
+
240
+ try:
241
+ for key in keys_vals:
242
+ self.client.delete(key)
243
+ success, msg = True, "Success"
244
+ except Exception as e:
245
+ success = False
246
+ msg = f"Failed to delete user:\n{e}"
247
+
248
+ if not success:
249
+ try:
250
+ for key, old_val in old_keys_vals.items():
251
+ self.set(key, old_val)
252
+ except Exception:
253
+ pass
254
+
255
+ return success, msg
256
+
257
+
258
+ def get_users(
259
+ self,
260
+ debug: bool = False,
261
+ **kw: Any
262
+ ) -> List[str]:
263
+ """
264
+ Get the registered usernames.
265
+ """
266
+ users_pipe = self.get_users_pipe()
267
+ df = users_pipe.get_data()
268
+ if df is None:
269
+ return []
270
+
271
+ return list(df['username'])
272
+
273
+
274
+ def get_user_password_hash(
275
+ self,
276
+ user: 'mrsm.core.User',
277
+ debug: bool = False,
278
+ **kw: Any
279
+ ) -> Union[str, None]:
280
+ """
281
+ Return the password has for a user.
282
+ """
283
+ user_id = user.user_id if user.user_id is not None else self.get_user_id(user, debug=debug)
284
+ user_id_password_hash_key = self.get_user_key(user_id, 'password_hash')
285
+ try:
286
+ return self.get(user_id_password_hash_key)
287
+ except Exception:
288
+ return None
289
+
290
+
291
+ def get_user_type(
292
+ self,
293
+ user: 'mrsm.core.User',
294
+ debug: bool = False,
295
+ **kw: Any
296
+ ) -> Union[str, None]:
297
+ """
298
+ Return the user's type.
299
+ """
300
+ user_id = user.user_id if user.user_id is not None else self.get_user_id(user, debug=debug)
301
+ user_id_type_key = self.get_user_key(user_id, 'type')
302
+ try:
303
+ return self.get(user_id_type_key)
304
+ except Exception:
305
+ return None
@@ -121,6 +121,8 @@ class Pipe:
121
121
  filter_existing,
122
122
  _get_chunk_label,
123
123
  get_num_workers,
124
+ _persist_new_json_columns,
125
+ _persist_new_numeric_columns,
124
126
  )
125
127
  from ._verify import (
126
128
  verify,
@@ -133,6 +135,7 @@ class Pipe:
133
135
  from ._deduplicate import deduplicate
134
136
  from ._bootstrap import bootstrap
135
137
  from ._dtypes import enforce_dtypes, infer_dtypes
138
+ from ._copy import copy_to
136
139
 
137
140
  def __init__(
138
141
  self,
@@ -122,8 +122,7 @@ def dtypes(self) -> Union[Dict[str, Any], None]:
122
122
  configured_dtypes = self.parameters.get('dtypes', {})
123
123
  remote_dtypes = self.infer_dtypes(persist=False)
124
124
  patched_dtypes = apply_patch_to_config(remote_dtypes, configured_dtypes)
125
- self.parameters['dtypes'] = patched_dtypes
126
- return self.parameters['dtypes']
125
+ return patched_dtypes
127
126
 
128
127
 
129
128
  @dtypes.setter
@@ -7,25 +7,28 @@ Clear pipe data within a bounded or unbounded interval.
7
7
  """
8
8
 
9
9
  from __future__ import annotations
10
+
11
+ from datetime import datetime
10
12
  from meerschaum.utils.typing import SuccessTuple, Any, Optional, Dict
11
13
 
14
+
12
15
  def clear(
13
- self,
14
- begin: Optional[datetime.datetime] = None,
15
- end: Optional[datetime.datetime] = None,
16
- params: Optional[Dict[str, Any]] = None,
17
- debug: bool = False,
18
- **kwargs: Any
19
- ) -> SuccessTuple:
16
+ self,
17
+ begin: Optional[datetime] = None,
18
+ end: Optional[datetime] = None,
19
+ params: Optional[Dict[str, Any]] = None,
20
+ debug: bool = False,
21
+ **kwargs: Any
22
+ ) -> SuccessTuple:
20
23
  """
21
24
  Call the Pipe's instance connector's `clear_pipe` method.
22
25
 
23
26
  Parameters
24
27
  ----------
25
- begin: Optional[datetime.datetime], default None:
28
+ begin: Optional[datetime], default None:
26
29
  If provided, only remove rows newer than this datetime value.
27
30
 
28
- end: Optional[datetime.datetime], default None:
31
+ end: Optional[datetime], default None:
29
32
  If provided, only remove rows older than this datetime column (not including end).
30
33
 
31
34
  params: Optional[Dict[str, Any]], default None
@@ -41,11 +44,11 @@ def clear(
41
44
  Examples
42
45
  --------
43
46
  >>> pipe = mrsm.Pipe('test', 'test', columns={'datetime': 'dt'}, instance='sql:local')
44
- >>> pipe.sync({'dt': [datetime.datetime(2020, 1, 1, 0, 0)]})
45
- >>> pipe.sync({'dt': [datetime.datetime(2021, 1, 1, 0, 0)]})
46
- >>> pipe.sync({'dt': [datetime.datetime(2022, 1, 1, 0, 0)]})
47
+ >>> pipe.sync({'dt': [datetime(2020, 1, 1, 0, 0)]})
48
+ >>> pipe.sync({'dt': [datetime(2021, 1, 1, 0, 0)]})
49
+ >>> pipe.sync({'dt': [datetime(2022, 1, 1, 0, 0)]})
47
50
  >>>
48
- >>> pipe.clear(begin=datetime.datetime(2021, 1, 1, 0, 0))
51
+ >>> pipe.clear(begin=datetime(2021, 1, 1, 0, 0))
49
52
  >>> pipe.get_data()
50
53
  dt
51
54
  0 2020-01-01