meerschaum 2.9.5__py3-none-any.whl → 3.0.0rc2__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 (158) 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 +19 -2
  5. meerschaum/_internal/docs/index.py +49 -2
  6. meerschaum/_internal/entry.py +6 -6
  7. meerschaum/_internal/shell/Shell.py +1 -1
  8. meerschaum/_internal/static.py +356 -0
  9. meerschaum/actions/api.py +12 -2
  10. meerschaum/actions/bootstrap.py +7 -7
  11. meerschaum/actions/edit.py +142 -18
  12. meerschaum/actions/register.py +137 -6
  13. meerschaum/actions/show.py +117 -29
  14. meerschaum/actions/stop.py +4 -1
  15. meerschaum/actions/sync.py +1 -1
  16. meerschaum/actions/tag.py +9 -8
  17. meerschaum/actions/verify.py +5 -8
  18. meerschaum/api/__init__.py +11 -3
  19. meerschaum/api/_events.py +39 -2
  20. meerschaum/api/_oauth2.py +118 -8
  21. meerschaum/api/_tokens.py +102 -0
  22. meerschaum/api/dash/__init__.py +0 -3
  23. meerschaum/api/dash/callbacks/custom.py +2 -2
  24. meerschaum/api/dash/callbacks/dashboard.py +103 -19
  25. meerschaum/api/dash/callbacks/plugins.py +0 -1
  26. meerschaum/api/dash/callbacks/register.py +1 -1
  27. meerschaum/api/dash/callbacks/settings/__init__.py +1 -0
  28. meerschaum/api/dash/callbacks/settings/password_reset.py +2 -2
  29. meerschaum/api/dash/callbacks/settings/tokens.py +388 -0
  30. meerschaum/api/dash/components.py +30 -8
  31. meerschaum/api/dash/keys.py +19 -93
  32. meerschaum/api/dash/pages/dashboard.py +1 -20
  33. meerschaum/api/dash/pages/settings/__init__.py +1 -0
  34. meerschaum/api/dash/pages/settings/password_reset.py +1 -1
  35. meerschaum/api/dash/pages/settings/tokens.py +55 -0
  36. meerschaum/api/dash/pipes.py +94 -59
  37. meerschaum/api/dash/sessions.py +12 -0
  38. meerschaum/api/dash/tokens.py +606 -0
  39. meerschaum/api/dash/websockets.py +1 -1
  40. meerschaum/api/dash/webterm.py +4 -0
  41. meerschaum/api/models/__init__.py +23 -3
  42. meerschaum/api/models/_actions.py +22 -0
  43. meerschaum/api/models/_pipes.py +85 -7
  44. meerschaum/api/models/_tokens.py +81 -0
  45. meerschaum/api/resources/templates/termpage.html +12 -0
  46. meerschaum/api/routes/__init__.py +1 -0
  47. meerschaum/api/routes/_actions.py +3 -4
  48. meerschaum/api/routes/_connectors.py +3 -7
  49. meerschaum/api/routes/_jobs.py +14 -35
  50. meerschaum/api/routes/_login.py +49 -12
  51. meerschaum/api/routes/_misc.py +5 -10
  52. meerschaum/api/routes/_pipes.py +173 -140
  53. meerschaum/api/routes/_plugins.py +38 -28
  54. meerschaum/api/routes/_tokens.py +236 -0
  55. meerschaum/api/routes/_users.py +47 -35
  56. meerschaum/api/routes/_version.py +3 -3
  57. meerschaum/config/__init__.py +43 -20
  58. meerschaum/config/_default.py +43 -6
  59. meerschaum/config/_edit.py +28 -24
  60. meerschaum/config/_environment.py +1 -1
  61. meerschaum/config/_patch.py +6 -6
  62. meerschaum/config/_paths.py +5 -1
  63. meerschaum/config/_read_config.py +65 -34
  64. meerschaum/config/_sync.py +6 -3
  65. meerschaum/config/_version.py +1 -1
  66. meerschaum/config/stack/__init__.py +31 -11
  67. meerschaum/config/static.py +18 -0
  68. meerschaum/connectors/_Connector.py +10 -4
  69. meerschaum/connectors/__init__.py +4 -20
  70. meerschaum/connectors/api/_APIConnector.py +34 -6
  71. meerschaum/connectors/api/_actions.py +2 -2
  72. meerschaum/connectors/api/_jobs.py +1 -1
  73. meerschaum/connectors/api/_login.py +33 -7
  74. meerschaum/connectors/api/_misc.py +2 -2
  75. meerschaum/connectors/api/_pipes.py +16 -31
  76. meerschaum/connectors/api/_plugins.py +2 -2
  77. meerschaum/connectors/api/_request.py +1 -1
  78. meerschaum/connectors/api/_tokens.py +146 -0
  79. meerschaum/connectors/api/_users.py +70 -58
  80. meerschaum/connectors/instance/_InstanceConnector.py +83 -0
  81. meerschaum/connectors/instance/__init__.py +10 -0
  82. meerschaum/connectors/instance/_pipes.py +442 -0
  83. meerschaum/connectors/instance/_plugins.py +151 -0
  84. meerschaum/connectors/instance/_tokens.py +296 -0
  85. meerschaum/connectors/instance/_users.py +181 -0
  86. meerschaum/connectors/parse.py +4 -1
  87. meerschaum/connectors/sql/_SQLConnector.py +8 -5
  88. meerschaum/connectors/sql/_cli.py +12 -11
  89. meerschaum/connectors/sql/_create_engine.py +9 -168
  90. meerschaum/connectors/sql/_fetch.py +2 -18
  91. meerschaum/connectors/sql/_pipes.py +156 -190
  92. meerschaum/connectors/sql/_plugins.py +29 -0
  93. meerschaum/connectors/sql/_sql.py +46 -21
  94. meerschaum/connectors/sql/_users.py +29 -2
  95. meerschaum/connectors/sql/tables/__init__.py +1 -1
  96. meerschaum/connectors/valkey/_ValkeyConnector.py +2 -4
  97. meerschaum/connectors/valkey/_pipes.py +53 -26
  98. meerschaum/connectors/valkey/_plugins.py +2 -26
  99. meerschaum/core/Pipe/__init__.py +59 -19
  100. meerschaum/core/Pipe/_attributes.py +412 -90
  101. meerschaum/core/Pipe/_bootstrap.py +54 -24
  102. meerschaum/core/Pipe/_data.py +96 -18
  103. meerschaum/core/Pipe/_dtypes.py +48 -18
  104. meerschaum/core/Pipe/_edit.py +14 -4
  105. meerschaum/core/Pipe/_fetch.py +1 -1
  106. meerschaum/core/Pipe/_show.py +5 -5
  107. meerschaum/core/Pipe/_sync.py +118 -193
  108. meerschaum/core/Pipe/_verify.py +4 -4
  109. meerschaum/{plugins → core/Plugin}/_Plugin.py +9 -11
  110. meerschaum/core/Plugin/__init__.py +1 -1
  111. meerschaum/core/Token/_Token.py +220 -0
  112. meerschaum/core/Token/__init__.py +12 -0
  113. meerschaum/core/User/_User.py +34 -8
  114. meerschaum/core/User/__init__.py +9 -1
  115. meerschaum/core/__init__.py +1 -0
  116. meerschaum/jobs/_Job.py +3 -2
  117. meerschaum/jobs/__init__.py +3 -2
  118. meerschaum/jobs/systemd.py +1 -1
  119. meerschaum/models/__init__.py +35 -0
  120. meerschaum/models/pipes.py +247 -0
  121. meerschaum/models/tokens.py +38 -0
  122. meerschaum/models/users.py +26 -0
  123. meerschaum/plugins/__init__.py +22 -7
  124. meerschaum/plugins/bootstrap.py +2 -1
  125. meerschaum/utils/_get_pipes.py +68 -27
  126. meerschaum/utils/daemon/Daemon.py +2 -1
  127. meerschaum/utils/daemon/__init__.py +30 -2
  128. meerschaum/utils/dataframe.py +473 -81
  129. meerschaum/utils/debug.py +15 -15
  130. meerschaum/utils/dtypes/__init__.py +473 -34
  131. meerschaum/utils/dtypes/sql.py +368 -28
  132. meerschaum/utils/formatting/__init__.py +1 -1
  133. meerschaum/utils/formatting/_pipes.py +5 -4
  134. meerschaum/utils/formatting/_shell.py +11 -9
  135. meerschaum/utils/misc.py +246 -148
  136. meerschaum/utils/packages/__init__.py +10 -27
  137. meerschaum/utils/packages/_packages.py +41 -34
  138. meerschaum/utils/pipes.py +181 -0
  139. meerschaum/utils/process.py +1 -1
  140. meerschaum/utils/prompt.py +3 -1
  141. meerschaum/utils/schedule.py +2 -1
  142. meerschaum/utils/sql.py +121 -44
  143. meerschaum/utils/typing.py +1 -4
  144. meerschaum/utils/venv/_Venv.py +2 -2
  145. meerschaum/utils/venv/__init__.py +5 -7
  146. {meerschaum-2.9.5.dist-info → meerschaum-3.0.0rc2.dist-info}/METADATA +92 -96
  147. meerschaum-3.0.0rc2.dist-info/RECORD +283 -0
  148. {meerschaum-2.9.5.dist-info → meerschaum-3.0.0rc2.dist-info}/WHEEL +1 -1
  149. meerschaum-3.0.0rc2.dist-info/licenses/NOTICE +2 -0
  150. meerschaum/api/models/_interfaces.py +0 -15
  151. meerschaum/api/models/_locations.py +0 -15
  152. meerschaum/api/models/_metrics.py +0 -15
  153. meerschaum/config/static/__init__.py +0 -186
  154. meerschaum-2.9.5.dist-info/RECORD +0 -263
  155. {meerschaum-2.9.5.dist-info → meerschaum-3.0.0rc2.dist-info}/entry_points.txt +0 -0
  156. {meerschaum-2.9.5.dist-info → meerschaum-3.0.0rc2.dist-info}/licenses/LICENSE +0 -0
  157. {meerschaum-2.9.5.dist-info → meerschaum-3.0.0rc2.dist-info}/top_level.txt +0 -0
  158. {meerschaum-2.9.5.dist-info → meerschaum-3.0.0rc2.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():
@@ -268,7 +106,7 @@ def create_engine(
268
106
 
269
107
  ### Sometimes the timescaledb:// flavor can slip in.
270
108
  if _uri and self.flavor in _uri:
271
- if self.flavor in ('timescaledb', 'postgis'):
109
+ if self.flavor in ('timescaledb', 'timescaledb-ha', 'postgis'):
272
110
  engine_str = engine_str.replace(self.flavor, 'postgresql', 1)
273
111
  elif _uri.startswith('postgresql://'):
274
112
  engine_str = engine_str.replace('postgresql://', 'postgresql+psycopg2://')
@@ -337,6 +175,9 @@ def _init_mssql_sqlalchemy():
337
175
  lazy=False,
338
176
  warn=False,
339
177
  )
178
+ if pyodbc is None:
179
+ raise EnvironmentError("Cannot import pyodbc. Is the MSSQL driver installed?")
180
+
340
181
  pyodbc.pooling = False
341
182
 
342
183
  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