singlestoredb 1.14.2__py3-none-any.whl → 1.15.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.
Potentially problematic release.
This version of singlestoredb might be problematic. Click here for more details.
- singlestoredb/__init__.py +2 -2
- singlestoredb/ai/chat.py +14 -0
- singlestoredb/apps/_python_udfs.py +3 -3
- singlestoredb/config.py +11 -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/functions/decorator.py +51 -31
- singlestoredb/functions/ext/asgi.py +381 -35
- singlestoredb/functions/ext/timer.py +98 -0
- singlestoredb/functions/signature.py +374 -241
- 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/fusion/handlers/files.py +4 -4
- singlestoredb/fusion/handlers/models.py +1 -1
- singlestoredb/fusion/handlers/stage.py +4 -4
- singlestoredb/magics/run_personal.py +82 -1
- singlestoredb/magics/run_shared.py +82 -1
- singlestoredb/management/__init__.py +1 -0
- singlestoredb/management/cluster.py +1 -1
- singlestoredb/management/manager.py +15 -5
- singlestoredb/management/region.py +104 -2
- singlestoredb/management/workspace.py +174 -3
- singlestoredb/tests/ext_funcs/__init__.py +133 -55
- singlestoredb/tests/test.sql +22 -0
- singlestoredb/tests/test_connection.py +18 -8
- singlestoredb/tests/test_ext_func.py +90 -0
- singlestoredb/tests/test_management.py +190 -0
- singlestoredb/tests/test_udf.py +43 -15
- {singlestoredb-1.14.2.dist-info → singlestoredb-1.15.1.dist-info}/METADATA +1 -1
- {singlestoredb-1.14.2.dist-info → singlestoredb-1.15.1.dist-info}/RECORD +54 -30
- /singlestoredb/functions/{typing.py → typing/__init__.py} +0 -0
- {singlestoredb-1.14.2.dist-info → singlestoredb-1.15.1.dist-info}/LICENSE +0 -0
- {singlestoredb-1.14.2.dist-info → singlestoredb-1.15.1.dist-info}/WHEEL +0 -0
- {singlestoredb-1.14.2.dist-info → singlestoredb-1.15.1.dist-info}/entry_points.txt +0 -0
- {singlestoredb-1.14.2.dist-info → singlestoredb-1.15.1.dist-info}/top_level.txt +0 -0
|
@@ -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]
|
|
@@ -89,7 +89,7 @@ class ShowPersonalFilesHandler(ShowFilesHandler):
|
|
|
89
89
|
specified number.
|
|
90
90
|
* Use the ``ORDER BY`` clause to sort the results by the specified
|
|
91
91
|
key. By default, the results are sorted in the ascending order.
|
|
92
|
-
* The ``AT
|
|
92
|
+
* The ``AT`` clause specifies the path in the personal/shared
|
|
93
93
|
space to list the files from.
|
|
94
94
|
* Use the ``RECURSIVE`` clause to list the files recursively.
|
|
95
95
|
* To return more information about the files, use the ``EXTENDED``
|
|
@@ -99,7 +99,7 @@ class ShowPersonalFilesHandler(ShowFilesHandler):
|
|
|
99
99
|
--------
|
|
100
100
|
The following command lists the files at a specific path::
|
|
101
101
|
|
|
102
|
-
SHOW PERSONAL FILES AT
|
|
102
|
+
SHOW PERSONAL FILES AT "/data/";
|
|
103
103
|
|
|
104
104
|
The following command lists the files recursively with
|
|
105
105
|
additional information::
|
|
@@ -154,7 +154,7 @@ class ShowSharedFilesHandler(ShowFilesHandler):
|
|
|
154
154
|
specified number.
|
|
155
155
|
* Use the ``ORDER BY`` clause to sort the results by the specified
|
|
156
156
|
key. By default, the results are sorted in the ascending order.
|
|
157
|
-
* The ``AT
|
|
157
|
+
* The ``AT`` clause specifies the path in the personal/shared
|
|
158
158
|
space to list the files from.
|
|
159
159
|
* Use the ``RECURSIVE`` clause to list the files recursively.
|
|
160
160
|
* To return more information about the files, use the ``EXTENDED``
|
|
@@ -164,7 +164,7 @@ class ShowSharedFilesHandler(ShowFilesHandler):
|
|
|
164
164
|
--------
|
|
165
165
|
The following command lists the files at a specific path::
|
|
166
166
|
|
|
167
|
-
SHOW SHARED FILES AT
|
|
167
|
+
SHOW SHARED FILES AT "/data/";
|
|
168
168
|
|
|
169
169
|
The following command lists the files recursively with
|
|
170
170
|
additional information::
|
|
@@ -44,7 +44,7 @@ class ShowModelsHandler(ShowFilesHandler):
|
|
|
44
44
|
specified number.
|
|
45
45
|
* Use the ``ORDER BY`` clause to sort the results by the specified
|
|
46
46
|
key. By default, the results are sorted in the ascending order.
|
|
47
|
-
* The ``AT
|
|
47
|
+
* The ``AT`` clause specifies the path in the models
|
|
48
48
|
space to list the files from.
|
|
49
49
|
* To return more information about the files, use the ``EXTENDED``
|
|
50
50
|
clause.
|
|
@@ -62,7 +62,7 @@ class ShowStageFilesHandler(SQLHandler):
|
|
|
62
62
|
specified number.
|
|
63
63
|
* Use the ``ORDER BY`` clause to sort the results by the specified
|
|
64
64
|
key. By default, the results are sorted in the ascending order.
|
|
65
|
-
* The ``AT
|
|
65
|
+
* The ``AT`` clause specifies the path in the Stage to list
|
|
66
66
|
the files from.
|
|
67
67
|
* The ``IN`` clause specifies the ID or the name of the
|
|
68
68
|
deployment in which the Stage is attached.
|
|
@@ -74,7 +74,7 @@ class ShowStageFilesHandler(SQLHandler):
|
|
|
74
74
|
--------
|
|
75
75
|
The following command lists the files at a specific path::
|
|
76
76
|
|
|
77
|
-
SHOW STAGE FILES IN 'wsg1' AT
|
|
77
|
+
SHOW STAGE FILES IN 'wsg1' AT "/data/";
|
|
78
78
|
|
|
79
79
|
The following command lists the files recursively with
|
|
80
80
|
additional information::
|
|
@@ -393,7 +393,7 @@ class DropStageFolderHandler(SQLHandler):
|
|
|
393
393
|
# Name of deployment
|
|
394
394
|
deployment_name = '<deployment-name>'
|
|
395
395
|
|
|
396
|
-
# Should
|
|
396
|
+
# Should folders be deleted recursively?
|
|
397
397
|
recursive = RECURSIVE
|
|
398
398
|
|
|
399
399
|
Description
|
|
@@ -474,7 +474,7 @@ class CreateStageFolderHandler(SQLHandler):
|
|
|
474
474
|
is created. The path must end with a trailing slash (/).
|
|
475
475
|
* ``<deployment-id>``: The ID of the deployment in which
|
|
476
476
|
the Stage is attached.
|
|
477
|
-
* ``<deployment-name>``: The name of the deployment in
|
|
477
|
+
* ``<deployment-name>``: The name of the deployment in
|
|
478
478
|
which the Stage is attached.
|
|
479
479
|
|
|
480
480
|
Remarks
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import tempfile
|
|
3
|
+
from pathlib import Path
|
|
3
4
|
from typing import Any
|
|
5
|
+
from warnings import warn
|
|
4
6
|
|
|
5
7
|
from IPython.core.interactiveshell import InteractiveShell
|
|
6
8
|
from IPython.core.magic import line_magic
|
|
@@ -8,6 +10,8 @@ from IPython.core.magic import Magics
|
|
|
8
10
|
from IPython.core.magic import magics_class
|
|
9
11
|
from IPython.core.magic import needs_local_scope
|
|
10
12
|
from IPython.core.magic import no_var_expand
|
|
13
|
+
from IPython.utils.contexts import preserve_keys
|
|
14
|
+
from IPython.utils.syspathcontext import prepended_to_syspath
|
|
11
15
|
from jinja2 import Template
|
|
12
16
|
|
|
13
17
|
|
|
@@ -53,4 +57,81 @@ class RunPersonalMagic(Magics):
|
|
|
53
57
|
# Execute the SQL command
|
|
54
58
|
self.shell.run_line_magic('sql', sql_command)
|
|
55
59
|
# Run the downloaded file
|
|
56
|
-
self.shell.
|
|
60
|
+
with preserve_keys(self.shell.user_ns, '__file__'):
|
|
61
|
+
self.shell.user_ns['__file__'] = temp_file_path
|
|
62
|
+
self.safe_execfile_ipy(temp_file_path, raise_exceptions=True)
|
|
63
|
+
|
|
64
|
+
def safe_execfile_ipy(
|
|
65
|
+
self,
|
|
66
|
+
fname: str,
|
|
67
|
+
shell_futures: bool = False,
|
|
68
|
+
raise_exceptions: bool = False,
|
|
69
|
+
) -> None:
|
|
70
|
+
"""Like safe_execfile, but for .ipy or .ipynb files with IPython syntax.
|
|
71
|
+
|
|
72
|
+
Parameters
|
|
73
|
+
----------
|
|
74
|
+
fname : str
|
|
75
|
+
The name of the file to execute. The filename must have a
|
|
76
|
+
.ipy or .ipynb extension.
|
|
77
|
+
shell_futures : bool (False)
|
|
78
|
+
If True, the code will share future statements with the interactive
|
|
79
|
+
shell. It will both be affected by previous __future__ imports, and
|
|
80
|
+
any __future__ imports in the code will affect the shell. If False,
|
|
81
|
+
__future__ imports are not shared in either direction.
|
|
82
|
+
raise_exceptions : bool (False)
|
|
83
|
+
If True raise exceptions everywhere. Meant for testing.
|
|
84
|
+
"""
|
|
85
|
+
fpath = Path(fname).expanduser().resolve()
|
|
86
|
+
|
|
87
|
+
# Make sure we can open the file
|
|
88
|
+
try:
|
|
89
|
+
with fpath.open('rb'):
|
|
90
|
+
pass
|
|
91
|
+
except Exception:
|
|
92
|
+
warn('Could not open file <%s> for safe execution.' % fpath)
|
|
93
|
+
return
|
|
94
|
+
|
|
95
|
+
# Find things also in current directory. This is needed to mimic the
|
|
96
|
+
# behavior of running a script from the system command line, where
|
|
97
|
+
# Python inserts the script's directory into sys.path
|
|
98
|
+
dname = str(fpath.parent)
|
|
99
|
+
|
|
100
|
+
def get_cells() -> Any:
|
|
101
|
+
"""generator for sequence of code blocks to run"""
|
|
102
|
+
if fpath.suffix == '.ipynb':
|
|
103
|
+
from nbformat import read
|
|
104
|
+
nb = read(fpath, as_version=4)
|
|
105
|
+
if not nb.cells:
|
|
106
|
+
return
|
|
107
|
+
for cell in nb.cells:
|
|
108
|
+
if cell.cell_type == 'code':
|
|
109
|
+
if not cell.source.strip():
|
|
110
|
+
continue
|
|
111
|
+
if getattr(cell, 'metadata', {}).get('language', '') == 'sql':
|
|
112
|
+
output_redirect = getattr(
|
|
113
|
+
cell, 'metadata', {},
|
|
114
|
+
).get('output_variable', '') or ''
|
|
115
|
+
if output_redirect:
|
|
116
|
+
output_redirect = f' {output_redirect} <<'
|
|
117
|
+
yield f'%%sql{output_redirect}\n{cell.source}'
|
|
118
|
+
else:
|
|
119
|
+
yield cell.source
|
|
120
|
+
else:
|
|
121
|
+
yield fpath.read_text(encoding='utf-8')
|
|
122
|
+
|
|
123
|
+
with prepended_to_syspath(dname):
|
|
124
|
+
try:
|
|
125
|
+
for cell in get_cells():
|
|
126
|
+
result = self.shell.run_cell(
|
|
127
|
+
cell, silent=True, shell_futures=shell_futures,
|
|
128
|
+
)
|
|
129
|
+
if raise_exceptions:
|
|
130
|
+
result.raise_error()
|
|
131
|
+
elif not result.success:
|
|
132
|
+
break
|
|
133
|
+
except Exception:
|
|
134
|
+
if raise_exceptions:
|
|
135
|
+
raise
|
|
136
|
+
self.shell.showtraceback()
|
|
137
|
+
warn('Unknown failure executing file: <%s>' % fpath)
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import tempfile
|
|
3
|
+
from pathlib import Path
|
|
3
4
|
from typing import Any
|
|
5
|
+
from warnings import warn
|
|
4
6
|
|
|
5
7
|
from IPython.core.interactiveshell import InteractiveShell
|
|
6
8
|
from IPython.core.magic import line_magic
|
|
@@ -8,6 +10,8 @@ from IPython.core.magic import Magics
|
|
|
8
10
|
from IPython.core.magic import magics_class
|
|
9
11
|
from IPython.core.magic import needs_local_scope
|
|
10
12
|
from IPython.core.magic import no_var_expand
|
|
13
|
+
from IPython.utils.contexts import preserve_keys
|
|
14
|
+
from IPython.utils.syspathcontext import prepended_to_syspath
|
|
11
15
|
from jinja2 import Template
|
|
12
16
|
|
|
13
17
|
|
|
@@ -50,4 +54,81 @@ class RunSharedMagic(Magics):
|
|
|
50
54
|
# Execute the SQL command
|
|
51
55
|
self.shell.run_line_magic('sql', sql_command)
|
|
52
56
|
# Run the downloaded file
|
|
53
|
-
self.shell.
|
|
57
|
+
with preserve_keys(self.shell.user_ns, '__file__'):
|
|
58
|
+
self.shell.user_ns['__file__'] = temp_file_path
|
|
59
|
+
self.safe_execfile_ipy(temp_file_path, raise_exceptions=True)
|
|
60
|
+
|
|
61
|
+
def safe_execfile_ipy(
|
|
62
|
+
self,
|
|
63
|
+
fname: str,
|
|
64
|
+
shell_futures: bool = False,
|
|
65
|
+
raise_exceptions: bool = False,
|
|
66
|
+
) -> None:
|
|
67
|
+
"""Like safe_execfile, but for .ipy or .ipynb files with IPython syntax.
|
|
68
|
+
|
|
69
|
+
Parameters
|
|
70
|
+
----------
|
|
71
|
+
fname : str
|
|
72
|
+
The name of the file to execute. The filename must have a
|
|
73
|
+
.ipy or .ipynb extension.
|
|
74
|
+
shell_futures : bool (False)
|
|
75
|
+
If True, the code will share future statements with the interactive
|
|
76
|
+
shell. It will both be affected by previous __future__ imports, and
|
|
77
|
+
any __future__ imports in the code will affect the shell. If False,
|
|
78
|
+
__future__ imports are not shared in either direction.
|
|
79
|
+
raise_exceptions : bool (False)
|
|
80
|
+
If True raise exceptions everywhere. Meant for testing.
|
|
81
|
+
"""
|
|
82
|
+
fpath = Path(fname).expanduser().resolve()
|
|
83
|
+
|
|
84
|
+
# Make sure we can open the file
|
|
85
|
+
try:
|
|
86
|
+
with fpath.open('rb'):
|
|
87
|
+
pass
|
|
88
|
+
except Exception:
|
|
89
|
+
warn('Could not open file <%s> for safe execution.' % fpath)
|
|
90
|
+
return
|
|
91
|
+
|
|
92
|
+
# Find things also in current directory. This is needed to mimic the
|
|
93
|
+
# behavior of running a script from the system command line, where
|
|
94
|
+
# Python inserts the script's directory into sys.path
|
|
95
|
+
dname = str(fpath.parent)
|
|
96
|
+
|
|
97
|
+
def get_cells() -> Any:
|
|
98
|
+
"""generator for sequence of code blocks to run"""
|
|
99
|
+
if fpath.suffix == '.ipynb':
|
|
100
|
+
from nbformat import read
|
|
101
|
+
nb = read(fpath, as_version=4)
|
|
102
|
+
if not nb.cells:
|
|
103
|
+
return
|
|
104
|
+
for cell in nb.cells:
|
|
105
|
+
if cell.cell_type == 'code':
|
|
106
|
+
if not cell.source.strip():
|
|
107
|
+
continue
|
|
108
|
+
if getattr(cell, 'metadata', {}).get('language', '') == 'sql':
|
|
109
|
+
output_redirect = getattr(
|
|
110
|
+
cell, 'metadata', {},
|
|
111
|
+
).get('output_variable', '') or ''
|
|
112
|
+
if output_redirect:
|
|
113
|
+
output_redirect = f' {output_redirect} <<'
|
|
114
|
+
yield f'%%sql{output_redirect}\n{cell.source}'
|
|
115
|
+
else:
|
|
116
|
+
yield cell.source
|
|
117
|
+
else:
|
|
118
|
+
yield fpath.read_text(encoding='utf-8')
|
|
119
|
+
|
|
120
|
+
with prepended_to_syspath(dname):
|
|
121
|
+
try:
|
|
122
|
+
for cell in get_cells():
|
|
123
|
+
result = self.shell.run_cell(
|
|
124
|
+
cell, silent=True, shell_futures=shell_futures,
|
|
125
|
+
)
|
|
126
|
+
if raise_exceptions:
|
|
127
|
+
result.raise_error()
|
|
128
|
+
elif not result.success:
|
|
129
|
+
break
|
|
130
|
+
except Exception:
|
|
131
|
+
if raise_exceptions:
|
|
132
|
+
raise
|
|
133
|
+
self.shell.showtraceback()
|
|
134
|
+
warn('Unknown failure executing file: <%s>' % fpath)
|
|
@@ -148,7 +148,9 @@ class Manager(object):
|
|
|
148
148
|
|
|
149
149
|
"""
|
|
150
150
|
if self._params:
|
|
151
|
-
|
|
151
|
+
params = dict(self._params)
|
|
152
|
+
params.update(kwargs.get('params', {}))
|
|
153
|
+
kwargs['params'] = params
|
|
152
154
|
set_organization(kwargs)
|
|
153
155
|
return self._check(self._doit('get', path, *args, **kwargs), path, kwargs)
|
|
154
156
|
|
|
@@ -171,7 +173,9 @@ class Manager(object):
|
|
|
171
173
|
|
|
172
174
|
"""
|
|
173
175
|
if self._params:
|
|
174
|
-
|
|
176
|
+
params = dict(self._params)
|
|
177
|
+
params.update(kwargs.get('params', {}))
|
|
178
|
+
kwargs['params'] = params
|
|
175
179
|
set_organization(kwargs)
|
|
176
180
|
return self._check(self._doit('post', path, *args, **kwargs), path, kwargs)
|
|
177
181
|
|
|
@@ -194,7 +198,9 @@ class Manager(object):
|
|
|
194
198
|
|
|
195
199
|
"""
|
|
196
200
|
if self._params:
|
|
197
|
-
|
|
201
|
+
params = dict(self._params)
|
|
202
|
+
params.update(kwargs.get('params', {}))
|
|
203
|
+
kwargs['params'] = params
|
|
198
204
|
set_organization(kwargs)
|
|
199
205
|
return self._check(self._doit('put', path, *args, **kwargs), path, kwargs)
|
|
200
206
|
|
|
@@ -217,7 +223,9 @@ class Manager(object):
|
|
|
217
223
|
|
|
218
224
|
"""
|
|
219
225
|
if self._params:
|
|
220
|
-
|
|
226
|
+
params = dict(self._params)
|
|
227
|
+
params.update(kwargs.get('params', {}))
|
|
228
|
+
kwargs['params'] = params
|
|
221
229
|
set_organization(kwargs)
|
|
222
230
|
return self._check(self._doit('delete', path, *args, **kwargs), path, kwargs)
|
|
223
231
|
|
|
@@ -240,7 +248,9 @@ class Manager(object):
|
|
|
240
248
|
|
|
241
249
|
"""
|
|
242
250
|
if self._params:
|
|
243
|
-
|
|
251
|
+
params = dict(self._params)
|
|
252
|
+
params.update(kwargs.get('params', {}))
|
|
253
|
+
kwargs['params'] = params
|
|
244
254
|
set_organization(kwargs)
|
|
245
255
|
return self._check(self._doit('patch', path, *args, **kwargs), path, kwargs)
|
|
246
256
|
|
|
@@ -4,6 +4,7 @@ from typing import Dict
|
|
|
4
4
|
from typing import Optional
|
|
5
5
|
|
|
6
6
|
from .manager import Manager
|
|
7
|
+
from .utils import NamedList
|
|
7
8
|
from .utils import vars_to_str
|
|
8
9
|
|
|
9
10
|
|
|
@@ -20,7 +21,10 @@ class Region(object):
|
|
|
20
21
|
|
|
21
22
|
"""
|
|
22
23
|
|
|
23
|
-
def __init__(
|
|
24
|
+
def __init__(
|
|
25
|
+
self, name: str, provider: str, id: Optional[str] = None,
|
|
26
|
+
region_name: Optional[str] = None,
|
|
27
|
+
) -> None:
|
|
24
28
|
"""Use :attr:`WorkspaceManager.regions` instead."""
|
|
25
29
|
#: Unique ID of the region
|
|
26
30
|
self.id = id
|
|
@@ -31,6 +35,9 @@ class Region(object):
|
|
|
31
35
|
#: Name of the cloud provider
|
|
32
36
|
self.provider = provider
|
|
33
37
|
|
|
38
|
+
#: Name of the provider region
|
|
39
|
+
self.region_name = region_name
|
|
40
|
+
|
|
34
41
|
self._manager: Optional[Manager] = None
|
|
35
42
|
|
|
36
43
|
def __str__(self) -> str:
|
|
@@ -58,10 +65,105 @@ class Region(object):
|
|
|
58
65
|
:class:`Region`
|
|
59
66
|
|
|
60
67
|
"""
|
|
68
|
+
id = obj.get('regionID', None)
|
|
69
|
+
region_name = obj.get('regionName', None)
|
|
70
|
+
|
|
61
71
|
out = cls(
|
|
62
|
-
id=
|
|
72
|
+
id=id,
|
|
63
73
|
name=obj['region'],
|
|
64
74
|
provider=obj['provider'],
|
|
75
|
+
region_name=region_name,
|
|
65
76
|
)
|
|
66
77
|
out._manager = manager
|
|
67
78
|
return out
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class RegionManager(Manager):
|
|
82
|
+
"""
|
|
83
|
+
SingleStoreDB region manager.
|
|
84
|
+
|
|
85
|
+
This class should be instantiated using :func:`singlestoredb.manage_regions`.
|
|
86
|
+
|
|
87
|
+
Parameters
|
|
88
|
+
----------
|
|
89
|
+
access_token : str, optional
|
|
90
|
+
The API key or other access token for the workspace management API
|
|
91
|
+
version : str, optional
|
|
92
|
+
Version of the API to use
|
|
93
|
+
base_url : str, optional
|
|
94
|
+
Base URL of the workspace management API
|
|
95
|
+
|
|
96
|
+
See Also
|
|
97
|
+
--------
|
|
98
|
+
:func:`singlestoredb.manage_regions`
|
|
99
|
+
"""
|
|
100
|
+
|
|
101
|
+
#: Object type
|
|
102
|
+
obj_type = 'region'
|
|
103
|
+
|
|
104
|
+
def list_regions(self) -> NamedList[Region]:
|
|
105
|
+
"""
|
|
106
|
+
List all available regions.
|
|
107
|
+
|
|
108
|
+
Returns
|
|
109
|
+
-------
|
|
110
|
+
NamedList[Region]
|
|
111
|
+
List of available regions
|
|
112
|
+
|
|
113
|
+
Raises
|
|
114
|
+
------
|
|
115
|
+
ManagementError
|
|
116
|
+
If there is an error getting the regions
|
|
117
|
+
"""
|
|
118
|
+
res = self._get('regions')
|
|
119
|
+
return NamedList(
|
|
120
|
+
[Region.from_dict(item, self) for item in res.json()],
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
def list_shared_tier_regions(self) -> NamedList[Region]:
|
|
124
|
+
"""
|
|
125
|
+
List regions that support shared tier workspaces.
|
|
126
|
+
|
|
127
|
+
Returns
|
|
128
|
+
-------
|
|
129
|
+
NamedList[Region]
|
|
130
|
+
List of regions that support shared tier workspaces
|
|
131
|
+
|
|
132
|
+
Raises
|
|
133
|
+
------
|
|
134
|
+
ManagementError
|
|
135
|
+
If there is an error getting the regions
|
|
136
|
+
"""
|
|
137
|
+
res = self._get('regions/sharedtier')
|
|
138
|
+
return NamedList(
|
|
139
|
+
[Region.from_dict(item, self) for item in res.json()],
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def manage_regions(
|
|
144
|
+
access_token: Optional[str] = None,
|
|
145
|
+
version: Optional[str] = None,
|
|
146
|
+
base_url: Optional[str] = None,
|
|
147
|
+
) -> RegionManager:
|
|
148
|
+
"""
|
|
149
|
+
Retrieve a SingleStoreDB region manager.
|
|
150
|
+
|
|
151
|
+
Parameters
|
|
152
|
+
----------
|
|
153
|
+
access_token : str, optional
|
|
154
|
+
The API key or other access token for the workspace management API
|
|
155
|
+
version : str, optional
|
|
156
|
+
Version of the API to use
|
|
157
|
+
base_url : str, optional
|
|
158
|
+
Base URL of the workspace management API
|
|
159
|
+
|
|
160
|
+
Returns
|
|
161
|
+
-------
|
|
162
|
+
:class:`RegionManager`
|
|
163
|
+
|
|
164
|
+
"""
|
|
165
|
+
return RegionManager(
|
|
166
|
+
access_token=access_token,
|
|
167
|
+
version=version,
|
|
168
|
+
base_url=base_url,
|
|
169
|
+
)
|