meerschaum 2.9.4__py3-none-any.whl → 3.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (201) hide show
  1. meerschaum/__init__.py +5 -2
  2. meerschaum/_internal/__init__.py +1 -0
  3. meerschaum/_internal/arguments/_parse_arguments.py +4 -4
  4. meerschaum/_internal/arguments/_parser.py +33 -4
  5. meerschaum/_internal/cli/__init__.py +6 -0
  6. meerschaum/_internal/cli/daemons.py +103 -0
  7. meerschaum/_internal/cli/entry.py +220 -0
  8. meerschaum/_internal/cli/workers.py +435 -0
  9. meerschaum/_internal/docs/index.py +48 -2
  10. meerschaum/_internal/entry.py +50 -14
  11. meerschaum/_internal/shell/Shell.py +121 -29
  12. meerschaum/_internal/shell/__init__.py +4 -1
  13. meerschaum/_internal/static.py +359 -0
  14. meerschaum/_internal/term/TermPageHandler.py +1 -2
  15. meerschaum/_internal/term/__init__.py +40 -6
  16. meerschaum/_internal/term/tools.py +33 -8
  17. meerschaum/actions/__init__.py +6 -4
  18. meerschaum/actions/api.py +53 -13
  19. meerschaum/actions/attach.py +1 -0
  20. meerschaum/actions/bootstrap.py +8 -8
  21. meerschaum/actions/delete.py +4 -2
  22. meerschaum/actions/edit.py +171 -25
  23. meerschaum/actions/login.py +8 -8
  24. meerschaum/actions/register.py +143 -6
  25. meerschaum/actions/reload.py +22 -5
  26. meerschaum/actions/restart.py +14 -0
  27. meerschaum/actions/show.py +184 -31
  28. meerschaum/actions/start.py +166 -17
  29. meerschaum/actions/stop.py +38 -2
  30. meerschaum/actions/sync.py +7 -2
  31. meerschaum/actions/tag.py +9 -8
  32. meerschaum/actions/verify.py +5 -8
  33. meerschaum/api/__init__.py +45 -15
  34. meerschaum/api/_events.py +46 -4
  35. meerschaum/api/_oauth2.py +162 -9
  36. meerschaum/api/_tokens.py +102 -0
  37. meerschaum/api/dash/__init__.py +0 -3
  38. meerschaum/api/dash/callbacks/__init__.py +1 -0
  39. meerschaum/api/dash/callbacks/custom.py +4 -3
  40. meerschaum/api/dash/callbacks/dashboard.py +228 -117
  41. meerschaum/api/dash/callbacks/jobs.py +14 -7
  42. meerschaum/api/dash/callbacks/login.py +10 -1
  43. meerschaum/api/dash/callbacks/pipes.py +194 -14
  44. meerschaum/api/dash/callbacks/plugins.py +0 -1
  45. meerschaum/api/dash/callbacks/register.py +10 -3
  46. meerschaum/api/dash/callbacks/settings/password_reset.py +2 -2
  47. meerschaum/api/dash/callbacks/tokens.py +389 -0
  48. meerschaum/api/dash/components.py +36 -15
  49. meerschaum/api/dash/jobs.py +1 -1
  50. meerschaum/api/dash/keys.py +35 -93
  51. meerschaum/api/dash/pages/__init__.py +2 -1
  52. meerschaum/api/dash/pages/dashboard.py +1 -20
  53. meerschaum/api/dash/pages/{job.py → jobs.py} +10 -7
  54. meerschaum/api/dash/pages/login.py +2 -2
  55. meerschaum/api/dash/pages/pipes.py +16 -5
  56. meerschaum/api/dash/pages/settings/password_reset.py +1 -1
  57. meerschaum/api/dash/pages/tokens.py +53 -0
  58. meerschaum/api/dash/pipes.py +438 -88
  59. meerschaum/api/dash/sessions.py +12 -0
  60. meerschaum/api/dash/tokens.py +603 -0
  61. meerschaum/api/dash/websockets.py +1 -1
  62. meerschaum/api/dash/webterm.py +18 -6
  63. meerschaum/api/models/__init__.py +23 -3
  64. meerschaum/api/models/_actions.py +22 -0
  65. meerschaum/api/models/_pipes.py +91 -7
  66. meerschaum/api/models/_tokens.py +81 -0
  67. meerschaum/api/resources/static/css/dash.css +16 -0
  68. meerschaum/api/resources/static/js/terminado.js +3 -0
  69. meerschaum/api/resources/static/js/xterm-addon-unicode11.js +2 -0
  70. meerschaum/api/resources/templates/termpage.html +13 -0
  71. meerschaum/api/routes/__init__.py +1 -0
  72. meerschaum/api/routes/_actions.py +3 -4
  73. meerschaum/api/routes/_connectors.py +3 -7
  74. meerschaum/api/routes/_jobs.py +26 -35
  75. meerschaum/api/routes/_login.py +120 -15
  76. meerschaum/api/routes/_misc.py +5 -10
  77. meerschaum/api/routes/_pipes.py +178 -143
  78. meerschaum/api/routes/_plugins.py +38 -28
  79. meerschaum/api/routes/_tokens.py +236 -0
  80. meerschaum/api/routes/_users.py +47 -35
  81. meerschaum/api/routes/_version.py +3 -3
  82. meerschaum/api/routes/_webterm.py +3 -3
  83. meerschaum/config/__init__.py +100 -30
  84. meerschaum/config/_default.py +132 -64
  85. meerschaum/config/_edit.py +38 -32
  86. meerschaum/config/_formatting.py +2 -0
  87. meerschaum/config/_patch.py +10 -8
  88. meerschaum/config/_paths.py +133 -13
  89. meerschaum/config/_read_config.py +87 -36
  90. meerschaum/config/_sync.py +6 -3
  91. meerschaum/config/_version.py +1 -1
  92. meerschaum/config/environment.py +262 -0
  93. meerschaum/config/stack/__init__.py +37 -15
  94. meerschaum/config/static.py +18 -0
  95. meerschaum/connectors/_Connector.py +11 -6
  96. meerschaum/connectors/__init__.py +41 -22
  97. meerschaum/connectors/api/_APIConnector.py +34 -6
  98. meerschaum/connectors/api/_actions.py +2 -2
  99. meerschaum/connectors/api/_jobs.py +12 -1
  100. meerschaum/connectors/api/_login.py +33 -7
  101. meerschaum/connectors/api/_misc.py +2 -2
  102. meerschaum/connectors/api/_pipes.py +23 -32
  103. meerschaum/connectors/api/_plugins.py +2 -2
  104. meerschaum/connectors/api/_request.py +1 -1
  105. meerschaum/connectors/api/_tokens.py +146 -0
  106. meerschaum/connectors/api/_users.py +70 -58
  107. meerschaum/connectors/instance/_InstanceConnector.py +83 -0
  108. meerschaum/connectors/instance/__init__.py +10 -0
  109. meerschaum/connectors/instance/_pipes.py +442 -0
  110. meerschaum/connectors/instance/_plugins.py +159 -0
  111. meerschaum/connectors/instance/_tokens.py +317 -0
  112. meerschaum/connectors/instance/_users.py +188 -0
  113. meerschaum/connectors/parse.py +5 -2
  114. meerschaum/connectors/sql/_SQLConnector.py +22 -5
  115. meerschaum/connectors/sql/_cli.py +12 -11
  116. meerschaum/connectors/sql/_create_engine.py +12 -168
  117. meerschaum/connectors/sql/_fetch.py +2 -18
  118. meerschaum/connectors/sql/_pipes.py +295 -278
  119. meerschaum/connectors/sql/_plugins.py +29 -0
  120. meerschaum/connectors/sql/_sql.py +47 -22
  121. meerschaum/connectors/sql/_users.py +36 -2
  122. meerschaum/connectors/sql/tables/__init__.py +254 -122
  123. meerschaum/connectors/valkey/_ValkeyConnector.py +5 -7
  124. meerschaum/connectors/valkey/_pipes.py +60 -31
  125. meerschaum/connectors/valkey/_plugins.py +2 -26
  126. meerschaum/core/Pipe/__init__.py +115 -85
  127. meerschaum/core/Pipe/_attributes.py +425 -124
  128. meerschaum/core/Pipe/_bootstrap.py +54 -24
  129. meerschaum/core/Pipe/_cache.py +555 -0
  130. meerschaum/core/Pipe/_clear.py +0 -11
  131. meerschaum/core/Pipe/_data.py +96 -68
  132. meerschaum/core/Pipe/_deduplicate.py +0 -13
  133. meerschaum/core/Pipe/_delete.py +12 -21
  134. meerschaum/core/Pipe/_drop.py +11 -23
  135. meerschaum/core/Pipe/_dtypes.py +49 -19
  136. meerschaum/core/Pipe/_edit.py +14 -4
  137. meerschaum/core/Pipe/_fetch.py +1 -1
  138. meerschaum/core/Pipe/_index.py +8 -14
  139. meerschaum/core/Pipe/_show.py +5 -5
  140. meerschaum/core/Pipe/_sync.py +123 -204
  141. meerschaum/core/Pipe/_verify.py +4 -4
  142. meerschaum/{plugins → core/Plugin}/_Plugin.py +16 -12
  143. meerschaum/core/Plugin/__init__.py +1 -1
  144. meerschaum/core/Token/_Token.py +220 -0
  145. meerschaum/core/Token/__init__.py +12 -0
  146. meerschaum/core/User/_User.py +35 -10
  147. meerschaum/core/User/__init__.py +9 -1
  148. meerschaum/core/__init__.py +1 -0
  149. meerschaum/jobs/_Executor.py +88 -4
  150. meerschaum/jobs/_Job.py +149 -38
  151. meerschaum/jobs/__init__.py +3 -2
  152. meerschaum/jobs/systemd.py +8 -3
  153. meerschaum/models/__init__.py +35 -0
  154. meerschaum/models/pipes.py +247 -0
  155. meerschaum/models/tokens.py +38 -0
  156. meerschaum/models/users.py +26 -0
  157. meerschaum/plugins/__init__.py +301 -88
  158. meerschaum/plugins/bootstrap.py +510 -4
  159. meerschaum/utils/_get_pipes.py +97 -30
  160. meerschaum/utils/daemon/Daemon.py +199 -43
  161. meerschaum/utils/daemon/FileDescriptorInterceptor.py +0 -1
  162. meerschaum/utils/daemon/RotatingFile.py +63 -36
  163. meerschaum/utils/daemon/StdinFile.py +53 -13
  164. meerschaum/utils/daemon/__init__.py +47 -6
  165. meerschaum/utils/daemon/_names.py +6 -3
  166. meerschaum/utils/dataframe.py +480 -82
  167. meerschaum/utils/debug.py +49 -19
  168. meerschaum/utils/dtypes/__init__.py +478 -37
  169. meerschaum/utils/dtypes/sql.py +369 -29
  170. meerschaum/utils/formatting/__init__.py +5 -2
  171. meerschaum/utils/formatting/_jobs.py +1 -1
  172. meerschaum/utils/formatting/_pipes.py +52 -50
  173. meerschaum/utils/formatting/_pprint.py +1 -0
  174. meerschaum/utils/formatting/_shell.py +44 -18
  175. meerschaum/utils/misc.py +268 -186
  176. meerschaum/utils/packages/__init__.py +25 -40
  177. meerschaum/utils/packages/_packages.py +42 -34
  178. meerschaum/utils/pipes.py +213 -0
  179. meerschaum/utils/process.py +2 -2
  180. meerschaum/utils/prompt.py +175 -144
  181. meerschaum/utils/schedule.py +2 -1
  182. meerschaum/utils/sql.py +135 -49
  183. meerschaum/utils/threading.py +42 -0
  184. meerschaum/utils/typing.py +1 -4
  185. meerschaum/utils/venv/_Venv.py +2 -2
  186. meerschaum/utils/venv/__init__.py +7 -7
  187. meerschaum/utils/warnings.py +19 -13
  188. {meerschaum-2.9.4.dist-info → meerschaum-3.0.0.dist-info}/METADATA +94 -96
  189. meerschaum-3.0.0.dist-info/RECORD +289 -0
  190. {meerschaum-2.9.4.dist-info → meerschaum-3.0.0.dist-info}/WHEEL +1 -1
  191. meerschaum-3.0.0.dist-info/licenses/NOTICE +2 -0
  192. meerschaum/api/models/_interfaces.py +0 -15
  193. meerschaum/api/models/_locations.py +0 -15
  194. meerschaum/api/models/_metrics.py +0 -15
  195. meerschaum/config/_environment.py +0 -145
  196. meerschaum/config/static/__init__.py +0 -186
  197. meerschaum-2.9.4.dist-info/RECORD +0 -263
  198. {meerschaum-2.9.4.dist-info → meerschaum-3.0.0.dist-info}/entry_points.txt +0 -0
  199. {meerschaum-2.9.4.dist-info → meerschaum-3.0.0.dist-info}/licenses/LICENSE +0 -0
  200. {meerschaum-2.9.4.dist-info → meerschaum-3.0.0.dist-info}/top_level.txt +0 -0
  201. {meerschaum-2.9.4.dist-info → meerschaum-3.0.0.dist-info}/zip-safe +0 -0
@@ -7,171 +7,23 @@ This module contains the logic that builds the sqlalchemy engine string.
7
7
  """
8
8
 
9
9
  import traceback
10
+
10
11
  import meerschaum as mrsm
11
12
  from meerschaum.utils.debug import dprint
13
+ from meerschaum._internal.static import STATIC_CONFIG
12
14
 
13
- ### determine driver and requirements from flavor
14
- default_requirements = {
15
- 'username',
16
- 'password',
17
- 'host',
18
- 'database',
19
- }
20
15
 
21
16
  ### NOTE: These are defined in the `system.json` config file and so this dictionary's values
22
17
  ### will all be overwritten if applicable.
23
- default_create_engine_args = {
24
- # 'method': 'multi',
25
- 'pool_size': 5,
26
- 'max_overflow': 10,
27
- 'pool_recycle': 3600,
28
- 'connect_args': {},
29
- }
30
- flavor_configs = {
31
- 'timescaledb': {
32
- 'engine': 'postgresql+psycopg',
33
- 'create_engine': default_create_engine_args,
34
- 'omit_create_engine': {'method',},
35
- 'to_sql': {},
36
- 'requirements': default_requirements,
37
- 'defaults': {
38
- 'port': 5432,
39
- },
40
- },
41
- 'postgresql': {
42
- 'engine': 'postgresql+psycopg',
43
- 'create_engine': default_create_engine_args,
44
- 'omit_create_engine': {'method',},
45
- 'to_sql': {},
46
- 'requirements': default_requirements,
47
- 'defaults': {
48
- 'port': 5432,
49
- },
50
- },
51
- 'postgis': {
52
- 'engine': 'postgresql+psycopg',
53
- 'create_engine': default_create_engine_args,
54
- 'omit_create_engine': {'method',},
55
- 'to_sql': {},
56
- 'requirements': default_requirements,
57
- 'defaults': {
58
- 'port': 5432,
59
- },
60
- },
61
- 'citus': {
62
- 'engine': 'postgresql+psycopg',
63
- 'create_engine': default_create_engine_args,
64
- 'omit_create_engine': {'method',},
65
- 'to_sql': {},
66
- 'requirements': default_requirements,
67
- 'defaults': {
68
- 'port': 5432,
69
- },
70
- },
71
- 'mssql': {
72
- 'engine': 'mssql+pyodbc',
73
- 'create_engine': {
74
- 'fast_executemany': True,
75
- 'use_insertmanyvalues': False,
76
- 'isolation_level': 'AUTOCOMMIT',
77
- 'use_setinputsizes': False,
78
- 'pool_pre_ping': True,
79
- 'ignore_no_transaction_on_rollback': True,
80
- },
81
- 'omit_create_engine': {'method',},
82
- 'to_sql': {
83
- 'method': None,
84
- },
85
- 'requirements': default_requirements,
86
- 'defaults': {
87
- 'port': 1433,
88
- 'options': (
89
- "driver=ODBC Driver 18 for SQL Server"
90
- "&UseFMTONLY=Yes"
91
- "&TrustServerCertificate=yes"
92
- "&Encrypt=no"
93
- "&MARS_Connection=yes"
94
- ),
95
- },
96
- },
97
- 'mysql': {
98
- 'engine': 'mysql+pymysql',
99
- 'create_engine': default_create_engine_args,
100
- 'omit_create_engine': {'method',},
101
- 'to_sql': {
102
- 'method': 'multi',
103
- },
104
- 'requirements': default_requirements,
105
- 'defaults': {
106
- 'port': 3306,
107
- },
108
- },
109
- 'mariadb': {
110
- 'engine': 'mysql+pymysql',
111
- 'create_engine': default_create_engine_args,
112
- 'omit_create_engine': {'method',},
113
- 'to_sql': {
114
- 'method': 'multi',
115
- },
116
- 'requirements': default_requirements,
117
- 'defaults': {
118
- 'port': 3306,
119
- },
120
- },
121
- 'oracle': {
122
- 'engine': 'oracle+oracledb',
123
- 'create_engine': default_create_engine_args,
124
- 'omit_create_engine': {'method',},
125
- 'to_sql': {
126
- 'method': None,
127
- },
128
- 'requirements': default_requirements,
129
- 'defaults': {
130
- 'port': 1521,
131
- },
132
- },
133
- 'sqlite': {
134
- 'engine': 'sqlite',
135
- 'create_engine': default_create_engine_args,
136
- 'omit_create_engine': {'method',},
137
- 'to_sql': {
138
- 'method': 'multi',
139
- },
140
- 'requirements': {'database'},
141
- 'defaults': {},
142
- },
143
- 'duckdb': {
144
- 'engine': 'duckdb',
145
- 'create_engine': {},
146
- 'omit_create_engine': {'ALL',},
147
- 'to_sql': {
148
- 'method': 'multi',
149
- },
150
- 'requirements': '',
151
- 'defaults': {},
152
- },
153
- 'cockroachdb': {
154
- 'engine': 'cockroachdb',
155
- 'omit_create_engine': {'method',},
156
- 'create_engine': default_create_engine_args,
157
- 'to_sql': {
158
- 'method': 'multi',
159
- },
160
- 'requirements': {'host'},
161
- 'defaults': {
162
- 'port': 26257,
163
- 'database': 'defaultdb',
164
- 'username': 'root',
165
- 'password': 'admin',
166
- },
167
- },
168
- }
18
+
19
+ flavor_configs = STATIC_CONFIG['sql']['create_engine_flavors']
169
20
  install_flavor_drivers = {
170
21
  'sqlite': ['aiosqlite'],
171
22
  'duckdb': ['duckdb', 'duckdb_engine'],
172
23
  'mysql': ['pymysql'],
173
24
  'mariadb': ['pymysql'],
174
25
  'timescaledb': ['psycopg'],
26
+ 'timescaledb-ha': ['psycopg', 'geoalchemy'],
175
27
  'postgresql': ['psycopg'],
176
28
  'postgis': ['psycopg', 'geoalchemy'],
177
29
  'citus': ['psycopg'],
@@ -179,7 +31,6 @@ install_flavor_drivers = {
179
31
  'mssql': ['pyodbc'],
180
32
  'oracle': ['oracledb'],
181
33
  }
182
- require_patching_flavors = {'cockroachdb': [('sqlalchemy-cockroachdb', 'sqlalchemy_cockroachdb')]}
183
34
 
184
35
  flavor_dialects = {
185
36
  'cockroachdb': (
@@ -211,19 +62,6 @@ def create_engine(
211
62
  )
212
63
  if self.flavor == 'mssql':
213
64
  _init_mssql_sqlalchemy()
214
- if self.flavor in require_patching_flavors:
215
- from meerschaum.utils.packages import determine_version, _monkey_patch_get_distribution
216
- import pathlib
217
- for install_name, import_name in require_patching_flavors[self.flavor]:
218
- pkg = attempt_import(
219
- import_name,
220
- debug=debug,
221
- lazy=False,
222
- warn=False
223
- )
224
- _monkey_patch_get_distribution(
225
- install_name, determine_version(pathlib.Path(pkg.__file__), venv='mrsm')
226
- )
227
65
 
228
66
  ### supplement missing values with defaults (e.g. port number)
229
67
  for a, value in flavor_configs[self.flavor]['defaults'].items():
@@ -240,6 +78,9 @@ def create_engine(
240
78
  _host = self.__dict__.get('host', None)
241
79
  _port = self.__dict__.get('port', None)
242
80
  _database = self.__dict__.get('database', None)
81
+ if _database == '{SQLITE_DB_PATH}':
82
+ from meerschaum.config.paths import SQLITE_DB_PATH
83
+ _database = SQLITE_DB_PATH.as_posix()
243
84
  _options = self.__dict__.get('options', {})
244
85
  if isinstance(_options, str):
245
86
  _options = dict(urllib.parse.parse_qsl(_options))
@@ -268,7 +109,7 @@ def create_engine(
268
109
 
269
110
  ### Sometimes the timescaledb:// flavor can slip in.
270
111
  if _uri and self.flavor in _uri:
271
- if self.flavor in ('timescaledb', 'postgis'):
112
+ if self.flavor in ('timescaledb', 'timescaledb-ha', 'postgis'):
272
113
  engine_str = engine_str.replace(self.flavor, 'postgresql', 1)
273
114
  elif _uri.startswith('postgresql://'):
274
115
  engine_str = engine_str.replace('postgresql://', 'postgresql+psycopg2://')
@@ -337,6 +178,9 @@ def _init_mssql_sqlalchemy():
337
178
  lazy=False,
338
179
  warn=False,
339
180
  )
181
+ if pyodbc is None:
182
+ raise EnvironmentError("Cannot import pyodbc. Is the MSSQL driver installed?")
183
+
340
184
  pyodbc.pooling = False
341
185
 
342
186
  MSDialect_pyodbc = sqlalchemy_dialects_mssql_pyodbc.MSDialect_pyodbc
@@ -230,11 +230,9 @@ def get_pipe_query(pipe: mrsm.Pipe, warn: bool = True) -> Union[str, None]:
230
230
  - query
231
231
  - sql
232
232
  """
233
- import re
234
233
  import textwrap
235
234
  from meerschaum.utils.warnings import warn as _warn
236
- from meerschaum.utils.misc import parse_arguments_str
237
- from meerschaum.utils.sql import sql_item_name
235
+ from meerschaum.utils.pipes import replace_pipes_syntax
238
236
  if pipe.parameters.get('fetch', {}).get('definition', None):
239
237
  definition = pipe.parameters['fetch']['definition']
240
238
  elif pipe.parameters.get('definition', None):
@@ -251,21 +249,7 @@ def get_pipe_query(pipe: mrsm.Pipe, warn: bool = True) -> Union[str, None]:
251
249
  )
252
250
  return None
253
251
 
254
- def replace_pipe_match(pipe_match):
255
- try:
256
- args_str = pipe_match.group(1)
257
- args, kwargs = parse_arguments_str(args_str)
258
- pipe = mrsm.Pipe(*args, **kwargs)
259
- except Exception as e:
260
- if warn:
261
- _warn(f"Failed to parse pipe from SQL definition:\n{e}")
262
- raise e
263
-
264
- target = pipe.target
265
- schema = pipe.instance_connector.get_pipe_schema(pipe)
266
- return sql_item_name(target, pipe.instance_connector.flavor, schema)
267
-
268
- definition = re.sub(r'\{\{Pipe\((.*?)\)\}\}', replace_pipe_match, definition)
252
+ definition = replace_pipes_syntax(definition)
269
253
  return textwrap.dedent(definition.lstrip().rstrip())
270
254
 
271
255