From d173b4ed5dc5be214643c7f1900a0d43b7fe4114 Mon Sep 17 00:00:00 2001 From: Volodymyr Tkachuk Date: Wed, 28 May 2025 14:43:02 +0300 Subject: [PATCH 1/5] Add vectorstore API support --- docs/src/whatsnew.rst | 5 + requirements.txt | 1 + setup.cfg | 3 +- singlestoredb/__init__.py | 4 +- singlestoredb/connection.py | 11 ++ singlestoredb/tests/test_vectorstore.py | 41 +++++ singlestoredb/vectorstore.py | 189 ++++++++++++++++++++++++ 7 files changed, 251 insertions(+), 3 deletions(-) create mode 100644 singlestoredb/tests/test_vectorstore.py create mode 100644 singlestoredb/vectorstore.py diff --git a/docs/src/whatsnew.rst b/docs/src/whatsnew.rst index ed87341a0..6b40b4a51 100644 --- a/docs/src/whatsnew.rst +++ b/docs/src/whatsnew.rst @@ -8,6 +8,11 @@ This document outlines features and improvements from each release. are for non-production testing and evaluation, and may include changes to the API. +v1.14.0 - May 28, 2025 +------------------------ +* Add ``vector_db`` property to a ``Connection`` object to get the vectorstor API to the current database +* Add ``vector_db(...)`` function to connect to a database and optain a vectorstor API + v1.13.0 - April 16, 2025 ------------------------ * Refactor external function server (experimental) type system diff --git a/requirements.txt b/requirements.txt index bdc386103..5ea39e998 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,3 +7,4 @@ sqlparams tomli>=1.1.0; python_version < '3.11' typing_extensions<=4.13.2 wheel +singlestore-vecorstore>=0.1.1 diff --git a/setup.cfg b/setup.cfg index 724606d91..debcc925a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = singlestoredb -version = 1.13.1 +version = 1.14.0 description = Interface to the SingleStoreDB database and workspace management APIs long_description = file: README.md long_description_content_type = text/markdown @@ -26,6 +26,7 @@ install_requires = setuptools sqlparams wheel + singlestore-vecorstore>=0.1.1 tomli>=1.1.0;python_version < '3.11' typing-extensions<=4.13.2;python_version < '3.11' python_requires = >=3.8 diff --git a/singlestoredb/__init__.py b/singlestoredb/__init__.py index 1030a5473..7101dbc91 100644 --- a/singlestoredb/__init__.py +++ b/singlestoredb/__init__.py @@ -13,7 +13,7 @@ """ -__version__ = '1.13.1' +__version__ = '1.14.0' from typing import Any @@ -31,7 +31,7 @@ Date, Time, Timestamp, DateFromTicks, TimeFromTicks, TimestampFromTicks, Binary, STRING, BINARY, NUMBER, DATETIME, ROWID, ) - +from .vectorstore import vector_db # # This function is defined here to prevent the side-effect of diff --git a/singlestoredb/connection.py b/singlestoredb/connection.py index 55be0da99..1fd543db7 100644 --- a/singlestoredb/connection.py +++ b/singlestoredb/connection.py @@ -1,5 +1,6 @@ #!/usr/bin/env python """SingleStoreDB connections and cursors.""" + import abc import inspect import io @@ -23,6 +24,7 @@ from urllib.parse import unquote_plus from urllib.parse import urlparse + import sqlparams try: from pandas import DataFrame @@ -1288,6 +1290,15 @@ def show(self) -> ShowAccessor: """Access server properties managed by the SHOW statement.""" return ShowAccessor(self) + @property + def vector_db(self) -> Any: + """ + Get vectorstore API accessor + """ + from vectorstore import VectorDB + if not hasattr(self, '_vector_db'): + self._vector_db = VectorDB(connection=self) + return self._vector_db # # NOTE: When adding parameters to this function, you should always diff --git a/singlestoredb/tests/test_vectorstore.py b/singlestoredb/tests/test_vectorstore.py new file mode 100644 index 000000000..317b57bd7 --- /dev/null +++ b/singlestoredb/tests/test_vectorstore.py @@ -0,0 +1,41 @@ +import os +import unittest + +import singlestoredb as s2 +from . import utils + +from vectorstore import VectorDB + +class TestVectorDB(unittest.TestCase): + + driver = s2 + + dbname: str = '' + dbexisted: bool = False + + @classmethod + def setUpClass(cls): + sql_file = os.path.join(os.path.dirname(__file__), 'empty.sql') + cls.dbname, cls.dbexisted = utils.load_sql(sql_file) + + @classmethod + def tearDownClass(cls): + if not cls.dbexisted: + utils.drop_database(cls.dbname) + + def test_vectordb_from_params(self): + db: VectorDB = s2.vector_db(database=type(self).dbname) + index = db.create_index(name="test_index", dimension=3, tags={"name": "test_tag"}) + assert index.name == "test_index" + assert index.dimension == 3 + assert index.tags == {"name": "test_tag"} + assert db.has_index("test_index") + + def test_vectordb_from_connection(self): + with s2.connect(database=type(self).dbname) as conn: + db: VectorDB = conn.vector_db + index = db.create_index(name="test_index_1", dimension=4, tags={"name": "test_tag"}) + assert index.name == "test_index_1" + assert index.dimension == 4 + assert index.tags == {"name": "test_tag"} + assert db.has_index("test_index_1") \ No newline at end of file diff --git a/singlestoredb/vectorstore.py b/singlestoredb/vectorstore.py new file mode 100644 index 000000000..be04ab879 --- /dev/null +++ b/singlestoredb/vectorstore.py @@ -0,0 +1,189 @@ +from __future__ import annotations +from typing import Optional, Dict, Callable, Any + +from vectorstore import ( + IndexInterface, + IndexList, + IndexModel, + MatchTypedDict, + Metric, + IndexStatsTypedDict, + NamespaceStatsTypedDict, + Vector, + VectorDictMetadataValue, + VectorMetadataTypedDict, + VectorTuple, + VectorTupleWithMetadata, + DeletionProtection, + AndFilter, + EqFilter, + ExactMatchFilter, + FilterTypedDict, + GteFilter, + GtFilter, + InFilter, + LteFilter, + LtFilter, + NeFilter, + NinFilter, + OrFilter, + SimpleFilter +) + +def vector_db( + host: Optional[str] = None, user: Optional[str] = None, + password: Optional[str] = None, port: Optional[int] = None, + database: Optional[str] = None, driver: Optional[str] = None, + pure_python: Optional[bool] = None, local_infile: Optional[bool] = None, + charset: Optional[str] = None, + ssl_key: Optional[str] = None, ssl_cert: Optional[str] = None, + ssl_ca: Optional[str] = None, ssl_disabled: Optional[bool] = None, + ssl_cipher: Optional[str] = None, ssl_verify_cert: Optional[bool] = None, + tls_sni_servername: Optional[str] = None, + ssl_verify_identity: Optional[bool] = None, + conv: Optional[Dict[int, Callable[..., Any]]] = None, + credential_type: Optional[str] = None, + autocommit: Optional[bool] = None, + results_type: Optional[str] = None, + buffered: Optional[bool] = None, + results_format: Optional[str] = None, + program_name: Optional[str] = None, + conn_attrs: Optional[Dict[str, str]] = {}, + multi_statements: Optional[bool] = None, + client_found_rows: Optional[bool] = None, + connect_timeout: Optional[int] = None, + nan_as_null: Optional[bool] = None, + inf_as_null: Optional[bool] = None, + encoding_errors: Optional[str] = None, + track_env: Optional[bool] = None, + enable_extended_data_types: Optional[bool] = None, + vector_data_format: Optional[str] = None, + parse_json: Optional[bool] = None, + pool_size: Optional[int] = 5, + max_overflow: Optional[int] = 10, + timeout: Optional[float] = 30, +) -> "VectorDB": + """ + Return a vectorstore API connection. + Database should be specified in the URL or as a keyword. + + Parameters + ---------- + host : str, optional + Hostname, IP address, or URL that describes the connection. + The scheme or protocol defines which database connector to use. + By default, the ``mysql`` scheme is used. To connect to the + HTTP API, the scheme can be set to ``http`` or ``https``. The username, + password, host, and port are specified as in a standard URL. The path + indicates the database name. The overall form of the URL is: + ``scheme://user:password@host:port/db_name``. The scheme can + typically be left off (unless you are using the HTTP API): + ``user:password@host:port/db_name``. + user : str, optional + Database user name + password : str, optional + Database user password + port : int, optional + Database port. This defaults to 3306 for non-HTTP connections, 80 + for HTTP connections, and 443 for HTTPS connections. + database : str, optional + Database name. + pure_python : bool, optional + Use the connector in pure Python mode + local_infile : bool, optional + Allow local file uploads + charset : str, optional + Character set for string values + ssl_key : str, optional + File containing SSL key + ssl_cert : str, optional + File containing SSL certificate + ssl_ca : str, optional + File containing SSL certificate authority + ssl_cipher : str, optional + Sets the SSL cipher list + ssl_disabled : bool, optional + Disable SSL usage + ssl_verify_cert : bool, optional + Verify the server's certificate. This is automatically enabled if + ``ssl_ca`` is also specified. + ssl_verify_identity : bool, optional + Verify the server's identity + conv : dict[int, Callable], optional + Dictionary of data conversion functions + credential_type : str, optional + Type of authentication to use: auth.PASSWORD, auth.JWT, or auth.BROWSER_SSO + autocommit : bool, optional + Enable autocommits + results_type : str, optional + The form of the query results: tuples, namedtuples, dicts, + numpy, polars, pandas, arrow + buffered : bool, optional + Should the entire query result be buffered in memory? This is the default + behavior which allows full cursor control of the result, but does consume + more memory. + results_format : str, optional + Deprecated. This option has been renamed to results_type. + program_name : str, optional + Name of the program + conn_attrs : dict, optional + Additional connection attributes for telemetry. Example: + {'program_version': "1.0.2", "_connector_name": "dbt connector"} + multi_statements: bool, optional + Should multiple statements be allowed within a single query? + connect_timeout : int, optional + The timeout for connecting to the database in seconds. + (default: 10, min: 1, max: 31536000) + nan_as_null : bool, optional + Should NaN values be treated as NULLs when used in parameter + substitutions including uploaded data? + inf_as_null : bool, optional + Should Inf values be treated as NULLs when used in parameter + substitutions including uploaded data? + encoding_errors : str, optional + The error handler name for value decoding errors + track_env : bool, optional + Should the connection track the SINGLESTOREDB_URL environment variable? + enable_extended_data_types : bool, optional + Should extended data types (BSON, vector) be enabled? + vector_data_format : str, optional + Format for vector types: json or binary + pool_size : int, optional + The number of connections to keep in the connection pool. Default is 5. + max_overflow : int, optional + The maximum number of connections to allow beyond the pool size. + Default is 10. + timeout : float, optional + The timeout for acquiring a connection from the pool in seconds. + Default is 30 seconds. + + See Also + -------- + :class:`Connection` + + Returns + ------- + :class:`VectorDB` + + """ + from vectorstore import VectorDB + return VectorDB(host=host, user=user, password=password, port=port, + database=database, driver=driver, pure_python=pure_python, + local_infile=local_infile, charset=charset, + ssl_key=ssl_key, ssl_cert=ssl_cert, ssl_ca=ssl_ca, + ssl_disabled=ssl_disabled, ssl_cipher=ssl_cipher, + ssl_verify_cert=ssl_verify_cert, + tls_sni_servername=tls_sni_servername, + ssl_verify_identity=ssl_verify_identity, conv=conv, + credential_type=credential_type, autocommit=autocommit, + results_type=results_type, buffered=buffered, + results_format=results_format, program_name=program_name, + conn_attrs=conn_attrs, multi_statements=multi_statements, + client_found_rows=client_found_rows, + connect_timeout=connect_timeout, nan_as_null=nan_as_null, + inf_as_null=inf_as_null, encoding_errors=encoding_errors, + track_env=track_env, + enable_extended_data_types=enable_extended_data_types, + vector_data_format=vector_data_format, + parse_json=parse_json, pool_size=pool_size, + max_overflow=max_overflow, timeout=timeout) \ No newline at end of file From 79f45bc0ed776caf1f211e48ea33d2e01c75b9a0 Mon Sep 17 00:00:00 2001 From: Volodymyr Tkachuk Date: Wed, 28 May 2025 15:14:43 +0300 Subject: [PATCH 2/5] fix style --- docs/src/whatsnew.rst | 2 +- requirements.txt | 2 +- setup.cfg | 2 +- singlestoredb/__init__.py | 10 ++- singlestoredb/connection.py | 5 +- singlestoredb/tests/test_vectorstore.py | 37 ++++---- singlestoredb/vectorstore.py | 109 ++++++++++++------------ 7 files changed, 92 insertions(+), 75 deletions(-) diff --git a/docs/src/whatsnew.rst b/docs/src/whatsnew.rst index 6b40b4a51..6b35966db 100644 --- a/docs/src/whatsnew.rst +++ b/docs/src/whatsnew.rst @@ -11,7 +11,7 @@ This document outlines features and improvements from each release. v1.14.0 - May 28, 2025 ------------------------ * Add ``vector_db`` property to a ``Connection`` object to get the vectorstor API to the current database -* Add ``vector_db(...)`` function to connect to a database and optain a vectorstor API +* Add ``vector_db(...)`` function to connect to a database and optain a vectorstor API v1.13.0 - April 16, 2025 ------------------------ diff --git a/requirements.txt b/requirements.txt index 5ea39e998..293900f9d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,8 +3,8 @@ parsimonious PyJWT requests setuptools +singlestore-vecorstore sqlparams tomli>=1.1.0; python_version < '3.11' typing_extensions<=4.13.2 wheel -singlestore-vecorstore>=0.1.1 diff --git a/setup.cfg b/setup.cfg index debcc925a..3d8fc9a67 100644 --- a/setup.cfg +++ b/setup.cfg @@ -24,9 +24,9 @@ install_requires = parsimonious requests setuptools + singlestore-vecorstore sqlparams wheel - singlestore-vecorstore>=0.1.1 tomli>=1.1.0;python_version < '3.11' typing-extensions<=4.13.2;python_version < '3.11' python_requires = >=3.8 diff --git a/singlestoredb/__init__.py b/singlestoredb/__init__.py index 7101dbc91..0961b9ed4 100644 --- a/singlestoredb/__init__.py +++ b/singlestoredb/__init__.py @@ -31,7 +31,15 @@ Date, Time, Timestamp, DateFromTicks, TimeFromTicks, TimestampFromTicks, Binary, STRING, BINARY, NUMBER, DATETIME, ROWID, ) -from .vectorstore import vector_db +from .vectorstore import ( + vector_db, IndexInterface, IndexList, IndexModel, MatchTypedDict, + Metric, IndexStatsTypedDict, NamespaceStatsTypedDict, Vector, + VectorDictMetadataValue, VectorMetadataTypedDict, VectorTuple, + VectorTupleWithMetadata, DeletionProtection, AndFilter, EqFilter, + ExactMatchFilter, FilterTypedDict, GteFilter, GtFilter, InFilter, + LteFilter, LtFilter, NeFilter, NinFilter, OrFilter, SimpleFilter, +) + # # This function is defined here to prevent the side-effect of diff --git a/singlestoredb/connection.py b/singlestoredb/connection.py index 1fd543db7..3a4e88698 100644 --- a/singlestoredb/connection.py +++ b/singlestoredb/connection.py @@ -1,6 +1,5 @@ #!/usr/bin/env python """SingleStoreDB connections and cursors.""" - import abc import inspect import io @@ -24,7 +23,6 @@ from urllib.parse import unquote_plus from urllib.parse import urlparse - import sqlparams try: from pandas import DataFrame @@ -1293,13 +1291,14 @@ def show(self) -> ShowAccessor: @property def vector_db(self) -> Any: """ - Get vectorstore API accessor + Get vectorstore API accessor """ from vectorstore import VectorDB if not hasattr(self, '_vector_db'): self._vector_db = VectorDB(connection=self) return self._vector_db + # # NOTE: When adding parameters to this function, you should always # make the value optional with a default of None. The options diff --git a/singlestoredb/tests/test_vectorstore.py b/singlestoredb/tests/test_vectorstore.py index 317b57bd7..cb90321c4 100644 --- a/singlestoredb/tests/test_vectorstore.py +++ b/singlestoredb/tests/test_vectorstore.py @@ -1,10 +1,11 @@ import os import unittest +from vectorstore import VectorDB + import singlestoredb as s2 from . import utils -from vectorstore import VectorDB class TestVectorDB(unittest.TestCase): @@ -14,28 +15,34 @@ class TestVectorDB(unittest.TestCase): dbexisted: bool = False @classmethod - def setUpClass(cls): + def setUpClass(cls) -> None: sql_file = os.path.join(os.path.dirname(__file__), 'empty.sql') - cls.dbname, cls.dbexisted = utils.load_sql(sql_file) + cls.dbname, cls.dbexisted = utils.load_sql(sql_file) # type: ignore @classmethod - def tearDownClass(cls): + def tearDownClass(cls) -> None: if not cls.dbexisted: - utils.drop_database(cls.dbname) + utils.drop_database(cls.dbname) # type: ignore - def test_vectordb_from_params(self): + def test_vectordb_from_params(self) -> None: db: VectorDB = s2.vector_db(database=type(self).dbname) - index = db.create_index(name="test_index", dimension=3, tags={"name": "test_tag"}) - assert index.name == "test_index" + index = db.create_index( + name='test_index', dimension=3, + tags={'name': 'test_tag'}, + ) + assert index.name == 'test_index' assert index.dimension == 3 - assert index.tags == {"name": "test_tag"} - assert db.has_index("test_index") + assert index.tags == {'name': 'test_tag'} + assert db.has_index('test_index') - def test_vectordb_from_connection(self): + def test_vectordb_from_connection(self) -> None: with s2.connect(database=type(self).dbname) as conn: db: VectorDB = conn.vector_db - index = db.create_index(name="test_index_1", dimension=4, tags={"name": "test_tag"}) - assert index.name == "test_index_1" + index = db.create_index( + name='test_index_1', + dimension=4, tags={'name': 'test_tag'}, + ) + assert index.name == 'test_index_1' assert index.dimension == 4 - assert index.tags == {"name": "test_tag"} - assert db.has_index("test_index_1") \ No newline at end of file + assert index.tags == {'name': 'test_tag'} + assert db.has_index('test_index_1') diff --git a/singlestoredb/vectorstore.py b/singlestoredb/vectorstore.py index be04ab879..67fc3b6dc 100644 --- a/singlestoredb/vectorstore.py +++ b/singlestoredb/vectorstore.py @@ -1,34 +1,35 @@ -from __future__ import annotations -from typing import Optional, Dict, Callable, Any +from typing import Any +from typing import Callable +from typing import Dict +from typing import Optional + +from vectorstore import AndFilter # noqa: F401 +from vectorstore import DeletionProtection # noqa: F401 +from vectorstore import EqFilter # noqa: F401 +from vectorstore import ExactMatchFilter # noqa: F401 +from vectorstore import FilterTypedDict # noqa: F401 +from vectorstore import GteFilter # noqa: F401 +from vectorstore import GtFilter # noqa: F401 +from vectorstore import IndexInterface # noqa: F401 +from vectorstore import IndexList # noqa: F401 +from vectorstore import IndexModel # noqa: F401 +from vectorstore import IndexStatsTypedDict # noqa: F401 +from vectorstore import InFilter # noqa: F401 +from vectorstore import LteFilter # noqa: F401 +from vectorstore import LtFilter # noqa: F401 +from vectorstore import MatchTypedDict # noqa: F401 +from vectorstore import Metric # noqa: F401 +from vectorstore import NamespaceStatsTypedDict # noqa: F401 +from vectorstore import NeFilter # noqa: F401 +from vectorstore import NinFilter # noqa: F401 +from vectorstore import OrFilter # noqa: F401 +from vectorstore import SimpleFilter # noqa: F401 +from vectorstore import Vector # noqa: F401 +from vectorstore import VectorDictMetadataValue # noqa: F401 +from vectorstore import VectorMetadataTypedDict # noqa: F401 +from vectorstore import VectorTuple # noqa: F401 +from vectorstore import VectorTupleWithMetadata # noqa: F401 -from vectorstore import ( - IndexInterface, - IndexList, - IndexModel, - MatchTypedDict, - Metric, - IndexStatsTypedDict, - NamespaceStatsTypedDict, - Vector, - VectorDictMetadataValue, - VectorMetadataTypedDict, - VectorTuple, - VectorTupleWithMetadata, - DeletionProtection, - AndFilter, - EqFilter, - ExactMatchFilter, - FilterTypedDict, - GteFilter, - GtFilter, - InFilter, - LteFilter, - LtFilter, - NeFilter, - NinFilter, - OrFilter, - SimpleFilter -) def vector_db( host: Optional[str] = None, user: Optional[str] = None, @@ -62,9 +63,9 @@ def vector_db( pool_size: Optional[int] = 5, max_overflow: Optional[int] = 10, timeout: Optional[float] = 30, -) -> "VectorDB": +) -> Any: """ - Return a vectorstore API connection. + Return a vectorstore API connection. Database should be specified in the URL or as a keyword. Parameters @@ -87,7 +88,7 @@ def vector_db( Database port. This defaults to 3306 for non-HTTP connections, 80 for HTTP connections, and 443 for HTTPS connections. database : str, optional - Database name. + Database name. pure_python : bool, optional Use the connector in pure Python mode local_infile : bool, optional @@ -167,23 +168,25 @@ def vector_db( """ from vectorstore import VectorDB - return VectorDB(host=host, user=user, password=password, port=port, - database=database, driver=driver, pure_python=pure_python, - local_infile=local_infile, charset=charset, - ssl_key=ssl_key, ssl_cert=ssl_cert, ssl_ca=ssl_ca, - ssl_disabled=ssl_disabled, ssl_cipher=ssl_cipher, - ssl_verify_cert=ssl_verify_cert, - tls_sni_servername=tls_sni_servername, - ssl_verify_identity=ssl_verify_identity, conv=conv, - credential_type=credential_type, autocommit=autocommit, - results_type=results_type, buffered=buffered, - results_format=results_format, program_name=program_name, - conn_attrs=conn_attrs, multi_statements=multi_statements, - client_found_rows=client_found_rows, - connect_timeout=connect_timeout, nan_as_null=nan_as_null, - inf_as_null=inf_as_null, encoding_errors=encoding_errors, - track_env=track_env, - enable_extended_data_types=enable_extended_data_types, - vector_data_format=vector_data_format, - parse_json=parse_json, pool_size=pool_size, - max_overflow=max_overflow, timeout=timeout) \ No newline at end of file + return VectorDB( + host=host, user=user, password=password, port=port, + database=database, driver=driver, pure_python=pure_python, + local_infile=local_infile, charset=charset, + ssl_key=ssl_key, ssl_cert=ssl_cert, ssl_ca=ssl_ca, + ssl_disabled=ssl_disabled, ssl_cipher=ssl_cipher, + ssl_verify_cert=ssl_verify_cert, + tls_sni_servername=tls_sni_servername, + ssl_verify_identity=ssl_verify_identity, conv=conv, + credential_type=credential_type, autocommit=autocommit, + results_type=results_type, buffered=buffered, + results_format=results_format, program_name=program_name, + conn_attrs=conn_attrs, multi_statements=multi_statements, + client_found_rows=client_found_rows, + connect_timeout=connect_timeout, nan_as_null=nan_as_null, + inf_as_null=inf_as_null, encoding_errors=encoding_errors, + track_env=track_env, + enable_extended_data_types=enable_extended_data_types, + vector_data_format=vector_data_format, + parse_json=parse_json, pool_size=pool_size, + max_overflow=max_overflow, timeout=timeout, + ) From 2bd94188f861ba968cba6fa18082e4b9391bcec1 Mon Sep 17 00:00:00 2001 From: Volodymyr Tkachuk Date: Wed, 28 May 2025 15:17:16 +0300 Subject: [PATCH 3/5] fix imports --- requirements.txt | 2 +- setup.cfg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 293900f9d..f513d47e3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ parsimonious PyJWT requests setuptools -singlestore-vecorstore +singlestore-vectorstore>=0.1.1 sqlparams tomli>=1.1.0; python_version < '3.11' typing_extensions<=4.13.2 diff --git a/setup.cfg b/setup.cfg index 3d8fc9a67..4c94078ab 100644 --- a/setup.cfg +++ b/setup.cfg @@ -24,7 +24,7 @@ install_requires = parsimonious requests setuptools - singlestore-vecorstore + singlestore-vectorstore>=0.1.1 sqlparams wheel tomli>=1.1.0;python_version < '3.11' From 92f402e62ea75864860986399096c8c9202fc661 Mon Sep 17 00:00:00 2001 From: Volodymyr Tkachuk Date: Thu, 29 May 2025 11:51:07 +0300 Subject: [PATCH 4/5] review comments --- docs/src/whatsnew.rst | 5 ----- requirements.txt | 2 +- setup.cfg | 4 ++-- singlestoredb/__init__.py | 2 +- singlestoredb/connection.py | 7 +++---- singlestoredb/tests/test_vectorstore.py | 3 +++ 6 files changed, 10 insertions(+), 13 deletions(-) diff --git a/docs/src/whatsnew.rst b/docs/src/whatsnew.rst index 6b35966db..ed87341a0 100644 --- a/docs/src/whatsnew.rst +++ b/docs/src/whatsnew.rst @@ -8,11 +8,6 @@ This document outlines features and improvements from each release. are for non-production testing and evaluation, and may include changes to the API. -v1.14.0 - May 28, 2025 ------------------------- -* Add ``vector_db`` property to a ``Connection`` object to get the vectorstor API to the current database -* Add ``vector_db(...)`` function to connect to a database and optain a vectorstor API - v1.13.0 - April 16, 2025 ------------------------ * Refactor external function server (experimental) type system diff --git a/requirements.txt b/requirements.txt index f513d47e3..c31abed07 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ parsimonious PyJWT requests setuptools -singlestore-vectorstore>=0.1.1 +singlestore-vectorstore>=0.1.2 sqlparams tomli>=1.1.0; python_version < '3.11' typing_extensions<=4.13.2 diff --git a/setup.cfg b/setup.cfg index 4c94078ab..a2311f615 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = singlestoredb -version = 1.14.0 +version = 1.13.1 description = Interface to the SingleStoreDB database and workspace management APIs long_description = file: README.md long_description_content_type = text/markdown @@ -24,7 +24,7 @@ install_requires = parsimonious requests setuptools - singlestore-vectorstore>=0.1.1 + singlestore-vectorstore>=0.1.2 sqlparams wheel tomli>=1.1.0;python_version < '3.11' diff --git a/singlestoredb/__init__.py b/singlestoredb/__init__.py index 0961b9ed4..c269d13ba 100644 --- a/singlestoredb/__init__.py +++ b/singlestoredb/__init__.py @@ -13,7 +13,7 @@ """ -__version__ = '1.14.0' +__version__ = '1.13.1' from typing import Any diff --git a/singlestoredb/connection.py b/singlestoredb/connection.py index 3a4e88698..258ab5813 100644 --- a/singlestoredb/connection.py +++ b/singlestoredb/connection.py @@ -1,6 +1,7 @@ #!/usr/bin/env python """SingleStoreDB connections and cursors.""" import abc +import functools import inspect import io import queue @@ -1288,15 +1289,13 @@ def show(self) -> ShowAccessor: """Access server properties managed by the SHOW statement.""" return ShowAccessor(self) - @property + @functools.cached_property def vector_db(self) -> Any: """ Get vectorstore API accessor """ from vectorstore import VectorDB - if not hasattr(self, '_vector_db'): - self._vector_db = VectorDB(connection=self) - return self._vector_db + return VectorDB(connection=self) # diff --git a/singlestoredb/tests/test_vectorstore.py b/singlestoredb/tests/test_vectorstore.py index cb90321c4..bccc2b473 100644 --- a/singlestoredb/tests/test_vectorstore.py +++ b/singlestoredb/tests/test_vectorstore.py @@ -46,3 +46,6 @@ def test_vectordb_from_connection(self) -> None: assert index.dimension == 4 assert index.tags == {'name': 'test_tag'} assert db.has_index('test_index_1') + + db2: VectorDB = conn.vector_db + assert db2.has_index('test_index_1') From 00750fbf3482ab2256009e9929073581d3e45a8c Mon Sep 17 00:00:00 2001 From: Volodymyr Tkachuk Date: Thu, 29 May 2025 12:07:57 +0300 Subject: [PATCH 5/5] update python version --- .github/workflows/pre-commit.yml | 1 - setup.cfg | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 7d535e37f..a9217a93f 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -9,7 +9,6 @@ jobs: strategy: matrix: python-version: - - "3.8" - "3.9" - "3.10" - "3.11" diff --git a/setup.cfg b/setup.cfg index a2311f615..e14e73cfd 100644 --- a/setup.cfg +++ b/setup.cfg @@ -29,7 +29,7 @@ install_requires = wheel tomli>=1.1.0;python_version < '3.11' typing-extensions<=4.13.2;python_version < '3.11' -python_requires = >=3.8 +python_requires = >=3.9 include_package_data = True tests_require = coverage