singlestoredb 1.15.7__cp38-abi3-win32.whl → 1.16.0__cp38-abi3-win32.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_accel.pyd +0 -0
- singlestoredb/__init__.py +1 -1
- singlestoredb/ai/__init__.py +0 -3
- singlestoredb/ai/chat.py +21 -41
- singlestoredb/ai/embeddings.py +21 -18
- singlestoredb/connection.py +2 -2
- singlestoredb/functions/ext/asgi.py +3 -3
- singlestoredb/functions/ext/rowdat_1.py +1 -1
- singlestoredb/functions/signature.py +1 -1
- singlestoredb/functions/typing/__init__.py +1 -1
- singlestoredb/functions/utils.py +1 -1
- singlestoredb/fusion/handler.py +1 -1
- singlestoredb/fusion/result.py +1 -1
- singlestoredb/http/connection.py +2 -2
- singlestoredb/management/manager.py +61 -0
- singlestoredb/management/utils.py +1 -1
- singlestoredb/management/workspace.py +6 -0
- singlestoredb/mysql/connection.py +1 -1
- singlestoredb/pytest.py +78 -9
- singlestoredb/tests/test_management.py +151 -124
- singlestoredb/utils/config.py +2 -2
- singlestoredb/utils/mogrify.py +1 -1
- singlestoredb/utils/results.py +2 -2
- singlestoredb/utils/xdict.py +4 -4
- {singlestoredb-1.15.7.dist-info → singlestoredb-1.16.0.dist-info}/METADATA +42 -22
- {singlestoredb-1.15.7.dist-info → singlestoredb-1.16.0.dist-info}/RECORD +30 -30
- {singlestoredb-1.15.7.dist-info → singlestoredb-1.16.0.dist-info}/WHEEL +1 -1
- {singlestoredb-1.15.7.dist-info → singlestoredb-1.16.0.dist-info}/top_level.txt +1 -0
- {singlestoredb-1.15.7.dist-info → singlestoredb-1.16.0.dist-info}/entry_points.txt +0 -0
- {singlestoredb-1.15.7.dist-info → singlestoredb-1.16.0.dist-info/licenses}/LICENSE +0 -0
|
@@ -30,6 +30,7 @@ def shared_database_name(s):
|
|
|
30
30
|
return re.sub(r'[^\w]', '', s).replace('-', '_').lower()
|
|
31
31
|
|
|
32
32
|
|
|
33
|
+
@pytest.mark.skip(reason='Legacy cluster Management API is going away')
|
|
33
34
|
@pytest.mark.management
|
|
34
35
|
class TestCluster(unittest.TestCase):
|
|
35
36
|
|
|
@@ -675,184 +676,201 @@ class TestStage(unittest.TestCase):
|
|
|
675
676
|
def test_os_directories(self):
|
|
676
677
|
st = self.wg.stage
|
|
677
678
|
|
|
679
|
+
mkdir_test_1 = f'mkdir_test_1_{id(self)}'
|
|
680
|
+
mkdir_test_2 = f'mkdir_test_2_{id(self)}'
|
|
681
|
+
mkdir_test_3 = f'mkdir_test_3_{id(self)}'
|
|
682
|
+
|
|
678
683
|
# mkdir
|
|
679
|
-
st.mkdir(
|
|
680
|
-
st.mkdir(
|
|
684
|
+
st.mkdir(mkdir_test_1)
|
|
685
|
+
st.mkdir(mkdir_test_2)
|
|
681
686
|
with self.assertRaises(s2.ManagementError):
|
|
682
|
-
st.mkdir('mkdir_test_2/nest_1/nest_2')
|
|
683
|
-
st.mkdir('mkdir_test_2/nest_1')
|
|
684
|
-
st.mkdir('mkdir_test_2/nest_1/nest_2')
|
|
685
|
-
st.mkdir('mkdir_test_3')
|
|
686
|
-
|
|
687
|
-
assert st.exists('mkdir_test_1/')
|
|
688
|
-
assert st.exists('mkdir_test_2/')
|
|
689
|
-
assert st.exists('mkdir_test_2/nest_1/')
|
|
690
|
-
assert st.exists('mkdir_test_2/nest_1/nest_2/')
|
|
687
|
+
st.mkdir(f'{mkdir_test_2}/nest_1/nest_2')
|
|
688
|
+
st.mkdir(f'{mkdir_test_2}/nest_1')
|
|
689
|
+
st.mkdir(f'{mkdir_test_2}/nest_1/nest_2')
|
|
690
|
+
st.mkdir(f'{mkdir_test_3}')
|
|
691
|
+
|
|
692
|
+
assert st.exists(f'{mkdir_test_1}/')
|
|
693
|
+
assert st.exists(f'{mkdir_test_2}/')
|
|
694
|
+
assert st.exists(f'{mkdir_test_2}/nest_1/')
|
|
695
|
+
assert st.exists(f'{mkdir_test_2}/nest_1/nest_2/')
|
|
691
696
|
assert not st.exists('foo/')
|
|
692
697
|
assert not st.exists('foo/bar/')
|
|
693
698
|
|
|
694
|
-
assert st.is_dir('mkdir_test_1/')
|
|
695
|
-
assert st.is_dir('mkdir_test_2/')
|
|
696
|
-
assert st.is_dir('mkdir_test_2/nest_1/')
|
|
697
|
-
assert st.is_dir('mkdir_test_2/nest_1/nest_2/')
|
|
699
|
+
assert st.is_dir(f'{mkdir_test_1}/')
|
|
700
|
+
assert st.is_dir(f'{mkdir_test_2}/')
|
|
701
|
+
assert st.is_dir(f'{mkdir_test_2}/nest_1/')
|
|
702
|
+
assert st.is_dir(f'{mkdir_test_2}/nest_1/nest_2/')
|
|
698
703
|
|
|
699
|
-
assert not st.is_file('mkdir_test_1/')
|
|
700
|
-
assert not st.is_file('mkdir_test_2/')
|
|
701
|
-
assert not st.is_file('mkdir_test_2/nest_1/')
|
|
702
|
-
assert not st.is_file('mkdir_test_2/nest_1/nest_2/')
|
|
704
|
+
assert not st.is_file(f'{mkdir_test_1}/')
|
|
705
|
+
assert not st.is_file(f'{mkdir_test_2}/')
|
|
706
|
+
assert not st.is_file(f'{mkdir_test_2}/nest_1/')
|
|
707
|
+
assert not st.is_file(f'{mkdir_test_2}/nest_1/nest_2/')
|
|
703
708
|
|
|
704
709
|
out = st.listdir('/')
|
|
705
|
-
assert 'mkdir_test_1/' in out
|
|
706
|
-
assert 'mkdir_test_2/' in out
|
|
707
|
-
assert 'mkdir_test_2/nest_1/nest_2/' not in out
|
|
710
|
+
assert f'{mkdir_test_1}/' in out
|
|
711
|
+
assert f'{mkdir_test_2}/' in out
|
|
712
|
+
assert f'{mkdir_test_2}/nest_1/nest_2/' not in out
|
|
708
713
|
|
|
709
714
|
out = st.listdir('/', recursive=True)
|
|
710
|
-
assert 'mkdir_test_1/' in out
|
|
711
|
-
assert 'mkdir_test_2/' in out
|
|
712
|
-
assert 'mkdir_test_2/nest_1/nest_2/' in out
|
|
715
|
+
assert f'{mkdir_test_1}/' in out
|
|
716
|
+
assert f'{mkdir_test_2}/' in out
|
|
717
|
+
assert f'{mkdir_test_2}/nest_1/nest_2/' in out
|
|
713
718
|
|
|
714
|
-
out = st.listdir(
|
|
715
|
-
assert 'mkdir_test_1/' not in out
|
|
719
|
+
out = st.listdir(mkdir_test_2)
|
|
720
|
+
assert f'{mkdir_test_1}/' not in out
|
|
716
721
|
assert 'nest_1/' in out
|
|
717
722
|
assert 'nest_2/' not in out
|
|
718
723
|
assert 'nest_1/nest_2/' not in out
|
|
719
724
|
|
|
720
|
-
out = st.listdir(
|
|
721
|
-
assert 'mkdir_test_1/' not in out
|
|
725
|
+
out = st.listdir(mkdir_test_2, recursive=True)
|
|
726
|
+
assert f'{mkdir_test_1}/' not in out
|
|
722
727
|
assert 'nest_1/' in out
|
|
723
728
|
assert 'nest_2/' not in out
|
|
724
729
|
assert 'nest_1/nest_2/' in out
|
|
725
730
|
|
|
726
731
|
# rmdir
|
|
727
732
|
before = st.listdir('/', recursive=True)
|
|
728
|
-
st.rmdir('mkdir_test_1/')
|
|
733
|
+
st.rmdir(f'{mkdir_test_1}/')
|
|
729
734
|
after = st.listdir('/', recursive=True)
|
|
730
|
-
assert 'mkdir_test_1/' in before
|
|
731
|
-
assert 'mkdir_test_1/' not in after
|
|
732
|
-
assert list(sorted(before)) == list(sorted(after + ['mkdir_test_1/']))
|
|
735
|
+
assert f'{mkdir_test_1}/' in before
|
|
736
|
+
assert f'{mkdir_test_1}/' not in after
|
|
737
|
+
assert list(sorted(before)) == list(sorted(after + [f'{mkdir_test_1}/']))
|
|
733
738
|
|
|
734
739
|
with self.assertRaises(OSError):
|
|
735
|
-
st.rmdir('mkdir_test_2/')
|
|
740
|
+
st.rmdir(f'{mkdir_test_2}/')
|
|
741
|
+
|
|
742
|
+
mkdir_test_sql = f'mkdir_test_{id(self)}.sql'
|
|
736
743
|
|
|
737
|
-
st.upload_file(TEST_DIR / 'test.sql',
|
|
744
|
+
st.upload_file(TEST_DIR / 'test.sql', mkdir_test_sql)
|
|
738
745
|
|
|
739
746
|
with self.assertRaises(NotADirectoryError):
|
|
740
|
-
st.rmdir(
|
|
747
|
+
st.rmdir(mkdir_test_sql)
|
|
741
748
|
|
|
742
749
|
# removedirs
|
|
743
750
|
before = st.listdir('/')
|
|
744
|
-
st.removedirs('mkdir_test_2/')
|
|
751
|
+
st.removedirs(f'{mkdir_test_2}/')
|
|
745
752
|
after = st.listdir('/')
|
|
746
|
-
assert 'mkdir_test_2/' in before
|
|
747
|
-
assert 'mkdir_test_2/' not in after
|
|
748
|
-
assert list(sorted(before)) == list(sorted(after + ['mkdir_test_2/']))
|
|
753
|
+
assert f'{mkdir_test_2}/' in before
|
|
754
|
+
assert f'{mkdir_test_2}/' not in after
|
|
755
|
+
assert list(sorted(before)) == list(sorted(after + [f'{mkdir_test_2}/']))
|
|
749
756
|
|
|
750
757
|
with self.assertRaises(s2.ManagementError):
|
|
751
|
-
st.removedirs(
|
|
758
|
+
st.removedirs(mkdir_test_sql)
|
|
752
759
|
|
|
753
760
|
def test_os_files(self):
|
|
754
761
|
st = self.wg.stage
|
|
755
762
|
|
|
756
|
-
|
|
757
|
-
|
|
763
|
+
files_test_sql = f'files_test_{id(self)}.sql'
|
|
764
|
+
files_test_1_dir = f'files_test_1_{id(self)}'
|
|
765
|
+
|
|
766
|
+
st.mkdir(files_test_1_dir)
|
|
767
|
+
st.mkdir(f'{files_test_1_dir}/nest_1')
|
|
758
768
|
|
|
759
|
-
st.upload_file(TEST_DIR / 'test.sql',
|
|
760
|
-
st.upload_file(
|
|
769
|
+
st.upload_file(TEST_DIR / 'test.sql', files_test_sql)
|
|
770
|
+
st.upload_file(
|
|
771
|
+
TEST_DIR / 'test.sql',
|
|
772
|
+
f'{files_test_1_dir}/nest_1/nested_files_test.sql',
|
|
773
|
+
)
|
|
761
774
|
st.upload_file(
|
|
762
775
|
TEST_DIR / 'test.sql',
|
|
763
|
-
'
|
|
776
|
+
f'{files_test_1_dir}/nest_1/nested_files_test_2.sql',
|
|
764
777
|
)
|
|
765
778
|
|
|
766
779
|
# remove
|
|
767
780
|
with self.assertRaises(IsADirectoryError):
|
|
768
|
-
st.remove('
|
|
781
|
+
st.remove(f'{files_test_1_dir}/')
|
|
769
782
|
|
|
770
783
|
before = st.listdir('/')
|
|
771
|
-
st.remove(
|
|
784
|
+
st.remove(files_test_sql)
|
|
772
785
|
after = st.listdir('/')
|
|
773
|
-
assert
|
|
774
|
-
assert
|
|
775
|
-
assert list(sorted(before)) == list(sorted(after + [
|
|
786
|
+
assert files_test_sql in before
|
|
787
|
+
assert files_test_sql not in after
|
|
788
|
+
assert list(sorted(before)) == list(sorted(after + [files_test_sql]))
|
|
776
789
|
|
|
777
|
-
before = st.listdir('
|
|
778
|
-
st.remove('
|
|
779
|
-
after = st.listdir('
|
|
790
|
+
before = st.listdir(f'{files_test_1_dir}/nest_1/')
|
|
791
|
+
st.remove(f'{files_test_1_dir}/nest_1/nested_files_test.sql')
|
|
792
|
+
after = st.listdir(f'{files_test_1_dir}/nest_1/')
|
|
780
793
|
assert 'nested_files_test.sql' in before
|
|
781
794
|
assert 'nested_files_test.sql' not in after
|
|
782
|
-
assert st.is_dir('
|
|
795
|
+
assert st.is_dir(f'{files_test_1_dir}/nest_1/')
|
|
783
796
|
|
|
784
797
|
# Removing the last file does not remove empty directories
|
|
785
|
-
st.remove('
|
|
786
|
-
assert not st.is_file('
|
|
787
|
-
assert st.is_dir('
|
|
788
|
-
assert st.is_dir('
|
|
798
|
+
st.remove(f'{files_test_1_dir}/nest_1/nested_files_test_2.sql')
|
|
799
|
+
assert not st.is_file(f'{files_test_1_dir}/nest_1/nested_files_test_2.sql')
|
|
800
|
+
assert st.is_dir(f'{files_test_1_dir}/nest_1/')
|
|
801
|
+
assert st.is_dir(f'{files_test_1_dir}/')
|
|
789
802
|
|
|
790
|
-
st.removedirs(
|
|
791
|
-
assert not st.is_dir('
|
|
792
|
-
assert not st.is_dir('
|
|
803
|
+
st.removedirs(files_test_1_dir)
|
|
804
|
+
assert not st.is_dir(f'{files_test_1_dir}/nest_1/')
|
|
805
|
+
assert not st.is_dir(f'{files_test_1_dir}/')
|
|
793
806
|
|
|
794
807
|
def test_os_rename(self):
|
|
795
808
|
st = self.wg.stage
|
|
796
809
|
|
|
797
|
-
|
|
810
|
+
rename_test_sql = f'rename_test_{id(self)}.sql'
|
|
811
|
+
rename_test_2_sql = f'rename_test_2_{id(self)}.sql'
|
|
812
|
+
rename_test_1_dir = f'rename_test_1_{id(self)}'
|
|
813
|
+
rename_test_2_dir = f'rename_test_2_{id(self)}'
|
|
814
|
+
|
|
815
|
+
st.upload_file(TEST_DIR / 'test.sql', rename_test_sql)
|
|
798
816
|
|
|
799
817
|
with self.assertRaises(s2.ManagementError):
|
|
800
818
|
st.upload_file(
|
|
801
819
|
TEST_DIR / 'test.sql',
|
|
802
|
-
'
|
|
820
|
+
f'{rename_test_1_dir}/nest_1/nested_rename_test.sql',
|
|
803
821
|
)
|
|
804
822
|
|
|
805
|
-
st.mkdir(
|
|
806
|
-
st.mkdir('
|
|
823
|
+
st.mkdir(rename_test_1_dir)
|
|
824
|
+
st.mkdir(f'{rename_test_1_dir}/nest_1')
|
|
807
825
|
|
|
808
|
-
assert st.exists('/
|
|
826
|
+
assert st.exists(f'/{rename_test_1_dir}/nest_1/')
|
|
809
827
|
|
|
810
828
|
st.upload_file(
|
|
811
829
|
TEST_DIR / 'test.sql',
|
|
812
|
-
'
|
|
830
|
+
f'{rename_test_1_dir}/nest_1/nested_rename_test.sql',
|
|
813
831
|
)
|
|
814
832
|
|
|
815
833
|
st.upload_file(
|
|
816
834
|
TEST_DIR / 'test.sql',
|
|
817
|
-
'
|
|
835
|
+
f'{rename_test_1_dir}/nest_1/nested_rename_test_2.sql',
|
|
818
836
|
)
|
|
819
837
|
|
|
820
838
|
# rename file
|
|
821
|
-
assert
|
|
822
|
-
assert
|
|
823
|
-
st.rename(
|
|
824
|
-
assert
|
|
825
|
-
assert
|
|
839
|
+
assert rename_test_sql in st.listdir('/')
|
|
840
|
+
assert rename_test_2_sql not in st.listdir('/')
|
|
841
|
+
st.rename(rename_test_sql, rename_test_2_sql)
|
|
842
|
+
assert rename_test_sql not in st.listdir('/')
|
|
843
|
+
assert rename_test_2_sql in st.listdir('/')
|
|
826
844
|
|
|
827
845
|
# rename directory
|
|
828
|
-
assert '
|
|
829
|
-
assert '
|
|
830
|
-
st.rename('
|
|
831
|
-
assert '
|
|
832
|
-
assert '
|
|
833
|
-
assert st.is_file('
|
|
834
|
-
assert st.is_file('
|
|
846
|
+
assert f'{rename_test_1_dir}/' in st.listdir('/')
|
|
847
|
+
assert f'{rename_test_2_dir}/' not in st.listdir('/')
|
|
848
|
+
st.rename(f'{rename_test_1_dir}/', f'{rename_test_2_dir}/')
|
|
849
|
+
assert f'{rename_test_1_dir}/' not in st.listdir('/')
|
|
850
|
+
assert f'{rename_test_2_dir}/' in st.listdir('/')
|
|
851
|
+
assert st.is_file(f'{rename_test_2_dir}/nest_1/nested_rename_test.sql')
|
|
852
|
+
assert st.is_file(f'{rename_test_2_dir}/nest_1/nested_rename_test_2.sql')
|
|
835
853
|
|
|
836
854
|
# rename nested
|
|
837
|
-
assert '
|
|
855
|
+
assert f'{rename_test_2_dir}/nest_1/nested_rename_test.sql' in st.listdir(
|
|
838
856
|
'/', recursive=True,
|
|
839
857
|
)
|
|
840
|
-
assert '
|
|
858
|
+
assert f'{rename_test_2_dir}/nest_1/nested_rename_test_3.sql' not in st.listdir(
|
|
841
859
|
'/', recursive=True,
|
|
842
860
|
)
|
|
843
861
|
st.rename(
|
|
844
|
-
'
|
|
845
|
-
'
|
|
862
|
+
f'{rename_test_2_dir}/nest_1/nested_rename_test.sql',
|
|
863
|
+
f'{rename_test_2_dir}/nest_1/nested_rename_test_3.sql',
|
|
846
864
|
)
|
|
847
|
-
assert '
|
|
865
|
+
assert f'{rename_test_2_dir}/nest_1/nested_rename_test.sql' not in st.listdir(
|
|
848
866
|
'/', recursive=True,
|
|
849
867
|
)
|
|
850
|
-
assert '
|
|
868
|
+
assert f'{rename_test_2_dir}/nest_1/nested_rename_test_3.sql' in st.listdir(
|
|
851
869
|
'/', recursive=True,
|
|
852
870
|
)
|
|
853
|
-
assert not st.is_file('
|
|
854
|
-
assert st.is_file('
|
|
855
|
-
assert st.is_file('
|
|
871
|
+
assert not st.is_file(f'{rename_test_2_dir}/nest_1/nested_rename_test.sql')
|
|
872
|
+
assert st.is_file(f'{rename_test_2_dir}/nest_1/nested_rename_test_2.sql')
|
|
873
|
+
assert st.is_file(f'{rename_test_2_dir}/nest_1/nested_rename_test_3.sql')
|
|
856
874
|
|
|
857
875
|
# non-existent file
|
|
858
876
|
with self.assertRaises(OSError):
|
|
@@ -861,13 +879,13 @@ class TestStage(unittest.TestCase):
|
|
|
861
879
|
# overwrite
|
|
862
880
|
with self.assertRaises(OSError):
|
|
863
881
|
st.rename(
|
|
864
|
-
|
|
865
|
-
'
|
|
882
|
+
rename_test_2_sql,
|
|
883
|
+
f'{rename_test_2_dir}/nest_1/nested_rename_test_3.sql',
|
|
866
884
|
)
|
|
867
885
|
|
|
868
886
|
st.rename(
|
|
869
|
-
|
|
870
|
-
'
|
|
887
|
+
rename_test_2_sql,
|
|
888
|
+
f'{rename_test_2_dir}/nest_1/nested_rename_test_3.sql', overwrite=True,
|
|
871
889
|
)
|
|
872
890
|
|
|
873
891
|
def test_file_object(self):
|
|
@@ -1399,35 +1417,41 @@ class TestFileSpaces(unittest.TestCase):
|
|
|
1399
1417
|
space.remove(obj_open_test_ipynb)
|
|
1400
1418
|
|
|
1401
1419
|
def test_os_directories(self):
|
|
1420
|
+
mkdir_test_1_dir = f'mkdir_test_1_{id(self)}'
|
|
1421
|
+
|
|
1402
1422
|
for space in [self.personal_space, self.shared_space]:
|
|
1403
1423
|
# Make sure directories error out
|
|
1404
1424
|
with self.assertRaises(s2.ManagementError):
|
|
1405
|
-
space.mkdir(
|
|
1425
|
+
space.mkdir(mkdir_test_1_dir)
|
|
1406
1426
|
|
|
1407
1427
|
with self.assertRaises(s2.ManagementError):
|
|
1408
|
-
space.exists('
|
|
1428
|
+
space.exists(f'{mkdir_test_1_dir}/')
|
|
1409
1429
|
|
|
1410
1430
|
out = space.listdir('/')
|
|
1411
|
-
assert '
|
|
1431
|
+
assert f'{mkdir_test_1_dir}/' not in out
|
|
1412
1432
|
|
|
1413
1433
|
with self.assertRaises(s2.ManagementError):
|
|
1414
|
-
space.rmdir('
|
|
1434
|
+
space.rmdir(f'{mkdir_test_1_dir}/')
|
|
1415
1435
|
|
|
1416
1436
|
def test_os_rename(self):
|
|
1437
|
+
rename_test_ipynb = f'rename_test_{id(self)}.ipynb'
|
|
1438
|
+
rename_test_2_ipynb = f'rename_test_2_{id(self)}.ipynb'
|
|
1439
|
+
rename_test_3_ipynb = f'rename_test_3_{id(self)}.ipynb'
|
|
1440
|
+
|
|
1417
1441
|
for space in [self.personal_space, self.shared_space]:
|
|
1418
1442
|
space.upload_file(
|
|
1419
1443
|
TEST_DIR / 'test.ipynb',
|
|
1420
|
-
|
|
1444
|
+
rename_test_ipynb,
|
|
1421
1445
|
)
|
|
1422
|
-
assert
|
|
1423
|
-
assert
|
|
1446
|
+
assert rename_test_ipynb in space.listdir('/')
|
|
1447
|
+
assert rename_test_2_ipynb not in space.listdir('/')
|
|
1424
1448
|
|
|
1425
1449
|
space.rename(
|
|
1426
|
-
|
|
1427
|
-
|
|
1450
|
+
rename_test_ipynb,
|
|
1451
|
+
rename_test_2_ipynb,
|
|
1428
1452
|
)
|
|
1429
|
-
assert
|
|
1430
|
-
assert
|
|
1453
|
+
assert rename_test_ipynb not in space.listdir('/')
|
|
1454
|
+
assert rename_test_2_ipynb in space.listdir('/')
|
|
1431
1455
|
|
|
1432
1456
|
# non-existent file
|
|
1433
1457
|
with self.assertRaises(OSError):
|
|
@@ -1435,37 +1459,40 @@ class TestFileSpaces(unittest.TestCase):
|
|
|
1435
1459
|
|
|
1436
1460
|
space.upload_file(
|
|
1437
1461
|
TEST_DIR / 'test.ipynb',
|
|
1438
|
-
|
|
1462
|
+
rename_test_3_ipynb,
|
|
1439
1463
|
)
|
|
1440
1464
|
|
|
1441
1465
|
# overwrite
|
|
1442
1466
|
with self.assertRaises(OSError):
|
|
1443
1467
|
space.rename(
|
|
1444
|
-
|
|
1445
|
-
|
|
1468
|
+
rename_test_2_ipynb,
|
|
1469
|
+
rename_test_3_ipynb,
|
|
1446
1470
|
)
|
|
1447
1471
|
|
|
1448
1472
|
space.rename(
|
|
1449
|
-
|
|
1450
|
-
|
|
1473
|
+
rename_test_2_ipynb,
|
|
1474
|
+
rename_test_3_ipynb, overwrite=True,
|
|
1451
1475
|
)
|
|
1452
1476
|
|
|
1453
1477
|
# Cleanup
|
|
1454
|
-
space.remove(
|
|
1478
|
+
space.remove(rename_test_3_ipynb)
|
|
1455
1479
|
|
|
1456
1480
|
def test_file_object(self):
|
|
1481
|
+
obj_test_ipynb = f'obj_test_{id(self)}.ipynb'
|
|
1482
|
+
obj_test_2_ipynb = f'obj_test_2_{id(self)}.ipynb'
|
|
1483
|
+
|
|
1457
1484
|
for space in [self.personal_space, self.shared_space]:
|
|
1458
1485
|
f = space.upload_file(
|
|
1459
1486
|
TEST_DIR / 'test.ipynb',
|
|
1460
|
-
|
|
1487
|
+
obj_test_ipynb,
|
|
1461
1488
|
)
|
|
1462
1489
|
|
|
1463
1490
|
assert not f.is_dir()
|
|
1464
1491
|
assert f.is_file()
|
|
1465
1492
|
|
|
1466
1493
|
# abspath / basename / dirname / exists
|
|
1467
|
-
assert f.abspath() ==
|
|
1468
|
-
assert f.basename() ==
|
|
1494
|
+
assert f.abspath() == obj_test_ipynb
|
|
1495
|
+
assert f.basename() == obj_test_ipynb
|
|
1469
1496
|
assert f.dirname() == '/'
|
|
1470
1497
|
assert f.exists()
|
|
1471
1498
|
|
|
@@ -1474,9 +1501,9 @@ class TestFileSpaces(unittest.TestCase):
|
|
|
1474
1501
|
open(TEST_DIR / 'test.ipynb', 'r').read()
|
|
1475
1502
|
assert f.download() == open(TEST_DIR / 'test.ipynb', 'rb').read()
|
|
1476
1503
|
|
|
1477
|
-
assert space.is_file(
|
|
1504
|
+
assert space.is_file(obj_test_ipynb)
|
|
1478
1505
|
f.remove()
|
|
1479
|
-
assert not space.is_file(
|
|
1506
|
+
assert not space.is_file(obj_test_ipynb)
|
|
1480
1507
|
|
|
1481
1508
|
# mtime / ctime
|
|
1482
1509
|
assert f.getmtime() > 0
|
|
@@ -1485,17 +1512,17 @@ class TestFileSpaces(unittest.TestCase):
|
|
|
1485
1512
|
# rename
|
|
1486
1513
|
f = space.upload_file(
|
|
1487
1514
|
TEST_DIR / 'test.ipynb',
|
|
1488
|
-
|
|
1515
|
+
obj_test_ipynb,
|
|
1489
1516
|
)
|
|
1490
|
-
assert space.exists(
|
|
1491
|
-
assert not space.exists(
|
|
1492
|
-
f.rename(
|
|
1493
|
-
assert not space.exists(
|
|
1494
|
-
assert space.exists(
|
|
1495
|
-
assert f.abspath() ==
|
|
1517
|
+
assert space.exists(obj_test_ipynb)
|
|
1518
|
+
assert not space.exists(obj_test_2_ipynb)
|
|
1519
|
+
f.rename(obj_test_2_ipynb)
|
|
1520
|
+
assert not space.exists(obj_test_ipynb)
|
|
1521
|
+
assert space.exists(obj_test_2_ipynb)
|
|
1522
|
+
assert f.abspath() == obj_test_2_ipynb
|
|
1496
1523
|
|
|
1497
1524
|
# Cleanup
|
|
1498
|
-
space.remove(
|
|
1525
|
+
space.remove(obj_test_2_ipynb)
|
|
1499
1526
|
|
|
1500
1527
|
|
|
1501
1528
|
@pytest.mark.management
|
singlestoredb/utils/config.py
CHANGED
|
@@ -27,12 +27,12 @@ a description of one or more options.
|
|
|
27
27
|
import contextlib
|
|
28
28
|
import os
|
|
29
29
|
import re
|
|
30
|
+
from collections.abc import Iterator
|
|
31
|
+
from collections.abc import Mapping
|
|
30
32
|
from typing import Any
|
|
31
33
|
from typing import Callable
|
|
32
34
|
from typing import Dict
|
|
33
|
-
from typing import Iterator
|
|
34
35
|
from typing import List
|
|
35
|
-
from typing import Mapping
|
|
36
36
|
from typing import Optional
|
|
37
37
|
from typing import Tuple
|
|
38
38
|
from typing import Union
|
singlestoredb/utils/mogrify.py
CHANGED
singlestoredb/utils/results.py
CHANGED
|
@@ -300,9 +300,9 @@ def results_to_polars(
|
|
|
300
300
|
if has_polars:
|
|
301
301
|
schema = _description_to_polars_schema(desc) if schema is None else schema
|
|
302
302
|
if single:
|
|
303
|
-
out = pl.DataFrame([res], **schema.get('schema', {}))
|
|
303
|
+
out = pl.DataFrame([res], orient='row', **schema.get('schema', {}))
|
|
304
304
|
else:
|
|
305
|
-
out = pl.DataFrame(res, **schema.get('schema', {}))
|
|
305
|
+
out = pl.DataFrame(res, orient='row', **schema.get('schema', {}))
|
|
306
306
|
with_columns = schema.get('with_columns')
|
|
307
307
|
if with_columns:
|
|
308
308
|
return out.with_columns(**with_columns)
|
singlestoredb/utils/xdict.py
CHANGED
|
@@ -19,14 +19,14 @@
|
|
|
19
19
|
"""Dictionary that allows setting nested keys by period (.) delimited strings."""
|
|
20
20
|
import copy
|
|
21
21
|
import re
|
|
22
|
+
from collections.abc import ItemsView
|
|
23
|
+
from collections.abc import Iterable
|
|
24
|
+
from collections.abc import KeysView
|
|
25
|
+
from collections.abc import ValuesView
|
|
22
26
|
from typing import Any
|
|
23
27
|
from typing import Dict
|
|
24
|
-
from typing import ItemsView
|
|
25
|
-
from typing import Iterable
|
|
26
|
-
from typing import KeysView
|
|
27
28
|
from typing import List
|
|
28
29
|
from typing import Tuple
|
|
29
|
-
from typing import ValuesView
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
def _is_compound_key(key: str) -> bool:
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: singlestoredb
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.16.0
|
|
4
4
|
Summary: Interface to the SingleStoreDB database and workspace management APIs
|
|
5
|
-
|
|
6
|
-
Author: SingleStore
|
|
7
|
-
Author-email: support@singlestore.com
|
|
5
|
+
Author-email: SingleStore <support@singlestore.com>
|
|
8
6
|
License: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/singlestore-labs/singlestoredb-python
|
|
9
8
|
Classifier: Development Status :: 5 - Production/Stable
|
|
10
|
-
Classifier: License :: OSI Approved :: Apache Software License
|
|
11
9
|
Classifier: Programming Language :: Python :: 3
|
|
12
10
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
13
11
|
Classifier: Topic :: Database
|
|
@@ -15,36 +13,58 @@ Requires-Python: >=3.9
|
|
|
15
13
|
Description-Content-Type: text/markdown
|
|
16
14
|
License-File: LICENSE
|
|
17
15
|
Requires-Dist: PyJWT
|
|
18
|
-
Requires-Dist: build
|
|
19
16
|
Requires-Dist: parsimonious
|
|
20
17
|
Requires-Dist: requests
|
|
21
|
-
Requires-Dist: setuptools
|
|
22
18
|
Requires-Dist: sqlparams
|
|
23
|
-
Requires-Dist:
|
|
24
|
-
Requires-Dist:
|
|
25
|
-
Requires-Dist: typing-extensions <=4.13.2 ; python_version < "3.11"
|
|
19
|
+
Requires-Dist: tomli>=1.1.0; python_version < "3.11"
|
|
20
|
+
Requires-Dist: typing-extensions<=4.13.2; python_version < "3.11"
|
|
26
21
|
Provides-Extra: dataframe
|
|
27
|
-
Requires-Dist: ibis-singlestoredb
|
|
22
|
+
Requires-Dist: ibis-singlestoredb; extra == "dataframe"
|
|
28
23
|
Provides-Extra: dbt
|
|
29
|
-
Requires-Dist: dbt-singlestore
|
|
24
|
+
Requires-Dist: dbt-singlestore; extra == "dbt"
|
|
30
25
|
Provides-Extra: docker
|
|
31
|
-
Requires-Dist: docker
|
|
26
|
+
Requires-Dist: docker; extra == "docker"
|
|
32
27
|
Provides-Extra: ed22519
|
|
33
|
-
Requires-Dist: PyNaCl
|
|
28
|
+
Requires-Dist: PyNaCl>=1.4.0; extra == "ed22519"
|
|
34
29
|
Provides-Extra: gssapi
|
|
35
|
-
Requires-Dist: gssapi
|
|
30
|
+
Requires-Dist: gssapi; extra == "gssapi"
|
|
36
31
|
Provides-Extra: ibis
|
|
37
|
-
Requires-Dist: ibis-singlestoredb
|
|
32
|
+
Requires-Dist: ibis-singlestoredb; extra == "ibis"
|
|
38
33
|
Provides-Extra: kerberos
|
|
39
|
-
Requires-Dist: gssapi
|
|
34
|
+
Requires-Dist: gssapi; extra == "kerberos"
|
|
40
35
|
Provides-Extra: pytest
|
|
41
|
-
Requires-Dist: pytest
|
|
36
|
+
Requires-Dist: pytest; extra == "pytest"
|
|
42
37
|
Provides-Extra: rsa
|
|
43
|
-
Requires-Dist: cryptography
|
|
38
|
+
Requires-Dist: cryptography; extra == "rsa"
|
|
44
39
|
Provides-Extra: sqlalchemy
|
|
45
|
-
Requires-Dist: sqlalchemy-singlestoredb
|
|
40
|
+
Requires-Dist: sqlalchemy-singlestoredb>=1.0.0; extra == "sqlalchemy"
|
|
46
41
|
Provides-Extra: vectorstore
|
|
47
|
-
Requires-Dist: singlestore-vectorstore
|
|
42
|
+
Requires-Dist: singlestore-vectorstore>=0.1.2; extra == "vectorstore"
|
|
43
|
+
Provides-Extra: test
|
|
44
|
+
Requires-Dist: coverage; extra == "test"
|
|
45
|
+
Requires-Dist: dash; extra == "test"
|
|
46
|
+
Requires-Dist: fastapi; extra == "test"
|
|
47
|
+
Requires-Dist: ipython; extra == "test"
|
|
48
|
+
Requires-Dist: jupysql; extra == "test"
|
|
49
|
+
Requires-Dist: pandas; extra == "test"
|
|
50
|
+
Requires-Dist: parameterized; extra == "test"
|
|
51
|
+
Requires-Dist: polars; extra == "test"
|
|
52
|
+
Requires-Dist: pyarrow; extra == "test"
|
|
53
|
+
Requires-Dist: pydantic; extra == "test"
|
|
54
|
+
Requires-Dist: pytest; extra == "test"
|
|
55
|
+
Requires-Dist: pytest-cov; extra == "test"
|
|
56
|
+
Requires-Dist: singlestore-vectorstore>=0.1.2; extra == "test"
|
|
57
|
+
Requires-Dist: uvicorn; extra == "test"
|
|
58
|
+
Provides-Extra: docs
|
|
59
|
+
Requires-Dist: sphinx; extra == "docs"
|
|
60
|
+
Requires-Dist: sphinx_rtd_theme; extra == "docs"
|
|
61
|
+
Provides-Extra: build
|
|
62
|
+
Requires-Dist: build; extra == "build"
|
|
63
|
+
Requires-Dist: setuptools>=61.0; extra == "build"
|
|
64
|
+
Requires-Dist: wheel; extra == "build"
|
|
65
|
+
Provides-Extra: dev
|
|
66
|
+
Requires-Dist: singlestoredb[build,docs,test]; extra == "dev"
|
|
67
|
+
Dynamic: license-file
|
|
48
68
|
|
|
49
69
|
# <img src="https://github.com/singlestore-labs/singlestoredb-python/blob/main/resources/singlestore-logo.png" height="60" valign="middle"/> SingleStoreDB Python SDK
|
|
50
70
|
|