singlestoredb 0.4.0__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 (120) hide show
  1. singlestoredb/__init__.py +33 -1
  2. singlestoredb/alchemy/__init__.py +90 -0
  3. singlestoredb/auth.py +5 -1
  4. singlestoredb/config.py +116 -14
  5. singlestoredb/connection.py +483 -516
  6. singlestoredb/converters.py +238 -135
  7. singlestoredb/exceptions.py +30 -2
  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/stage.py +257 -0
  22. singlestoredb/fusion/handlers/utils.py +162 -0
  23. singlestoredb/fusion/handlers/workspace.py +412 -0
  24. singlestoredb/fusion/registry.py +164 -0
  25. singlestoredb/fusion/result.py +399 -0
  26. singlestoredb/http/__init__.py +27 -0
  27. singlestoredb/{http.py → http/connection.py} +555 -154
  28. singlestoredb/management/__init__.py +3 -0
  29. singlestoredb/management/billing_usage.py +148 -0
  30. singlestoredb/management/cluster.py +14 -6
  31. singlestoredb/management/manager.py +100 -38
  32. singlestoredb/management/organization.py +188 -0
  33. singlestoredb/management/region.py +5 -5
  34. singlestoredb/management/utils.py +251 -2
  35. singlestoredb/management/workspace.py +1149 -28
  36. singlestoredb/{clients/pymysqlsv → mysql}/__init__.py +16 -21
  37. singlestoredb/{clients/pymysqlsv → mysql}/_auth.py +39 -8
  38. singlestoredb/{clients/pymysqlsv → mysql}/charset.py +26 -23
  39. singlestoredb/{clients/pymysqlsv/connections.py → mysql/connection.py} +532 -165
  40. singlestoredb/{clients/pymysqlsv → mysql}/constants/CLIENT.py +0 -1
  41. singlestoredb/{clients/pymysqlsv → mysql}/constants/COMMAND.py +0 -1
  42. singlestoredb/{clients/pymysqlsv → mysql}/constants/CR.py +0 -2
  43. singlestoredb/{clients/pymysqlsv → mysql}/constants/ER.py +0 -1
  44. singlestoredb/{clients/pymysqlsv → mysql}/constants/FIELD_TYPE.py +1 -1
  45. singlestoredb/{clients/pymysqlsv → mysql}/constants/FLAG.py +0 -1
  46. singlestoredb/{clients/pymysqlsv → mysql}/constants/SERVER_STATUS.py +0 -1
  47. singlestoredb/mysql/converters.py +271 -0
  48. singlestoredb/{clients/pymysqlsv → mysql}/cursors.py +228 -112
  49. singlestoredb/mysql/err.py +92 -0
  50. singlestoredb/{clients/pymysqlsv → mysql}/optionfile.py +5 -4
  51. singlestoredb/{clients/pymysqlsv → mysql}/protocol.py +49 -20
  52. singlestoredb/mysql/tests/__init__.py +19 -0
  53. singlestoredb/{clients/pymysqlsv → mysql}/tests/base.py +32 -12
  54. singlestoredb/mysql/tests/conftest.py +37 -0
  55. singlestoredb/{clients/pymysqlsv → mysql}/tests/test_DictCursor.py +11 -7
  56. singlestoredb/{clients/pymysqlsv → mysql}/tests/test_SSCursor.py +17 -12
  57. singlestoredb/{clients/pymysqlsv → mysql}/tests/test_basic.py +32 -24
  58. singlestoredb/{clients/pymysqlsv → mysql}/tests/test_connection.py +130 -119
  59. singlestoredb/{clients/pymysqlsv → mysql}/tests/test_converters.py +9 -7
  60. singlestoredb/mysql/tests/test_cursor.py +141 -0
  61. singlestoredb/{clients/pymysqlsv → mysql}/tests/test_err.py +3 -2
  62. singlestoredb/{clients/pymysqlsv → mysql}/tests/test_issues.py +35 -27
  63. singlestoredb/{clients/pymysqlsv → mysql}/tests/test_load_local.py +13 -11
  64. singlestoredb/{clients/pymysqlsv → mysql}/tests/test_nextset.py +7 -3
  65. singlestoredb/{clients/pymysqlsv → mysql}/tests/test_optionfile.py +2 -1
  66. singlestoredb/{clients/pymysqlsv → mysql}/tests/thirdparty/__init__.py +1 -1
  67. singlestoredb/mysql/tests/thirdparty/test_MySQLdb/__init__.py +9 -0
  68. singlestoredb/{clients/pymysqlsv → mysql}/tests/thirdparty/test_MySQLdb/capabilities.py +19 -17
  69. singlestoredb/{clients/pymysqlsv → mysql}/tests/thirdparty/test_MySQLdb/dbapi20.py +31 -22
  70. singlestoredb/{clients/pymysqlsv → mysql}/tests/thirdparty/test_MySQLdb/test_MySQLdb_capabilities.py +3 -4
  71. singlestoredb/{clients/pymysqlsv → mysql}/tests/thirdparty/test_MySQLdb/test_MySQLdb_dbapi20.py +24 -20
  72. singlestoredb/{clients/pymysqlsv → mysql}/tests/thirdparty/test_MySQLdb/test_MySQLdb_nonstandard.py +4 -4
  73. singlestoredb/{clients/pymysqlsv → mysql}/times.py +3 -4
  74. singlestoredb/pytest.py +283 -0
  75. singlestoredb/tests/empty.sql +0 -0
  76. singlestoredb/tests/ext_funcs/__init__.py +385 -0
  77. singlestoredb/tests/test.sql +210 -0
  78. singlestoredb/tests/test2.sql +1 -0
  79. singlestoredb/tests/test_basics.py +482 -115
  80. singlestoredb/tests/test_config.py +13 -13
  81. singlestoredb/tests/test_connection.py +241 -305
  82. singlestoredb/tests/test_dbapi.py +27 -0
  83. singlestoredb/tests/test_ext_func.py +1193 -0
  84. singlestoredb/tests/test_ext_func_data.py +1101 -0
  85. singlestoredb/tests/test_fusion.py +465 -0
  86. singlestoredb/tests/test_http.py +32 -26
  87. singlestoredb/tests/test_management.py +588 -8
  88. singlestoredb/tests/test_plugin.py +33 -0
  89. singlestoredb/tests/test_results.py +11 -12
  90. singlestoredb/tests/test_udf.py +687 -0
  91. singlestoredb/tests/utils.py +3 -2
  92. singlestoredb/utils/config.py +58 -0
  93. singlestoredb/utils/debug.py +13 -0
  94. singlestoredb/utils/mogrify.py +151 -0
  95. singlestoredb/utils/results.py +4 -1
  96. singlestoredb-1.0.3.dist-info/METADATA +139 -0
  97. singlestoredb-1.0.3.dist-info/RECORD +112 -0
  98. {singlestoredb-0.4.0.dist-info → singlestoredb-1.0.3.dist-info}/WHEEL +1 -1
  99. singlestoredb-1.0.3.dist-info/entry_points.txt +2 -0
  100. singlestoredb/clients/pymysqlsv/converters.py +0 -365
  101. singlestoredb/clients/pymysqlsv/err.py +0 -144
  102. singlestoredb/clients/pymysqlsv/tests/__init__.py +0 -19
  103. singlestoredb/clients/pymysqlsv/tests/test_cursor.py +0 -133
  104. singlestoredb/clients/pymysqlsv/tests/thirdparty/test_MySQLdb/__init__.py +0 -9
  105. singlestoredb/drivers/__init__.py +0 -45
  106. singlestoredb/drivers/base.py +0 -198
  107. singlestoredb/drivers/cymysql.py +0 -38
  108. singlestoredb/drivers/http.py +0 -47
  109. singlestoredb/drivers/mariadb.py +0 -40
  110. singlestoredb/drivers/mysqlconnector.py +0 -49
  111. singlestoredb/drivers/mysqldb.py +0 -60
  112. singlestoredb/drivers/pymysql.py +0 -37
  113. singlestoredb/drivers/pymysqlsv.py +0 -35
  114. singlestoredb/drivers/pyodbc.py +0 -65
  115. singlestoredb-0.4.0.dist-info/METADATA +0 -111
  116. singlestoredb-0.4.0.dist-info/RECORD +0 -86
  117. /singlestoredb/{clients → fusion/handlers}/__init__.py +0 -0
  118. /singlestoredb/{clients/pymysqlsv → mysql}/constants/__init__.py +0 -0
  119. {singlestoredb-0.4.0.dist-info → singlestoredb-1.0.3.dist-info}/LICENSE +0 -0
  120. {singlestoredb-0.4.0.dist-info → singlestoredb-1.0.3.dist-info}/top_level.txt +0 -0
singlestoredb/__init__.py CHANGED
@@ -13,7 +13,9 @@ Examples
13
13
 
14
14
  """
15
15
 
16
- __version__ = '0.4.0'
16
+ __version__ = '1.0.3'
17
+
18
+ from typing import Any
17
19
 
18
20
  from .config import options, get_option, set_option, describe_option
19
21
  from .connection import connect, apilevel, threadsafety, paramstyle
@@ -29,3 +31,33 @@ from .types import (
29
31
  Date, Time, Timestamp, DateFromTicks, TimeFromTicks, TimestampFromTicks,
30
32
  Binary, STRING, BINARY, NUMBER, DATETIME, ROWID,
31
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
@@ -183,10 +183,14 @@ def get_jwt(
183
183
  server = HTTPServer(('127.0.0.1', 0), AuthServer)
184
184
  threading.Thread(target=server.serve_forever).start()
185
185
 
186
+ host = server.server_address[0]
187
+ if isinstance(host, bytes):
188
+ host = host.decode('utf-8')
189
+
186
190
  query = urllib.parse.urlencode({
187
191
  k: v for k, v in dict(
188
192
  email=email,
189
- returnTo=f'http://{server.server_address[0]}:{server.server_address[1]}',
193
+ returnTo=f'http://{host}:{server.server_address[1]}',
190
194
  db=_listify(databases),
191
195
  cluster=_listify(clusters),
192
196
  ).items() if v is not None
singlestoredb/config.py CHANGED
@@ -4,8 +4,10 @@ import functools
4
4
 
5
5
  from . import auth
6
6
  from .utils.config import check_bool # noqa: F401
7
+ from .utils.config import check_dict_str_str # noqa: F401
7
8
  from .utils.config import check_float # noqa: F401
8
9
  from .utils.config import check_int # noqa: F401
10
+ from .utils.config import check_optional_bool # noqa: F401
9
11
  from .utils.config import check_str # noqa: F401
10
12
  from .utils.config import check_url # noqa: F401
11
13
  from .utils.config import describe_option # noqa: F401
@@ -53,7 +55,7 @@ register_option(
53
55
  )
54
56
 
55
57
  register_option(
56
- 'driver', 'string', check_str, 'pymysqlsv',
58
+ 'driver', 'string', check_str, 'mysql',
57
59
  'Specifies the Python DB-API module to use for communicating'
58
60
  'with the database.',
59
61
  environ='SINGLESTOREDB_DRIVER',
@@ -66,8 +68,13 @@ register_option(
66
68
  )
67
69
 
68
70
  register_option(
69
- 'pure_python', 'bool', check_bool, False,
70
- '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.',
71
78
  environ='SINGLESTOREDB_PURE_PYTHON',
72
79
  )
73
80
 
@@ -77,6 +84,12 @@ register_option(
77
84
  environ='SINGLESTOREDB_CHARSET',
78
85
  )
79
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
+
80
93
  register_option(
81
94
  'local_infile', 'bool', check_bool, False,
82
95
  'Should it be possible to load local files?',
@@ -84,9 +97,9 @@ register_option(
84
97
  )
85
98
 
86
99
  register_option(
87
- 'odbc_driver', 'str', check_str, 'SingleStore ODBC 1.0 Unicode Driver',
88
- 'Name of the ODBC driver for ODBC connections',
89
- 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',
90
103
  )
91
104
 
92
105
  register_option(
@@ -119,6 +132,28 @@ register_option(
119
132
  environ='SINGLESTOREDB_SSL_DISABLED',
120
133
  )
121
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
+
122
157
  register_option(
123
158
  'credential_type', 'str',
124
159
  functools.partial(
@@ -146,35 +181,102 @@ register_option(
146
181
  environ='SINGLESTOREDB_AUTOCOMMIT',
147
182
  )
148
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
+
149
223
  #
150
224
  # Query results options
151
225
  #
152
226
  register_option(
153
- 'results.format', 'string',
227
+ 'results.type', 'string',
154
228
  functools.partial(
155
229
  check_str,
156
230
  valid_values=[
157
- 'tuple', 'namedtuple',
158
- 'dict', 'dataframe',
231
+ 'tuple', 'tuples', 'namedtuple', 'namedtuples',
232
+ 'dict', 'dicts', 'structsequence', 'structsequences',
159
233
  ],
160
234
  ),
161
- 'tuple',
235
+ 'tuples',
162
236
  'What form should the query results take?',
163
- environ='SINGLESTOREDB_RESULTS_FORMAT',
237
+ environ='SINGLESTOREDB_RESULTS_TYPE',
164
238
  )
165
239
 
166
240
  register_option(
167
- 'results.arraysize', 'int', check_int, 100,
168
- '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.',
169
243
  environ='SINGLESTOREDB_RESULTS_ARRAYSIZE',
170
244
  )
171
245
 
172
246
 
173
247
  #
174
- # Cluster manager options
248
+ # Workspace manager options
175
249
  #
176
250
  register_option(
177
251
  'management.token', 'string', check_str, None,
178
252
  'Specifies the authentication token for the management API.',
179
253
  environ=['SINGLESTOREDB_MANAGEMENT_TOKEN'],
180
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
+ )