meerschaum 2.9.5__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 (200) 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 +198 -118
  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 +382 -95
  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/js/terminado.js +3 -0
  68. meerschaum/api/resources/static/js/xterm-addon-unicode11.js +2 -0
  69. meerschaum/api/resources/templates/termpage.html +13 -0
  70. meerschaum/api/routes/__init__.py +1 -0
  71. meerschaum/api/routes/_actions.py +3 -4
  72. meerschaum/api/routes/_connectors.py +3 -7
  73. meerschaum/api/routes/_jobs.py +26 -35
  74. meerschaum/api/routes/_login.py +120 -15
  75. meerschaum/api/routes/_misc.py +5 -10
  76. meerschaum/api/routes/_pipes.py +178 -143
  77. meerschaum/api/routes/_plugins.py +38 -28
  78. meerschaum/api/routes/_tokens.py +236 -0
  79. meerschaum/api/routes/_users.py +47 -35
  80. meerschaum/api/routes/_version.py +3 -3
  81. meerschaum/api/routes/_webterm.py +3 -3
  82. meerschaum/config/__init__.py +100 -30
  83. meerschaum/config/_default.py +132 -64
  84. meerschaum/config/_edit.py +38 -32
  85. meerschaum/config/_formatting.py +2 -0
  86. meerschaum/config/_patch.py +10 -8
  87. meerschaum/config/_paths.py +133 -13
  88. meerschaum/config/_read_config.py +87 -36
  89. meerschaum/config/_sync.py +6 -3
  90. meerschaum/config/_version.py +1 -1
  91. meerschaum/config/environment.py +262 -0
  92. meerschaum/config/stack/__init__.py +37 -15
  93. meerschaum/config/static.py +18 -0
  94. meerschaum/connectors/_Connector.py +11 -6
  95. meerschaum/connectors/__init__.py +41 -22
  96. meerschaum/connectors/api/_APIConnector.py +34 -6
  97. meerschaum/connectors/api/_actions.py +2 -2
  98. meerschaum/connectors/api/_jobs.py +12 -1
  99. meerschaum/connectors/api/_login.py +33 -7
  100. meerschaum/connectors/api/_misc.py +2 -2
  101. meerschaum/connectors/api/_pipes.py +23 -32
  102. meerschaum/connectors/api/_plugins.py +2 -2
  103. meerschaum/connectors/api/_request.py +1 -1
  104. meerschaum/connectors/api/_tokens.py +146 -0
  105. meerschaum/connectors/api/_users.py +70 -58
  106. meerschaum/connectors/instance/_InstanceConnector.py +83 -0
  107. meerschaum/connectors/instance/__init__.py +10 -0
  108. meerschaum/connectors/instance/_pipes.py +442 -0
  109. meerschaum/connectors/instance/_plugins.py +159 -0
  110. meerschaum/connectors/instance/_tokens.py +317 -0
  111. meerschaum/connectors/instance/_users.py +188 -0
  112. meerschaum/connectors/parse.py +5 -2
  113. meerschaum/connectors/sql/_SQLConnector.py +22 -5
  114. meerschaum/connectors/sql/_cli.py +12 -11
  115. meerschaum/connectors/sql/_create_engine.py +12 -168
  116. meerschaum/connectors/sql/_fetch.py +2 -18
  117. meerschaum/connectors/sql/_pipes.py +295 -278
  118. meerschaum/connectors/sql/_plugins.py +29 -0
  119. meerschaum/connectors/sql/_sql.py +46 -21
  120. meerschaum/connectors/sql/_users.py +36 -2
  121. meerschaum/connectors/sql/tables/__init__.py +254 -122
  122. meerschaum/connectors/valkey/_ValkeyConnector.py +5 -7
  123. meerschaum/connectors/valkey/_pipes.py +60 -31
  124. meerschaum/connectors/valkey/_plugins.py +2 -26
  125. meerschaum/core/Pipe/__init__.py +115 -85
  126. meerschaum/core/Pipe/_attributes.py +425 -124
  127. meerschaum/core/Pipe/_bootstrap.py +54 -24
  128. meerschaum/core/Pipe/_cache.py +555 -0
  129. meerschaum/core/Pipe/_clear.py +0 -11
  130. meerschaum/core/Pipe/_data.py +96 -68
  131. meerschaum/core/Pipe/_deduplicate.py +0 -13
  132. meerschaum/core/Pipe/_delete.py +12 -21
  133. meerschaum/core/Pipe/_drop.py +11 -23
  134. meerschaum/core/Pipe/_dtypes.py +49 -19
  135. meerschaum/core/Pipe/_edit.py +14 -4
  136. meerschaum/core/Pipe/_fetch.py +1 -1
  137. meerschaum/core/Pipe/_index.py +8 -14
  138. meerschaum/core/Pipe/_show.py +5 -5
  139. meerschaum/core/Pipe/_sync.py +123 -204
  140. meerschaum/core/Pipe/_verify.py +4 -4
  141. meerschaum/{plugins → core/Plugin}/_Plugin.py +16 -12
  142. meerschaum/core/Plugin/__init__.py +1 -1
  143. meerschaum/core/Token/_Token.py +220 -0
  144. meerschaum/core/Token/__init__.py +12 -0
  145. meerschaum/core/User/_User.py +35 -10
  146. meerschaum/core/User/__init__.py +9 -1
  147. meerschaum/core/__init__.py +1 -0
  148. meerschaum/jobs/_Executor.py +88 -4
  149. meerschaum/jobs/_Job.py +149 -38
  150. meerschaum/jobs/__init__.py +3 -2
  151. meerschaum/jobs/systemd.py +8 -3
  152. meerschaum/models/__init__.py +35 -0
  153. meerschaum/models/pipes.py +247 -0
  154. meerschaum/models/tokens.py +38 -0
  155. meerschaum/models/users.py +26 -0
  156. meerschaum/plugins/__init__.py +301 -88
  157. meerschaum/plugins/bootstrap.py +510 -4
  158. meerschaum/utils/_get_pipes.py +97 -30
  159. meerschaum/utils/daemon/Daemon.py +199 -43
  160. meerschaum/utils/daemon/FileDescriptorInterceptor.py +0 -1
  161. meerschaum/utils/daemon/RotatingFile.py +63 -36
  162. meerschaum/utils/daemon/StdinFile.py +53 -13
  163. meerschaum/utils/daemon/__init__.py +47 -6
  164. meerschaum/utils/daemon/_names.py +6 -3
  165. meerschaum/utils/dataframe.py +479 -81
  166. meerschaum/utils/debug.py +49 -19
  167. meerschaum/utils/dtypes/__init__.py +476 -34
  168. meerschaum/utils/dtypes/sql.py +369 -29
  169. meerschaum/utils/formatting/__init__.py +5 -2
  170. meerschaum/utils/formatting/_jobs.py +1 -1
  171. meerschaum/utils/formatting/_pipes.py +52 -50
  172. meerschaum/utils/formatting/_pprint.py +1 -0
  173. meerschaum/utils/formatting/_shell.py +44 -18
  174. meerschaum/utils/misc.py +268 -186
  175. meerschaum/utils/packages/__init__.py +25 -40
  176. meerschaum/utils/packages/_packages.py +42 -34
  177. meerschaum/utils/pipes.py +213 -0
  178. meerschaum/utils/process.py +2 -2
  179. meerschaum/utils/prompt.py +175 -144
  180. meerschaum/utils/schedule.py +2 -1
  181. meerschaum/utils/sql.py +134 -47
  182. meerschaum/utils/threading.py +42 -0
  183. meerschaum/utils/typing.py +1 -4
  184. meerschaum/utils/venv/_Venv.py +2 -2
  185. meerschaum/utils/venv/__init__.py +7 -7
  186. meerschaum/utils/warnings.py +19 -13
  187. {meerschaum-2.9.5.dist-info → meerschaum-3.0.0.dist-info}/METADATA +94 -96
  188. meerschaum-3.0.0.dist-info/RECORD +289 -0
  189. {meerschaum-2.9.5.dist-info → meerschaum-3.0.0.dist-info}/WHEEL +1 -1
  190. meerschaum-3.0.0.dist-info/licenses/NOTICE +2 -0
  191. meerschaum/api/models/_interfaces.py +0 -15
  192. meerschaum/api/models/_locations.py +0 -15
  193. meerschaum/api/models/_metrics.py +0 -15
  194. meerschaum/config/_environment.py +0 -145
  195. meerschaum/config/static/__init__.py +0 -186
  196. meerschaum-2.9.5.dist-info/RECORD +0 -263
  197. {meerschaum-2.9.5.dist-info → meerschaum-3.0.0.dist-info}/entry_points.txt +0 -0
  198. {meerschaum-2.9.5.dist-info → meerschaum-3.0.0.dist-info}/licenses/LICENSE +0 -0
  199. {meerschaum-2.9.5.dist-info → meerschaum-3.0.0.dist-info}/top_level.txt +0 -0
  200. {meerschaum-2.9.5.dist-info → meerschaum-3.0.0.dist-info}/zip-safe +0 -0
@@ -0,0 +1,359 @@
1
+ #! /usr/bin/env python3
2
+ # vim:fenc=utf-8
3
+
4
+ """
5
+ Define internal static config (formerly `meerschaum.config.static`).
6
+ """
7
+
8
+ import os
9
+ import random
10
+ import string
11
+ from typing import Dict, Any
12
+
13
+ __all__ = ('STATIC_CONFIG',)
14
+
15
+ _default_create_engine_args = {
16
+ # 'method': 'multi',
17
+ 'pool_size': (os.cpu_count() or 5),
18
+ 'max_overflow': (os.cpu_count() or 10),
19
+ 'pool_recycle': 3600,
20
+ 'connect_args': {},
21
+ }
22
+ _default_db_requirements = {
23
+ 'username',
24
+ 'password',
25
+ 'host',
26
+ 'database',
27
+ }
28
+ SERVER_ID: str = os.environ.get('MRSM_SERVER_ID', ''.join(random.sample(string.ascii_lowercase+string.digits, 6)))
29
+ STATIC_CONFIG: Dict[str, Any] = {
30
+ 'api': {
31
+ 'endpoints': {
32
+ 'index': '/',
33
+ 'favicon': '/favicon.ico',
34
+ 'plugins': '/plugins',
35
+ 'pipes': '/pipes',
36
+ 'metadata': '/metadata',
37
+ 'actions': '/actions',
38
+ 'jobs': '/jobs',
39
+ 'logs': '/logs',
40
+ 'users': '/users',
41
+ 'tokens': '/tokens',
42
+ 'login': '/login',
43
+ 'connectors': '/connectors',
44
+ 'version': '/version',
45
+ 'chaining': '/chaining',
46
+ 'websocket': '/ws',
47
+ 'dash': '/dash',
48
+ 'webterm': r'/webterm/{session_id}',
49
+ 'webterm_websocket': r'/websocket/{session_id}',
50
+ 'info': '/info',
51
+ 'healthcheck': '/healthcheck',
52
+ 'docs': '/docs',
53
+ 'redoc': '/redoc',
54
+ 'openapi': '/openapi.json',
55
+ },
56
+ 'oauth': {
57
+ 'token_expires_minutes': 720,
58
+ },
59
+ 'webterm_job_name': '_webterm',
60
+ 'default_timeout': 600,
61
+ 'jobs': {
62
+ 'stdin_message': 'MRSM_STDIN',
63
+ 'stop_message': 'MRSM_STOP',
64
+ 'metadata_cache_seconds': 5,
65
+ 'temp_prefix': '.api-temp-',
66
+ },
67
+ },
68
+ 'sql': {
69
+ 'internal_schema': '_mrsm_internal',
70
+ 'instance_schema': 'mrsm',
71
+ 'default_create_engine_args': _default_create_engine_args,
72
+ 'create_engine_flavors': {
73
+ 'timescaledb': {
74
+ 'engine': 'postgresql+psycopg',
75
+ 'create_engine': _default_create_engine_args,
76
+ 'omit_create_engine': {'method',},
77
+ 'to_sql': {},
78
+ 'requirements': _default_db_requirements,
79
+ 'defaults': {
80
+ 'port': 5432,
81
+ },
82
+ },
83
+ 'timescaledb-ha': {
84
+ 'engine': 'postgresql+psycopg',
85
+ 'create_engine': _default_create_engine_args,
86
+ 'omit_create_engine': {'method',},
87
+ 'to_sql': {},
88
+ 'requirements': _default_db_requirements,
89
+ 'defaults': {
90
+ 'port': 5432,
91
+ },
92
+ },
93
+ 'postgresql': {
94
+ 'engine': 'postgresql+psycopg',
95
+ 'create_engine': _default_create_engine_args,
96
+ 'omit_create_engine': {'method',},
97
+ 'to_sql': {},
98
+ 'requirements': _default_db_requirements,
99
+ 'defaults': {
100
+ 'port': 5432,
101
+ },
102
+ },
103
+ 'postgis': {
104
+ 'engine': 'postgresql+psycopg',
105
+ 'create_engine': _default_create_engine_args,
106
+ 'omit_create_engine': {'method',},
107
+ 'to_sql': {},
108
+ 'requirements': _default_db_requirements,
109
+ 'defaults': {
110
+ 'port': 5432,
111
+ },
112
+ },
113
+ 'citus': {
114
+ 'engine': 'postgresql+psycopg',
115
+ 'create_engine': _default_create_engine_args,
116
+ 'omit_create_engine': {'method',},
117
+ 'to_sql': {},
118
+ 'requirements': _default_db_requirements,
119
+ 'defaults': {
120
+ 'port': 5432,
121
+ },
122
+ },
123
+ 'mssql': {
124
+ 'engine': 'mssql+pyodbc',
125
+ 'create_engine': {
126
+ 'fast_executemany': True,
127
+ 'use_insertmanyvalues': False,
128
+ 'isolation_level': 'AUTOCOMMIT',
129
+ 'use_setinputsizes': False,
130
+ 'pool_pre_ping': True,
131
+ 'ignore_no_transaction_on_rollback': True,
132
+ },
133
+ 'omit_create_engine': {'method',},
134
+ 'to_sql': {
135
+ 'method': None,
136
+ },
137
+ 'requirements': _default_db_requirements,
138
+ 'defaults': {
139
+ 'port': 1433,
140
+ 'options': (
141
+ "driver=ODBC Driver 18 for SQL Server"
142
+ "&UseFMTONLY=Yes"
143
+ "&TrustServerCertificate=yes"
144
+ "&Encrypt=no"
145
+ "&MARS_Connection=yes"
146
+ ),
147
+ },
148
+ },
149
+ 'mysql': {
150
+ 'engine': 'mysql+pymysql',
151
+ 'create_engine': _default_create_engine_args,
152
+ 'omit_create_engine': {'method',},
153
+ 'to_sql': {
154
+ 'method': 'multi',
155
+ },
156
+ 'requirements': _default_db_requirements,
157
+ 'defaults': {
158
+ 'port': 3306,
159
+ },
160
+ },
161
+ 'mariadb': {
162
+ 'engine': 'mysql+pymysql',
163
+ 'create_engine': _default_create_engine_args,
164
+ 'omit_create_engine': {'method',},
165
+ 'to_sql': {
166
+ 'method': 'multi',
167
+ },
168
+ 'requirements': _default_db_requirements,
169
+ 'defaults': {
170
+ 'port': 3306,
171
+ },
172
+ },
173
+ 'oracle': {
174
+ 'engine': 'oracle+oracledb',
175
+ 'create_engine': _default_create_engine_args,
176
+ 'omit_create_engine': {'method',},
177
+ 'to_sql': {
178
+ 'method': None,
179
+ },
180
+ 'requirements': _default_db_requirements,
181
+ 'defaults': {
182
+ 'port': 1521,
183
+ },
184
+ },
185
+ 'sqlite': {
186
+ 'engine': 'sqlite',
187
+ 'create_engine': _default_create_engine_args,
188
+ 'omit_create_engine': {'method',},
189
+ 'to_sql': {
190
+ 'method': 'multi',
191
+ },
192
+ 'requirements': {'database'},
193
+ 'defaults': {},
194
+ },
195
+ 'duckdb': {
196
+ 'engine': 'duckdb',
197
+ 'create_engine': {},
198
+ 'omit_create_engine': {'ALL',},
199
+ 'to_sql': {
200
+ 'method': 'multi',
201
+ },
202
+ 'requirements': '',
203
+ 'defaults': {},
204
+ },
205
+ 'cockroachdb': {
206
+ 'engine': 'cockroachdb',
207
+ 'omit_create_engine': {'method',},
208
+ 'create_engine': _default_create_engine_args,
209
+ 'to_sql': {
210
+ 'method': 'multi',
211
+ },
212
+ 'requirements': {'host'},
213
+ 'defaults': {
214
+ 'port': 26257,
215
+ 'database': 'defaultdb',
216
+ 'username': 'root',
217
+ 'password': 'admin',
218
+ },
219
+ },
220
+ },
221
+ },
222
+ 'valkey': {
223
+ 'colon': '-_',
224
+ },
225
+ 'environment': {
226
+ 'config': 'MRSM_CONFIG',
227
+ 'config_dir': 'MRSM_CONFIG_DIR',
228
+ 'patch': 'MRSM_PATCH',
229
+ 'root': 'MRSM_ROOT_DIR',
230
+ 'plugins': 'MRSM_PLUGINS_DIR',
231
+ 'venvs': 'MRSM_VENVS_DIR',
232
+ 'runtime': 'MRSM_RUNTIME',
233
+ 'work_dir': 'MRSM_WORK_DIR',
234
+ 'user': 'MRSM_USER',
235
+ 'dep_group': 'MRSM_DEP_GROUP',
236
+ 'home': 'MRSM_HOME',
237
+ 'src': 'MRSM_SRC',
238
+ 'uid': 'MRSM_UID',
239
+ 'gid': 'MRSM_GID',
240
+ 'noask': 'MRSM_NOASK',
241
+ 'noninteractive': 'MRSM_NONINTERACTIVE',
242
+ 'id': 'MRSM_SERVER_ID',
243
+ 'test_flavors': 'MRSM_TEST_FLAVORS',
244
+ 'daemon_id': 'MRSM_DAEMON_ID',
245
+ 'systemd_log_path': 'MRSM_SYSTEMD_LOG_PATH',
246
+ 'systemd_stdin_path': 'MRSM_SYSTEMD_STDIN_PATH',
247
+ 'systemd_result_path': 'MRSM_SYSTEMD_RESULT_PATH',
248
+ 'systemd_delete_job': 'MRSM_SYSTEMD_DELETE_JOB',
249
+ 'uri_regex': r'MRSM_([a-zA-Z0-9]*)_(\d*[a-zA-Z][a-zA-Z0-9-_+]*$)',
250
+ 'prefix': 'MRSM_',
251
+ },
252
+ 'config': {
253
+ 'default_filetype': 'json',
254
+ 'symlinks_key': '_symlinks',
255
+ },
256
+ 'system': {
257
+ 'arguments': {
258
+ 'sub_decorators': (
259
+ '[',
260
+ ']'
261
+ ),
262
+ 'underscore_standin': '<UNDERSCORE>', ### Temporary replacement for parsing.
263
+ 'failure_key': '_argparse_exception',
264
+ 'and_key': '+',
265
+ 'escaped_and_key': '++',
266
+ 'pipeline_key': ':',
267
+ 'escaped_pipeline_key': '::',
268
+ },
269
+ 'urls': {
270
+ 'get-pip.py': 'https://bootstrap.pypa.io/get-pip.py',
271
+ },
272
+ 'success': {
273
+ 'ignore': (
274
+ 'Success',
275
+ 'success'
276
+ 'Succeeded',
277
+ '',
278
+ None,
279
+ ),
280
+ },
281
+ 'prompt': {
282
+ 'web': False,
283
+ },
284
+ 'fetch_pipes_keys': {
285
+ 'negation_prefix': '_',
286
+ },
287
+ },
288
+ 'connectors': {
289
+ 'default_label': 'main',
290
+ },
291
+ 'dtypes': {
292
+ 'datetime': {
293
+ 'default_precision_unit': 'microsecond',
294
+ },
295
+ },
296
+ 'stack': {
297
+ 'dollar_standin': '<DOLLAR>', ### Temporary replacement for docker-compose.yaml.
298
+ },
299
+ 'users': {
300
+ 'password_hash': {
301
+ 'algorithm_name': 'sha256',
302
+ 'salt_bytes': 16,
303
+ 'schemes': [
304
+ 'pbkdf2_sha256',
305
+ ],
306
+ 'default': 'pbkdf2_sha256',
307
+ 'pbkdf2_sha256__default_rounds': 1_000_000,
308
+ },
309
+ 'min_username_length': 1,
310
+ 'max_username_length': 60,
311
+ 'min_password_length': 5,
312
+ },
313
+ 'plugins': {
314
+ 'repo_separator': '@',
315
+ 'lock_sleep_total': 1.0,
316
+ 'lock_sleep_increment': 0.1,
317
+ },
318
+ 'pipes': {
319
+ 'dtypes': {
320
+ 'min_ratio_columns_changed_for_full_astype': 0.5,
321
+ },
322
+ 'max_bound_time_days': 36525,
323
+ },
324
+ 'jobs': {
325
+ 'check_restart_seconds': 1.0,
326
+ 'stop_token': '<------- MRSM_STOP_TOKEN ------->',
327
+ 'clear_token': '<------- MRSM_CLEAR_TOKEN ------->',
328
+ 'flush_token': '<------- MRSM_FLUSH_TOKEN ------->\n',
329
+ },
330
+ 'tokens': {
331
+ 'minimum_length': 24,
332
+ 'maximum_length': 32,
333
+ 'hash_rounds': 100_000,
334
+ 'scopes': {
335
+ 'pipes:read': "Read pipes' parameters and the contents of target tables.",
336
+ 'pipes:write': "Update pipes' parameters and sync to target tables.",
337
+ 'pipes:drop': "Drop target tables.",
338
+ 'pipes:delete': "Delete pipes' parameters and drop target tables.",
339
+ 'actions:execute': "Execute arbitrary actions.",
340
+ 'connectors:read': "Read the available connectors.",
341
+ 'jobs:read': "Read jobs' properties",
342
+ 'jobs:write': "Write jobs' properties",
343
+ 'jobs:execute': "Run jobs.",
344
+ 'jobs:delete': "Delete jobs.",
345
+ 'logs:read': "Read jobs' logs.",
346
+ 'jobs:stop': "Stop running jobs.",
347
+ 'jobs:pause': "Pause running jobs.",
348
+ 'instance:read': "Read an instance's system-level metadata.",
349
+ 'instance:chain': "Allow chaining API instances using the associated credentials.",
350
+ 'plugins:write': "Register and update plugins' metadata.",
351
+ 'plugins:read': "Read attributes of registered plugins.",
352
+ 'plugins:delete': "Delete plugins (owned by user) from the repository.",
353
+ 'users:read': "Read metadata about the associated account.",
354
+ 'users:write': "Write metadata for the associated account.",
355
+ 'users:register': "Register new user accounts.",
356
+ 'users:delete': "Delete the associated user account (or other users for admins).",
357
+ },
358
+ },
359
+ }
@@ -10,11 +10,10 @@ from __future__ import annotations
10
10
  from typing import Any
11
11
 
12
12
  import meerschaum as mrsm
13
- from meerschaum.utils.warnings import warn
14
13
  tornado_web = mrsm.attempt_import('tornado.web', lazy=False)
15
14
  terminado = mrsm.attempt_import('terminado', lazy=False)
16
15
 
17
- tmux_suffix = mrsm.get_config('system', 'webterm', 'tmux', 'session_suffix')
16
+ tmux_suffix = mrsm.get_config('api', 'webterm', 'tmux', 'session_suffix')
18
17
 
19
18
 
20
19
  class TermPageHandler(tornado_web.RequestHandler):
@@ -8,6 +8,9 @@ Build the web console virtual terminal using Tornado and xterm.js.
8
8
 
9
9
  from __future__ import annotations
10
10
 
11
+ import os
12
+ import json
13
+ import pathlib
11
14
  from typing import Optional, Tuple
12
15
 
13
16
  import meerschaum as mrsm
@@ -16,7 +19,6 @@ from meerschaum._internal.term.TermPageHandler import TermPageHandler, CustomTer
16
19
  from meerschaum.config._paths import API_TEMPLATES_PATH, API_STATIC_PATH
17
20
  from meerschaum.utils.venv import venv_executable
18
21
  from meerschaum.utils.misc import is_tmux_available
19
- from meerschaum.utils.daemon._names import get_new_daemon_name
20
22
 
21
23
  tornado, tornado_ioloop, terminado = attempt_import(
22
24
  'tornado', 'tornado.ioloop', 'terminado', lazy=False,
@@ -25,6 +27,8 @@ tornado, tornado_ioloop, terminado = attempt_import(
25
27
 
26
28
  def get_webterm_app_and_manager(
27
29
  instance_keys: Optional[str] = None,
30
+ port: Optional[int] = None,
31
+ env_path: Optional[pathlib.Path] = None,
28
32
  ) -> Tuple[
29
33
  tornado.web.Application,
30
34
  terminado.UniqueTermManager,
@@ -36,19 +40,49 @@ def get_webterm_app_and_manager(
36
40
  -------
37
41
  A tuple of the Tornado web application and term manager.
38
42
  """
43
+ from meerschaum.config.environment import get_env_vars
44
+ from meerschaum._internal.static import STATIC_CONFIG
45
+ if env_path is None:
46
+ from meerschaum.config.paths import WEBTERM_INTERNAL_RESOURCES_PATH
47
+ env_path = WEBTERM_INTERNAL_RESOURCES_PATH / (str(port) + '.json')
48
+
49
+ env_vars = get_env_vars()
50
+ env_dict = {
51
+ env_var: os.environ[env_var]
52
+ for env_var in env_vars
53
+ if env_var not in (
54
+ STATIC_CONFIG['environment']['systemd_log_path'],
55
+ STATIC_CONFIG['environment']['systemd_result_path'],
56
+ STATIC_CONFIG['environment']['systemd_delete_job'],
57
+ STATIC_CONFIG['environment']['systemd_stdin_path'],
58
+ STATIC_CONFIG['environment']['daemon_id'],
59
+ )
60
+ }
61
+ with open(env_path, 'w+', encoding='utf-8') as f:
62
+ json.dump(env_dict, f)
63
+
39
64
  shell_kwargs_str = f"mrsm_instance='{instance_keys}'" if instance_keys else ""
40
65
  commands = [
41
66
  venv_executable(None),
42
67
  '-c',
43
- "import os; _ = os.environ.pop('COLUMNS', None); _ = os.environ.pop('LINES', None); "
44
- "from meerschaum._internal.entry import get_shell; "
68
+ "import os\n"
69
+ "import pathlib\n"
70
+ "import json\n"
71
+ f"env_path = pathlib.Path('{env_path.as_posix()}')\n"
72
+ "with open(env_path, 'r', encoding='utf-8') as f:\n"
73
+ " env_dict = json.load(f)\n"
74
+ "os.environ.update(env_dict)\n"
75
+ "_ = os.environ.pop('COLUMNS', None)\n"
76
+ "_ = os.environ.pop('LINES', None)\n"
77
+ "from meerschaum._internal.entry import get_shell\n"
45
78
  f"get_shell({shell_kwargs_str}).cmdloop()"
46
79
  ]
47
- webterm_cf = mrsm.get_config('system', 'webterm')
80
+ webterm_cf = mrsm.get_config('api', 'webterm')
48
81
  if webterm_cf.get('tmux', {}).get('enabled', False) and is_tmux_available():
49
- commands = ['tmux', 'new-session', '-A', '-s', 'MRSM_SESSION'] + commands
82
+ commands = ['tmux', 'new-session', '-A', '-s', f'MRSM_SESSION--{port}'] + commands
50
83
 
51
- term_manager = terminado.NamedTermManager(shell_command=commands)
84
+ term_manager = terminado.NamedTermManager(shell_command=commands, extra_env=env_dict)
85
+ term_manager._port = port
52
86
  handlers = [
53
87
  (
54
88
  r"/websocket/(.+)/?",
@@ -6,13 +6,14 @@
6
6
  Utility functions regarding the webterm.
7
7
  """
8
8
 
9
+ from typing import List, Optional
10
+
9
11
  import meerschaum as mrsm
10
- from meerschaum.utils.typing import List
11
12
 
12
13
 
13
14
  def is_webterm_running(
14
- host: str,
15
- port: int,
15
+ host: Optional[str] = None,
16
+ port: Optional[int] = None,
16
17
  protocol: str = 'http',
17
18
  session_id: str = 'mrsm',
18
19
  ) -> int:
@@ -20,10 +21,12 @@ def is_webterm_running(
20
21
  Determine whether the webterm service is running on a given host and port.
21
22
  """
22
23
  requests = mrsm.attempt_import('requests', lazy=False)
24
+ host = host or mrsm.get_config('api', 'webterm', 'host')
25
+ port = port or mrsm.get_config('api', 'webterm', 'port')
23
26
  url = f'{protocol}://{host}:{port}/webterm/{session_id}'
24
27
  try:
25
28
  r = requests.get(url, timeout=3)
26
- except Exception as e:
29
+ except Exception:
27
30
  return False
28
31
  if not r:
29
32
  return False
@@ -39,22 +42,44 @@ def kill_tmux_session(session: str) -> bool:
39
42
  return run_process(command, capture_output=True) == 0
40
43
 
41
44
 
42
- def get_mrsm_tmux_sessions() -> List[str]:
45
+ def get_mrsm_tmux_sessions(port: Optional[int] = None) -> List[str]:
43
46
  """
44
47
  Return a list of tmux sessions created by Meerschaum.
45
48
  """
46
49
  from meerschaum.utils.process import run_process
47
- tmux_suffix = mrsm.get_config('system', 'webterm', 'tmux', 'session_suffix')
50
+ tmux_suffix = mrsm.get_config('api', 'webterm', 'tmux', 'session_suffix')
48
51
  command = ['tmux', 'ls']
49
52
  proc = run_process(command, capture_output=True, as_proc=True)
50
53
  if proc.returncode != 0:
51
54
  return []
55
+
56
+ port = port or mrsm.get_config('api', 'webterm', 'port')
57
+
52
58
  sessions = [
53
59
  line.split(':', maxsplit=1)[0]
54
60
  for line in proc.stdout.read().decode('utf-8').split('\n')
55
61
  ]
62
+ mrsm_sessions_ports = []
63
+ for session in sessions:
64
+ if '--' not in session:
65
+ continue
66
+
67
+ parts = session.split('--', maxsplit=1)
68
+ if len(parts) != 2:
69
+ continue
70
+
71
+ if not parts[0].endswith(tmux_suffix):
72
+ continue
73
+
74
+ try:
75
+ session_port = int(parts[1])
76
+ except Exception:
77
+ continue
78
+
79
+ mrsm_sessions_ports.append((session, session_port))
80
+
56
81
  return [
57
82
  session
58
- for session in sessions
59
- if session.endswith(tmux_suffix)
83
+ for session, session_port in mrsm_sessions_ports
84
+ if session_port == port
60
85
  ]
@@ -9,7 +9,6 @@ Default actions available to the mrsm CLI.
9
9
  from __future__ import annotations
10
10
  from meerschaum.utils.typing import Callable, Any, Optional, Union, List, Dict, SuccessTuple
11
11
  from meerschaum.utils.packages import get_modules_from_package
12
- _custom_actions = []
13
12
 
14
13
  __all__ = (
15
14
  'get_action',
@@ -307,6 +306,8 @@ __all__ = ['actions', 'get_subactions', 'get_action', 'get_main_action_name', 'g
307
306
  ### functions that do not begin with '_' from all submodules.
308
307
  from inspect import getmembers, isfunction
309
308
  actions = {}
309
+ _custom_actions_plugins: Dict[str, str] = {}
310
+ _plugins_actions: Dict[str, List[str]] = {}
310
311
 
311
312
  for module in modules:
312
313
  ### A couple important things happening here:
@@ -329,8 +330,8 @@ for module in modules:
329
330
  if isfunction(ob[1])
330
331
  ### check that the function belongs to the module
331
332
  and ob[0] == module.__name__.replace('_', '').split('.')[-1]
332
- ### skip functions that start with '_'
333
- and ob[0][0] != '_'
333
+ ### skip functions that start with '__'
334
+ and ob[0][0] != '__'
334
335
  ]
335
336
  )
336
337
  )
@@ -362,4 +363,5 @@ __pdoc__ = {
362
363
  }
363
364
  for a in actions:
364
365
  __pdoc__[a] = False
365
- meerschaum.plugins.load_plugins()
366
+
367
+ meerschaum.plugins.load_plugins(skip_if_loaded=True)