singlestoredb 1.8.0__cp38-abi3-win_amd64.whl → 1.10.0__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.

@@ -0,0 +1,56 @@
1
+ import os
2
+ import tempfile
3
+ from typing import Any
4
+
5
+ from IPython.core.interactiveshell import InteractiveShell
6
+ from IPython.core.magic import line_magic
7
+ from IPython.core.magic import Magics
8
+ from IPython.core.magic import magics_class
9
+ from IPython.core.magic import needs_local_scope
10
+ from IPython.core.magic import no_var_expand
11
+ from jinja2 import Template
12
+
13
+
14
+ @magics_class
15
+ class RunPersonalMagic(Magics):
16
+ def __init__(self, shell: InteractiveShell):
17
+ Magics.__init__(self, shell=shell)
18
+
19
+ @no_var_expand
20
+ @needs_local_scope
21
+ @line_magic('run_personal')
22
+ def run_personal(self, line: str, local_ns: Any = None) -> Any:
23
+ """
24
+ Downloads a personal file using the %sql magic and then runs it using %run.
25
+
26
+ Examples::
27
+
28
+ # Line usage
29
+
30
+ %run_personal personal_file.ipynb
31
+
32
+ %run_personal {{ sample_notebook_name }}
33
+
34
+ """
35
+
36
+ template = Template(line.strip())
37
+ personal_file = template.render(local_ns)
38
+ if not personal_file:
39
+ raise ValueError('No personal file specified.')
40
+ if (personal_file.startswith("'") and personal_file.endswith("'")) or \
41
+ (personal_file.startswith('"') and personal_file.endswith('"')):
42
+ personal_file = personal_file[1:-1]
43
+ if not personal_file:
44
+ raise ValueError('No personal file specified.')
45
+
46
+ with tempfile.TemporaryDirectory() as temp_dir:
47
+ temp_file_path = os.path.join(temp_dir, personal_file)
48
+ sql_command = (
49
+ f"DOWNLOAD PERSONAL FILE '{personal_file}' "
50
+ f"TO '{temp_file_path}'"
51
+ )
52
+
53
+ # Execute the SQL command
54
+ self.shell.run_line_magic('sql', sql_command)
55
+ # Run the downloaded file
56
+ self.shell.run_line_magic('run', f'"{temp_file_path}"')
@@ -0,0 +1,53 @@
1
+ import os
2
+ import tempfile
3
+ from typing import Any
4
+
5
+ from IPython.core.interactiveshell import InteractiveShell
6
+ from IPython.core.magic import line_magic
7
+ from IPython.core.magic import Magics
8
+ from IPython.core.magic import magics_class
9
+ from IPython.core.magic import needs_local_scope
10
+ from IPython.core.magic import no_var_expand
11
+ from jinja2 import Template
12
+
13
+
14
+ @magics_class
15
+ class RunSharedMagic(Magics):
16
+ def __init__(self, shell: InteractiveShell):
17
+ Magics.__init__(self, shell=shell)
18
+
19
+ @no_var_expand
20
+ @needs_local_scope
21
+ @line_magic('run_shared')
22
+ def run_shared(self, line: str, local_ns: Any = None) -> Any:
23
+ """
24
+ Downloads a shared file using the %sql magic and then runs it using %run.
25
+
26
+ Examples::
27
+
28
+ # Line usage
29
+
30
+ %run_shared shared_file.ipynb
31
+
32
+ %run_shared {{ sample_notebook_name }}
33
+
34
+ """
35
+
36
+ template = Template(line.strip())
37
+ shared_file = template.render(local_ns)
38
+ if not shared_file:
39
+ raise ValueError('No shared file specified.')
40
+ if (shared_file.startswith("'") and shared_file.endswith("'")) or \
41
+ (shared_file.startswith('"') and shared_file.endswith('"')):
42
+ shared_file = shared_file[1:-1]
43
+ if not shared_file:
44
+ raise ValueError('No personal file specified.')
45
+
46
+ with tempfile.TemporaryDirectory() as temp_dir:
47
+ temp_file_path = os.path.join(temp_dir, shared_file)
48
+ sql_command = f"DOWNLOAD SHARED FILE '{shared_file}' TO '{temp_file_path}'"
49
+
50
+ # Execute the SQL command
51
+ self.shell.run_line_magic('sql', sql_command)
52
+ # Run the downloaded file
53
+ self.shell.run_line_magic('run', f'"{temp_file_path}"')
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env python
2
2
  from .cluster import manage_cluster
3
+ from .files import manage_files
3
4
  from .manager import get_token
4
5
  from .workspace import get_organization
5
6
  from .workspace import get_secret
@@ -333,7 +333,8 @@ class ClusterManager(Manager):
333
333
  default_version = 'v0beta'
334
334
 
335
335
  #: Base URL if none is specified.
336
- default_base_url = config.get_option('management.base_url')
336
+ default_base_url = config.get_option('management.base_url') \
337
+ or 'https://api.singlestore.com'
337
338
 
338
339
  #: Object type
339
340
  obj_type = 'cluster'
@@ -2,12 +2,13 @@
2
2
  """SingleStoreDB export service."""
3
3
  from __future__ import annotations
4
4
 
5
- import abc
6
- import re
5
+ import copy
6
+ import json
7
7
  from typing import Any
8
8
  from typing import Dict
9
9
  from typing import List
10
10
  from typing import Optional
11
+ from typing import Union
11
12
 
12
13
  from .. import ManagementError
13
14
  from .utils import vars_to_str
@@ -15,172 +16,13 @@ from .workspace import WorkspaceGroup
15
16
  from .workspace import WorkspaceManager
16
17
 
17
18
 
18
- class Link(object):
19
- """Generic storage base class."""
20
- scheme: str = 'unknown'
21
-
22
- def __str__(self) -> str:
23
- """Return string representation."""
24
- return vars_to_str(self)
25
-
26
- def __repr__(self) -> str:
27
- """Return string representation."""
28
- return str(self)
29
-
30
- @abc.abstractmethod
31
- def to_storage_location(self) -> Dict[str, Any]:
32
- raise NotImplementedError
33
-
34
- @classmethod
35
- def from_config_and_creds(
36
- cls,
37
- scheme: str,
38
- config: Dict[str, Any],
39
- credentials: Dict[str, Any],
40
- manager: 'WorkspaceManager',
41
- ) -> 'Link':
42
- out_cls = None
43
- for c in cls.__subclasses__():
44
- if c.scheme == scheme.upper():
45
- out_cls = c
46
- break
47
-
48
- if out_cls is None:
49
- raise TypeError(f'No link class found for given information: {scheme}')
50
-
51
- return out_cls.from_config_and_creds(scheme, config, credentials, manager)
52
-
53
-
54
- class S3Link(Link):
55
- """S3 link."""
56
-
57
- scheme: str = 'S3'
58
- region: str
59
- storage_base_url: str
60
-
61
- def __init__(self, region: str, storage_base_url: str):
62
- self.region = region
63
- self.storage_base_url = storage_base_url
64
- self._manager: Optional[WorkspaceManager] = None
65
-
66
- def to_storage_location(self) -> Dict[str, Any]:
67
- return dict(
68
- storageBaseURL=self.storage_base_url,
69
- storageRegion=self.region,
70
- )
71
-
72
- @classmethod
73
- def from_config_and_creds(
74
- cls,
75
- scheme: str,
76
- config: Dict[str, Any],
77
- credentials: Dict[str, Any],
78
- manager: 'WorkspaceManager',
79
- ) -> 'S3Link':
80
- assert scheme.upper() == cls.scheme
81
-
82
- params: Dict[str, Any] = {}
83
- params.update(config)
84
- params.update(credentials)
85
-
86
- assert params.get('region'), 'region is required'
87
- assert params.get('endpoint_url'), 'endpoint_url is required'
88
-
89
- out = cls(params['region'], params['endpoint_url'])
90
- out._manager = manager
91
- return out
92
-
93
-
94
- class Catalog(object):
95
- """Generic catalog base class."""
96
-
97
- catalog_type: str = 'UNKNOWN'
98
- table_format: str = 'UNKNOWN'
99
-
100
- def __str__(self) -> str:
101
- """Return string representation."""
102
- return vars_to_str(self)
103
-
104
- def __repr__(self) -> str:
105
- """Return string representation."""
106
- return str(self)
107
-
108
- @classmethod
109
- def from_config_and_creds(
110
- cls,
111
- config: Dict[str, Any],
112
- credentials: Dict[str, Any],
113
- manager: 'WorkspaceManager',
114
- ) -> 'Catalog':
115
- catalog_type = config['type'].upper()
116
- table_format = config['table_format'].upper()
117
-
118
- out_cls = None
119
- for c in cls.__subclasses__():
120
- if c.catalog_type == catalog_type and c.table_format == table_format:
121
- out_cls = c
122
- break
123
-
124
- if out_cls is None:
125
- raise TypeError(f'No catalog class found for given information: {config}')
126
-
127
- return out_cls.from_config_and_creds(config, credentials, manager)
128
-
129
- @abc.abstractmethod
130
- def to_catalog_info(self) -> Dict[str, Any]:
131
- """Return a catalog info dictionary."""
132
- raise NotImplementedError
133
-
134
-
135
- class IcebergGlueCatalog(Catalog):
136
- """Iceberg glue catalog."""
137
-
138
- table_format = 'ICEBERG'
139
- catalog_type = 'GLUE'
140
-
141
- region: str
142
- catalog_id: str
143
-
144
- def __init__(self, region: str, catalog_id: str):
145
- self.region = region
146
- self.catalog_id = catalog_id
147
- self._manager: Optional[WorkspaceManager] = None
148
-
149
- @classmethod
150
- def from_config_and_creds(
151
- cls,
152
- config: Dict[str, Any],
153
- credentials: Dict[str, Any],
154
- manager: 'WorkspaceManager',
155
- ) -> 'IcebergGlueCatalog':
156
- params = {}
157
- params.update(config)
158
- params.update(credentials)
159
-
160
- out = cls(
161
- region=params['region'],
162
- catalog_id=params['id'],
163
- )
164
- out._manager = manager
165
- return out
166
-
167
- def to_catalog_info(self) -> Dict[str, Any]:
168
- """Return a catalog info dictionary."""
169
- return dict(
170
- catalogSource=self.catalog_type,
171
- tableFormat=self.table_format,
172
- glueRegion=self.region,
173
- glueCatalogID=self.catalog_id,
174
- )
175
-
176
-
177
19
  class ExportService(object):
178
20
  """Export service."""
179
21
 
180
22
  database: str
181
23
  table: str
182
- catalog: Catalog
183
- storage_link: Link
24
+ catalog_info: Dict[str, Any]
25
+ storage_info: Dict[str, Any]
184
26
  columns: Optional[List[str]]
185
27
 
186
28
  def __init__(
@@ -188,8 +30,8 @@ class ExportService(object):
188
30
  workspace_group: WorkspaceGroup,
189
31
  database: str,
190
32
  table: str,
191
- catalog: Catalog,
192
- storage_link: Link,
33
+ catalog_info: Union[str, Dict[str, Any]],
34
+ storage_info: Union[str, Dict[str, Any]],
193
35
  columns: Optional[List[str]],
194
36
  ):
195
37
  #: Workspace group
@@ -205,10 +47,16 @@ class ExportService(object):
205
47
  self.columns = columns
206
48
 
207
49
  #: Catalog
208
- self.catalog = catalog
50
+ if isinstance(catalog_info, str):
51
+ self.catalog_info = json.loads(catalog_info)
52
+ else:
53
+ self.catalog_info = copy.copy(catalog_info)
209
54
 
210
55
  #: Storage
211
- self.storage_link = storage_link
56
+ if isinstance(storage_info, str):
57
+ self.storage_info = json.loads(storage_info)
58
+ else:
59
+ self.storage_info = copy.copy(storage_info)
212
60
 
213
61
  self._manager: Optional[WorkspaceManager] = workspace_group._manager
214
62
 
@@ -227,21 +75,12 @@ class ExportService(object):
227
75
  msg='No workspace manager is associated with this object.',
228
76
  )
229
77
 
230
- if not isinstance(self.catalog, IcebergGlueCatalog):
231
- raise TypeError('Only Iceberg Glue catalog is supported at this time.')
232
-
233
- if not isinstance(self.storage_link, S3Link):
234
- raise TypeError('Only S3 links are supported at this time.')
235
-
236
78
  out = self._manager._post(
237
79
  f'workspaceGroups/{self.workspace_group.id}/'
238
80
  'egress/createEgressClusterIdentity',
239
81
  json=dict(
240
- storageBucketName=re.split(
241
- r'/+', self.storage_link.storage_base_url,
242
- )[1],
243
- glueRegion=self.catalog.region,
244
- glueCatalogID=self.catalog.catalog_id,
82
+ catalogInfo=self.catalog_info,
83
+ storageInfo=self.storage_info,
245
84
  ),
246
85
  )
247
86
 
@@ -254,16 +93,13 @@ class ExportService(object):
254
93
  msg='No workspace manager is associated with this object.',
255
94
  )
256
95
 
257
- if not isinstance(self.storage_link, S3Link):
258
- raise TypeError('Only S3 links are supported at this time.')
259
-
260
96
  out = self._manager._post(
261
97
  f'workspaceGroups/{self.workspace_group.id}/egress/startTableEgress',
262
98
  json=dict(
263
99
  databaseName=self.database,
264
100
  tableName=self.table,
265
- storageLocation=self.storage_link.to_storage_location(),
266
- catalogInfo=self.catalog.to_catalog_info(),
101
+ storageInfo=self.storage_info,
102
+ catalogInfo=self.catalog_info,
267
103
  ),
268
104
  )
269
105
 
@@ -286,7 +122,7 @@ class ExportStatus(object):
286
122
  msg='No workspace manager is associated with this object.',
287
123
  )
288
124
 
289
- out = self._manager._post(
125
+ out = self._manager._get(
290
126
  f'workspaceGroups/{self.workspace_group.id}/egress/tableEgressStatus',
291
127
  json=dict(egressID=self.export_id),
292
128
  )