singlestoredb 0.3.3__py3-none-any.whl → 1.0.3__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.

Files changed (121) hide show
  1. singlestoredb/__init__.py +33 -2
  2. singlestoredb/alchemy/__init__.py +90 -0
  3. singlestoredb/auth.py +6 -4
  4. singlestoredb/config.py +116 -16
  5. singlestoredb/connection.py +489 -523
  6. singlestoredb/converters.py +275 -26
  7. singlestoredb/exceptions.py +30 -4
  8. singlestoredb/functions/__init__.py +1 -0
  9. singlestoredb/functions/decorator.py +142 -0
  10. singlestoredb/functions/dtypes.py +1639 -0
  11. singlestoredb/functions/ext/__init__.py +2 -0
  12. singlestoredb/functions/ext/arrow.py +375 -0
  13. singlestoredb/functions/ext/asgi.py +661 -0
  14. singlestoredb/functions/ext/json.py +427 -0
  15. singlestoredb/functions/ext/mmap.py +306 -0
  16. singlestoredb/functions/ext/rowdat_1.py +744 -0
  17. singlestoredb/functions/signature.py +673 -0
  18. singlestoredb/fusion/__init__.py +11 -0
  19. singlestoredb/fusion/graphql.py +213 -0
  20. singlestoredb/fusion/handler.py +621 -0
  21. singlestoredb/fusion/handlers/__init__.py +0 -0
  22. singlestoredb/fusion/handlers/stage.py +257 -0
  23. singlestoredb/fusion/handlers/utils.py +162 -0
  24. singlestoredb/fusion/handlers/workspace.py +412 -0
  25. singlestoredb/fusion/registry.py +164 -0
  26. singlestoredb/fusion/result.py +399 -0
  27. singlestoredb/http/__init__.py +27 -0
  28. singlestoredb/http/connection.py +1192 -0
  29. singlestoredb/management/__init__.py +3 -2
  30. singlestoredb/management/billing_usage.py +148 -0
  31. singlestoredb/management/cluster.py +19 -14
  32. singlestoredb/management/manager.py +100 -40
  33. singlestoredb/management/organization.py +188 -0
  34. singlestoredb/management/region.py +6 -8
  35. singlestoredb/management/utils.py +253 -4
  36. singlestoredb/management/workspace.py +1153 -35
  37. singlestoredb/mysql/__init__.py +177 -0
  38. singlestoredb/mysql/_auth.py +298 -0
  39. singlestoredb/mysql/charset.py +214 -0
  40. singlestoredb/mysql/connection.py +1814 -0
  41. singlestoredb/mysql/constants/CLIENT.py +38 -0
  42. singlestoredb/mysql/constants/COMMAND.py +32 -0
  43. singlestoredb/mysql/constants/CR.py +78 -0
  44. singlestoredb/mysql/constants/ER.py +474 -0
  45. singlestoredb/mysql/constants/FIELD_TYPE.py +32 -0
  46. singlestoredb/mysql/constants/FLAG.py +15 -0
  47. singlestoredb/mysql/constants/SERVER_STATUS.py +10 -0
  48. singlestoredb/mysql/constants/__init__.py +0 -0
  49. singlestoredb/mysql/converters.py +271 -0
  50. singlestoredb/mysql/cursors.py +713 -0
  51. singlestoredb/mysql/err.py +92 -0
  52. singlestoredb/mysql/optionfile.py +20 -0
  53. singlestoredb/mysql/protocol.py +388 -0
  54. singlestoredb/mysql/tests/__init__.py +19 -0
  55. singlestoredb/mysql/tests/base.py +126 -0
  56. singlestoredb/mysql/tests/conftest.py +37 -0
  57. singlestoredb/mysql/tests/test_DictCursor.py +132 -0
  58. singlestoredb/mysql/tests/test_SSCursor.py +141 -0
  59. singlestoredb/mysql/tests/test_basic.py +452 -0
  60. singlestoredb/mysql/tests/test_connection.py +851 -0
  61. singlestoredb/mysql/tests/test_converters.py +58 -0
  62. singlestoredb/mysql/tests/test_cursor.py +141 -0
  63. singlestoredb/mysql/tests/test_err.py +16 -0
  64. singlestoredb/mysql/tests/test_issues.py +514 -0
  65. singlestoredb/mysql/tests/test_load_local.py +75 -0
  66. singlestoredb/mysql/tests/test_nextset.py +88 -0
  67. singlestoredb/mysql/tests/test_optionfile.py +27 -0
  68. singlestoredb/mysql/tests/thirdparty/__init__.py +6 -0
  69. singlestoredb/mysql/tests/thirdparty/test_MySQLdb/__init__.py +9 -0
  70. singlestoredb/mysql/tests/thirdparty/test_MySQLdb/capabilities.py +323 -0
  71. singlestoredb/mysql/tests/thirdparty/test_MySQLdb/dbapi20.py +865 -0
  72. singlestoredb/mysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_capabilities.py +110 -0
  73. singlestoredb/mysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_dbapi20.py +224 -0
  74. singlestoredb/mysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_nonstandard.py +101 -0
  75. singlestoredb/mysql/times.py +23 -0
  76. singlestoredb/pytest.py +283 -0
  77. singlestoredb/tests/empty.sql +0 -0
  78. singlestoredb/tests/ext_funcs/__init__.py +385 -0
  79. singlestoredb/tests/test.sql +210 -0
  80. singlestoredb/tests/test2.sql +1 -0
  81. singlestoredb/tests/test_basics.py +482 -117
  82. singlestoredb/tests/test_config.py +13 -15
  83. singlestoredb/tests/test_connection.py +241 -289
  84. singlestoredb/tests/test_dbapi.py +27 -0
  85. singlestoredb/tests/test_exceptions.py +0 -2
  86. singlestoredb/tests/test_ext_func.py +1193 -0
  87. singlestoredb/tests/test_ext_func_data.py +1101 -0
  88. singlestoredb/tests/test_fusion.py +465 -0
  89. singlestoredb/tests/test_http.py +32 -28
  90. singlestoredb/tests/test_management.py +588 -10
  91. singlestoredb/tests/test_plugin.py +33 -0
  92. singlestoredb/tests/test_results.py +11 -14
  93. singlestoredb/tests/test_types.py +0 -2
  94. singlestoredb/tests/test_udf.py +687 -0
  95. singlestoredb/tests/test_xdict.py +0 -2
  96. singlestoredb/tests/utils.py +3 -4
  97. singlestoredb/types.py +4 -5
  98. singlestoredb/utils/config.py +71 -12
  99. singlestoredb/utils/convert_rows.py +0 -2
  100. singlestoredb/utils/debug.py +13 -0
  101. singlestoredb/utils/mogrify.py +151 -0
  102. singlestoredb/utils/results.py +4 -3
  103. singlestoredb/utils/xdict.py +12 -12
  104. singlestoredb-1.0.3.dist-info/METADATA +139 -0
  105. singlestoredb-1.0.3.dist-info/RECORD +112 -0
  106. {singlestoredb-0.3.3.dist-info → singlestoredb-1.0.3.dist-info}/WHEEL +1 -1
  107. singlestoredb-1.0.3.dist-info/entry_points.txt +2 -0
  108. singlestoredb/drivers/__init__.py +0 -46
  109. singlestoredb/drivers/base.py +0 -200
  110. singlestoredb/drivers/cymysql.py +0 -40
  111. singlestoredb/drivers/http.py +0 -49
  112. singlestoredb/drivers/mariadb.py +0 -42
  113. singlestoredb/drivers/mysqlconnector.py +0 -51
  114. singlestoredb/drivers/mysqldb.py +0 -62
  115. singlestoredb/drivers/pymysql.py +0 -39
  116. singlestoredb/drivers/pyodbc.py +0 -67
  117. singlestoredb/http.py +0 -794
  118. singlestoredb-0.3.3.dist-info/METADATA +0 -105
  119. singlestoredb-0.3.3.dist-info/RECORD +0 -46
  120. {singlestoredb-0.3.3.dist-info → singlestoredb-1.0.3.dist-info}/LICENSE +0 -0
  121. {singlestoredb-0.3.3.dist-info → singlestoredb-1.0.3.dist-info}/top_level.txt +0 -0
singlestoredb/__init__.py CHANGED
@@ -12,9 +12,10 @@ Examples
12
12
  ... print(row)
13
13
 
14
14
  """
15
- from __future__ import annotations
16
15
 
17
- __version__ = '0.3.3'
16
+ __version__ = '1.0.3'
17
+
18
+ from typing import Any
18
19
 
19
20
  from .config import options, get_option, set_option, describe_option
20
21
  from .connection import connect, apilevel, threadsafety, paramstyle
@@ -30,3 +31,33 @@ from .types import (
30
31
  Date, Time, Timestamp, DateFromTicks, TimeFromTicks, TimestampFromTicks,
31
32
  Binary, STRING, BINARY, NUMBER, DATETIME, ROWID,
32
33
  )
34
+
35
+
36
+ #
37
+ # This function is defined here to prevent the side-effect of
38
+ # attempting to load the SQLAlchemy dialect in the core SDK.
39
+ #
40
+ def create_engine(*args: Any, **kwargs: Any) -> Any:
41
+ """
42
+ Create an SQLAlchemy engine for SingleStoreDB.
43
+
44
+ Parameters
45
+ ----------
46
+ **kwargs : Any
47
+ The parameters taken here are the same as for
48
+ `sqlalchemy.create_engine`. However, this function can be
49
+ called without any parameters in order to inherit parameters
50
+ set by environment variables or parameters set in by
51
+ options in Python code.
52
+
53
+ See Also
54
+ --------
55
+ `sqlalchemy.create_engine`
56
+
57
+ Returns
58
+ -------
59
+ SQLAlchemy engine
60
+
61
+ """
62
+ from .alchemy import create_engine
63
+ return create_engine(*args, **kwargs)
@@ -0,0 +1,90 @@
1
+ #!/usr/bin/env python3
2
+ import inspect
3
+ from typing import Any
4
+ from urllib.parse import quote
5
+
6
+ try:
7
+ import sqlalchemy
8
+ from sqlalchemy_singlestoredb import * # noqa: F403, F401
9
+ has_sqlalchemy = True
10
+ except ImportError:
11
+ import warnings
12
+ warnings.warn(
13
+ 'sqlalchemy_singlestoredb must be installed to use this module',
14
+ RuntimeWarning,
15
+ )
16
+ has_sqlalchemy = False
17
+
18
+ from ..connection import build_params
19
+ from ..connection import connect
20
+
21
+
22
+ def create_engine(*args: Any, **kwargs: Any) -> Any:
23
+ """
24
+ Create an SQLAlchemy engine for SingleStoreDB.
25
+
26
+ Parameters
27
+ ----------
28
+ **kwargs : Any
29
+ The parameters taken here are the same as for
30
+ `sqlalchemy.create_engine`. However, this function can be
31
+ called without any parameters in order to inherit parameters
32
+ set by environment variables or parameters set in by
33
+ options in Python code.
34
+
35
+ See Also
36
+ --------
37
+ `sqlalchemy.create_engine`
38
+
39
+ Returns
40
+ -------
41
+ SQLAlchemy engine
42
+
43
+ """
44
+ if not has_sqlalchemy:
45
+ raise RuntimeError('sqlalchemy_singlestoredb package is not installed')
46
+
47
+ if len(args) > 1:
48
+ raise ValueError(
49
+ '`args` can only have a single element '
50
+ 'containing the database URL',
51
+ )
52
+
53
+ if args:
54
+ kwargs['host'] = args[0]
55
+
56
+ conn_params = {}
57
+ sa_params = {}
58
+
59
+ conn_args = inspect.getfullargspec(connect).args
60
+
61
+ for key, value in kwargs.items():
62
+ if key in conn_args:
63
+ conn_params[key] = value
64
+ else:
65
+ sa_params[key] = value
66
+
67
+ params = build_params(**conn_params)
68
+ driver = params.pop('driver', None)
69
+ host = params.pop('host')
70
+ port = params.pop('port')
71
+ user = params.pop('user', None)
72
+ password = params.pop('password', None)
73
+ database = params.pop('database', '')
74
+
75
+ if not driver:
76
+ driver = 'singlestoredb+mysql'
77
+ elif not driver.startswith('singlestoredb'):
78
+ driver = f'singlestoredb+{driver}'
79
+
80
+ if user is not None and password is not None:
81
+ url = f'{driver}://{quote(user)}:{quote(password)}@' \
82
+ f'{host}:{port}/{quote(database)}'
83
+ elif user is not None:
84
+ url = f'{driver}://{quote(user)}@{host}:{port}/{quote(database)}'
85
+ elif password is not None:
86
+ url = f'{driver}://:{quote(password)}@{host}:{port}/{quote(database)}'
87
+ else:
88
+ url = f'{driver}://{host}:{port}/{quote(database)}'
89
+
90
+ return sqlalchemy.create_engine(url, connect_args=params, **sa_params)
singlestoredb/auth.py CHANGED
@@ -1,6 +1,4 @@
1
1
  #!/usr/bin/env python
2
- from __future__ import annotations
3
-
4
2
  import datetime
5
3
  from typing import Any
6
4
  from typing import List
@@ -42,7 +40,7 @@ class JSONWebToken(object):
42
40
  self.timeout = timeout
43
41
 
44
42
  @classmethod
45
- def from_token(cls, token: bytes, verify_signature: bool = False) -> JSONWebToken:
43
+ def from_token(cls, token: bytes, verify_signature: bool = False) -> 'JSONWebToken':
46
44
  """Validate the contents of the JWT."""
47
45
  info = jwt.decode(token, options={'verify_signature': verify_signature})
48
46
 
@@ -185,10 +183,14 @@ def get_jwt(
185
183
  server = HTTPServer(('127.0.0.1', 0), AuthServer)
186
184
  threading.Thread(target=server.serve_forever).start()
187
185
 
186
+ host = server.server_address[0]
187
+ if isinstance(host, bytes):
188
+ host = host.decode('utf-8')
189
+
188
190
  query = urllib.parse.urlencode({
189
191
  k: v for k, v in dict(
190
192
  email=email,
191
- returnTo=f'http://{server.server_address[0]}:{server.server_address[1]}',
193
+ returnTo=f'http://{host}:{server.server_address[1]}',
192
194
  db=_listify(databases),
193
195
  cluster=_listify(clusters),
194
196
  ).items() if v is not None
singlestoredb/config.py CHANGED
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env python
2
2
  """SingleStoreDB package options."""
3
- from __future__ import annotations
4
-
5
3
  import functools
6
4
 
7
5
  from . import auth
8
6
  from .utils.config import check_bool # noqa: F401
7
+ from .utils.config import check_dict_str_str # noqa: F401
9
8
  from .utils.config import check_float # noqa: F401
10
9
  from .utils.config import check_int # noqa: F401
10
+ from .utils.config import check_optional_bool # noqa: F401
11
11
  from .utils.config import check_str # noqa: F401
12
12
  from .utils.config import check_url # noqa: F401
13
13
  from .utils.config import describe_option # noqa: F401
@@ -55,7 +55,7 @@ register_option(
55
55
  )
56
56
 
57
57
  register_option(
58
- 'driver', 'string', check_str, 'pymysql',
58
+ 'driver', 'string', check_str, 'mysql',
59
59
  'Specifies the Python DB-API module to use for communicating'
60
60
  'with the database.',
61
61
  environ='SINGLESTOREDB_DRIVER',
@@ -68,8 +68,13 @@ register_option(
68
68
  )
69
69
 
70
70
  register_option(
71
- 'pure_python', 'bool', check_bool, False,
72
- 'Should the driver use a pure Python implementation?',
71
+ 'pure_python', 'bool', check_optional_bool, None,
72
+ 'Should the driver use a pure Python implementation? If the value is '
73
+ '`None`, the C extension will be used if it exists, and pure python '
74
+ 'will be used otherwise. If the value is `False`, the pure python '
75
+ 'implementation will be used. If the value is `True` and the C extension '
76
+ 'exists, it will be used. If the value is `True` and the C extension '
77
+ 'doesn\'t exist or can\'t be loaded, a `NotSupportedError` is raised.',
73
78
  environ='SINGLESTOREDB_PURE_PYTHON',
74
79
  )
75
80
 
@@ -79,6 +84,12 @@ register_option(
79
84
  environ='SINGLESTOREDB_CHARSET',
80
85
  )
81
86
 
87
+ register_option(
88
+ 'encoding_errors', 'string', check_str, 'strict',
89
+ 'Specifies the error handling behavior for decoding string values.',
90
+ environ='SINGLESTOREDB_ENCODING_ERRORS',
91
+ )
92
+
82
93
  register_option(
83
94
  'local_infile', 'bool', check_bool, False,
84
95
  'Should it be possible to load local files?',
@@ -86,9 +97,9 @@ register_option(
86
97
  )
87
98
 
88
99
  register_option(
89
- 'odbc_driver', 'str', check_str, 'SingleStore ODBC 1.0 Unicode Driver',
90
- 'Name of the ODBC driver for ODBC connections',
91
- environ='SINGLESTOREDB_ODBC_DRIVER',
100
+ 'multi_statements', 'bool', check_bool, False,
101
+ 'Should it be possible use multiple statements in one query?',
102
+ environ='SINGLESTOREDB_MULTI_STATEMENTS',
92
103
  )
93
104
 
94
105
  register_option(
@@ -121,6 +132,28 @@ register_option(
121
132
  environ='SINGLESTOREDB_SSL_DISABLED',
122
133
  )
123
134
 
135
+ register_option(
136
+ 'ssl_verify_cert', 'bool', check_optional_bool, None,
137
+ 'Verify the server\'s certificate',
138
+ environ='SINGLESTOREDB_SSL_VERIFY_CERT',
139
+ )
140
+
141
+ register_option(
142
+ 'ssl_verify_identity', 'bool', check_optional_bool, None,
143
+ 'Verify the server\'s identity',
144
+ environ='SINGLESTOREDB_SSL_VERIFY_IDENTITY',
145
+ )
146
+
147
+ register_option(
148
+ 'program_name', 'string', check_str, None,
149
+ 'Name of the program',
150
+ )
151
+
152
+ register_option(
153
+ 'conn_attrs', 'dict', check_dict_str_str, None,
154
+ 'Additional connection attributes for telemetry',
155
+ )
156
+
124
157
  register_option(
125
158
  'credential_type', 'str',
126
159
  functools.partial(
@@ -148,35 +181,102 @@ register_option(
148
181
  environ='SINGLESTOREDB_AUTOCOMMIT',
149
182
  )
150
183
 
184
+ register_option(
185
+ 'buffered', 'bool', check_bool, True,
186
+ 'Should query results be buffered before processing?',
187
+ environ='SINGLESTOREDB_BUFFERED',
188
+ )
189
+
190
+ register_option(
191
+ 'connect_timeout', 'int', check_int, 10,
192
+ 'The timeout for connecting to the database in seconds. '
193
+ '(default: 10, min: 1, max: 31536000)',
194
+ environ='SINGLESTOREDB_CONNECT_TIMEOUT',
195
+ )
196
+
197
+ register_option(
198
+ 'nan_as_null', 'bool', check_bool, False,
199
+ 'Should NaN values be treated as NULLs in query parameter substitutions '
200
+ 'including uploaded data?',
201
+ environ='SINGLESTOREDB_NAN_AS_NULL',
202
+ )
203
+
204
+ register_option(
205
+ 'inf_as_null', 'bool', check_bool, False,
206
+ 'Should Inf values be treated as NULLs in query parameter substitutions '
207
+ 'including uploaded data?',
208
+ environ='SINGLESTOREDB_INF_AS_NULL',
209
+ )
210
+
211
+ register_option(
212
+ 'track_env', 'bool', check_bool, False,
213
+ 'Should connections track the SINGLESTOREDB_URL environment variable?',
214
+ environ='SINGLESTOREDB_TRACK_ENV',
215
+ )
216
+
217
+ register_option(
218
+ 'fusion.enabled', 'bool', check_bool, False,
219
+ 'Should Fusion SQL queries be enabled?',
220
+ environ='SINGLESTOREDB_FUSION_ENABLED',
221
+ )
222
+
151
223
  #
152
224
  # Query results options
153
225
  #
154
226
  register_option(
155
- 'results.format', 'string',
227
+ 'results.type', 'string',
156
228
  functools.partial(
157
229
  check_str,
158
230
  valid_values=[
159
- 'tuple', 'namedtuple',
160
- 'dict', 'dataframe',
231
+ 'tuple', 'tuples', 'namedtuple', 'namedtuples',
232
+ 'dict', 'dicts', 'structsequence', 'structsequences',
161
233
  ],
162
234
  ),
163
- 'tuple',
235
+ 'tuples',
164
236
  'What form should the query results take?',
165
- environ='SINGLESTOREDB_RESULTS_FORMAT',
237
+ environ='SINGLESTOREDB_RESULTS_TYPE',
166
238
  )
167
239
 
168
240
  register_option(
169
- 'results.arraysize', 'int', check_int, 100,
170
- 'Number of result rows to download in `fetchmany` calls',
241
+ 'results.arraysize', 'int', check_int, 1,
242
+ 'Number of result rows to download in `fetchmany` calls.',
171
243
  environ='SINGLESTOREDB_RESULTS_ARRAYSIZE',
172
244
  )
173
245
 
174
246
 
175
247
  #
176
- # Cluster manager options
248
+ # Workspace manager options
177
249
  #
178
250
  register_option(
179
251
  'management.token', 'string', check_str, None,
180
252
  'Specifies the authentication token for the management API.',
181
253
  environ=['SINGLESTOREDB_MANAGEMENT_TOKEN'],
182
254
  )
255
+
256
+ register_option(
257
+ 'management.base_url', 'string', check_str, 'https://api.singlestore.com',
258
+ 'Specifies the base URL for the management API.',
259
+ environ=['SINGLESTOREDB_MANAGEMENT_BASE_URL'],
260
+ )
261
+
262
+ register_option(
263
+ 'management.version', 'string', check_str, 'v1',
264
+ 'Specifies the version for the management API.',
265
+ environ=['SINGLESTOREDB_MANAGEMENT_VERSION'],
266
+ )
267
+
268
+
269
+ #
270
+ # Debugging options
271
+ #
272
+ register_option(
273
+ 'debug.queries', 'bool', check_bool, False,
274
+ 'Print queries and parameters to stderr.',
275
+ environ='SINGLESTOREDB_DEBUG_QUERIES',
276
+ )
277
+
278
+ register_option(
279
+ 'debug.connection', 'bool', check_bool, False,
280
+ 'Print connection tracing information.',
281
+ environ='SINGLESTOREDB_DEBUG_CONNECTION',
282
+ )