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,452 @@
1
+ #!/usr/bin/env python
2
+ """Utilities for running singlestoredb-dev Docker image."""
3
+ from __future__ import annotations
4
+
5
+ import atexit
6
+ import os
7
+ import platform
8
+ import secrets
9
+ import signal
10
+ import socket
11
+ import subprocess
12
+ import time
13
+ import urllib.parse
14
+ from contextlib import closing
15
+ from types import TracebackType
16
+ from typing import Any
17
+ from typing import Dict
18
+ from typing import List
19
+ from typing import Optional
20
+ from typing import Type
21
+
22
+ try:
23
+ import docker
24
+ has_docker = True
25
+ except ImportError:
26
+ has_docker = False
27
+ raise RuntimeError('docker python package is not installed')
28
+
29
+ from .. import connect
30
+ from ..connection import Connection
31
+
32
+ try:
33
+ import pymongo
34
+ has_pymongo = True
35
+ except ImportError:
36
+ has_pymongo = False
37
+
38
+ DEFAULT_IMAGE = 'ghcr.io/singlestore-labs/singlestoredb-dev:latest'
39
+
40
+
41
+ class SingleStoreDB:
42
+ """
43
+ Manager for SingleStoreDB server running in Docker.
44
+
45
+ Parameters
46
+ -----------
47
+ name : str, optional
48
+ Name of the container.
49
+ password : str, optional
50
+ Password for the SingleStoreDB server.
51
+ license : str, optional
52
+ License key for SingleStoreDB.
53
+ enable_kai : bool, optional
54
+ Enable Kai (MongoDB) server.
55
+ server_port : int, optional
56
+ Port for the SingleStoreDB server.
57
+ studio_port : int, optional
58
+ Port for the SingleStoreDB Studio.
59
+ data_api_port : int, optional
60
+ Port for the SingleStoreDB Data API.
61
+ kai_port : int, optional
62
+ Port for the Kai server.
63
+ hostname : str, optional
64
+ Hostname for the container.
65
+ data_dir : str, optional
66
+ Path to the data directory.
67
+ logs_dir : str, optional
68
+ Path to the logs directory.
69
+ server_dir : str, optional
70
+ Path to the server directory.
71
+ global_vars : dict, optional
72
+ Global variables to set in the SingleStoreDB server.
73
+ init_sql : str, optional
74
+ Path to an SQL file to run on startup.
75
+ image : str, optional
76
+ Docker image to use.
77
+ database : str, optional
78
+ Default database to connect to.
79
+
80
+ """
81
+
82
+ user: str
83
+ password: str
84
+ kai_enabled: bool
85
+ server_port: int
86
+ studio_port: int
87
+ data_api_port: int
88
+ kai_port: Optional[int]
89
+ data_dir: Optional[str]
90
+ logs_dir: Optional[str]
91
+ server_dir: Optional[str]
92
+
93
+ def __init__(
94
+ self,
95
+ name: Optional[str] = None,
96
+ *,
97
+ password: Optional[str] = None,
98
+ license: Optional[str] = None,
99
+ enable_kai: bool = False,
100
+ server_port: Optional[int] = None,
101
+ studio_port: Optional[int] = None,
102
+ data_api_port: Optional[int] = None,
103
+ kai_port: Optional[int] = None,
104
+ hostname: Optional[str] = None,
105
+ data_dir: Optional[str] = None,
106
+ logs_dir: Optional[str] = None,
107
+ server_dir: Optional[str] = None,
108
+ global_vars: Optional[Dict[str, Any]] = None,
109
+ init_sql: Optional[str] = None,
110
+ image: str = DEFAULT_IMAGE,
111
+ database: Optional[str] = None,
112
+ ):
113
+ self.kai_enabled = enable_kai
114
+ self.kai_port = None
115
+ self.server_port = server_port or self._get_available_port()
116
+ self.studio_port = studio_port or self._get_available_port()
117
+ self.data_api_port = data_api_port or self._get_available_port()
118
+ self.data_dir = data_dir
119
+ self.logs_dir = logs_dir
120
+ self.server_dir = server_dir
121
+ self.user = 'root'
122
+
123
+ # Setup container ports
124
+ ports = {
125
+ '3306/tcp': self.server_port,
126
+ '8080/tcp': self.studio_port,
127
+ '9000/tcp': self.data_api_port,
128
+ }
129
+
130
+ if enable_kai:
131
+ self.kai_port = kai_port or self._get_available_port()
132
+ ports['27017/tcp'] = self.kai_port
133
+
134
+ # Setup password
135
+ self.password = password or secrets.token_urlsafe(10)
136
+
137
+ # Setup license value
138
+ if license is None:
139
+ license = os.environ.get('SINGLESTORE_LICENSE', None)
140
+
141
+ # Setup environment variables for the container
142
+ env = {'ROOT_PASSWORD': self.password}
143
+
144
+ if license:
145
+ env['SINGLESTORE_LICENSE'] = license
146
+
147
+ if enable_kai:
148
+ env['ENABLE_KAI'] = '1'
149
+
150
+ # Construct Docker arguments
151
+ kwargs = {
152
+ 'environment': env,
153
+ 'ports': ports,
154
+ 'detach': True,
155
+ 'auto_remove': True,
156
+ 'remove': True,
157
+ }
158
+
159
+ if 'macOS' in platform.platform():
160
+ kwargs['platform'] = 'linux/amd64'
161
+
162
+ for pname, pvalue in [
163
+ ('name', name),
164
+ ('hostname', hostname),
165
+ ]:
166
+ if pvalue is not None:
167
+ kwargs[pname] = pvalue
168
+
169
+ # Setup volumes
170
+ volumes: Dict[str, Dict[str, str]] = {}
171
+ if data_dir:
172
+ volumes[data_dir] = {'bind': '/data', 'mode': 'rw'}
173
+ if logs_dir:
174
+ volumes[logs_dir] = {'bind': '/logs', 'mode': 'ro'}
175
+ if server_dir:
176
+ volumes[server_dir] = {'bind': '/server', 'mode': 'ro'}
177
+ if init_sql:
178
+ volumes[os.path.abspath(init_sql)] = {'bind': '/init.sql', 'mode': 'ro'}
179
+ if volumes:
180
+ kwargs['volumes'] = volumes
181
+
182
+ # Setup global vars
183
+ for k, v in (global_vars or {}).items():
184
+ env['SINGLESTORE_SET_GLOBAL_' + k.upper()] = str(v)
185
+
186
+ self._saved_server_urls: Dict[str, Optional[str]] = {}
187
+
188
+ docker_client = docker.from_env()
189
+ self.container = docker_client.containers.run(image, **kwargs)
190
+
191
+ # Make sure container gets cleaned up at exit
192
+ atexit.register(self.stop)
193
+ signal.signal(signal.SIGINT, self.stop)
194
+ signal.signal(signal.SIGTERM, self.stop)
195
+
196
+ if not self._wait_on_ready():
197
+ raise RuntimeError('server did not come up properly')
198
+
199
+ self._database = database
200
+ self._set_server_urls()
201
+
202
+ def __str__(self) -> str:
203
+ return f"SingleStoreDB('{self.connection_url}')"
204
+
205
+ def __repr__(self) -> str:
206
+ return str(self)
207
+
208
+ def _get_available_port(self) -> int:
209
+ with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
210
+ s.bind(('', 0))
211
+ s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
212
+ return s.getsockname()[1]
213
+
214
+ def _set_server_urls(self) -> None:
215
+ self._saved_server_urls['DATABASE_URL'] = os.environ.get('DATABASE_URL')
216
+ os.environ['DATABASE_URL'] = self.connection_url
217
+ self._saved_server_urls['SINGLESTOREDB_URL'] = os.environ.get('SINGLESTOREDB_URL')
218
+ os.environ['SINGLESTOREDB_URL'] = self.connection_url
219
+
220
+ def _restore_server_urls(self) -> None:
221
+ try:
222
+ for k, v in self._saved_server_urls.items():
223
+ if v is None:
224
+ del os.environ[k]
225
+ else:
226
+ os.environ[k] = v
227
+ except KeyError:
228
+ pass
229
+
230
+ def _wait_on_ready(self) -> bool:
231
+ for i in range(80):
232
+ for line in self.logs():
233
+ if 'INFO: ' in line:
234
+ return True
235
+ time.sleep(3)
236
+ return False
237
+
238
+ def logs(self) -> List[str]:
239
+ return self.container.logs().decode('utf8').split('\n')
240
+
241
+ @property
242
+ def connection_url(self) -> str:
243
+ """Connection URL for the SingleStoreDB server."""
244
+ dbname = f'/{self._database}' if self._database else ''
245
+ password = urllib.parse.quote_plus(self.password)
246
+ return f'singlestoredb://{self.user}:{password}@' + \
247
+ f'localhost:{self.server_port}{dbname}'
248
+
249
+ @property
250
+ def http_connection_url(self) -> str:
251
+ """HTTP Connection URL for the SingleStoreDB server."""
252
+ dbname = f'/{self._database}' if self._database else ''
253
+ password = urllib.parse.quote_plus(self.password)
254
+ return f'singlestoredb+http://{self.user}:{password}@' + \
255
+ f'localhost:{self.data_api_port}{dbname}'
256
+
257
+ def connect(
258
+ self,
259
+ use_data_api: bool = False,
260
+ **kwargs: Any,
261
+ ) -> Connection:
262
+ """
263
+ Connect to the SingleStoreDB server.
264
+
265
+ Parameters
266
+ -----------
267
+ use_data_api : bool, optional
268
+ Use the Data API for the connection.
269
+ **kwargs : Any, optional
270
+ Additional keyword arguments to pass to the connection.
271
+
272
+ Returns
273
+ --------
274
+ Connection : Connection to the SingleStoreDB server.
275
+
276
+ """
277
+ if use_data_api:
278
+ return connect(self.http_connection_url, **kwargs)
279
+ return connect(self.connection_url, **kwargs)
280
+
281
+ @property
282
+ def kai_url(self) -> Optional[str]:
283
+ """Connection URL for the Kai (MongoDB) server."""
284
+ if not self.kai_enabled:
285
+ return None
286
+ password = urllib.parse.quote_plus(self.password)
287
+ return f'mongodb://{self.user}:{password}@' + \
288
+ f'localhost:{self.kai_port}/?authMechanism=PLAIN&loadBalanced=true'
289
+
290
+ def connect_kai(self) -> 'pymongo.MongoClient':
291
+ """Connect to the Kai (MongoDB) server."""
292
+ if not self.kai_enabled:
293
+ raise RuntimeError('kai is not enabled')
294
+ if not has_pymongo:
295
+ raise RuntimeError('pymongo is not installed')
296
+ return pymongo.MongoClient(self.kai_url)
297
+
298
+ @property
299
+ def studio_url(self) -> str:
300
+ """URL for the SingleStoreDB Studio."""
301
+ return f'http://localhost:{self.studio_port}'
302
+
303
+ def open_studio(self) -> None:
304
+ """Open the SingleStoreDB Studio in a web browser."""
305
+ import webbrowser
306
+ if platform.platform().lower().startswith('macos'):
307
+ chrome_path = r'open -a /Applications/Google\ Chrome.app %s'
308
+ webbrowser.get(chrome_path).open(self.studio_url, new=2)
309
+ else:
310
+ webbrowser.open(self.studio_url, new=2)
311
+
312
+ def open_shell(self) -> None:
313
+ """Open a shell in the SingleStoreDB server."""
314
+ if platform.platform().lower().startswith('macos'):
315
+ subprocess.call([
316
+ 'osascript', '-e',
317
+ 'tell app "Terminal" to do script '
318
+ f'"docker exec -it {self.container.id} singlestore-auth"',
319
+ ])
320
+ elif platform.platform().lower().startswith('linux'):
321
+ subprocess.call([
322
+ 'gnome-terminal', '--',
323
+ 'docker', 'exec', '-it', self.container.id, 'singlestore-auth',
324
+ ])
325
+ elif platform.platform().lower().startswith('windows'):
326
+ subprocess.call([
327
+ 'start', 'cmd', '/k'
328
+ 'docker', 'exec', '-it', self.container.id, 'singlestore-auth',
329
+ ])
330
+ else:
331
+ raise RuntimeError('unsupported platform')
332
+
333
+ def open_mongosh(self) -> None:
334
+ """Open a mongosh in the SingleStoreDB server."""
335
+ if not self.kai_enabled:
336
+ raise RuntimeError('kai interface is not enabled')
337
+ if platform.platform().lower().startswith('macos'):
338
+ subprocess.call([
339
+ 'osascript', '-e',
340
+ 'tell app "Terminal" to do script '
341
+ f'"docker exec -it {self.container.id} mongosh-auth"',
342
+ ])
343
+ elif platform.platform().lower().startswith('linux'):
344
+ subprocess.call([
345
+ 'gnome-terminal', '--',
346
+ 'docker', 'exec', '-it', self.container.id, 'mongosh-auth',
347
+ ])
348
+ elif platform.platform().lower().startswith('windows'):
349
+ subprocess.call([
350
+ 'start', 'cmd', '/k'
351
+ 'docker', 'exec', '-it', self.container.id, 'mongosh-auth',
352
+ ])
353
+ else:
354
+ raise RuntimeError('unsupported platform')
355
+
356
+ def __enter__(self) -> SingleStoreDB:
357
+ return self
358
+
359
+ def __exit__(
360
+ self,
361
+ exc_type: Optional[Type[BaseException]],
362
+ exc_val: Optional[BaseException],
363
+ exc_tb: Optional[TracebackType],
364
+ ) -> Optional[bool]:
365
+ self.stop()
366
+ return None
367
+
368
+ def stop(self, *args: Any) -> None:
369
+ """Stop the SingleStoreDB server."""
370
+ if self.container is not None:
371
+ self._restore_server_urls()
372
+ try:
373
+ self.container.stop()
374
+ finally:
375
+ self.container = None
376
+
377
+
378
+ def start(
379
+ name: Optional[str] = None,
380
+ password: Optional[str] = None,
381
+ license: Optional[str] = None,
382
+ enable_kai: bool = False,
383
+ server_port: Optional[int] = None,
384
+ studio_port: Optional[int] = None,
385
+ data_api_port: Optional[int] = None,
386
+ kai_port: Optional[int] = None,
387
+ hostname: Optional[str] = None,
388
+ data_dir: Optional[str] = None,
389
+ logs_dir: Optional[str] = None,
390
+ server_dir: Optional[str] = None,
391
+ global_vars: Optional[Dict[str, Any]] = None,
392
+ init_sql: Optional[str] = None,
393
+ image: str = DEFAULT_IMAGE,
394
+ database: Optional[str] = None,
395
+ ) -> SingleStoreDB:
396
+ """
397
+ Manager for SingleStoreDB server running in Docker.
398
+
399
+ Parameters
400
+ -----------
401
+ name : str, optional
402
+ Name of the container.
403
+ password : str, optional
404
+ Password for the SingleStoreDB server.
405
+ license : str, optional
406
+ License key for SingleStoreDB.
407
+ enable_kai : bool, optional
408
+ Enable Kai (MongoDB) server.
409
+ server_port : int, optional
410
+ Port for the SingleStoreDB server.
411
+ studio_port : int, optional
412
+ Port for the SingleStoreDB Studio.
413
+ data_api_port : int, optional
414
+ Port for the SingleStoreDB Data API.
415
+ kai_port : int, optional
416
+ Port for the Kai server.
417
+ hostname : str, optional
418
+ Hostname for the container.
419
+ data_dir : str, optional
420
+ Path to the data directory.
421
+ logs_dir : str, optional
422
+ Path to the logs directory.
423
+ server_dir : str, optional
424
+ Path to the server directory.
425
+ global_vars : dict, optional
426
+ Global variables to set in the SingleStoreDB server.
427
+ init_sql : str, optional
428
+ Path to an SQL file to run on startup.
429
+ image : str, optional
430
+ Docker image to use.
431
+ database : str, optional
432
+ Default database to connect to.
433
+
434
+ """
435
+ return SingleStoreDB(
436
+ name=name,
437
+ password=password,
438
+ license=license,
439
+ enable_kai=enable_kai,
440
+ server_port=server_port,
441
+ studio_port=studio_port,
442
+ data_api_port=data_api_port,
443
+ kai_port=kai_port,
444
+ hostname=hostname,
445
+ data_dir=data_dir,
446
+ logs_dir=logs_dir,
447
+ server_dir=server_dir,
448
+ global_vars=global_vars,
449
+ init_sql=init_sql,
450
+ image=image,
451
+ database=database,
452
+ )