singlestoredb 1.14.1__py3-none-any.whl → 1.15.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 +14 -10
- singlestoredb/apps/_python_udfs.py +3 -3
- singlestoredb/config.py +5 -0
- singlestoredb/functions/decorator.py +32 -13
- singlestoredb/functions/ext/asgi.py +287 -27
- singlestoredb/functions/ext/timer.py +98 -0
- singlestoredb/functions/typing/numpy.py +20 -0
- singlestoredb/functions/typing/pandas.py +2 -0
- singlestoredb/functions/typing/polars.py +2 -0
- singlestoredb/functions/typing/pyarrow.py +2 -0
- singlestoredb/fusion/handler.py +17 -4
- singlestoredb/magics/run_personal.py +82 -1
- singlestoredb/magics/run_shared.py +82 -1
- singlestoredb/management/__init__.py +1 -0
- singlestoredb/management/export.py +1 -1
- singlestoredb/management/region.py +92 -0
- singlestoredb/management/workspace.py +180 -1
- singlestoredb/tests/ext_funcs/__init__.py +94 -55
- singlestoredb/tests/test.sql +22 -0
- singlestoredb/tests/test_ext_func.py +90 -0
- singlestoredb/tests/test_fusion.py +4 -1
- singlestoredb/tests/test_management.py +253 -20
- {singlestoredb-1.14.1.dist-info → singlestoredb-1.15.0.dist-info}/METADATA +3 -2
- {singlestoredb-1.14.1.dist-info → singlestoredb-1.15.0.dist-info}/RECORD +29 -24
- /singlestoredb/functions/{typing.py → typing/__init__.py} +0 -0
- {singlestoredb-1.14.1.dist-info → singlestoredb-1.15.0.dist-info}/LICENSE +0 -0
- {singlestoredb-1.14.1.dist-info → singlestoredb-1.15.0.dist-info}/WHEEL +0 -0
- {singlestoredb-1.14.1.dist-info → singlestoredb-1.15.0.dist-info}/entry_points.txt +0 -0
- {singlestoredb-1.14.1.dist-info → singlestoredb-1.15.0.dist-info}/top_level.txt +0 -0
|
@@ -162,6 +162,43 @@ class TestExtFunc(unittest.TestCase):
|
|
|
162
162
|
'from data order by id',
|
|
163
163
|
)
|
|
164
164
|
|
|
165
|
+
def test_timeout_double_mult(self):
|
|
166
|
+
with self.assertRaises(self.conn.OperationalError) as exc:
|
|
167
|
+
self.cur.execute(
|
|
168
|
+
'select timeout_double_mult(value, 100) as res '
|
|
169
|
+
'from longer_data order by id',
|
|
170
|
+
)
|
|
171
|
+
assert 'timeout' in str(exc.exception).lower()
|
|
172
|
+
|
|
173
|
+
def test_async_double_mult(self):
|
|
174
|
+
self.cur.execute(
|
|
175
|
+
'select async_double_mult(value, 100) as res from data order by id',
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
assert [tuple(x) for x in self.cur] == \
|
|
179
|
+
[(200.0,), (200.0,), (500.0,), (400.0,), (0.0,)]
|
|
180
|
+
|
|
181
|
+
desc = self.cur.description
|
|
182
|
+
assert len(desc) == 1
|
|
183
|
+
assert desc[0].name == 'res'
|
|
184
|
+
assert desc[0].type_code == ft.DOUBLE
|
|
185
|
+
assert desc[0].null_ok is False
|
|
186
|
+
|
|
187
|
+
# NULL is not valid
|
|
188
|
+
with self.assertRaises(self.conn.OperationalError):
|
|
189
|
+
self.cur.execute(
|
|
190
|
+
'select async_double_mult(value, NULL) as res '
|
|
191
|
+
'from data order by id',
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
def test_async_timeout_double_mult(self):
|
|
195
|
+
with self.assertRaises(self.conn.OperationalError) as exc:
|
|
196
|
+
self.cur.execute(
|
|
197
|
+
'select async_timeout_double_mult(value, 100) as res '
|
|
198
|
+
'from longer_data order by id',
|
|
199
|
+
)
|
|
200
|
+
assert 'timeout' in str(exc.exception).lower()
|
|
201
|
+
|
|
165
202
|
def test_pandas_double_mult(self):
|
|
166
203
|
self.cur.execute(
|
|
167
204
|
'select pandas_double_mult(value, 100) as res '
|
|
@@ -206,6 +243,28 @@ class TestExtFunc(unittest.TestCase):
|
|
|
206
243
|
'from data order by id',
|
|
207
244
|
)
|
|
208
245
|
|
|
246
|
+
def test_async_numpy_double_mult(self):
|
|
247
|
+
self.cur.execute(
|
|
248
|
+
'select async_numpy_double_mult(value, 100) as res '
|
|
249
|
+
'from data order by id',
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
assert [tuple(x) for x in self.cur] == \
|
|
253
|
+
[(200.0,), (200.0,), (500.0,), (400.0,), (0.0,)]
|
|
254
|
+
|
|
255
|
+
desc = self.cur.description
|
|
256
|
+
assert len(desc) == 1
|
|
257
|
+
assert desc[0].name == 'res'
|
|
258
|
+
assert desc[0].type_code == ft.DOUBLE
|
|
259
|
+
assert desc[0].null_ok is False
|
|
260
|
+
|
|
261
|
+
# NULL is not valid
|
|
262
|
+
with self.assertRaises(self.conn.OperationalError):
|
|
263
|
+
self.cur.execute(
|
|
264
|
+
'select async_numpy_double_mult(value, NULL) as res '
|
|
265
|
+
'from data order by id',
|
|
266
|
+
)
|
|
267
|
+
|
|
209
268
|
def test_arrow_double_mult(self):
|
|
210
269
|
self.cur.execute(
|
|
211
270
|
'select arrow_double_mult(value, 100) as res '
|
|
@@ -1246,6 +1305,17 @@ class TestExtFunc(unittest.TestCase):
|
|
|
1246
1305
|
assert desc[0].type_code == ft.LONGLONG
|
|
1247
1306
|
assert desc[0].null_ok is False
|
|
1248
1307
|
|
|
1308
|
+
def test_async_table_function(self):
|
|
1309
|
+
self.cur.execute('select * from async_table_function(5)')
|
|
1310
|
+
|
|
1311
|
+
assert [x[0] for x in self.cur] == [10, 10, 10, 10, 10]
|
|
1312
|
+
|
|
1313
|
+
desc = self.cur.description
|
|
1314
|
+
assert len(desc) == 1
|
|
1315
|
+
assert desc[0].name == 'a'
|
|
1316
|
+
assert desc[0].type_code == ft.LONGLONG
|
|
1317
|
+
assert desc[0].null_ok is False
|
|
1318
|
+
|
|
1249
1319
|
def test_table_function_tuple(self):
|
|
1250
1320
|
self.cur.execute('select * from table_function_tuple(3)')
|
|
1251
1321
|
|
|
@@ -1310,6 +1380,26 @@ class TestExtFunc(unittest.TestCase):
|
|
|
1310
1380
|
assert desc[1].type_code == ft.DOUBLE
|
|
1311
1381
|
assert desc[1].null_ok is False
|
|
1312
1382
|
|
|
1383
|
+
def test_async_vec_function_df(self):
|
|
1384
|
+
self.cur.execute('select * from async_vec_function_df(5, 10)')
|
|
1385
|
+
|
|
1386
|
+
out = list(self.cur)
|
|
1387
|
+
|
|
1388
|
+
assert out == [
|
|
1389
|
+
(1, 1.1),
|
|
1390
|
+
(2, 2.2),
|
|
1391
|
+
(3, 3.3),
|
|
1392
|
+
]
|
|
1393
|
+
|
|
1394
|
+
desc = self.cur.description
|
|
1395
|
+
assert len(desc) == 2
|
|
1396
|
+
assert desc[0].name == 'res'
|
|
1397
|
+
assert desc[0].type_code == ft.SHORT
|
|
1398
|
+
assert desc[0].null_ok is False
|
|
1399
|
+
assert desc[1].name == 'res2'
|
|
1400
|
+
assert desc[1].type_code == ft.DOUBLE
|
|
1401
|
+
assert desc[1].null_ok is False
|
|
1402
|
+
|
|
1313
1403
|
def test_vec_function_ints_masked(self):
|
|
1314
1404
|
self.cur.execute('select * from vec_function_ints_masked(5, 10)')
|
|
1315
1405
|
|
|
@@ -499,7 +499,10 @@ class TestJobsFusion(unittest.TestCase):
|
|
|
499
499
|
@classmethod
|
|
500
500
|
def tearDownClass(cls):
|
|
501
501
|
for job_id in cls.job_ids:
|
|
502
|
-
|
|
502
|
+
try:
|
|
503
|
+
cls.manager.organizations.current.jobs.delete(job_id)
|
|
504
|
+
except Exception:
|
|
505
|
+
pass
|
|
503
506
|
if cls.workspace_group is not None:
|
|
504
507
|
cls.workspace_group.terminate(force=True)
|
|
505
508
|
cls.manager = None
|
|
@@ -13,6 +13,9 @@ import pytest
|
|
|
13
13
|
import singlestoredb as s2
|
|
14
14
|
from singlestoredb.management.job import Status
|
|
15
15
|
from singlestoredb.management.job import TargetType
|
|
16
|
+
from singlestoredb.management.region import Region
|
|
17
|
+
from singlestoredb.management.region import RegionManager
|
|
18
|
+
from singlestoredb.management.utils import NamedList
|
|
16
19
|
|
|
17
20
|
|
|
18
21
|
TEST_DIR = pathlib.Path(os.path.dirname(__file__))
|
|
@@ -363,6 +366,121 @@ class TestWorkspace(unittest.TestCase):
|
|
|
363
366
|
assert 'endpoint' in cm.exception.msg, cm.exception.msg
|
|
364
367
|
|
|
365
368
|
|
|
369
|
+
@pytest.mark.skip('Not implemented in server yet')
|
|
370
|
+
@pytest.mark.management
|
|
371
|
+
class TestStarterWorkspace(unittest.TestCase):
|
|
372
|
+
|
|
373
|
+
manager = None
|
|
374
|
+
starter_workspace = None
|
|
375
|
+
starter_workspace_user = {
|
|
376
|
+
'username': 'starter_user',
|
|
377
|
+
'password': None,
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
@property
|
|
381
|
+
def starter_username(self):
|
|
382
|
+
"""Return the username for the starter workspace user."""
|
|
383
|
+
return self.starter_workspace_user['username']
|
|
384
|
+
|
|
385
|
+
@property
|
|
386
|
+
def password(self):
|
|
387
|
+
"""Return the password for the starter workspace user."""
|
|
388
|
+
return self.starter_workspace_user['password']
|
|
389
|
+
|
|
390
|
+
@classmethod
|
|
391
|
+
def setUpClass(cls):
|
|
392
|
+
cls.manager = s2.manage_workspaces()
|
|
393
|
+
|
|
394
|
+
us_regions = [x for x in cls.manager.regions if 'US' in x.name]
|
|
395
|
+
cls.password = secrets.token_urlsafe(20) + '-x&$'
|
|
396
|
+
|
|
397
|
+
name = clean_name(secrets.token_urlsafe(20)[:20])
|
|
398
|
+
|
|
399
|
+
cls.starter_workspace = cls.manager.create_starter_workspace(
|
|
400
|
+
f'starter-ws-test-{name}',
|
|
401
|
+
database_name=f'starter_db_{name}',
|
|
402
|
+
workspace_group={
|
|
403
|
+
'cell_id': random.choice(us_regions).id,
|
|
404
|
+
},
|
|
405
|
+
)
|
|
406
|
+
|
|
407
|
+
cls.starter_workspace.create_user(
|
|
408
|
+
username=cls.starter_username,
|
|
409
|
+
password=cls.password,
|
|
410
|
+
)
|
|
411
|
+
|
|
412
|
+
@classmethod
|
|
413
|
+
def tearDownClass(cls):
|
|
414
|
+
if cls.starter_workspace is not None:
|
|
415
|
+
cls.starter_workspace.terminate()
|
|
416
|
+
cls.manager = None
|
|
417
|
+
cls.password = None
|
|
418
|
+
|
|
419
|
+
def test_str(self):
|
|
420
|
+
assert self.starter_workspace.name in str(self.starter_workspace.name)
|
|
421
|
+
|
|
422
|
+
def test_repr(self):
|
|
423
|
+
assert repr(self.starter_workspace) == str(self.starter_workspace)
|
|
424
|
+
|
|
425
|
+
def test_get_starter_workspace(self):
|
|
426
|
+
workspace = self.manager.get_starter_workspace(self.starter_workspace.id)
|
|
427
|
+
assert workspace.id == self.starter_workspace.id, workspace.id
|
|
428
|
+
|
|
429
|
+
with self.assertRaises(s2.ManagementError) as cm:
|
|
430
|
+
workspace = self.manager.get_starter_workspace('bad id')
|
|
431
|
+
|
|
432
|
+
assert 'UUID' in cm.exception.msg, cm.exception.msg
|
|
433
|
+
|
|
434
|
+
def test_starter_workspaces(self):
|
|
435
|
+
workspaces = self.manager.starter_workspaces
|
|
436
|
+
ids = [x.id for x in workspaces]
|
|
437
|
+
names = [x.name for x in workspaces]
|
|
438
|
+
assert self.starter_workspace.id in ids
|
|
439
|
+
assert self.starter_workspace.name in names
|
|
440
|
+
|
|
441
|
+
objs = {}
|
|
442
|
+
for item in workspaces:
|
|
443
|
+
objs[item.id] = item
|
|
444
|
+
objs[item.name] = item
|
|
445
|
+
|
|
446
|
+
name = random.choice(names)
|
|
447
|
+
assert workspaces[name] == objs[name]
|
|
448
|
+
id = random.choice(ids)
|
|
449
|
+
assert workspaces[id] == objs[id]
|
|
450
|
+
|
|
451
|
+
def test_no_manager(self):
|
|
452
|
+
workspace = self.manager.get_starter_workspace(self.starter_workspace.id)
|
|
453
|
+
workspace._manager = None
|
|
454
|
+
|
|
455
|
+
with self.assertRaises(s2.ManagementError) as cm:
|
|
456
|
+
workspace.refresh()
|
|
457
|
+
|
|
458
|
+
assert 'No workspace manager' in cm.exception.msg, cm.exception.msg
|
|
459
|
+
|
|
460
|
+
with self.assertRaises(s2.ManagementError) as cm:
|
|
461
|
+
workspace.terminate()
|
|
462
|
+
|
|
463
|
+
assert 'No workspace manager' in cm.exception.msg, cm.exception.msg
|
|
464
|
+
|
|
465
|
+
def test_connect(self):
|
|
466
|
+
with self.starter_workspace.connect(
|
|
467
|
+
user=self.starter_username,
|
|
468
|
+
password=self.password,
|
|
469
|
+
) as conn:
|
|
470
|
+
with conn.cursor() as cur:
|
|
471
|
+
cur.execute('show databases')
|
|
472
|
+
assert 'starter_db' in [x[0] for x in list(cur)]
|
|
473
|
+
|
|
474
|
+
# Test missing endpoint
|
|
475
|
+
workspace = self.manager.get_starter_workspace(self.starter_workspace.id)
|
|
476
|
+
workspace.endpoint = None
|
|
477
|
+
|
|
478
|
+
with self.assertRaises(s2.ManagementError) as cm:
|
|
479
|
+
workspace.connect(user='admin', password=self.password)
|
|
480
|
+
|
|
481
|
+
assert 'endpoint' in cm.exception.msg, cm.exception.msg
|
|
482
|
+
|
|
483
|
+
|
|
366
484
|
@pytest.mark.management
|
|
367
485
|
class TestStage(unittest.TestCase):
|
|
368
486
|
|
|
@@ -397,13 +515,16 @@ class TestStage(unittest.TestCase):
|
|
|
397
515
|
def test_upload_file(self):
|
|
398
516
|
st = self.wg.stage
|
|
399
517
|
|
|
518
|
+
upload_test_sql = f'upload_test_{id(self)}.sql'
|
|
519
|
+
upload_test2_sql = f'upload_test2_{id(self)}.sql'
|
|
520
|
+
|
|
400
521
|
root = st.info('/')
|
|
401
522
|
assert str(root.path) == '/'
|
|
402
523
|
assert root.type == 'directory'
|
|
403
524
|
|
|
404
525
|
# Upload file
|
|
405
|
-
f = st.upload_file(TEST_DIR / 'test.sql',
|
|
406
|
-
assert str(f.path) ==
|
|
526
|
+
f = st.upload_file(TEST_DIR / 'test.sql', upload_test_sql)
|
|
527
|
+
assert str(f.path) == upload_test_sql
|
|
407
528
|
assert f.type == 'file'
|
|
408
529
|
|
|
409
530
|
# Download and compare to original
|
|
@@ -412,15 +533,15 @@ class TestStage(unittest.TestCase):
|
|
|
412
533
|
|
|
413
534
|
# Make sure we can't overwrite
|
|
414
535
|
with self.assertRaises(OSError):
|
|
415
|
-
st.upload_file(TEST_DIR / 'test.sql',
|
|
536
|
+
st.upload_file(TEST_DIR / 'test.sql', upload_test_sql)
|
|
416
537
|
|
|
417
538
|
# Force overwrite with new content; use file object this time
|
|
418
539
|
f = st.upload_file(
|
|
419
540
|
open(TEST_DIR / 'test2.sql', 'r'),
|
|
420
|
-
|
|
541
|
+
upload_test_sql,
|
|
421
542
|
overwrite=True,
|
|
422
543
|
)
|
|
423
|
-
assert str(f.path) ==
|
|
544
|
+
assert str(f.path) == upload_test_sql
|
|
424
545
|
assert f.type == 'file'
|
|
425
546
|
|
|
426
547
|
# Verify new content
|
|
@@ -442,9 +563,9 @@ class TestStage(unittest.TestCase):
|
|
|
442
563
|
# Write file into folder
|
|
443
564
|
f = st.upload_file(
|
|
444
565
|
TEST_DIR / 'test2.sql',
|
|
445
|
-
os.path.join(lib.path,
|
|
566
|
+
os.path.join(lib.path, upload_test2_sql),
|
|
446
567
|
)
|
|
447
|
-
assert str(f.path) == 'lib/
|
|
568
|
+
assert str(f.path) == 'lib/' + upload_test2_sql
|
|
448
569
|
assert f.type == 'file'
|
|
449
570
|
|
|
450
571
|
def test_open(self):
|
|
@@ -928,7 +1049,10 @@ class TestJob(unittest.TestCase):
|
|
|
928
1049
|
@classmethod
|
|
929
1050
|
def tearDownClass(cls):
|
|
930
1051
|
for job_id in cls.job_ids:
|
|
931
|
-
|
|
1052
|
+
try:
|
|
1053
|
+
cls.manager.organizations.current.jobs.delete(job_id)
|
|
1054
|
+
except Exception:
|
|
1055
|
+
pass
|
|
932
1056
|
if cls.workspace_group is not None:
|
|
933
1057
|
cls.workspace_group.terminate(force=True)
|
|
934
1058
|
cls.workspace_group = None
|
|
@@ -1061,6 +1185,8 @@ class TestFileSpaces(unittest.TestCase):
|
|
|
1061
1185
|
cls.shared_space = None
|
|
1062
1186
|
|
|
1063
1187
|
def test_upload_file(self):
|
|
1188
|
+
upload_test_ipynb = f'upload_test_{id(self)}.ipynb'
|
|
1189
|
+
|
|
1064
1190
|
for space in [self.personal_space, self.shared_space]:
|
|
1065
1191
|
root = space.info('/')
|
|
1066
1192
|
assert str(root.path) == '/'
|
|
@@ -1069,9 +1195,9 @@ class TestFileSpaces(unittest.TestCase):
|
|
|
1069
1195
|
# Upload files
|
|
1070
1196
|
f = space.upload_file(
|
|
1071
1197
|
TEST_DIR / 'test.ipynb',
|
|
1072
|
-
|
|
1198
|
+
upload_test_ipynb,
|
|
1073
1199
|
)
|
|
1074
|
-
assert str(f.path) ==
|
|
1200
|
+
assert str(f.path) == upload_test_ipynb
|
|
1075
1201
|
assert f.type == 'notebook'
|
|
1076
1202
|
|
|
1077
1203
|
# Download and compare to original
|
|
@@ -1082,15 +1208,15 @@ class TestFileSpaces(unittest.TestCase):
|
|
|
1082
1208
|
with self.assertRaises(OSError):
|
|
1083
1209
|
space.upload_file(
|
|
1084
1210
|
TEST_DIR / 'test.ipynb',
|
|
1085
|
-
|
|
1211
|
+
upload_test_ipynb,
|
|
1086
1212
|
)
|
|
1087
1213
|
|
|
1088
1214
|
# Force overwrite with new content
|
|
1089
1215
|
f = space.upload_file(
|
|
1090
1216
|
TEST_DIR / 'test2.ipynb',
|
|
1091
|
-
|
|
1217
|
+
upload_test_ipynb, overwrite=True,
|
|
1092
1218
|
)
|
|
1093
|
-
assert str(f.path) ==
|
|
1219
|
+
assert str(f.path) == upload_test_ipynb
|
|
1094
1220
|
assert f.type == 'notebook'
|
|
1095
1221
|
|
|
1096
1222
|
# Verify new content
|
|
@@ -1102,9 +1228,11 @@ class TestFileSpaces(unittest.TestCase):
|
|
|
1102
1228
|
space.upload_folder(TEST_DIR, 'test')
|
|
1103
1229
|
|
|
1104
1230
|
# Cleanup
|
|
1105
|
-
space.remove(
|
|
1231
|
+
space.remove(upload_test_ipynb)
|
|
1106
1232
|
|
|
1107
1233
|
def test_upload_file_io(self):
|
|
1234
|
+
upload_test_ipynb = f'upload_test_{id(self)}.ipynb'
|
|
1235
|
+
|
|
1108
1236
|
for space in [self.personal_space, self.shared_space]:
|
|
1109
1237
|
root = space.info('/')
|
|
1110
1238
|
assert str(root.path) == '/'
|
|
@@ -1113,9 +1241,9 @@ class TestFileSpaces(unittest.TestCase):
|
|
|
1113
1241
|
# Upload files
|
|
1114
1242
|
f = space.upload_file(
|
|
1115
1243
|
open(TEST_DIR / 'test.ipynb', 'r'),
|
|
1116
|
-
|
|
1244
|
+
upload_test_ipynb,
|
|
1117
1245
|
)
|
|
1118
|
-
assert str(f.path) ==
|
|
1246
|
+
assert str(f.path) == upload_test_ipynb
|
|
1119
1247
|
assert f.type == 'notebook'
|
|
1120
1248
|
|
|
1121
1249
|
# Download and compare to original
|
|
@@ -1126,15 +1254,15 @@ class TestFileSpaces(unittest.TestCase):
|
|
|
1126
1254
|
with self.assertRaises(OSError):
|
|
1127
1255
|
space.upload_file(
|
|
1128
1256
|
open(TEST_DIR / 'test.ipynb', 'r'),
|
|
1129
|
-
|
|
1257
|
+
upload_test_ipynb,
|
|
1130
1258
|
)
|
|
1131
1259
|
|
|
1132
1260
|
# Force overwrite with new content
|
|
1133
1261
|
f = space.upload_file(
|
|
1134
1262
|
open(TEST_DIR / 'test2.ipynb', 'r'),
|
|
1135
|
-
|
|
1263
|
+
upload_test_ipynb, overwrite=True,
|
|
1136
1264
|
)
|
|
1137
|
-
assert str(f.path) ==
|
|
1265
|
+
assert str(f.path) == upload_test_ipynb
|
|
1138
1266
|
assert f.type == 'notebook'
|
|
1139
1267
|
|
|
1140
1268
|
# Verify new content
|
|
@@ -1146,7 +1274,7 @@ class TestFileSpaces(unittest.TestCase):
|
|
|
1146
1274
|
space.upload_folder(TEST_DIR, 'test')
|
|
1147
1275
|
|
|
1148
1276
|
# Cleanup
|
|
1149
|
-
space.remove(
|
|
1277
|
+
space.remove(upload_test_ipynb)
|
|
1150
1278
|
|
|
1151
1279
|
def test_open(self):
|
|
1152
1280
|
for space in [self.personal_space, self.shared_space]:
|
|
@@ -1362,3 +1490,108 @@ class TestFileSpaces(unittest.TestCase):
|
|
|
1362
1490
|
|
|
1363
1491
|
# Cleanup
|
|
1364
1492
|
space.remove('obj_test_2.ipynb')
|
|
1493
|
+
|
|
1494
|
+
|
|
1495
|
+
@pytest.mark.skip('Not implemented in server yet')
|
|
1496
|
+
@pytest.mark.management
|
|
1497
|
+
class TestRegions(unittest.TestCase):
|
|
1498
|
+
"""Test cases for region management."""
|
|
1499
|
+
|
|
1500
|
+
manager = None
|
|
1501
|
+
|
|
1502
|
+
@classmethod
|
|
1503
|
+
def setUpClass(cls):
|
|
1504
|
+
"""Set up the test environment."""
|
|
1505
|
+
cls.manager = s2.manage_regions()
|
|
1506
|
+
|
|
1507
|
+
@classmethod
|
|
1508
|
+
def tearDownClass(cls):
|
|
1509
|
+
"""Clean up the test environment."""
|
|
1510
|
+
cls.manager = None
|
|
1511
|
+
|
|
1512
|
+
def test_list_regions(self):
|
|
1513
|
+
"""Test listing all regions."""
|
|
1514
|
+
regions = self.manager.list_regions()
|
|
1515
|
+
|
|
1516
|
+
# Verify we get a NamedList
|
|
1517
|
+
assert isinstance(regions, NamedList)
|
|
1518
|
+
|
|
1519
|
+
# Verify we have at least one region
|
|
1520
|
+
assert len(regions) > 0
|
|
1521
|
+
|
|
1522
|
+
# Verify region properties
|
|
1523
|
+
region = regions[0]
|
|
1524
|
+
assert isinstance(region, Region)
|
|
1525
|
+
assert hasattr(region, 'id')
|
|
1526
|
+
assert hasattr(region, 'name')
|
|
1527
|
+
assert hasattr(region, 'provider')
|
|
1528
|
+
|
|
1529
|
+
# Verify provider values
|
|
1530
|
+
providers = {x.provider for x in regions}
|
|
1531
|
+
assert 'Azure' in providers or 'GCP' in providers or 'AWS' in providers
|
|
1532
|
+
|
|
1533
|
+
# Verify region can be accessed by name or ID
|
|
1534
|
+
region_by_name = regions[region.name]
|
|
1535
|
+
region_by_id = regions[region.id]
|
|
1536
|
+
assert region_by_name == region_by_id
|
|
1537
|
+
assert region_by_name.id == region.id
|
|
1538
|
+
assert region_by_name.name == region.name
|
|
1539
|
+
assert region_by_name.provider == region.provider
|
|
1540
|
+
|
|
1541
|
+
def test_list_shared_tier_regions(self):
|
|
1542
|
+
"""Test listing shared tier regions."""
|
|
1543
|
+
regions = self.manager.list_shared_tier_regions()
|
|
1544
|
+
|
|
1545
|
+
# Verify we get a NamedList
|
|
1546
|
+
assert isinstance(regions, NamedList)
|
|
1547
|
+
|
|
1548
|
+
# Verify region properties if we have any shared tier regions
|
|
1549
|
+
if regions:
|
|
1550
|
+
region = regions[0]
|
|
1551
|
+
assert isinstance(region, Region)
|
|
1552
|
+
assert hasattr(region, 'id')
|
|
1553
|
+
assert hasattr(region, 'name')
|
|
1554
|
+
assert hasattr(region, 'provider')
|
|
1555
|
+
|
|
1556
|
+
# Verify provider values
|
|
1557
|
+
providers = {x.provider for x in regions}
|
|
1558
|
+
assert any(p in providers for p in ['Azure', 'GCP', 'AWS'])
|
|
1559
|
+
|
|
1560
|
+
# Verify region can be accessed by name or ID
|
|
1561
|
+
region_by_name = regions[region.name]
|
|
1562
|
+
region_by_id = regions[region.id]
|
|
1563
|
+
assert region_by_name == region_by_id
|
|
1564
|
+
assert region_by_name.id == region.id
|
|
1565
|
+
assert region_by_name.name == region.name
|
|
1566
|
+
assert region_by_name.provider == region.provider
|
|
1567
|
+
|
|
1568
|
+
def test_str_repr(self):
|
|
1569
|
+
"""Test string representation of regions."""
|
|
1570
|
+
regions = self.manager.list_regions()
|
|
1571
|
+
if not regions:
|
|
1572
|
+
self.skipTest('No regions available for testing')
|
|
1573
|
+
|
|
1574
|
+
region = regions[0]
|
|
1575
|
+
|
|
1576
|
+
# Test __str__
|
|
1577
|
+
s = str(region)
|
|
1578
|
+
assert region.id in s
|
|
1579
|
+
assert region.name in s
|
|
1580
|
+
assert region.provider in s
|
|
1581
|
+
|
|
1582
|
+
# Test __repr__
|
|
1583
|
+
assert repr(region) == str(region)
|
|
1584
|
+
|
|
1585
|
+
def test_no_manager(self):
|
|
1586
|
+
"""Test behavior when manager is not available."""
|
|
1587
|
+
regions = self.manager.list_regions()
|
|
1588
|
+
if not regions:
|
|
1589
|
+
self.skipTest('No regions available for testing')
|
|
1590
|
+
|
|
1591
|
+
region = regions[0]
|
|
1592
|
+
region._manager = None
|
|
1593
|
+
|
|
1594
|
+
# Verify from_dict class method
|
|
1595
|
+
with self.assertRaises(s2.ManagementError) as cm:
|
|
1596
|
+
RegionManager.list_shared_tier_regions(None)
|
|
1597
|
+
assert 'No workspace manager' in str(cm.exception)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: singlestoredb
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.15.0
|
|
4
4
|
Summary: Interface to the SingleStoreDB database and workspace management APIs
|
|
5
5
|
Home-page: https://github.com/singlestore-labs/singlestoredb-python
|
|
6
6
|
Author: SingleStore
|
|
@@ -19,7 +19,6 @@ Requires-Dist: build
|
|
|
19
19
|
Requires-Dist: parsimonious
|
|
20
20
|
Requires-Dist: requests
|
|
21
21
|
Requires-Dist: setuptools
|
|
22
|
-
Requires-Dist: singlestore-vectorstore>=0.1.2
|
|
23
22
|
Requires-Dist: sqlparams
|
|
24
23
|
Requires-Dist: wheel
|
|
25
24
|
Requires-Dist: tomli>=1.1.0; python_version < "3.11"
|
|
@@ -44,6 +43,8 @@ Provides-Extra: rsa
|
|
|
44
43
|
Requires-Dist: cryptography; extra == "rsa"
|
|
45
44
|
Provides-Extra: sqlalchemy
|
|
46
45
|
Requires-Dist: sqlalchemy-singlestoredb>=1.0.0; extra == "sqlalchemy"
|
|
46
|
+
Provides-Extra: vectorstore
|
|
47
|
+
Requires-Dist: singlestore-vectorstore>=0.1.2; extra == "vectorstore"
|
|
47
48
|
|
|
48
49
|
# <img src="https://github.com/singlestore-labs/singlestoredb-python/blob/main/resources/singlestore-logo.png" height="60" valign="middle"/> SingleStoreDB Python SDK
|
|
49
50
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
singlestoredb/__init__.py,sha256=
|
|
1
|
+
singlestoredb/__init__.py,sha256=vzHEbxcHZTZuay7dGyuJZk-LVuyUnlgu-R7okiL4FEw,2272
|
|
2
2
|
singlestoredb/auth.py,sha256=u8D9tpKzrqa4ssaHjyZnGDX1q8XBpGtuoOkTkSv7B28,7599
|
|
3
|
-
singlestoredb/config.py,sha256=
|
|
3
|
+
singlestoredb/config.py,sha256=maEBo6epJpidVVD7QDkBAgE6tbQhYHxBVfouWmGR0cU,13169
|
|
4
4
|
singlestoredb/connection.py,sha256=ELk3-UpM6RaB993aIt08MydKiiDnejHQ1s8EFiacrAI,46055
|
|
5
5
|
singlestoredb/converters.py,sha256=Ui-AqdW3pRAQ8A_YcK9EqVYyM4Pt1_Q-tjlotbpK6Cw,20686
|
|
6
6
|
singlestoredb/exceptions.py,sha256=HuoA6sMRL5qiCiee-_5ddTGmFbYC9Euk8TYUsh5GvTw,3234
|
|
@@ -18,25 +18,30 @@ singlestoredb/apps/_config.py,sha256=FlV0ABP7qlBJoKo9NOme6Fpp4yUFm5QEpHEHbl1A24o
|
|
|
18
18
|
singlestoredb/apps/_connection_info.py,sha256=QOr-wcQJn6oCZw2kLEP0Uwzo85CGolGz0QIvlem3gug,303
|
|
19
19
|
singlestoredb/apps/_dashboards.py,sha256=_03fI-GJannamA5lxLvIoC6Mim-H1jTRuI8-dw_P--k,1474
|
|
20
20
|
singlestoredb/apps/_process.py,sha256=G37fk6bzIxzhfEqp2aJBk3JCij-T2HFtTd078k5Xq9I,944
|
|
21
|
-
singlestoredb/apps/_python_udfs.py,sha256
|
|
21
|
+
singlestoredb/apps/_python_udfs.py,sha256=hwncnfx7MpOsvCH0Ic64otDIo-GGPT3UC89y2uAA_Uw,2773
|
|
22
22
|
singlestoredb/apps/_stdout_supress.py,sha256=8s9zMIIRPpeu44yluJFc_0VueAxZDmr9QVGT6TGiFeY,659
|
|
23
23
|
singlestoredb/apps/_uvicorn_util.py,sha256=rEK4nEmq5hbpRgsmK16UVlxe2DyQSq7C5w5WZSp0kX8,962
|
|
24
24
|
singlestoredb/functions/__init__.py,sha256=I2GnxOhLb4_7xhgOxdIwmwD5NiK7QYPYaE3PUIX-7xk,471
|
|
25
|
-
singlestoredb/functions/decorator.py,sha256=
|
|
25
|
+
singlestoredb/functions/decorator.py,sha256=lMzTcndVffFUMkInxlp7R5akVAd10jMP5BqxkeGnQ7E,6397
|
|
26
26
|
singlestoredb/functions/dtypes.py,sha256=DgJaNXouJ2t-qIqDiQlUYU9IhkXXUTigWeE_MAcmvHM,39814
|
|
27
27
|
singlestoredb/functions/signature.py,sha256=avErza5t3p0vy94p4yjw7Hy2cCDvjolwCyYjEI0PKXM,42481
|
|
28
|
-
singlestoredb/functions/typing.py,sha256=gT_Sz5YH-L-9WeIHwWYMEx-hUCZqis7ec5Ipk3JXpnM,1339
|
|
29
28
|
singlestoredb/functions/utils.py,sha256=1L0Phgzq0XdWK3ecfOOydq4zV955yCwpDoAaCYRGldk,10769
|
|
30
29
|
singlestoredb/functions/ext/__init__.py,sha256=1oLL20yLB1GL9IbFiZD8OReDqiCpFr-yetIR6x1cNkI,23
|
|
31
30
|
singlestoredb/functions/ext/arrow.py,sha256=WB7n1ACslyd8nlbFzUvlbxn1BVuEjA9-BGBEqCWlSOo,9061
|
|
32
|
-
singlestoredb/functions/ext/asgi.py,sha256=
|
|
31
|
+
singlestoredb/functions/ext/asgi.py,sha256=IxVUUrz-fGmoxSXGlEb1COI-bXn2JcvLrVz4wa2Hx0o,60223
|
|
33
32
|
singlestoredb/functions/ext/json.py,sha256=RIuZdDybEdHuC-f2p6BdjhFjM3iGb3a1PRQ4k11P6N8,10102
|
|
34
33
|
singlestoredb/functions/ext/mmap.py,sha256=RzyNSLRpI5ZJ8YN6k-AvZlRTLjj80j52byHLtW8c3ps,13710
|
|
35
34
|
singlestoredb/functions/ext/rowdat_1.py,sha256=SlXbJ2042jEoaXw81y5llw1625w0aU2nZ8vI_O3qA-M,21112
|
|
35
|
+
singlestoredb/functions/ext/timer.py,sha256=kgmJACV6LAfev53XiGMwCv4DDlgF3Icg7G8VCuTQp4Q,2963
|
|
36
36
|
singlestoredb/functions/ext/utils.py,sha256=2-B8YU_Iekv8JcpI-ochs9TIeuyatLaLAH-AyYyUUIg,5311
|
|
37
|
+
singlestoredb/functions/typing/__init__.py,sha256=gT_Sz5YH-L-9WeIHwWYMEx-hUCZqis7ec5Ipk3JXpnM,1339
|
|
38
|
+
singlestoredb/functions/typing/numpy.py,sha256=WO64_HziveGk0dqRrkuZ51aohULy9qYuqaKHAoiiA3A,661
|
|
39
|
+
singlestoredb/functions/typing/pandas.py,sha256=wZUTMbte937EKtGdnFFWB0fFut5unTOyAbn8fSBsfro,83
|
|
40
|
+
singlestoredb/functions/typing/polars.py,sha256=b_UOIXLkvptHiAB7sXSzC7XPHMWNOglCz6h9amCA6Kg,83
|
|
41
|
+
singlestoredb/functions/typing/pyarrow.py,sha256=WkqQrUPS__jYzUJntLLUVDgYIcnqR9HU6Q5grZojZrc,80
|
|
37
42
|
singlestoredb/fusion/__init__.py,sha256=Qo7SuqGw-l-vE8-EI2jhm6hXJkYfOLUKIws9c7LFNX0,356
|
|
38
43
|
singlestoredb/fusion/graphql.py,sha256=ZA3HcDq5rER-dCEavwTqnF7KM0D2LCYIY7nLQk7lSso,5207
|
|
39
|
-
singlestoredb/fusion/handler.py,sha256=
|
|
44
|
+
singlestoredb/fusion/handler.py,sha256=M5iyNP4zOaGqUqnZg_b5xhRE-8tHgfZSHDH0zKTiJmE,27692
|
|
40
45
|
singlestoredb/fusion/registry.py,sha256=jjdRTYZ3ylhy6gAoW5xBj0tkxGFBT-2yLQ0tztTgDIY,6112
|
|
41
46
|
singlestoredb/fusion/result.py,sha256=p5I65C-Dhhl1yeZwetXXZabwritr8Ph2mFvJJ3ovcBM,11790
|
|
42
47
|
singlestoredb/fusion/handlers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -50,20 +55,20 @@ singlestoredb/fusion/handlers/workspace.py,sha256=4xN2TFO4yF7KZB2Fcht7IuvoDdAT6f
|
|
|
50
55
|
singlestoredb/http/__init__.py,sha256=A_2ZUCCpvRYIA6YDpPy57wL5R1eZ5SfP6I1To5nfJ2s,912
|
|
51
56
|
singlestoredb/http/connection.py,sha256=X5GEPPOE-rMm17d0-TPhcdxUHibcYl-MZAnPhut8xyo,39956
|
|
52
57
|
singlestoredb/magics/__init__.py,sha256=lZjkT3Webo9c1EQAzlRCRh6B2pckQH8uvNrrB__abcI,1210
|
|
53
|
-
singlestoredb/magics/run_personal.py,sha256=
|
|
54
|
-
singlestoredb/magics/run_shared.py,sha256=
|
|
55
|
-
singlestoredb/management/__init__.py,sha256=
|
|
58
|
+
singlestoredb/magics/run_personal.py,sha256=Y5lVpJ8vqOyEjtZkip04Hwi4uZ7CQLU5Rd1MrCmpNvs,5222
|
|
59
|
+
singlestoredb/magics/run_shared.py,sha256=czoO4z6gtoq9ek_41efRBRk-XQiHKuHdY0BOdfKkFrc,5130
|
|
60
|
+
singlestoredb/management/__init__.py,sha256=8q7i6-Cr9x-oZ8-NVAvTo_qtfHEndX4wx2g6GMAAgPQ,304
|
|
56
61
|
singlestoredb/management/billing_usage.py,sha256=9ighjIpcopgIyJOktBYQ6pahBZmWGHOPyyCW4gu9FGs,3735
|
|
57
62
|
singlestoredb/management/cluster.py,sha256=h75grXSxq4Anr4RxwKxcZW4TkWJ4bFg_ql5iRWCNLdQ,14405
|
|
58
|
-
singlestoredb/management/export.py,sha256=
|
|
63
|
+
singlestoredb/management/export.py,sha256=yR-yZUE9USFrP5OR_5iLFqEc8GLiKDQypSEp08CmT5k,9083
|
|
59
64
|
singlestoredb/management/files.py,sha256=89IhpGw9WdwxVeksavHEDMVn9wb_jxb-utZuIDqkLHw,30477
|
|
60
65
|
singlestoredb/management/inference_api.py,sha256=L6eFqaUaPugF_cmrZ4xlArj8CIv25vWqQs1vwgKPEF4,2583
|
|
61
66
|
singlestoredb/management/job.py,sha256=4-xLWzbE8odQogVVaFer80UEoTAZY1T28VZ9Ug4rbmM,24611
|
|
62
67
|
singlestoredb/management/manager.py,sha256=V9_PVMpUOj8laKwNFtp4Nd2Taww2Y65TeSRK5ZWzOo0,8922
|
|
63
68
|
singlestoredb/management/organization.py,sha256=_JvW0Znu5emR5uYGVEcZvakQqftNb_vRhzmkOoPRPfc,5869
|
|
64
|
-
singlestoredb/management/region.py,sha256=
|
|
69
|
+
singlestoredb/management/region.py,sha256=OIdWqQCDjwey9fPrLZFRPh9tA4M1pMjmzCBYrUHRC0Q,3838
|
|
65
70
|
singlestoredb/management/utils.py,sha256=QIhZCZSRaDbAG35xu1_n7ihmRXON8swc-gEK2FGYutI,13203
|
|
66
|
-
singlestoredb/management/workspace.py,sha256=
|
|
71
|
+
singlestoredb/management/workspace.py,sha256=ZtVklRGShucHwpT9qDojXOIPo-jTTbqu657-jnTBh1g,62334
|
|
67
72
|
singlestoredb/mysql/__init__.py,sha256=olUTAvkiERhDW41JXQMawkg-i0tvBEkoTkII1tt6lxU,4492
|
|
68
73
|
singlestoredb/mysql/_auth.py,sha256=AugRitoUwgRIDFuJxuAH4MWIAmckY7Ji2pP6r_Ng9dY,8043
|
|
69
74
|
singlestoredb/mysql/charset.py,sha256=-FlONDS_oAUF5B3mIgeHBPb_SCt4zHD33arUeBNctU0,10510
|
|
@@ -115,7 +120,7 @@ singlestoredb/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
|
|
|
115
120
|
singlestoredb/tests/empty.sql,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
116
121
|
singlestoredb/tests/local_infile.csv,sha256=sBtqjvfkS9aoOVx8nMXYgYv4rDuT4OuYhqUhNRu0O68,42
|
|
117
122
|
singlestoredb/tests/test.ipynb,sha256=jrkI2WoSsUA9xQpKTBCHnsDptryQhPdM5QaxfvYRGpg,216
|
|
118
|
-
singlestoredb/tests/test.sql,sha256=
|
|
123
|
+
singlestoredb/tests/test.sql,sha256=mErluOEZsN0QH5EuSVR8Ki-NSIpdpR8MStuchec_ZKc,18640
|
|
119
124
|
singlestoredb/tests/test2.ipynb,sha256=yd1PE1VK-DwiRd6mYS4_0cPBtuVkvcDtycvTwD-YnDo,218
|
|
120
125
|
singlestoredb/tests/test2.sql,sha256=D4U2GSlOVeo39U8-RMM4YziJzYFfi4Ztm2YXJVJVAS8,37
|
|
121
126
|
singlestoredb/tests/test_basics.py,sha256=Dw1irrtf3gWN7tqGruSH6uhWi5zkmCpJl6ZMQxMqlf4,48446
|
|
@@ -123,11 +128,11 @@ singlestoredb/tests/test_config.py,sha256=63lyIQ2KrvGE6C9403B_4Mc90mX4tp42ys5Bih
|
|
|
123
128
|
singlestoredb/tests/test_connection.py,sha256=fvn-kPdeIMI9RGNz0dNk5ZmTCep1amwWQDHYfPdqO60,119699
|
|
124
129
|
singlestoredb/tests/test_dbapi.py,sha256=IKq5Hcwx8WikASP8_AB5fo3TXv7ryWPCVGonoly00gI,652
|
|
125
130
|
singlestoredb/tests/test_exceptions.py,sha256=tfr_8X2w1UmG4nkSBzWGB0C7ehrf1GAVgj6_ODaG-TM,1131
|
|
126
|
-
singlestoredb/tests/test_ext_func.py,sha256=
|
|
131
|
+
singlestoredb/tests/test_ext_func.py,sha256=_YREceW1Llwx9Wcamj0up2IXLuBTnuvQqCFOWphckKI,46271
|
|
127
132
|
singlestoredb/tests/test_ext_func_data.py,sha256=yTADD93nPxX6_rZXXLZaOWEI_yPvYyir9psn5PK9ctU,47695
|
|
128
|
-
singlestoredb/tests/test_fusion.py,sha256=
|
|
133
|
+
singlestoredb/tests/test_fusion.py,sha256=7YQ_nOQoV_7yD4OEpJz2Ov-zok-cBFK9IOJ3FgZ0xo0,50593
|
|
129
134
|
singlestoredb/tests/test_http.py,sha256=RXasTqBWRn__omj0eLFTJYIbZjd0PPdIV2d4Cqz0MC8,8580
|
|
130
|
-
singlestoredb/tests/test_management.py,sha256=
|
|
135
|
+
singlestoredb/tests/test_management.py,sha256=D2-qarTzwWOlBTjL3XTmB76D9gUKmfbd2Gl1vQUQESk,53237
|
|
131
136
|
singlestoredb/tests/test_plugin.py,sha256=qpO9wmWc62VaijN1sJ97YSYIX7I7Y5C6sY-WzwrutDQ,812
|
|
132
137
|
singlestoredb/tests/test_results.py,sha256=wg93sujwt-R9_eJCgSCElgAZhLDkIiAo3qPkPydOv78,6582
|
|
133
138
|
singlestoredb/tests/test_types.py,sha256=jqoAaSjhbgwB3vt0KsTcl7XBWoMMIa0mPFKhEi5bBjo,4500
|
|
@@ -136,7 +141,7 @@ singlestoredb/tests/test_udf_returns.py,sha256=k31L6Ir2Xw8MEZ18upuu0p_D_OpbrPAzW
|
|
|
136
141
|
singlestoredb/tests/test_vectorstore.py,sha256=anHfp5gQrQy8Iw3Ub4mxFEkaZWahs566OXuKqjpkozM,1554
|
|
137
142
|
singlestoredb/tests/test_xdict.py,sha256=fqHspoi39nbX3fIDVkkRXcd5H50xdOsSvK0bxAMQnaE,10408
|
|
138
143
|
singlestoredb/tests/utils.py,sha256=2A2tEdD3t8aXWUnHtAIcFlWrflsz2MlMcCbUDaAG29c,4995
|
|
139
|
-
singlestoredb/tests/ext_funcs/__init__.py,sha256=
|
|
144
|
+
singlestoredb/tests/ext_funcs/__init__.py,sha256=KuA2ACn46O_f_z6gFP1biYm9D-xWDBctCV_IqnHCh6E,14947
|
|
140
145
|
singlestoredb/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
141
146
|
singlestoredb/utils/config.py,sha256=m3Xn6hsbdKyLufSnbokhFJ9Vfaz9Qpkj1IEnIiH9oJQ,24503
|
|
142
147
|
singlestoredb/utils/convert_rows.py,sha256=A6up7a8Bq-eV2BXdGCotQviqp1Q7XdJ2MA9339hLYVQ,1816
|
|
@@ -148,9 +153,9 @@ singlestoredb/utils/results.py,sha256=bJtaUaDiFq26IsPAKZ2FHGB7csMn94EAxLKrP4HaEE
|
|
|
148
153
|
singlestoredb/utils/xdict.py,sha256=S9HKgrPrnu_6b7iOwa2KrW8CmU1Uqx0BWdEyogFzWbE,12896
|
|
149
154
|
sqlx/__init__.py,sha256=aBYiU8DZXCogvWu3yWafOz7bZS5WWwLZXj7oL0dXGyU,85
|
|
150
155
|
sqlx/magic.py,sha256=JsS9_9aBFaOt91Torm1JPN0c8qB2QmYJmNSKtbSQIY0,3509
|
|
151
|
-
singlestoredb-1.
|
|
152
|
-
singlestoredb-1.
|
|
153
|
-
singlestoredb-1.
|
|
154
|
-
singlestoredb-1.
|
|
155
|
-
singlestoredb-1.
|
|
156
|
-
singlestoredb-1.
|
|
156
|
+
singlestoredb-1.15.0.dist-info/LICENSE,sha256=Mlq78idURT-9G026aMYswwwnnrLcgzTLuXeAs5hjDLM,11341
|
|
157
|
+
singlestoredb-1.15.0.dist-info/METADATA,sha256=_b9wfex4H3DNup18dBoa2oALthiwvg3Tv5ch29HIpFs,5786
|
|
158
|
+
singlestoredb-1.15.0.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
|
159
|
+
singlestoredb-1.15.0.dist-info/entry_points.txt,sha256=bSLaTWB5zGjpVYPAaI46MkkDup0su-eb3uAhCNYuRV0,48
|
|
160
|
+
singlestoredb-1.15.0.dist-info/top_level.txt,sha256=DfFGz7bM4XrshloiCeTABgylT3BUnS8T5pJam3ewT6Q,19
|
|
161
|
+
singlestoredb-1.15.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|