singlestoredb 1.8.0__py3-none-any.whl → 1.9.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.
Potentially problematic release.
This version of singlestoredb might be problematic. Click here for more details.
- singlestoredb/__init__.py +2 -2
- singlestoredb/config.py +6 -0
- singlestoredb/connection.py +11 -0
- singlestoredb/fusion/handler.py +3 -0
- singlestoredb/fusion/handlers/export.py +6 -14
- singlestoredb/fusion/handlers/files.py +690 -0
- singlestoredb/fusion/handlers/stage.py +103 -91
- singlestoredb/fusion/handlers/utils.py +148 -0
- singlestoredb/management/__init__.py +1 -0
- singlestoredb/management/export.py +20 -184
- singlestoredb/management/files.py +1038 -0
- singlestoredb/management/workspace.py +162 -349
- singlestoredb/mysql/connection.py +9 -1
- singlestoredb/tests/test.ipynb +18 -0
- singlestoredb/tests/test2.ipynb +18 -0
- singlestoredb/tests/test_management.py +273 -1
- {singlestoredb-1.8.0.dist-info → singlestoredb-1.9.0.dist-info}/METADATA +1 -1
- {singlestoredb-1.8.0.dist-info → singlestoredb-1.9.0.dist-info}/RECORD +24 -18
- {singlestoredb-1.8.0.dist-info → singlestoredb-1.9.0.dist-info}/WHEEL +1 -1
- {singlestoredb-1.8.0.dist-info → singlestoredb-1.9.0.dist-info}/top_level.txt +1 -0
- sqlx/__init__.py +4 -0
- sqlx/magic.py +113 -0
- {singlestoredb-1.8.0.dist-info → singlestoredb-1.9.0.dist-info}/LICENSE +0 -0
- {singlestoredb-1.8.0.dist-info → singlestoredb-1.9.0.dist-info}/entry_points.txt +0 -0
|
@@ -7,24 +7,26 @@ from .. import result
|
|
|
7
7
|
from ..handler import SQLHandler
|
|
8
8
|
from ..result import FusionSQLResult
|
|
9
9
|
from .utils import dt_isoformat
|
|
10
|
-
from .utils import
|
|
10
|
+
from .utils import get_deployment
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class ShowStageFilesHandler(SQLHandler):
|
|
14
14
|
"""
|
|
15
|
-
SHOW STAGE FILES [
|
|
15
|
+
SHOW STAGE FILES [ in ]
|
|
16
16
|
[ at_path ] [ <like> ]
|
|
17
17
|
[ <order-by> ]
|
|
18
18
|
[ <limit> ] [ recursive ] [ extended ];
|
|
19
19
|
|
|
20
|
-
#
|
|
21
|
-
|
|
20
|
+
# Deployment
|
|
21
|
+
in = { in_group | in_deployment }
|
|
22
|
+
in_group = IN GROUP { deployment_id | deployment_name }
|
|
23
|
+
in_deployment = IN { deployment_id | deployment_name }
|
|
22
24
|
|
|
23
|
-
# ID of
|
|
24
|
-
|
|
25
|
+
# ID of deployment
|
|
26
|
+
deployment_id = ID '<deployment-id>'
|
|
25
27
|
|
|
26
|
-
# Name of
|
|
27
|
-
|
|
28
|
+
# Name of deployment
|
|
29
|
+
deployment_name = '<deployment-name>'
|
|
28
30
|
|
|
29
31
|
# Stage path to list
|
|
30
32
|
at_path = AT '<path>'
|
|
@@ -44,10 +46,10 @@ class ShowStageFilesHandler(SQLHandler):
|
|
|
44
46
|
|
|
45
47
|
Arguments
|
|
46
48
|
---------
|
|
47
|
-
* ``<
|
|
48
|
-
the Stage is attached.
|
|
49
|
-
* ``<group_name>``: The name of the workspace group in which
|
|
49
|
+
* ``<deployment-id>``: The ID of the deployment in which
|
|
50
50
|
the Stage is attached.
|
|
51
|
+
* ``<deployment-name>``: The name of the deployment in which
|
|
52
|
+
which the Stage is attached.
|
|
51
53
|
* ``<path>``: A path in the Stage.
|
|
52
54
|
* ``<pattern>``: A pattern similar to SQL LIKE clause.
|
|
53
55
|
Uses ``%`` as the wildcard character.
|
|
@@ -62,8 +64,8 @@ class ShowStageFilesHandler(SQLHandler):
|
|
|
62
64
|
key. By default, the results are sorted in the ascending order.
|
|
63
65
|
* The ``AT PATH`` clause specifies the path in the Stage to list
|
|
64
66
|
the files from.
|
|
65
|
-
* The ``IN
|
|
66
|
-
|
|
67
|
+
* The ``IN`` clause specifies the ID or the name of the
|
|
68
|
+
deployment in which the Stage is attached.
|
|
67
69
|
* Use the ``RECURSIVE`` clause to list the files recursively.
|
|
68
70
|
* To return more information about the files, use the ``EXTENDED``
|
|
69
71
|
clause.
|
|
@@ -72,12 +74,12 @@ class ShowStageFilesHandler(SQLHandler):
|
|
|
72
74
|
--------
|
|
73
75
|
The following command lists the files at a specific path::
|
|
74
76
|
|
|
75
|
-
SHOW STAGE FILES IN
|
|
77
|
+
SHOW STAGE FILES IN 'wsg1' AT PATH "/data/";
|
|
76
78
|
|
|
77
79
|
The following command lists the files recursively with
|
|
78
80
|
additional information::
|
|
79
81
|
|
|
80
|
-
SHOW STAGE FILES IN
|
|
82
|
+
SHOW STAGE FILES IN 'wsg1' RECURSIVE EXTENDED;
|
|
81
83
|
|
|
82
84
|
See Also
|
|
83
85
|
--------
|
|
@@ -87,7 +89,7 @@ class ShowStageFilesHandler(SQLHandler):
|
|
|
87
89
|
""" # noqa: E501
|
|
88
90
|
|
|
89
91
|
def run(self, params: Dict[str, Any]) -> Optional[FusionSQLResult]:
|
|
90
|
-
wg =
|
|
92
|
+
wg = get_deployment(params)
|
|
91
93
|
|
|
92
94
|
res = FusionSQLResult()
|
|
93
95
|
res.add_field('Name', result.STRING)
|
|
@@ -132,20 +134,22 @@ ShowStageFilesHandler.register(overwrite=True)
|
|
|
132
134
|
class UploadStageFileHandler(SQLHandler):
|
|
133
135
|
"""
|
|
134
136
|
UPLOAD FILE TO STAGE stage_path
|
|
135
|
-
[
|
|
137
|
+
[ in ]
|
|
136
138
|
FROM local_path [ overwrite ];
|
|
137
139
|
|
|
138
140
|
# Path to stage file
|
|
139
141
|
stage_path = '<stage-path>'
|
|
140
142
|
|
|
141
|
-
#
|
|
142
|
-
|
|
143
|
+
# Deployment
|
|
144
|
+
in = { in_group | in_deployment }
|
|
145
|
+
in_group = IN GROUP { deployment_id | deployment_name }
|
|
146
|
+
in_deployment = IN { deployment_id | deployment_name }
|
|
143
147
|
|
|
144
|
-
# ID of
|
|
145
|
-
|
|
148
|
+
# ID of deployment
|
|
149
|
+
deployment_id = ID '<deployment-id>'
|
|
146
150
|
|
|
147
|
-
# Name of
|
|
148
|
-
|
|
151
|
+
# Name of deployment
|
|
152
|
+
deployment_name = '<deployment-name>'
|
|
149
153
|
|
|
150
154
|
# Path to local file
|
|
151
155
|
local_path = '<local-path>'
|
|
@@ -162,17 +166,17 @@ class UploadStageFileHandler(SQLHandler):
|
|
|
162
166
|
|
|
163
167
|
Arguments
|
|
164
168
|
---------
|
|
165
|
-
* ``<
|
|
166
|
-
* ``<
|
|
169
|
+
* ``<stage-path>``: The path in the Stage where the file is uploaded.
|
|
170
|
+
* ``<deployment-id>``: The ID of the deployment in which the Stage
|
|
167
171
|
is attached.
|
|
168
|
-
* ``<
|
|
169
|
-
Stage is attached.
|
|
172
|
+
* ``<deployment-name>``: The name of the deployment in which
|
|
173
|
+
which the Stage is attached.
|
|
170
174
|
* ``<local-path>``: The path to the file to upload in the local
|
|
171
175
|
directory.
|
|
172
176
|
|
|
173
177
|
Remarks
|
|
174
178
|
-------
|
|
175
|
-
* The ``IN
|
|
179
|
+
* The ``IN`` clause specifies the ID or the name of the workspace
|
|
176
180
|
group in which the Stage is attached.
|
|
177
181
|
* If the ``OVERWRITE`` clause is specified, any existing file at the
|
|
178
182
|
specified path in the Stage is overwritten.
|
|
@@ -182,7 +186,7 @@ class UploadStageFileHandler(SQLHandler):
|
|
|
182
186
|
The following command uploads a file to a Stage and overwrites any
|
|
183
187
|
existing files at the specified path::
|
|
184
188
|
|
|
185
|
-
UPLOAD FILE TO STAGE '/data/stats.csv' IN
|
|
189
|
+
UPLOAD FILE TO STAGE '/data/stats.csv' IN 'wsg1'
|
|
186
190
|
FROM '/tmp/user/stats.csv' OVERWRITE;
|
|
187
191
|
|
|
188
192
|
See Also
|
|
@@ -192,7 +196,7 @@ class UploadStageFileHandler(SQLHandler):
|
|
|
192
196
|
""" # noqa: E501
|
|
193
197
|
|
|
194
198
|
def run(self, params: Dict[str, Any]) -> Optional[FusionSQLResult]:
|
|
195
|
-
wg =
|
|
199
|
+
wg = get_deployment(params)
|
|
196
200
|
wg.stage.upload_file(
|
|
197
201
|
params['local_path'], params['stage_path'],
|
|
198
202
|
overwrite=params['overwrite'],
|
|
@@ -206,7 +210,7 @@ UploadStageFileHandler.register(overwrite=True)
|
|
|
206
210
|
class DownloadStageFileHandler(SQLHandler):
|
|
207
211
|
"""
|
|
208
212
|
DOWNLOAD STAGE FILE stage_path
|
|
209
|
-
[
|
|
213
|
+
[ in ]
|
|
210
214
|
[ local_path ]
|
|
211
215
|
[ overwrite ]
|
|
212
216
|
[ encoding ];
|
|
@@ -214,14 +218,16 @@ class DownloadStageFileHandler(SQLHandler):
|
|
|
214
218
|
# Path to stage file
|
|
215
219
|
stage_path = '<stage-path>'
|
|
216
220
|
|
|
217
|
-
#
|
|
218
|
-
|
|
221
|
+
# Deployment
|
|
222
|
+
in = { in_group | in_deployment }
|
|
223
|
+
in_group = IN GROUP { deployment_id | deployment_name }
|
|
224
|
+
in_deployment = IN { deployment_id | deployment_name }
|
|
219
225
|
|
|
220
|
-
# ID of
|
|
221
|
-
|
|
226
|
+
# ID of deployment
|
|
227
|
+
deployment_id = ID '<deployment-id>'
|
|
222
228
|
|
|
223
|
-
# Name of
|
|
224
|
-
|
|
229
|
+
# Name of deployment
|
|
230
|
+
deployment_name = '<deployment-name>'
|
|
225
231
|
|
|
226
232
|
# Path to local file
|
|
227
233
|
local_path = TO '<local-path>'
|
|
@@ -241,11 +247,11 @@ class DownloadStageFileHandler(SQLHandler):
|
|
|
241
247
|
|
|
242
248
|
Arguments
|
|
243
249
|
---------
|
|
244
|
-
* ``<
|
|
245
|
-
* ``<
|
|
246
|
-
Stage is attached.
|
|
247
|
-
* ``<group_name>``: The name of the workspace group in which the
|
|
250
|
+
* ``<stage-path>``: The path to the file to download in a Stage.
|
|
251
|
+
* ``<deployment-id>``: The ID of the deployment in which the
|
|
248
252
|
Stage is attached.
|
|
253
|
+
* ``<deployment-name>``: The name of the deployment in which
|
|
254
|
+
which the Stage is attached.
|
|
249
255
|
* ``<encoding>``: The encoding to apply to the downloaded file.
|
|
250
256
|
* ``<local-path>``: Specifies the path in the local directory
|
|
251
257
|
where the file is downloaded.
|
|
@@ -254,8 +260,8 @@ class DownloadStageFileHandler(SQLHandler):
|
|
|
254
260
|
-------
|
|
255
261
|
* If the ``OVERWRITE`` clause is specified, any existing file at
|
|
256
262
|
the download location is overwritten.
|
|
257
|
-
* The ``IN
|
|
258
|
-
|
|
263
|
+
* The ``IN`` clause specifies the ID or the name of the
|
|
264
|
+
deployment in which the Stage is attached.
|
|
259
265
|
* By default, files are downloaded in binary encoding. To view
|
|
260
266
|
the contents of the file on the standard output, use the
|
|
261
267
|
``ENCODING`` clause and specify an encoding.
|
|
@@ -267,12 +273,12 @@ class DownloadStageFileHandler(SQLHandler):
|
|
|
267
273
|
The following command displays the contents of the file on the
|
|
268
274
|
standard output::
|
|
269
275
|
|
|
270
|
-
DOWNLOAD STAGE FILE '/data/stats.csv' IN
|
|
276
|
+
DOWNLOAD STAGE FILE '/data/stats.csv' IN 'wsgroup1' ENCODING 'utf8';
|
|
271
277
|
|
|
272
278
|
The following command downloads a file to a specific location and
|
|
273
279
|
overwrites any existing file with the name ``stats.csv`` on the local storage::
|
|
274
280
|
|
|
275
|
-
DOWNLOAD STAGE FILE '/data/stats.csv' IN
|
|
281
|
+
DOWNLOAD STAGE FILE '/data/stats.csv' IN 'wsgroup1'
|
|
276
282
|
TO '/tmp/data.csv' OVERWRITE;
|
|
277
283
|
|
|
278
284
|
See Also
|
|
@@ -282,7 +288,7 @@ class DownloadStageFileHandler(SQLHandler):
|
|
|
282
288
|
""" # noqa: E501
|
|
283
289
|
|
|
284
290
|
def run(self, params: Dict[str, Any]) -> Optional[FusionSQLResult]:
|
|
285
|
-
wg =
|
|
291
|
+
wg = get_deployment(params)
|
|
286
292
|
|
|
287
293
|
out = wg.stage.download_file(
|
|
288
294
|
params['stage_path'],
|
|
@@ -309,19 +315,21 @@ DownloadStageFileHandler.register(overwrite=True)
|
|
|
309
315
|
class DropStageFileHandler(SQLHandler):
|
|
310
316
|
"""
|
|
311
317
|
DROP STAGE FILE stage_path
|
|
312
|
-
[
|
|
318
|
+
[ in ];
|
|
313
319
|
|
|
314
320
|
# Path to stage file
|
|
315
321
|
stage_path = '<stage-path>'
|
|
316
322
|
|
|
317
|
-
#
|
|
318
|
-
|
|
323
|
+
# Deployment
|
|
324
|
+
in = { in_group | in_deployment }
|
|
325
|
+
in_group = IN GROUP { deployment_id | deployment_name }
|
|
326
|
+
in_deployment = IN { deployment_id | deployment_name }
|
|
319
327
|
|
|
320
|
-
# ID of
|
|
321
|
-
|
|
328
|
+
# ID of deployment
|
|
329
|
+
deployment_id = ID '<deployment-id>'
|
|
322
330
|
|
|
323
|
-
# Name of
|
|
324
|
-
|
|
331
|
+
# Name of deployment
|
|
332
|
+
deployment_name = '<deployment-name>'
|
|
325
333
|
|
|
326
334
|
Description
|
|
327
335
|
-----------
|
|
@@ -332,23 +340,23 @@ class DropStageFileHandler(SQLHandler):
|
|
|
332
340
|
|
|
333
341
|
Arguments
|
|
334
342
|
---------
|
|
335
|
-
* ``<
|
|
336
|
-
* ``<
|
|
343
|
+
* ``<stage-path>``: The path to the file to delete in a Stage.
|
|
344
|
+
* ``<deployment-id>``: The ID of the deployment in which the
|
|
337
345
|
Stage is attached.
|
|
338
|
-
* ``<
|
|
339
|
-
the Stage is attached.
|
|
346
|
+
* ``<deployment-name>``: The name of the deployment in which
|
|
347
|
+
which the Stage is attached.
|
|
340
348
|
|
|
341
349
|
Remarks
|
|
342
350
|
-------
|
|
343
|
-
* The ``IN
|
|
344
|
-
|
|
351
|
+
* The ``IN`` clause specifies the ID or the name of the
|
|
352
|
+
deployment in which the Stage is attached.
|
|
345
353
|
|
|
346
354
|
Example
|
|
347
355
|
--------
|
|
348
356
|
The following command deletes a file from a Stage attached to
|
|
349
|
-
a
|
|
357
|
+
a deployment named **wsg1**::
|
|
350
358
|
|
|
351
|
-
DROP STAGE FILE '/data/stats.csv' IN
|
|
359
|
+
DROP STAGE FILE '/data/stats.csv' IN 'wsg1';
|
|
352
360
|
|
|
353
361
|
See Also
|
|
354
362
|
--------
|
|
@@ -357,7 +365,7 @@ class DropStageFileHandler(SQLHandler):
|
|
|
357
365
|
""" # noqa: E501
|
|
358
366
|
|
|
359
367
|
def run(self, params: Dict[str, Any]) -> Optional[FusionSQLResult]:
|
|
360
|
-
wg =
|
|
368
|
+
wg = get_deployment(params)
|
|
361
369
|
wg.stage.remove(params['stage_path'])
|
|
362
370
|
return None
|
|
363
371
|
|
|
@@ -368,20 +376,22 @@ DropStageFileHandler.register(overwrite=True)
|
|
|
368
376
|
class DropStageFolderHandler(SQLHandler):
|
|
369
377
|
"""
|
|
370
378
|
DROP STAGE FOLDER stage_path
|
|
371
|
-
[
|
|
379
|
+
[ in ]
|
|
372
380
|
[ recursive ];
|
|
373
381
|
|
|
374
382
|
# Path to stage folder
|
|
375
383
|
stage_path = '<stage-path>'
|
|
376
384
|
|
|
377
|
-
#
|
|
378
|
-
|
|
385
|
+
# Deployment
|
|
386
|
+
in = { in_group | in_deployment }
|
|
387
|
+
in_group = IN GROUP { deployment_id | deployment_name }
|
|
388
|
+
in_deployment = IN { deployment_id | deployment_name }
|
|
379
389
|
|
|
380
|
-
# ID of
|
|
381
|
-
|
|
390
|
+
# ID of deployment
|
|
391
|
+
deployment_id = ID '<deployment-id>'
|
|
382
392
|
|
|
383
|
-
# Name of
|
|
384
|
-
|
|
393
|
+
# Name of deployment
|
|
394
|
+
deployment_name = '<deployment-name>'
|
|
385
395
|
|
|
386
396
|
# Should folers be deleted recursively?
|
|
387
397
|
recursive = RECURSIVE
|
|
@@ -395,11 +405,11 @@ class DropStageFolderHandler(SQLHandler):
|
|
|
395
405
|
|
|
396
406
|
Arguments
|
|
397
407
|
---------
|
|
398
|
-
* ``<
|
|
399
|
-
* ``<
|
|
400
|
-
Stage is attached.
|
|
401
|
-
* ``<group_name>``: The name of the workspace group in which the
|
|
408
|
+
* ``<stage-path>``: The path to the folder to delete in a Stage.
|
|
409
|
+
* ``<deployment-id>``: The ID of the deployment in which the
|
|
402
410
|
Stage is attached.
|
|
411
|
+
* ``<deployment-name>``: The name of the deployment in which
|
|
412
|
+
which the Stage is attached.
|
|
403
413
|
|
|
404
414
|
Remarks
|
|
405
415
|
-------
|
|
@@ -409,9 +419,9 @@ class DropStageFolderHandler(SQLHandler):
|
|
|
409
419
|
Example
|
|
410
420
|
-------
|
|
411
421
|
The following command recursively deletes a folder from a Stage
|
|
412
|
-
attached to a
|
|
422
|
+
attached to a deployment named **wsg1**::
|
|
413
423
|
|
|
414
|
-
DROP STAGE FOLDER '/data/' IN
|
|
424
|
+
DROP STAGE FOLDER '/data/' IN 'wsg1' RECURSIVE;
|
|
415
425
|
|
|
416
426
|
See Also
|
|
417
427
|
--------
|
|
@@ -420,7 +430,7 @@ class DropStageFolderHandler(SQLHandler):
|
|
|
420
430
|
""" # noqa: E501
|
|
421
431
|
|
|
422
432
|
def run(self, params: Dict[str, Any]) -> Optional[FusionSQLResult]:
|
|
423
|
-
wg =
|
|
433
|
+
wg = get_deployment(params)
|
|
424
434
|
if params['recursive']:
|
|
425
435
|
wg.stage.removedirs(params['stage_path'])
|
|
426
436
|
else:
|
|
@@ -434,17 +444,19 @@ DropStageFolderHandler.register(overwrite=True)
|
|
|
434
444
|
class CreateStageFolderHandler(SQLHandler):
|
|
435
445
|
"""
|
|
436
446
|
CREATE STAGE FOLDER stage_path
|
|
437
|
-
[
|
|
447
|
+
[ in ]
|
|
438
448
|
[ overwrite ];
|
|
439
449
|
|
|
440
|
-
#
|
|
441
|
-
|
|
450
|
+
# Deployment
|
|
451
|
+
in = { in_group | in_deployment }
|
|
452
|
+
in_group = IN GROUP { deployment_id | deployment_name }
|
|
453
|
+
in_deployment = IN { deployment_id | deployment_name }
|
|
442
454
|
|
|
443
|
-
# ID of
|
|
444
|
-
|
|
455
|
+
# ID of deployment
|
|
456
|
+
deployment_id = ID '<deployment-id>'
|
|
445
457
|
|
|
446
|
-
# Name of
|
|
447
|
-
|
|
458
|
+
# Name of deployment
|
|
459
|
+
deployment_name = '<deployment-name>'
|
|
448
460
|
|
|
449
461
|
# Path to stage folder
|
|
450
462
|
stage_path = '<stage-path>'
|
|
@@ -458,31 +470,31 @@ class CreateStageFolderHandler(SQLHandler):
|
|
|
458
470
|
|
|
459
471
|
Arguments
|
|
460
472
|
---------
|
|
461
|
-
* ``<
|
|
473
|
+
* ``<stage-path>``: The path in a Stage where the folder
|
|
462
474
|
is created. The path must end with a trailing slash (/).
|
|
463
|
-
* ``<
|
|
475
|
+
* ``<deployment-id>``: The ID of the deployment in which
|
|
464
476
|
the Stage is attached.
|
|
465
|
-
* ``<
|
|
477
|
+
* ``<deployment-name>``: The name of the deployment in which
|
|
466
478
|
which the Stage is attached.
|
|
467
479
|
|
|
468
480
|
Remarks
|
|
469
481
|
-------
|
|
470
482
|
* If the ``OVERWRITE`` clause is specified, any existing
|
|
471
483
|
folder at the specified path is overwritten.
|
|
472
|
-
* The ``IN
|
|
473
|
-
the
|
|
484
|
+
* The ``IN`` clause specifies the ID or the name of
|
|
485
|
+
the deployment in which the Stage is attached.
|
|
474
486
|
|
|
475
487
|
Example
|
|
476
488
|
-------
|
|
477
489
|
The following command creates a folder in a Stage attached
|
|
478
|
-
to a
|
|
490
|
+
to a deployment named **wsg1**::
|
|
479
491
|
|
|
480
|
-
CREATE STAGE FOLDER `/data/csv/` IN
|
|
492
|
+
CREATE STAGE FOLDER `/data/csv/` IN 'wsg1';
|
|
481
493
|
|
|
482
494
|
"""
|
|
483
495
|
|
|
484
496
|
def run(self, params: Dict[str, Any]) -> Optional[FusionSQLResult]:
|
|
485
|
-
wg =
|
|
497
|
+
wg = get_deployment(params)
|
|
486
498
|
wg.stage.mkdir(params['stage_path'], overwrite=params['overwrite'])
|
|
487
499
|
return None
|
|
488
500
|
|
|
@@ -4,9 +4,16 @@ import os
|
|
|
4
4
|
from typing import Any
|
|
5
5
|
from typing import Dict
|
|
6
6
|
from typing import Optional
|
|
7
|
+
from typing import Union
|
|
7
8
|
|
|
8
9
|
from ...exceptions import ManagementError
|
|
9
10
|
from ...management import manage_workspaces
|
|
11
|
+
from ...management.files import FilesManager
|
|
12
|
+
from ...management.files import FileSpace
|
|
13
|
+
from ...management.files import manage_files
|
|
14
|
+
from ...management.files import PERSONAL_SPACE
|
|
15
|
+
from ...management.files import SHARED_SPACE
|
|
16
|
+
from ...management.workspace import StarterWorkspace
|
|
10
17
|
from ...management.workspace import Workspace
|
|
11
18
|
from ...management.workspace import WorkspaceGroup
|
|
12
19
|
from ...management.workspace import WorkspaceManager
|
|
@@ -17,6 +24,11 @@ def get_workspace_manager() -> WorkspaceManager:
|
|
|
17
24
|
return manage_workspaces()
|
|
18
25
|
|
|
19
26
|
|
|
27
|
+
def get_files_manager() -> FilesManager:
|
|
28
|
+
"""Return a new files manager."""
|
|
29
|
+
return manage_files()
|
|
30
|
+
|
|
31
|
+
|
|
20
32
|
def dt_isoformat(dt: Optional[datetime.datetime]) -> Optional[str]:
|
|
21
33
|
"""Convert datetime to string."""
|
|
22
34
|
if dt is None:
|
|
@@ -160,3 +172,139 @@ def get_workspace(params: Dict[str, Any]) -> Workspace:
|
|
|
160
172
|
raise ValueError('clusters and shared workspaces are not currently supported')
|
|
161
173
|
|
|
162
174
|
raise KeyError('no workspace was specified')
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def get_deployment(
|
|
178
|
+
params: Dict[str, Any],
|
|
179
|
+
) -> Union[WorkspaceGroup, StarterWorkspace]:
|
|
180
|
+
"""
|
|
181
|
+
Find a starter workspace matching deployment_id or deployment_name.
|
|
182
|
+
|
|
183
|
+
This function will get a starter workspace or ID from the
|
|
184
|
+
following parameters:
|
|
185
|
+
|
|
186
|
+
* params['deployment_name']
|
|
187
|
+
* params['deployment_id']
|
|
188
|
+
* params['group']['deployment_name']
|
|
189
|
+
* params['group']['deployment_id']
|
|
190
|
+
* params['in_deployment']['deployment_name']
|
|
191
|
+
* params['in_deployment']['deployment_id']
|
|
192
|
+
|
|
193
|
+
Or, from the SINGLESTOREDB_WORKSPACE_GROUP
|
|
194
|
+
or SINGLESTOREDB_CLUSTER environment variables.
|
|
195
|
+
|
|
196
|
+
"""
|
|
197
|
+
manager = get_workspace_manager()
|
|
198
|
+
|
|
199
|
+
deployment_name = params.get('deployment_name') or \
|
|
200
|
+
(params.get('in_deployment') or {}).get('deployment_name') or \
|
|
201
|
+
(params.get('group') or {}).get('deployment_name')
|
|
202
|
+
if deployment_name:
|
|
203
|
+
workspace_groups = [
|
|
204
|
+
x for x in manager.workspace_groups
|
|
205
|
+
if x.name == deployment_name
|
|
206
|
+
]
|
|
207
|
+
|
|
208
|
+
starter_workspaces = []
|
|
209
|
+
if not workspace_groups:
|
|
210
|
+
filtered_starter_workspaces = [
|
|
211
|
+
x for x in manager.starter_workspaces
|
|
212
|
+
if x.name == deployment_name
|
|
213
|
+
]
|
|
214
|
+
|
|
215
|
+
if not filtered_starter_workspaces:
|
|
216
|
+
raise KeyError(
|
|
217
|
+
f'no deployment found with name: {deployment_name}',
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
starter_workspaces = filtered_starter_workspaces
|
|
221
|
+
|
|
222
|
+
if len(workspace_groups) > 1:
|
|
223
|
+
ids = ', '.join(x.id for x in workspace_groups)
|
|
224
|
+
raise ValueError(
|
|
225
|
+
f'more than one workspace group with given name was found: {ids}',
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
if len(starter_workspaces) > 1:
|
|
229
|
+
ids = ', '.join(x.id for x in starter_workspaces)
|
|
230
|
+
raise ValueError(
|
|
231
|
+
f'more than one starter workspace with given name was found: {ids}',
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
if workspace_groups:
|
|
235
|
+
return workspace_groups[0]
|
|
236
|
+
else:
|
|
237
|
+
return starter_workspaces[0]
|
|
238
|
+
|
|
239
|
+
deployment_id = params.get('deployment_id') or \
|
|
240
|
+
(params.get('in_deployment') or {}).get('deployment_id') or \
|
|
241
|
+
(params.get('group') or {}).get('deployment_id')
|
|
242
|
+
if deployment_id:
|
|
243
|
+
try:
|
|
244
|
+
return manager.get_workspace_group(deployment_id)
|
|
245
|
+
except ManagementError as exc:
|
|
246
|
+
if exc.errno == 404:
|
|
247
|
+
try:
|
|
248
|
+
return manager.get_starter_workspace(deployment_id)
|
|
249
|
+
except ManagementError as exc:
|
|
250
|
+
if exc.errno == 404:
|
|
251
|
+
raise KeyError(f'no deployment found with ID: {deployment_id}')
|
|
252
|
+
raise
|
|
253
|
+
else:
|
|
254
|
+
raise
|
|
255
|
+
|
|
256
|
+
if os.environ.get('SINGLESTOREDB_WORKSPACE_GROUP'):
|
|
257
|
+
try:
|
|
258
|
+
return manager.get_workspace_group(
|
|
259
|
+
os.environ['SINGLESTOREDB_WORKSPACE_GROUP'],
|
|
260
|
+
)
|
|
261
|
+
except ManagementError as exc:
|
|
262
|
+
if exc.errno == 404:
|
|
263
|
+
raise KeyError(
|
|
264
|
+
'no workspace found with ID: '
|
|
265
|
+
f'{os.environ["SINGLESTOREDB_WORKSPACE_GROUP"]}',
|
|
266
|
+
)
|
|
267
|
+
raise
|
|
268
|
+
|
|
269
|
+
if os.environ.get('SINGLESTOREDB_CLUSTER'):
|
|
270
|
+
try:
|
|
271
|
+
return manager.get_starter_workspace(
|
|
272
|
+
os.environ['SINGLESTOREDB_CLUSTER'],
|
|
273
|
+
)
|
|
274
|
+
except ManagementError as exc:
|
|
275
|
+
if exc.errno == 404:
|
|
276
|
+
raise KeyError(
|
|
277
|
+
'no starter workspace found with ID: '
|
|
278
|
+
f'{os.environ["SINGLESTOREDB_CLUSTER"]}',
|
|
279
|
+
)
|
|
280
|
+
raise
|
|
281
|
+
|
|
282
|
+
raise KeyError('no deployment was specified')
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
def get_file_space(params: Dict[str, Any]) -> FileSpace:
|
|
286
|
+
"""
|
|
287
|
+
Retrieve the specified file space.
|
|
288
|
+
|
|
289
|
+
This function will get a file space from the
|
|
290
|
+
following parameters:
|
|
291
|
+
|
|
292
|
+
* params['file_location']
|
|
293
|
+
"""
|
|
294
|
+
manager = get_files_manager()
|
|
295
|
+
|
|
296
|
+
file_location = params.get('file_location')
|
|
297
|
+
if file_location:
|
|
298
|
+
file_location_lower_case = file_location.lower()
|
|
299
|
+
if (
|
|
300
|
+
file_location_lower_case != PERSONAL_SPACE and
|
|
301
|
+
file_location_lower_case != SHARED_SPACE
|
|
302
|
+
):
|
|
303
|
+
raise ValueError(f'invalid file location: {file_location}')
|
|
304
|
+
|
|
305
|
+
if file_location_lower_case == PERSONAL_SPACE:
|
|
306
|
+
return manager.personal_space
|
|
307
|
+
elif file_location_lower_case == SHARED_SPACE:
|
|
308
|
+
return manager.shared_space
|
|
309
|
+
|
|
310
|
+
raise KeyError('no file space was specified')
|