singlestoredb 0.10.0__cp38-abi3-win_amd64.whl → 0.10.2__cp38-abi3-win_amd64.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_accel.pyd +0 -0
- singlestoredb/__init__.py +1 -1
- singlestoredb/fusion/handlers/utils.py +20 -4
- singlestoredb/fusion/handlers/workspace.py +21 -15
- singlestoredb/management/utils.py +67 -25
- singlestoredb/management/workspace.py +6 -5
- {singlestoredb-0.10.0.dist-info → singlestoredb-0.10.2.dist-info}/METADATA +1 -1
- {singlestoredb-0.10.0.dist-info → singlestoredb-0.10.2.dist-info}/RECORD +11 -11
- {singlestoredb-0.10.0.dist-info → singlestoredb-0.10.2.dist-info}/LICENSE +0 -0
- {singlestoredb-0.10.0.dist-info → singlestoredb-0.10.2.dist-info}/WHEEL +0 -0
- {singlestoredb-0.10.0.dist-info → singlestoredb-0.10.2.dist-info}/top_level.txt +0 -0
_singlestoredb_accel.pyd
CHANGED
|
Binary file
|
singlestoredb/__init__.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
2
|
import datetime
|
|
3
|
+
import os
|
|
3
4
|
from typing import Any
|
|
4
5
|
from typing import Dict
|
|
5
6
|
from typing import Optional
|
|
@@ -26,15 +27,17 @@ def get_workspace_group(params: Dict[str, Any]) -> WorkspaceGroup:
|
|
|
26
27
|
"""Find a workspace group matching group_id or group_name."""
|
|
27
28
|
manager = get_workspace_manager()
|
|
28
29
|
|
|
29
|
-
|
|
30
|
+
group_name = params.get('group_name') or \
|
|
31
|
+
(params.get('in_group') or {}).get('group_name')
|
|
32
|
+
if group_name:
|
|
30
33
|
workspace_groups = [
|
|
31
34
|
x for x in manager.workspace_groups
|
|
32
|
-
if x.name ==
|
|
35
|
+
if x.name == group_name
|
|
33
36
|
]
|
|
34
37
|
|
|
35
38
|
if not workspace_groups:
|
|
36
39
|
raise KeyError(
|
|
37
|
-
'no workspace group found with name "{}"'.format(
|
|
40
|
+
'no workspace group found with name "{}"'.format(group_name),
|
|
38
41
|
)
|
|
39
42
|
|
|
40
43
|
if len(workspace_groups) > 1:
|
|
@@ -45,4 +48,17 @@ def get_workspace_group(params: Dict[str, Any]) -> WorkspaceGroup:
|
|
|
45
48
|
|
|
46
49
|
return workspace_groups[0]
|
|
47
50
|
|
|
48
|
-
|
|
51
|
+
group_id = params.get('group_id') or \
|
|
52
|
+
(params.get('in_group') or {}).get('group_id')
|
|
53
|
+
if group_id:
|
|
54
|
+
return manager.get_workspace_group(group_id)
|
|
55
|
+
|
|
56
|
+
if os.environ.get('SINGLESTOREDB_WORKSPACE_GROUP'):
|
|
57
|
+
return manager.get_workspace_group(
|
|
58
|
+
os.environ['SINGLESTOREDB_WORKSPACE_GROUP'],
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
if os.environ.get('SINGLESTOREDB_CLUSTER'):
|
|
62
|
+
raise ValueError('clusters and shared workspaces are not currently supported')
|
|
63
|
+
|
|
64
|
+
raise KeyError('no workspace group was specified')
|
|
@@ -80,8 +80,10 @@ ShowWorkspaceGroupsHandler.register()
|
|
|
80
80
|
|
|
81
81
|
class ShowWorkspacesHandler(SQLHandler):
|
|
82
82
|
"""
|
|
83
|
-
SHOW WORKSPACES
|
|
84
|
-
|
|
83
|
+
SHOW WORKSPACES [ in_group ] [ <like> ] [ <extended> ] [ <order-by> ] [ <limit> ];
|
|
84
|
+
|
|
85
|
+
# Workspace group
|
|
86
|
+
in_group = IN GROUP { group_id | group_name }
|
|
85
87
|
|
|
86
88
|
# ID of group
|
|
87
89
|
group_id = ID '<group-id>'
|
|
@@ -198,10 +200,12 @@ CreateWorkspaceGroupHandler.register()
|
|
|
198
200
|
|
|
199
201
|
class CreateWorkspaceHandler(SQLHandler):
|
|
200
202
|
"""
|
|
201
|
-
CREATE WORKSPACE [ if_not_exists ] workspace_name
|
|
202
|
-
IN GROUP { group_id | group_name }
|
|
203
|
+
CREATE WORKSPACE [ if_not_exists ] workspace_name [ in_group ]
|
|
203
204
|
WITH SIZE size [ wait_on_active ];
|
|
204
205
|
|
|
206
|
+
# Create workspace in workspace group
|
|
207
|
+
in_group = IN GROUP { group_id | group_name }
|
|
208
|
+
|
|
205
209
|
# Only run command if workspace doesn't already exist
|
|
206
210
|
if_not_exists = IF NOT EXISTS
|
|
207
211
|
|
|
@@ -264,15 +268,15 @@ class DropWorkspaceGroupHandler(SQLHandler):
|
|
|
264
268
|
"""
|
|
265
269
|
|
|
266
270
|
def run(self, params: Dict[str, Any]) -> Optional[FusionSQLResult]:
|
|
267
|
-
manager = get_workspace_manager()
|
|
268
|
-
|
|
269
271
|
try:
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
272
|
+
workspace_group = get_workspace_group(params)
|
|
273
|
+
if workspace_group.terminated_at is not None:
|
|
274
|
+
raise KeyError
|
|
275
|
+
workspace_group.terminate(wait_on_terminated=params['wait_on_terminated'])
|
|
273
276
|
|
|
274
277
|
except KeyError:
|
|
275
278
|
if not params['if_exists']:
|
|
279
|
+
name_or_id = params['group_id'] or params['group_name']
|
|
276
280
|
raise KeyError(f"could not find workspace group '{name_or_id}'")
|
|
277
281
|
|
|
278
282
|
return None
|
|
@@ -284,7 +288,10 @@ DropWorkspaceGroupHandler.register()
|
|
|
284
288
|
class DropWorkspaceHandler(SQLHandler):
|
|
285
289
|
"""
|
|
286
290
|
DROP WORKSPACE [ if_exists ] { workspace_id | workspace_name }
|
|
287
|
-
|
|
291
|
+
[ in_group ] [ wait_on_terminated ];
|
|
292
|
+
|
|
293
|
+
# Workspace group
|
|
294
|
+
in_group = IN GROUP { group_id | group_name }
|
|
288
295
|
|
|
289
296
|
# Only drop workspace if it exists
|
|
290
297
|
if_exists = IF EXISTS
|
|
@@ -307,16 +314,15 @@ class DropWorkspaceHandler(SQLHandler):
|
|
|
307
314
|
"""
|
|
308
315
|
|
|
309
316
|
def run(self, params: Dict[str, Any]) -> Optional[FusionSQLResult]:
|
|
310
|
-
manager = get_workspace_manager()
|
|
311
|
-
|
|
312
317
|
try:
|
|
318
|
+
workspace_group = get_workspace_group(params)
|
|
313
319
|
workspace_name_or_id = params['workspace_name'] or params['workspace_id']
|
|
314
|
-
|
|
315
|
-
wg = manager.workspace_groups[group_name_or_id]
|
|
316
|
-
ws = wg.workspaces[workspace_name_or_id]
|
|
320
|
+
ws = workspace_group.workspaces[workspace_name_or_id]
|
|
317
321
|
ws.terminate(wait_on_terminated=params['wait_on_terminated'])
|
|
318
322
|
|
|
319
323
|
except KeyError:
|
|
324
|
+
group_name_or_id = params['in_group'].get('group_id', None) or \
|
|
325
|
+
params['in_group'].get('group_name', None)
|
|
320
326
|
if not params['if_exists']:
|
|
321
327
|
raise KeyError(
|
|
322
328
|
f"could not find workspace '{workspace_name_or_id}' "
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
2
|
"""SingleStoreDB Cluster Management."""
|
|
3
3
|
import datetime
|
|
4
|
+
import functools
|
|
4
5
|
import os
|
|
5
6
|
import re
|
|
6
7
|
import sys
|
|
7
8
|
from typing import Any
|
|
9
|
+
from typing import Callable
|
|
8
10
|
from typing import Dict
|
|
9
11
|
from typing import List
|
|
10
12
|
from typing import Optional
|
|
@@ -31,37 +33,44 @@ else:
|
|
|
31
33
|
PathLikeABC = os.PathLike[str]
|
|
32
34
|
|
|
33
35
|
|
|
34
|
-
|
|
35
|
-
"""
|
|
36
|
-
# See if an API key is configured
|
|
37
|
-
tok = get_option('management.token')
|
|
38
|
-
if tok:
|
|
39
|
-
return tok
|
|
36
|
+
class TTLProperty(object):
|
|
37
|
+
"""Property with time limit."""
|
|
40
38
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
def __init__(self, fget: Callable[[Any], Any], ttl: datetime.timedelta):
|
|
40
|
+
self.fget = fget
|
|
41
|
+
self.ttl = ttl
|
|
42
|
+
self._last_executed = datetime.datetime(2000, 1, 1)
|
|
43
|
+
self._last_result = None
|
|
44
|
+
self.__doc__ = fget.__doc__
|
|
45
|
+
self._name = ''
|
|
45
46
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
jwt.decode(urlp.password, options={'verify_signature': False})
|
|
50
|
-
return urlp.password
|
|
51
|
-
except jwt.DecodeError:
|
|
52
|
-
pass
|
|
47
|
+
def reset(self) -> None:
|
|
48
|
+
self._last_executed = datetime.datetime(2000, 1, 1)
|
|
49
|
+
self._last_result = None
|
|
53
50
|
|
|
54
|
-
|
|
55
|
-
|
|
51
|
+
def __set_name__(self, owner: Any, name: str) -> None:
|
|
52
|
+
self._name = name
|
|
56
53
|
|
|
54
|
+
def __get__(self, obj: Any, objtype: Any = None) -> Any:
|
|
55
|
+
if obj is None:
|
|
56
|
+
return self
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
if org:
|
|
62
|
-
return org
|
|
58
|
+
if self._last_result is not None \
|
|
59
|
+
and (datetime.datetime.now() - self._last_executed) < self.ttl:
|
|
60
|
+
return self._last_result
|
|
63
61
|
|
|
64
|
-
|
|
62
|
+
self._last_result = self.fget(obj)
|
|
63
|
+
self._last_executed = datetime.datetime.now()
|
|
64
|
+
|
|
65
|
+
return self._last_result
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def ttl_property(ttl: datetime.timedelta) -> Callable[[Any], Any]:
|
|
69
|
+
"""Property with a time-to-live."""
|
|
70
|
+
def wrapper(func: Callable[[Any], Any]) -> Any:
|
|
71
|
+
out = TTLProperty(func, ttl=ttl)
|
|
72
|
+
return functools.wraps(func)(out)
|
|
73
|
+
return wrapper
|
|
65
74
|
|
|
66
75
|
|
|
67
76
|
class NamedList(List[T]):
|
|
@@ -107,6 +116,39 @@ class NamedList(List[T]):
|
|
|
107
116
|
raise
|
|
108
117
|
|
|
109
118
|
|
|
119
|
+
def get_token() -> Optional[str]:
|
|
120
|
+
"""Return the token for the Management API."""
|
|
121
|
+
# See if an API key is configured
|
|
122
|
+
tok = get_option('management.token')
|
|
123
|
+
if tok:
|
|
124
|
+
return tok
|
|
125
|
+
|
|
126
|
+
# See if the connection URL contains a JWT
|
|
127
|
+
url = get_option('host')
|
|
128
|
+
if not url:
|
|
129
|
+
return None
|
|
130
|
+
|
|
131
|
+
urlp = urlparse(url, scheme='singlestoredb', allow_fragments=True)
|
|
132
|
+
if urlp.password:
|
|
133
|
+
try:
|
|
134
|
+
jwt.decode(urlp.password, options={'verify_signature': False})
|
|
135
|
+
return urlp.password
|
|
136
|
+
except jwt.DecodeError:
|
|
137
|
+
pass
|
|
138
|
+
|
|
139
|
+
# Didn't find a key anywhere
|
|
140
|
+
return None
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def get_organization() -> Optional[str]:
|
|
144
|
+
"""Return the organization for the current token or environment."""
|
|
145
|
+
org = os.environ.get('SINGLESTOREDB_ORGANIZATION')
|
|
146
|
+
if org:
|
|
147
|
+
return org
|
|
148
|
+
|
|
149
|
+
return None
|
|
150
|
+
|
|
151
|
+
|
|
110
152
|
def enable_http_tracing() -> None:
|
|
111
153
|
"""Enable tracing of HTTP requests."""
|
|
112
154
|
import logging
|
|
@@ -28,6 +28,7 @@ from .utils import NamedList
|
|
|
28
28
|
from .utils import PathLike
|
|
29
29
|
from .utils import snake_to_camel
|
|
30
30
|
from .utils import to_datetime
|
|
31
|
+
from .utils import ttl_property
|
|
31
32
|
from .utils import vars_to_str
|
|
32
33
|
|
|
33
34
|
|
|
@@ -1119,7 +1120,7 @@ class WorkspaceGroup(object):
|
|
|
1119
1120
|
try:
|
|
1120
1121
|
region = [x for x in manager.regions if x.id == obj['regionID']][0]
|
|
1121
1122
|
except IndexError:
|
|
1122
|
-
region =
|
|
1123
|
+
region = Region(obj.get('regionID', '<unknown>'), '<unknown>', '<unknown>')
|
|
1123
1124
|
out = cls(
|
|
1124
1125
|
name=obj['name'],
|
|
1125
1126
|
id=obj['workspaceGroupID'],
|
|
@@ -1377,23 +1378,23 @@ class WorkspaceManager(Manager):
|
|
|
1377
1378
|
#: Object type
|
|
1378
1379
|
obj_type = 'workspace'
|
|
1379
1380
|
|
|
1380
|
-
@
|
|
1381
|
+
@property
|
|
1381
1382
|
def workspace_groups(self) -> NamedList[WorkspaceGroup]:
|
|
1382
1383
|
"""Return a list of available workspace groups."""
|
|
1383
1384
|
res = self._get('workspaceGroups')
|
|
1384
1385
|
return NamedList([WorkspaceGroup.from_dict(item, self) for item in res.json()])
|
|
1385
1386
|
|
|
1386
|
-
@
|
|
1387
|
+
@property
|
|
1387
1388
|
def organizations(self) -> Organizations:
|
|
1388
1389
|
"""Return the organizations."""
|
|
1389
1390
|
return Organizations(self)
|
|
1390
1391
|
|
|
1391
|
-
@
|
|
1392
|
+
@property
|
|
1392
1393
|
def billing(self) -> Billing:
|
|
1393
1394
|
"""Return the current billing information."""
|
|
1394
1395
|
return Billing(self)
|
|
1395
1396
|
|
|
1396
|
-
@
|
|
1397
|
+
@ttl_property(datetime.timedelta(hours=1))
|
|
1397
1398
|
def regions(self) -> NamedList[Region]:
|
|
1398
1399
|
"""Return a list of available regions."""
|
|
1399
1400
|
res = self._get('regions')
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
_singlestoredb_accel.pyd,sha256=
|
|
2
|
-
singlestoredb/__init__.py,sha256=
|
|
1
|
+
_singlestoredb_accel.pyd,sha256=8PqjY5PQXqifYCe96103HTZ-dhDT7H-1FTJ5gx84_B8,45568
|
|
2
|
+
singlestoredb/__init__.py,sha256=HVmH2GEx2_Vmnv0hvAFuRaB2yiP3MMmGY6cfiqJ2AFo,910
|
|
3
3
|
singlestoredb/auth.py,sha256=RmYiH0Wlc2RXc4pTlRMysxtBI445ggCIwojWKC_eDLE,7844
|
|
4
4
|
singlestoredb/config.py,sha256=Uq7LWKlIwMAJC3_G3j5dUIQVJf2JzbDVtRK6votjuDw,7746
|
|
5
5
|
singlestoredb/connection.py,sha256=gSKmMN1d_ZSXVTmzfuHK3BXcLyNGiaSi2Vy6z7nymjg,45657
|
|
@@ -22,8 +22,8 @@ singlestoredb/fusion/registry.py,sha256=7wELKu09I6N4Oif4lpqAHCy8p_C4COn85hhtoCN5
|
|
|
22
22
|
singlestoredb/fusion/result.py,sha256=EcFY5Qv43ySlQsfl_JB-I3ko7PzVdjuhhoKN96uHSAM,12171
|
|
23
23
|
singlestoredb/fusion/handlers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
24
24
|
singlestoredb/fusion/handlers/stage.py,sha256=VEoHU3q5BX3lCl6pG9jVf-eviqkTZhyzTbO3sRKrMPs,5426
|
|
25
|
-
singlestoredb/fusion/handlers/utils.py,sha256=
|
|
26
|
-
singlestoredb/fusion/handlers/workspace.py,sha256=
|
|
25
|
+
singlestoredb/fusion/handlers/utils.py,sha256=H79iVSp0EZKyL3vI8OX8m8cBuFfU-7X9u5CjqnFBmRs,2045
|
|
26
|
+
singlestoredb/fusion/handlers/workspace.py,sha256=b21Vi6zZPi8TyWaI7BcAF4L7KGU6xFNV3EAN7wF1fN4,10045
|
|
27
27
|
singlestoredb/http/__init__.py,sha256=4cEDvLloGc3LSpU-PnIwacyu0n5oIIIE6xk2SPyWD_w,939
|
|
28
28
|
singlestoredb/http/connection.py,sha256=vYP10ZsqrhK8RrLS17OVuMkpTsO0VZQu3bxx1FQzUwU,37839
|
|
29
29
|
singlestoredb/management/__init__.py,sha256=kdKM-wErALWaEHYBLx_raHkJ8xUvUPflhOk8OBJyn58,173
|
|
@@ -32,8 +32,8 @@ singlestoredb/management/cluster.py,sha256=0GhpuSt_rcFz5f1hzcRHK911KWFewljlV4GFt
|
|
|
32
32
|
singlestoredb/management/manager.py,sha256=-fcuqyM3amze72kNF8JXjQOkWzZrdp9LVDd1ySNWHzI,8813
|
|
33
33
|
singlestoredb/management/organization.py,sha256=iz5Mde0lat3EYLpwNDbnS0ytI33O6tG6-wYDL4-TGdM,2200
|
|
34
34
|
singlestoredb/management/region.py,sha256=oGoLLS88dE1GmY7GCc0BV7X3f7bWwKQyeXOVBFmK9Pk,1678
|
|
35
|
-
singlestoredb/management/utils.py,sha256
|
|
36
|
-
singlestoredb/management/workspace.py,sha256=
|
|
35
|
+
singlestoredb/management/utils.py,sha256=-XXP7FnCRWlDcPMo6oOG-_UYI00QQqUpXM4TlILu5Kw,8533
|
|
36
|
+
singlestoredb/management/workspace.py,sha256=Bzkzp2_UymVfyOJDg4SjtPa2MsWAC0UinofR-xMxYN0,49253
|
|
37
37
|
singlestoredb/mysql/__init__.py,sha256=CbpwzNUJPAmKPpIobC0-ugBta_RgHCMq7X7N75QLReY,4669
|
|
38
38
|
singlestoredb/mysql/_auth.py,sha256=YaqqyvAHmeraBv3BM207rNveUVPM-mPnW20ts_ynVWg,8341
|
|
39
39
|
singlestoredb/mysql/charset.py,sha256=mnCdMpvdub1S2mm2PSk2j5JddgsWRjsVLtGx-y9TskE,10724
|
|
@@ -98,8 +98,8 @@ singlestoredb/utils/debug.py,sha256=y7dnJeJGt3U_BWXz9pLt1qNQREpPtumYX_sk1DiqG6Y,
|
|
|
98
98
|
singlestoredb/utils/mogrify.py,sha256=gCcn99-vgsGVjTUV7RHJ6hH4vCNrsGB_Xo4z8kiSPDQ,4201
|
|
99
99
|
singlestoredb/utils/results.py,sha256=ely2XVAHHejObjLibS3UcrPOuCO2g5aRtA3PxAMtE-g,5432
|
|
100
100
|
singlestoredb/utils/xdict.py,sha256=-wi1lSPTnY99fhVMBhPKJ8cCsQhNG4GMUfkEBDKYgCw,13321
|
|
101
|
-
singlestoredb-0.10.
|
|
102
|
-
singlestoredb-0.10.
|
|
103
|
-
singlestoredb-0.10.
|
|
104
|
-
singlestoredb-0.10.
|
|
105
|
-
singlestoredb-0.10.
|
|
101
|
+
singlestoredb-0.10.2.dist-info/LICENSE,sha256=Bojenzui8aPNjlF3w4ojguDP7sTf8vFV_9Gc2UAG1sg,11542
|
|
102
|
+
singlestoredb-0.10.2.dist-info/METADATA,sha256=WJLPuZGqhIr4yEui0bNp7_4jhJkryaQ4-ZdHRkhkXus,7794
|
|
103
|
+
singlestoredb-0.10.2.dist-info/WHEEL,sha256=NWRSyYmhZPn8_0pCTTzBY74ihO0hpYMm3KvprjPFRJU,100
|
|
104
|
+
singlestoredb-0.10.2.dist-info/top_level.txt,sha256=SDtemIXf-Kp-_F2f_S6x0db33cHGOILdAEsIQZe2LZc,35
|
|
105
|
+
singlestoredb-0.10.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|