singlestoredb 1.16.1__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.
- singlestoredb/__init__.py +75 -0
- singlestoredb/ai/__init__.py +2 -0
- singlestoredb/ai/chat.py +139 -0
- singlestoredb/ai/embeddings.py +128 -0
- singlestoredb/alchemy/__init__.py +90 -0
- singlestoredb/apps/__init__.py +3 -0
- singlestoredb/apps/_cloud_functions.py +90 -0
- singlestoredb/apps/_config.py +72 -0
- singlestoredb/apps/_connection_info.py +18 -0
- singlestoredb/apps/_dashboards.py +47 -0
- singlestoredb/apps/_process.py +32 -0
- singlestoredb/apps/_python_udfs.py +100 -0
- singlestoredb/apps/_stdout_supress.py +30 -0
- singlestoredb/apps/_uvicorn_util.py +36 -0
- singlestoredb/auth.py +245 -0
- singlestoredb/config.py +484 -0
- singlestoredb/connection.py +1487 -0
- singlestoredb/converters.py +950 -0
- singlestoredb/docstring/__init__.py +33 -0
- singlestoredb/docstring/attrdoc.py +126 -0
- singlestoredb/docstring/common.py +230 -0
- singlestoredb/docstring/epydoc.py +267 -0
- singlestoredb/docstring/google.py +412 -0
- singlestoredb/docstring/numpydoc.py +562 -0
- singlestoredb/docstring/parser.py +100 -0
- singlestoredb/docstring/py.typed +1 -0
- singlestoredb/docstring/rest.py +256 -0
- singlestoredb/docstring/tests/__init__.py +1 -0
- singlestoredb/docstring/tests/_pydoctor.py +21 -0
- singlestoredb/docstring/tests/test_epydoc.py +729 -0
- singlestoredb/docstring/tests/test_google.py +1007 -0
- singlestoredb/docstring/tests/test_numpydoc.py +1100 -0
- singlestoredb/docstring/tests/test_parse_from_object.py +109 -0
- singlestoredb/docstring/tests/test_parser.py +248 -0
- singlestoredb/docstring/tests/test_rest.py +547 -0
- singlestoredb/docstring/tests/test_util.py +70 -0
- singlestoredb/docstring/util.py +141 -0
- singlestoredb/exceptions.py +120 -0
- singlestoredb/functions/__init__.py +16 -0
- singlestoredb/functions/decorator.py +201 -0
- singlestoredb/functions/dtypes.py +1793 -0
- singlestoredb/functions/ext/__init__.py +1 -0
- singlestoredb/functions/ext/arrow.py +375 -0
- singlestoredb/functions/ext/asgi.py +2133 -0
- singlestoredb/functions/ext/json.py +420 -0
- singlestoredb/functions/ext/mmap.py +413 -0
- singlestoredb/functions/ext/rowdat_1.py +724 -0
- singlestoredb/functions/ext/timer.py +89 -0
- singlestoredb/functions/ext/utils.py +218 -0
- singlestoredb/functions/signature.py +1578 -0
- singlestoredb/functions/typing/__init__.py +41 -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/functions/utils.py +421 -0
- singlestoredb/fusion/__init__.py +11 -0
- singlestoredb/fusion/graphql.py +213 -0
- singlestoredb/fusion/handler.py +916 -0
- singlestoredb/fusion/handlers/__init__.py +0 -0
- singlestoredb/fusion/handlers/export.py +525 -0
- singlestoredb/fusion/handlers/files.py +690 -0
- singlestoredb/fusion/handlers/job.py +660 -0
- singlestoredb/fusion/handlers/models.py +250 -0
- singlestoredb/fusion/handlers/stage.py +502 -0
- singlestoredb/fusion/handlers/utils.py +324 -0
- singlestoredb/fusion/handlers/workspace.py +956 -0
- singlestoredb/fusion/registry.py +249 -0
- singlestoredb/fusion/result.py +399 -0
- singlestoredb/http/__init__.py +27 -0
- singlestoredb/http/connection.py +1267 -0
- singlestoredb/magics/__init__.py +34 -0
- singlestoredb/magics/run_personal.py +137 -0
- singlestoredb/magics/run_shared.py +134 -0
- singlestoredb/management/__init__.py +9 -0
- singlestoredb/management/billing_usage.py +148 -0
- singlestoredb/management/cluster.py +462 -0
- singlestoredb/management/export.py +295 -0
- singlestoredb/management/files.py +1102 -0
- singlestoredb/management/inference_api.py +105 -0
- singlestoredb/management/job.py +887 -0
- singlestoredb/management/manager.py +373 -0
- singlestoredb/management/organization.py +226 -0
- singlestoredb/management/region.py +169 -0
- singlestoredb/management/utils.py +423 -0
- singlestoredb/management/workspace.py +1927 -0
- singlestoredb/mysql/__init__.py +177 -0
- singlestoredb/mysql/_auth.py +298 -0
- singlestoredb/mysql/charset.py +214 -0
- singlestoredb/mysql/connection.py +2032 -0
- singlestoredb/mysql/constants/CLIENT.py +38 -0
- singlestoredb/mysql/constants/COMMAND.py +32 -0
- singlestoredb/mysql/constants/CR.py +78 -0
- singlestoredb/mysql/constants/ER.py +474 -0
- singlestoredb/mysql/constants/EXTENDED_TYPE.py +3 -0
- singlestoredb/mysql/constants/FIELD_TYPE.py +48 -0
- singlestoredb/mysql/constants/FLAG.py +15 -0
- singlestoredb/mysql/constants/SERVER_STATUS.py +10 -0
- singlestoredb/mysql/constants/VECTOR_TYPE.py +6 -0
- singlestoredb/mysql/constants/__init__.py +0 -0
- singlestoredb/mysql/converters.py +271 -0
- singlestoredb/mysql/cursors.py +896 -0
- singlestoredb/mysql/err.py +92 -0
- singlestoredb/mysql/optionfile.py +20 -0
- singlestoredb/mysql/protocol.py +450 -0
- singlestoredb/mysql/tests/__init__.py +19 -0
- singlestoredb/mysql/tests/base.py +126 -0
- singlestoredb/mysql/tests/conftest.py +37 -0
- singlestoredb/mysql/tests/test_DictCursor.py +132 -0
- singlestoredb/mysql/tests/test_SSCursor.py +141 -0
- singlestoredb/mysql/tests/test_basic.py +452 -0
- singlestoredb/mysql/tests/test_connection.py +851 -0
- singlestoredb/mysql/tests/test_converters.py +58 -0
- singlestoredb/mysql/tests/test_cursor.py +141 -0
- singlestoredb/mysql/tests/test_err.py +16 -0
- singlestoredb/mysql/tests/test_issues.py +514 -0
- singlestoredb/mysql/tests/test_load_local.py +75 -0
- singlestoredb/mysql/tests/test_nextset.py +88 -0
- singlestoredb/mysql/tests/test_optionfile.py +27 -0
- singlestoredb/mysql/tests/thirdparty/__init__.py +6 -0
- singlestoredb/mysql/tests/thirdparty/test_MySQLdb/__init__.py +9 -0
- singlestoredb/mysql/tests/thirdparty/test_MySQLdb/capabilities.py +323 -0
- singlestoredb/mysql/tests/thirdparty/test_MySQLdb/dbapi20.py +865 -0
- singlestoredb/mysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_capabilities.py +110 -0
- singlestoredb/mysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_dbapi20.py +224 -0
- singlestoredb/mysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_nonstandard.py +101 -0
- singlestoredb/mysql/times.py +23 -0
- singlestoredb/notebook/__init__.py +16 -0
- singlestoredb/notebook/_objects.py +213 -0
- singlestoredb/notebook/_portal.py +352 -0
- singlestoredb/py.typed +0 -0
- singlestoredb/pytest.py +352 -0
- singlestoredb/server/__init__.py +0 -0
- singlestoredb/server/docker.py +452 -0
- singlestoredb/server/free_tier.py +267 -0
- singlestoredb/tests/__init__.py +0 -0
- singlestoredb/tests/alltypes.sql +307 -0
- singlestoredb/tests/alltypes_no_nulls.sql +208 -0
- singlestoredb/tests/empty.sql +0 -0
- singlestoredb/tests/ext_funcs/__init__.py +702 -0
- singlestoredb/tests/local_infile.csv +3 -0
- singlestoredb/tests/test.ipynb +18 -0
- singlestoredb/tests/test.sql +680 -0
- singlestoredb/tests/test2.ipynb +18 -0
- singlestoredb/tests/test2.sql +1 -0
- singlestoredb/tests/test_basics.py +1332 -0
- singlestoredb/tests/test_config.py +318 -0
- singlestoredb/tests/test_connection.py +3103 -0
- singlestoredb/tests/test_dbapi.py +27 -0
- singlestoredb/tests/test_exceptions.py +45 -0
- singlestoredb/tests/test_ext_func.py +1472 -0
- singlestoredb/tests/test_ext_func_data.py +1101 -0
- singlestoredb/tests/test_fusion.py +1527 -0
- singlestoredb/tests/test_http.py +288 -0
- singlestoredb/tests/test_management.py +1599 -0
- singlestoredb/tests/test_plugin.py +33 -0
- singlestoredb/tests/test_results.py +171 -0
- singlestoredb/tests/test_types.py +132 -0
- singlestoredb/tests/test_udf.py +737 -0
- singlestoredb/tests/test_udf_returns.py +459 -0
- singlestoredb/tests/test_vectorstore.py +51 -0
- singlestoredb/tests/test_xdict.py +333 -0
- singlestoredb/tests/utils.py +141 -0
- singlestoredb/types.py +373 -0
- singlestoredb/utils/__init__.py +0 -0
- singlestoredb/utils/config.py +950 -0
- singlestoredb/utils/convert_rows.py +69 -0
- singlestoredb/utils/debug.py +13 -0
- singlestoredb/utils/dtypes.py +205 -0
- singlestoredb/utils/events.py +65 -0
- singlestoredb/utils/mogrify.py +151 -0
- singlestoredb/utils/results.py +585 -0
- singlestoredb/utils/xdict.py +425 -0
- singlestoredb/vectorstore.py +192 -0
- singlestoredb/warnings.py +5 -0
- singlestoredb-1.16.1.dist-info/METADATA +165 -0
- singlestoredb-1.16.1.dist-info/RECORD +183 -0
- singlestoredb-1.16.1.dist-info/WHEEL +5 -0
- singlestoredb-1.16.1.dist-info/entry_points.txt +2 -0
- singlestoredb-1.16.1.dist-info/licenses/LICENSE +201 -0
- singlestoredb-1.16.1.dist-info/top_level.txt +3 -0
- sqlx/__init__.py +4 -0
- sqlx/magic.py +113 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from collections.abc import Iterable
|
|
2
|
+
from typing import Any
|
|
3
|
+
from typing import Tuple
|
|
4
|
+
from typing import TypeVar
|
|
5
|
+
|
|
6
|
+
try:
|
|
7
|
+
from typing import TypeVarTuple # type: ignore
|
|
8
|
+
from typing import Unpack # type: ignore
|
|
9
|
+
except ImportError:
|
|
10
|
+
# Python 3.8 and earlier do not have TypeVarTuple
|
|
11
|
+
from typing_extensions import TypeVarTuple # type: ignore
|
|
12
|
+
from typing_extensions import Unpack # type: ignore
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
T = TypeVar('T', bound=Iterable[Any]) # Generic type for iterable types
|
|
16
|
+
|
|
17
|
+
#
|
|
18
|
+
# Masked types are used for pairs of vectors where the first element is the
|
|
19
|
+
# vector and the second element is a boolean mask indicating which elements
|
|
20
|
+
# are NULL. The boolean mask is a vector of the same length as the first
|
|
21
|
+
# element, where True indicates that the corresponding element in the first
|
|
22
|
+
# element is NULL.
|
|
23
|
+
#
|
|
24
|
+
# This is needed for vector types that do not support NULL values, such as
|
|
25
|
+
# numpy arrays and pandas Series.
|
|
26
|
+
#
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class Masked(Tuple[T, T]):
|
|
30
|
+
def __new__(cls, *args: T) -> 'Masked[Tuple[T, T]]': # type: ignore
|
|
31
|
+
return tuple.__new__(cls, (args[0], args[1])) # type: ignore
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
Ts = TypeVarTuple('Ts')
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class Table(Tuple[Unpack[Ts]]):
|
|
38
|
+
"""Return type for a table valued function."""
|
|
39
|
+
|
|
40
|
+
def __new__(cls, *args: Unpack[Ts]) -> 'Table[Tuple[Unpack[Ts]]]': # type: ignore
|
|
41
|
+
return tuple.__new__(cls, args) # type: ignore
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import numpy.typing as npt
|
|
3
|
+
|
|
4
|
+
NDArray = npt.NDArray
|
|
5
|
+
|
|
6
|
+
StringArray = StrArray = npt.NDArray[np.str_]
|
|
7
|
+
BytesArray = npt.NDArray[np.bytes_]
|
|
8
|
+
Float32Array = FloatArray = npt.NDArray[np.float32]
|
|
9
|
+
Float64Array = DoubleArray = npt.NDArray[np.float64]
|
|
10
|
+
IntArray = npt.NDArray[np.int_]
|
|
11
|
+
Int8Array = npt.NDArray[np.int8]
|
|
12
|
+
Int16Array = npt.NDArray[np.int16]
|
|
13
|
+
Int32Array = npt.NDArray[np.int32]
|
|
14
|
+
Int64Array = npt.NDArray[np.int64]
|
|
15
|
+
UInt8Array = npt.NDArray[np.uint8]
|
|
16
|
+
UInt16Array = npt.NDArray[np.uint16]
|
|
17
|
+
UInt32Array = npt.NDArray[np.uint32]
|
|
18
|
+
UInt64Array = npt.NDArray[np.uint64]
|
|
19
|
+
DateTimeArray = npt.NDArray[np.datetime64]
|
|
20
|
+
TimeDeltaArray = npt.NDArray[np.timedelta64]
|
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
import dataclasses
|
|
2
|
+
import inspect
|
|
3
|
+
import struct
|
|
4
|
+
import sys
|
|
5
|
+
import types
|
|
6
|
+
import typing
|
|
7
|
+
from collections.abc import Iterable
|
|
8
|
+
from enum import Enum
|
|
9
|
+
from typing import Any
|
|
10
|
+
from typing import Dict
|
|
11
|
+
from typing import Tuple
|
|
12
|
+
from typing import Union
|
|
13
|
+
|
|
14
|
+
from .typing import Masked
|
|
15
|
+
|
|
16
|
+
if sys.version_info >= (3, 10):
|
|
17
|
+
_UNION_TYPES = {typing.Union, types.UnionType}
|
|
18
|
+
else:
|
|
19
|
+
_UNION_TYPES = {typing.Union}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
is_dataclass = dataclasses.is_dataclass
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def is_masked(obj: Any) -> bool:
|
|
26
|
+
"""Check if an object is a Masked type."""
|
|
27
|
+
origin = typing.get_origin(obj)
|
|
28
|
+
if origin is not None:
|
|
29
|
+
return origin is Masked or \
|
|
30
|
+
(inspect.isclass(origin) and issubclass(origin, Masked))
|
|
31
|
+
return False
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def is_union(x: Any) -> bool:
|
|
35
|
+
"""Check if the object is a Union."""
|
|
36
|
+
return typing.get_origin(x) in _UNION_TYPES
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def get_annotations(obj: Any) -> Dict[str, Any]:
|
|
40
|
+
"""Get the annotations of an object."""
|
|
41
|
+
return typing.get_type_hints(obj)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def get_module(obj: Any) -> str:
|
|
45
|
+
"""Get the module of an object."""
|
|
46
|
+
module = getattr(obj, '__module__', '').split('.')
|
|
47
|
+
if module:
|
|
48
|
+
return module[0]
|
|
49
|
+
return ''
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def get_type_name(obj: Any) -> str:
|
|
53
|
+
"""Get the type name of an object."""
|
|
54
|
+
if hasattr(obj, '__name__'):
|
|
55
|
+
return obj.__name__
|
|
56
|
+
if hasattr(obj, '__class__'):
|
|
57
|
+
return obj.__class__.__name__
|
|
58
|
+
return ''
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def is_numpy(obj: Any) -> bool:
|
|
62
|
+
"""Check if an object is a numpy array."""
|
|
63
|
+
if str(obj).startswith('numpy.ndarray['):
|
|
64
|
+
return True
|
|
65
|
+
|
|
66
|
+
if inspect.isclass(obj):
|
|
67
|
+
if get_module(obj) == 'numpy':
|
|
68
|
+
return get_type_name(obj) == 'ndarray'
|
|
69
|
+
|
|
70
|
+
origin = typing.get_origin(obj)
|
|
71
|
+
if get_module(origin) == 'numpy':
|
|
72
|
+
if get_type_name(origin) == 'ndarray':
|
|
73
|
+
return True
|
|
74
|
+
|
|
75
|
+
dtype = type(obj)
|
|
76
|
+
if get_module(dtype) == 'numpy':
|
|
77
|
+
return get_type_name(dtype) == 'ndarray'
|
|
78
|
+
|
|
79
|
+
return False
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def is_dataframe(obj: Any) -> bool:
|
|
83
|
+
"""Check if an object is a DataFrame."""
|
|
84
|
+
# Cheating here a bit so we don't have to import pandas / polars / pyarrow:
|
|
85
|
+
# unless we absolutely need to
|
|
86
|
+
if get_module(obj) == 'pandas':
|
|
87
|
+
return get_type_name(obj) == 'DataFrame'
|
|
88
|
+
if get_module(obj) == 'polars':
|
|
89
|
+
return get_type_name(obj) == 'DataFrame'
|
|
90
|
+
if get_module(obj) == 'pyarrow':
|
|
91
|
+
return get_type_name(obj) == 'Table'
|
|
92
|
+
return False
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def is_vector(obj: Any, include_masks: bool = False) -> bool:
|
|
96
|
+
"""Check if an object is a vector type."""
|
|
97
|
+
return is_pandas_series(obj) \
|
|
98
|
+
or is_polars_series(obj) \
|
|
99
|
+
or is_pyarrow_array(obj) \
|
|
100
|
+
or is_numpy(obj) \
|
|
101
|
+
or is_masked(obj)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def get_data_format(obj: Any) -> str:
|
|
105
|
+
"""Return the data format of the DataFrame / Table / vector."""
|
|
106
|
+
# Cheating here a bit so we don't have to import pandas / polars / pyarrow
|
|
107
|
+
# unless we absolutely need to
|
|
108
|
+
if get_module(obj) == 'pandas':
|
|
109
|
+
return 'pandas'
|
|
110
|
+
if get_module(obj) == 'polars':
|
|
111
|
+
return 'polars'
|
|
112
|
+
if get_module(obj) == 'pyarrow':
|
|
113
|
+
return 'arrow'
|
|
114
|
+
if get_module(obj) == 'numpy':
|
|
115
|
+
return 'numpy'
|
|
116
|
+
if isinstance(obj, list):
|
|
117
|
+
return 'list'
|
|
118
|
+
return 'scalar'
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def is_pandas_series(obj: Any) -> bool:
|
|
122
|
+
"""Check if an object is a pandas Series."""
|
|
123
|
+
if is_union(obj):
|
|
124
|
+
obj = typing.get_args(obj)[0]
|
|
125
|
+
return (
|
|
126
|
+
get_module(obj) == 'pandas' and
|
|
127
|
+
get_type_name(obj) == 'Series'
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def is_polars_series(obj: Any) -> bool:
|
|
132
|
+
"""Check if an object is a polars Series."""
|
|
133
|
+
if is_union(obj):
|
|
134
|
+
obj = typing.get_args(obj)[0]
|
|
135
|
+
return (
|
|
136
|
+
get_module(obj) == 'polars' and
|
|
137
|
+
get_type_name(obj) == 'Series'
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def is_pyarrow_array(obj: Any) -> bool:
|
|
142
|
+
"""Check if an object is a pyarrow Array."""
|
|
143
|
+
if is_union(obj):
|
|
144
|
+
obj = typing.get_args(obj)[0]
|
|
145
|
+
return (
|
|
146
|
+
get_module(obj) == 'pyarrow' and
|
|
147
|
+
get_type_name(obj) == 'Array'
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def is_typeddict(obj: Any) -> bool:
|
|
152
|
+
"""Check if an object is a TypedDict."""
|
|
153
|
+
if hasattr(typing, 'is_typeddict'):
|
|
154
|
+
return typing.is_typeddict(obj) # noqa: TYP006
|
|
155
|
+
return False
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def is_namedtuple(obj: Any) -> bool:
|
|
159
|
+
"""Check if an object is a named tuple."""
|
|
160
|
+
if inspect.isclass(obj):
|
|
161
|
+
return (
|
|
162
|
+
issubclass(obj, tuple) and
|
|
163
|
+
hasattr(obj, '_asdict') and
|
|
164
|
+
hasattr(obj, '_fields')
|
|
165
|
+
)
|
|
166
|
+
return (
|
|
167
|
+
isinstance(obj, tuple) and
|
|
168
|
+
hasattr(obj, '_asdict') and
|
|
169
|
+
hasattr(obj, '_fields')
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def is_pydantic(obj: Any) -> bool:
|
|
174
|
+
"""Check if an object is a pydantic model."""
|
|
175
|
+
if not inspect.isclass(obj):
|
|
176
|
+
return False
|
|
177
|
+
# We don't want to import pydantic here, so we check if
|
|
178
|
+
# the class is a subclass
|
|
179
|
+
return bool([
|
|
180
|
+
x for x in inspect.getmro(obj)
|
|
181
|
+
if get_module(x) == 'pydantic'
|
|
182
|
+
and get_type_name(x) == 'BaseModel'
|
|
183
|
+
])
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
class VectorTypes(str, Enum):
|
|
187
|
+
"""Enum for vector types."""
|
|
188
|
+
F16 = 'f16'
|
|
189
|
+
F32 = 'f32'
|
|
190
|
+
F64 = 'f64'
|
|
191
|
+
I8 = 'i8'
|
|
192
|
+
I16 = 'i16'
|
|
193
|
+
I32 = 'i32'
|
|
194
|
+
I64 = 'i64'
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def _vector_type_to_numpy_type(
|
|
198
|
+
vector_type: VectorTypes,
|
|
199
|
+
) -> str:
|
|
200
|
+
"""Convert a vector type to a numpy type."""
|
|
201
|
+
if vector_type == VectorTypes.F32:
|
|
202
|
+
return 'f4'
|
|
203
|
+
elif vector_type == VectorTypes.F64:
|
|
204
|
+
return 'f8'
|
|
205
|
+
elif vector_type == VectorTypes.I8:
|
|
206
|
+
return 'i1'
|
|
207
|
+
elif vector_type == VectorTypes.I16:
|
|
208
|
+
return 'i2'
|
|
209
|
+
elif vector_type == VectorTypes.I32:
|
|
210
|
+
return 'i4'
|
|
211
|
+
elif vector_type == VectorTypes.I64:
|
|
212
|
+
return 'i8'
|
|
213
|
+
raise ValueError(f'unsupported element type: {vector_type}')
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def _vector_type_to_struct_format(
|
|
217
|
+
vec: Any,
|
|
218
|
+
vector_type: VectorTypes,
|
|
219
|
+
) -> str:
|
|
220
|
+
"""Convert a vector type to a struct format string."""
|
|
221
|
+
n = len(vec)
|
|
222
|
+
if vector_type == VectorTypes.F32:
|
|
223
|
+
if isinstance(vec, (bytes, bytearray)):
|
|
224
|
+
n = n // 4
|
|
225
|
+
return f'<{n}f'
|
|
226
|
+
elif vector_type == VectorTypes.F64:
|
|
227
|
+
if isinstance(vec, (bytes, bytearray)):
|
|
228
|
+
n = n // 8
|
|
229
|
+
return f'<{n}d'
|
|
230
|
+
elif vector_type == VectorTypes.I8:
|
|
231
|
+
return f'<{n}b'
|
|
232
|
+
elif vector_type == VectorTypes.I16:
|
|
233
|
+
if isinstance(vec, (bytes, bytearray)):
|
|
234
|
+
n = n // 2
|
|
235
|
+
return f'<{n}h'
|
|
236
|
+
elif vector_type == VectorTypes.I32:
|
|
237
|
+
if isinstance(vec, (bytes, bytearray)):
|
|
238
|
+
n = n // 4
|
|
239
|
+
return f'<{n}i'
|
|
240
|
+
elif vector_type == VectorTypes.I64:
|
|
241
|
+
if isinstance(vec, (bytes, bytearray)):
|
|
242
|
+
n = n // 8
|
|
243
|
+
return f'<{n}q'
|
|
244
|
+
raise ValueError(f'unsupported element type: {vector_type}')
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
def unpack_vector(
|
|
248
|
+
obj: Union[bytes, bytearray],
|
|
249
|
+
vec_type: VectorTypes = VectorTypes.F32,
|
|
250
|
+
) -> Tuple[Any]:
|
|
251
|
+
"""
|
|
252
|
+
Unpack a vector from bytes.
|
|
253
|
+
|
|
254
|
+
Parameters
|
|
255
|
+
----------
|
|
256
|
+
obj : bytes or bytearray
|
|
257
|
+
The object to unpack.
|
|
258
|
+
vec_type : VectorTypes
|
|
259
|
+
The type of the elements in the vector.
|
|
260
|
+
Can be one of 'f32', 'f64', 'i8', 'i16', 'i32', or 'i64'.
|
|
261
|
+
Default is 'f32'.
|
|
262
|
+
|
|
263
|
+
Returns
|
|
264
|
+
-------
|
|
265
|
+
Tuple[Any]
|
|
266
|
+
The unpacked vector.
|
|
267
|
+
|
|
268
|
+
"""
|
|
269
|
+
return struct.unpack(_vector_type_to_struct_format(obj, vec_type), obj)
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
def pack_vector(
|
|
273
|
+
obj: Any,
|
|
274
|
+
vec_type: VectorTypes = VectorTypes.F32,
|
|
275
|
+
) -> bytes:
|
|
276
|
+
"""
|
|
277
|
+
Pack a vector into bytes.
|
|
278
|
+
|
|
279
|
+
Parameters
|
|
280
|
+
----------
|
|
281
|
+
obj : Any
|
|
282
|
+
The object to pack.
|
|
283
|
+
vec_type : VectorTypes
|
|
284
|
+
The type of the elements in the vector.
|
|
285
|
+
Can be one of 'f32', 'f64', 'i8', 'i16', 'i32', or 'i64'.
|
|
286
|
+
Default is 'f32'.
|
|
287
|
+
|
|
288
|
+
Returns
|
|
289
|
+
-------
|
|
290
|
+
bytes
|
|
291
|
+
The packed vector.
|
|
292
|
+
|
|
293
|
+
"""
|
|
294
|
+
if isinstance(obj, (list, tuple)):
|
|
295
|
+
return struct.pack(_vector_type_to_struct_format(obj, vec_type), *obj)
|
|
296
|
+
|
|
297
|
+
if is_numpy(obj):
|
|
298
|
+
return obj.tobytes()
|
|
299
|
+
|
|
300
|
+
if is_pandas_series(obj):
|
|
301
|
+
import pandas as pd
|
|
302
|
+
return pd.Series(obj).to_numpy().tobytes()
|
|
303
|
+
|
|
304
|
+
if is_polars_series(obj):
|
|
305
|
+
import polars as pl
|
|
306
|
+
return pl.Series(obj).to_numpy().tobytes()
|
|
307
|
+
|
|
308
|
+
if is_pyarrow_array(obj):
|
|
309
|
+
import pyarrow as pa
|
|
310
|
+
return pa.array(obj).to_numpy().tobytes()
|
|
311
|
+
|
|
312
|
+
raise ValueError(
|
|
313
|
+
f'unsupported object type: {type(obj)}',
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
def unpack_vectors(
|
|
318
|
+
arr_of_vec: Any,
|
|
319
|
+
vec_type: VectorTypes = VectorTypes.F32,
|
|
320
|
+
) -> Iterable[Any]:
|
|
321
|
+
"""
|
|
322
|
+
Unpack a vector from an array of bytes.
|
|
323
|
+
|
|
324
|
+
Parameters
|
|
325
|
+
----------
|
|
326
|
+
arr_of_vec : Iterable[Any]
|
|
327
|
+
The array of bytes to unpack.
|
|
328
|
+
vec_type : VectorTypes
|
|
329
|
+
The type of the elements in the vector.
|
|
330
|
+
Can be one of 'f32', 'f64', 'i8', 'i16', 'i32', or 'i64'.
|
|
331
|
+
Default is 'f32'.
|
|
332
|
+
|
|
333
|
+
Returns
|
|
334
|
+
-------
|
|
335
|
+
Iterable[Any]
|
|
336
|
+
The unpacked vector.
|
|
337
|
+
|
|
338
|
+
"""
|
|
339
|
+
if isinstance(arr_of_vec, (list, tuple)):
|
|
340
|
+
return [unpack_vector(x, vec_type) for x in arr_of_vec]
|
|
341
|
+
|
|
342
|
+
import numpy as np
|
|
343
|
+
|
|
344
|
+
dtype = _vector_type_to_numpy_type(vec_type)
|
|
345
|
+
|
|
346
|
+
np_arr = np.array(
|
|
347
|
+
[np.frombuffer(x, dtype=dtype) for x in arr_of_vec],
|
|
348
|
+
dtype=dtype,
|
|
349
|
+
)
|
|
350
|
+
|
|
351
|
+
if is_numpy(arr_of_vec):
|
|
352
|
+
return np_arr
|
|
353
|
+
|
|
354
|
+
if is_pandas_series(arr_of_vec):
|
|
355
|
+
import pandas as pd
|
|
356
|
+
return pd.Series(np_arr)
|
|
357
|
+
|
|
358
|
+
if is_polars_series(arr_of_vec):
|
|
359
|
+
import polars as pl
|
|
360
|
+
return pl.Series(np_arr)
|
|
361
|
+
|
|
362
|
+
if is_pyarrow_array(arr_of_vec):
|
|
363
|
+
import pyarrow as pa
|
|
364
|
+
return pa.array(np_arr)
|
|
365
|
+
|
|
366
|
+
raise ValueError(
|
|
367
|
+
f'unsupported object type: {type(arr_of_vec)}',
|
|
368
|
+
)
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
def pack_vectors(
|
|
372
|
+
arr_of_arr: Iterable[Any],
|
|
373
|
+
vec_type: VectorTypes = VectorTypes.F32,
|
|
374
|
+
) -> Iterable[Any]:
|
|
375
|
+
"""
|
|
376
|
+
Pack a vector into an array of bytes.
|
|
377
|
+
|
|
378
|
+
Parameters
|
|
379
|
+
----------
|
|
380
|
+
arr_of_arr : Iterable[Any]
|
|
381
|
+
The array of bytes to pack.
|
|
382
|
+
vec_type : VectorTypes
|
|
383
|
+
The type of the elements in the vector.
|
|
384
|
+
Can be one of 'f32', 'f64', 'i8', 'i16', 'i32', or 'i64'.
|
|
385
|
+
Default is 'f32'.
|
|
386
|
+
|
|
387
|
+
Returns
|
|
388
|
+
-------
|
|
389
|
+
Iterable[Any]
|
|
390
|
+
The array of packed vectors.
|
|
391
|
+
|
|
392
|
+
"""
|
|
393
|
+
if isinstance(arr_of_arr, (list, tuple)):
|
|
394
|
+
if not arr_of_arr:
|
|
395
|
+
return []
|
|
396
|
+
fmt = _vector_type_to_struct_format(arr_of_arr[0], vec_type)
|
|
397
|
+
return [struct.pack(fmt, x) for x in arr_of_arr]
|
|
398
|
+
|
|
399
|
+
import numpy as np
|
|
400
|
+
|
|
401
|
+
# Use object type because numpy truncates nulls at the end of fixed binary
|
|
402
|
+
np_arr = np.array([x.tobytes() for x in arr_of_arr], dtype=np.object_)
|
|
403
|
+
|
|
404
|
+
if is_numpy(arr_of_arr):
|
|
405
|
+
return np_arr
|
|
406
|
+
|
|
407
|
+
if is_pandas_series(arr_of_arr):
|
|
408
|
+
import pandas as pd
|
|
409
|
+
return pd.Series(np_arr)
|
|
410
|
+
|
|
411
|
+
if is_polars_series(arr_of_arr):
|
|
412
|
+
import polars as pl
|
|
413
|
+
return pl.Series(np_arr)
|
|
414
|
+
|
|
415
|
+
if is_pyarrow_array(arr_of_arr):
|
|
416
|
+
import pyarrow as pa
|
|
417
|
+
return pa.array(np_arr)
|
|
418
|
+
|
|
419
|
+
raise ValueError(
|
|
420
|
+
f'unsupported object type: {type(arr_of_arr)}',
|
|
421
|
+
)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import importlib
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
from .registry import execute
|
|
6
|
+
from .registry import get_handler
|
|
7
|
+
|
|
8
|
+
# Load all files in handlers directory
|
|
9
|
+
for f in os.listdir(os.path.join(os.path.dirname(__file__), 'handlers')):
|
|
10
|
+
if f.endswith('.py') and not f.startswith('_'):
|
|
11
|
+
importlib.import_module(f'singlestoredb.fusion.handlers.{f[:-3]}')
|