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.
Files changed (183) hide show
  1. singlestoredb/__init__.py +75 -0
  2. singlestoredb/ai/__init__.py +2 -0
  3. singlestoredb/ai/chat.py +139 -0
  4. singlestoredb/ai/embeddings.py +128 -0
  5. singlestoredb/alchemy/__init__.py +90 -0
  6. singlestoredb/apps/__init__.py +3 -0
  7. singlestoredb/apps/_cloud_functions.py +90 -0
  8. singlestoredb/apps/_config.py +72 -0
  9. singlestoredb/apps/_connection_info.py +18 -0
  10. singlestoredb/apps/_dashboards.py +47 -0
  11. singlestoredb/apps/_process.py +32 -0
  12. singlestoredb/apps/_python_udfs.py +100 -0
  13. singlestoredb/apps/_stdout_supress.py +30 -0
  14. singlestoredb/apps/_uvicorn_util.py +36 -0
  15. singlestoredb/auth.py +245 -0
  16. singlestoredb/config.py +484 -0
  17. singlestoredb/connection.py +1487 -0
  18. singlestoredb/converters.py +950 -0
  19. singlestoredb/docstring/__init__.py +33 -0
  20. singlestoredb/docstring/attrdoc.py +126 -0
  21. singlestoredb/docstring/common.py +230 -0
  22. singlestoredb/docstring/epydoc.py +267 -0
  23. singlestoredb/docstring/google.py +412 -0
  24. singlestoredb/docstring/numpydoc.py +562 -0
  25. singlestoredb/docstring/parser.py +100 -0
  26. singlestoredb/docstring/py.typed +1 -0
  27. singlestoredb/docstring/rest.py +256 -0
  28. singlestoredb/docstring/tests/__init__.py +1 -0
  29. singlestoredb/docstring/tests/_pydoctor.py +21 -0
  30. singlestoredb/docstring/tests/test_epydoc.py +729 -0
  31. singlestoredb/docstring/tests/test_google.py +1007 -0
  32. singlestoredb/docstring/tests/test_numpydoc.py +1100 -0
  33. singlestoredb/docstring/tests/test_parse_from_object.py +109 -0
  34. singlestoredb/docstring/tests/test_parser.py +248 -0
  35. singlestoredb/docstring/tests/test_rest.py +547 -0
  36. singlestoredb/docstring/tests/test_util.py +70 -0
  37. singlestoredb/docstring/util.py +141 -0
  38. singlestoredb/exceptions.py +120 -0
  39. singlestoredb/functions/__init__.py +16 -0
  40. singlestoredb/functions/decorator.py +201 -0
  41. singlestoredb/functions/dtypes.py +1793 -0
  42. singlestoredb/functions/ext/__init__.py +1 -0
  43. singlestoredb/functions/ext/arrow.py +375 -0
  44. singlestoredb/functions/ext/asgi.py +2133 -0
  45. singlestoredb/functions/ext/json.py +420 -0
  46. singlestoredb/functions/ext/mmap.py +413 -0
  47. singlestoredb/functions/ext/rowdat_1.py +724 -0
  48. singlestoredb/functions/ext/timer.py +89 -0
  49. singlestoredb/functions/ext/utils.py +218 -0
  50. singlestoredb/functions/signature.py +1578 -0
  51. singlestoredb/functions/typing/__init__.py +41 -0
  52. singlestoredb/functions/typing/numpy.py +20 -0
  53. singlestoredb/functions/typing/pandas.py +2 -0
  54. singlestoredb/functions/typing/polars.py +2 -0
  55. singlestoredb/functions/typing/pyarrow.py +2 -0
  56. singlestoredb/functions/utils.py +421 -0
  57. singlestoredb/fusion/__init__.py +11 -0
  58. singlestoredb/fusion/graphql.py +213 -0
  59. singlestoredb/fusion/handler.py +916 -0
  60. singlestoredb/fusion/handlers/__init__.py +0 -0
  61. singlestoredb/fusion/handlers/export.py +525 -0
  62. singlestoredb/fusion/handlers/files.py +690 -0
  63. singlestoredb/fusion/handlers/job.py +660 -0
  64. singlestoredb/fusion/handlers/models.py +250 -0
  65. singlestoredb/fusion/handlers/stage.py +502 -0
  66. singlestoredb/fusion/handlers/utils.py +324 -0
  67. singlestoredb/fusion/handlers/workspace.py +956 -0
  68. singlestoredb/fusion/registry.py +249 -0
  69. singlestoredb/fusion/result.py +399 -0
  70. singlestoredb/http/__init__.py +27 -0
  71. singlestoredb/http/connection.py +1267 -0
  72. singlestoredb/magics/__init__.py +34 -0
  73. singlestoredb/magics/run_personal.py +137 -0
  74. singlestoredb/magics/run_shared.py +134 -0
  75. singlestoredb/management/__init__.py +9 -0
  76. singlestoredb/management/billing_usage.py +148 -0
  77. singlestoredb/management/cluster.py +462 -0
  78. singlestoredb/management/export.py +295 -0
  79. singlestoredb/management/files.py +1102 -0
  80. singlestoredb/management/inference_api.py +105 -0
  81. singlestoredb/management/job.py +887 -0
  82. singlestoredb/management/manager.py +373 -0
  83. singlestoredb/management/organization.py +226 -0
  84. singlestoredb/management/region.py +169 -0
  85. singlestoredb/management/utils.py +423 -0
  86. singlestoredb/management/workspace.py +1927 -0
  87. singlestoredb/mysql/__init__.py +177 -0
  88. singlestoredb/mysql/_auth.py +298 -0
  89. singlestoredb/mysql/charset.py +214 -0
  90. singlestoredb/mysql/connection.py +2032 -0
  91. singlestoredb/mysql/constants/CLIENT.py +38 -0
  92. singlestoredb/mysql/constants/COMMAND.py +32 -0
  93. singlestoredb/mysql/constants/CR.py +78 -0
  94. singlestoredb/mysql/constants/ER.py +474 -0
  95. singlestoredb/mysql/constants/EXTENDED_TYPE.py +3 -0
  96. singlestoredb/mysql/constants/FIELD_TYPE.py +48 -0
  97. singlestoredb/mysql/constants/FLAG.py +15 -0
  98. singlestoredb/mysql/constants/SERVER_STATUS.py +10 -0
  99. singlestoredb/mysql/constants/VECTOR_TYPE.py +6 -0
  100. singlestoredb/mysql/constants/__init__.py +0 -0
  101. singlestoredb/mysql/converters.py +271 -0
  102. singlestoredb/mysql/cursors.py +896 -0
  103. singlestoredb/mysql/err.py +92 -0
  104. singlestoredb/mysql/optionfile.py +20 -0
  105. singlestoredb/mysql/protocol.py +450 -0
  106. singlestoredb/mysql/tests/__init__.py +19 -0
  107. singlestoredb/mysql/tests/base.py +126 -0
  108. singlestoredb/mysql/tests/conftest.py +37 -0
  109. singlestoredb/mysql/tests/test_DictCursor.py +132 -0
  110. singlestoredb/mysql/tests/test_SSCursor.py +141 -0
  111. singlestoredb/mysql/tests/test_basic.py +452 -0
  112. singlestoredb/mysql/tests/test_connection.py +851 -0
  113. singlestoredb/mysql/tests/test_converters.py +58 -0
  114. singlestoredb/mysql/tests/test_cursor.py +141 -0
  115. singlestoredb/mysql/tests/test_err.py +16 -0
  116. singlestoredb/mysql/tests/test_issues.py +514 -0
  117. singlestoredb/mysql/tests/test_load_local.py +75 -0
  118. singlestoredb/mysql/tests/test_nextset.py +88 -0
  119. singlestoredb/mysql/tests/test_optionfile.py +27 -0
  120. singlestoredb/mysql/tests/thirdparty/__init__.py +6 -0
  121. singlestoredb/mysql/tests/thirdparty/test_MySQLdb/__init__.py +9 -0
  122. singlestoredb/mysql/tests/thirdparty/test_MySQLdb/capabilities.py +323 -0
  123. singlestoredb/mysql/tests/thirdparty/test_MySQLdb/dbapi20.py +865 -0
  124. singlestoredb/mysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_capabilities.py +110 -0
  125. singlestoredb/mysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_dbapi20.py +224 -0
  126. singlestoredb/mysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_nonstandard.py +101 -0
  127. singlestoredb/mysql/times.py +23 -0
  128. singlestoredb/notebook/__init__.py +16 -0
  129. singlestoredb/notebook/_objects.py +213 -0
  130. singlestoredb/notebook/_portal.py +352 -0
  131. singlestoredb/py.typed +0 -0
  132. singlestoredb/pytest.py +352 -0
  133. singlestoredb/server/__init__.py +0 -0
  134. singlestoredb/server/docker.py +452 -0
  135. singlestoredb/server/free_tier.py +267 -0
  136. singlestoredb/tests/__init__.py +0 -0
  137. singlestoredb/tests/alltypes.sql +307 -0
  138. singlestoredb/tests/alltypes_no_nulls.sql +208 -0
  139. singlestoredb/tests/empty.sql +0 -0
  140. singlestoredb/tests/ext_funcs/__init__.py +702 -0
  141. singlestoredb/tests/local_infile.csv +3 -0
  142. singlestoredb/tests/test.ipynb +18 -0
  143. singlestoredb/tests/test.sql +680 -0
  144. singlestoredb/tests/test2.ipynb +18 -0
  145. singlestoredb/tests/test2.sql +1 -0
  146. singlestoredb/tests/test_basics.py +1332 -0
  147. singlestoredb/tests/test_config.py +318 -0
  148. singlestoredb/tests/test_connection.py +3103 -0
  149. singlestoredb/tests/test_dbapi.py +27 -0
  150. singlestoredb/tests/test_exceptions.py +45 -0
  151. singlestoredb/tests/test_ext_func.py +1472 -0
  152. singlestoredb/tests/test_ext_func_data.py +1101 -0
  153. singlestoredb/tests/test_fusion.py +1527 -0
  154. singlestoredb/tests/test_http.py +288 -0
  155. singlestoredb/tests/test_management.py +1599 -0
  156. singlestoredb/tests/test_plugin.py +33 -0
  157. singlestoredb/tests/test_results.py +171 -0
  158. singlestoredb/tests/test_types.py +132 -0
  159. singlestoredb/tests/test_udf.py +737 -0
  160. singlestoredb/tests/test_udf_returns.py +459 -0
  161. singlestoredb/tests/test_vectorstore.py +51 -0
  162. singlestoredb/tests/test_xdict.py +333 -0
  163. singlestoredb/tests/utils.py +141 -0
  164. singlestoredb/types.py +373 -0
  165. singlestoredb/utils/__init__.py +0 -0
  166. singlestoredb/utils/config.py +950 -0
  167. singlestoredb/utils/convert_rows.py +69 -0
  168. singlestoredb/utils/debug.py +13 -0
  169. singlestoredb/utils/dtypes.py +205 -0
  170. singlestoredb/utils/events.py +65 -0
  171. singlestoredb/utils/mogrify.py +151 -0
  172. singlestoredb/utils/results.py +585 -0
  173. singlestoredb/utils/xdict.py +425 -0
  174. singlestoredb/vectorstore.py +192 -0
  175. singlestoredb/warnings.py +5 -0
  176. singlestoredb-1.16.1.dist-info/METADATA +165 -0
  177. singlestoredb-1.16.1.dist-info/RECORD +183 -0
  178. singlestoredb-1.16.1.dist-info/WHEEL +5 -0
  179. singlestoredb-1.16.1.dist-info/entry_points.txt +2 -0
  180. singlestoredb-1.16.1.dist-info/licenses/LICENSE +201 -0
  181. singlestoredb-1.16.1.dist-info/top_level.txt +3 -0
  182. sqlx/__init__.py +4 -0
  183. 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,2 @@
1
+ from pandas import DataFrame # noqa: F401
2
+ from pandas import Series # noqa: F401
@@ -0,0 +1,2 @@
1
+ from polars import DataFrame # noqa: F401
2
+ from polars import Series # noqa: F401
@@ -0,0 +1,2 @@
1
+ from pyarrow import Array # noqa: F401
2
+ from pyarrow import Table # noqa: F401
@@ -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]}')