singlestoredb 0.4.0__py3-none-any.whl → 1.0.4__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 +281 -2
  35. singlestoredb/management/workspace.py +1344 -49
  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.4.dist-info/METADATA +139 -0
  97. singlestoredb-1.0.4.dist-info/RECORD +112 -0
  98. {singlestoredb-0.4.0.dist-info → singlestoredb-1.0.4.dist-info}/WHEEL +1 -1
  99. singlestoredb-1.0.4.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.4.dist-info}/LICENSE +0 -0
  120. {singlestoredb-0.4.0.dist-info → singlestoredb-1.0.4.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,3 @@
1
- # type: ignore
2
1
  """
3
2
  PyMySQL: A pure-Python MySQL client library.
4
3
 
@@ -23,6 +22,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
22
  THE SOFTWARE.
24
23
  """
25
24
  import sys
25
+ from typing import Any
26
+ from typing import FrozenSet
26
27
 
27
28
  from .constants import FIELD_TYPE
28
29
  from .err import DatabaseError
@@ -44,32 +45,28 @@ from .times import Timestamp
44
45
  from .times import TimestampFromTicks
45
46
 
46
47
 
47
- VERSION = (1, 0, 2, None)
48
- if VERSION[3] is not None:
49
- VERSION_STRING = '%d.%d.%d_%s' % VERSION
50
- else:
51
- VERSION_STRING = '%d.%d.%d' % VERSION[:3]
52
48
  threadsafety = 1
53
49
  apilevel = '2.0'
54
50
  paramstyle = 'pyformat'
55
51
 
56
- from . import connections # noqa: E402
52
+ from . import connection # noqa: E402
57
53
 
58
54
 
59
- class DBAPISet(frozenset):
60
- def __ne__(self, other):
55
+ class DBAPISet(FrozenSet[Any]):
56
+
57
+ def __ne__(self, other: Any) -> bool:
61
58
  if isinstance(other, set):
62
59
  return frozenset.__ne__(self, other)
63
60
  else:
64
61
  return other not in self
65
62
 
66
- def __eq__(self, other):
63
+ def __eq__(self, other: Any) -> bool:
67
64
  if isinstance(other, frozenset):
68
65
  return frozenset.__eq__(self, other)
69
66
  else:
70
67
  return other in self
71
68
 
72
- def __hash__(self):
69
+ def __hash__(self) -> int:
73
70
  return frozenset.__hash__(self)
74
71
 
75
72
 
@@ -101,19 +98,17 @@ DATETIME = TIMESTAMP
101
98
  ROWID = DBAPISet()
102
99
 
103
100
 
104
- def Binary(x):
101
+ def Binary(x: Any) -> bytes:
105
102
  """Return x as a binary type."""
106
103
  return bytes(x)
107
104
 
108
105
 
109
- Connect = connect = Connection = connections.Connection
106
+ Connect = connect = Connection = connection.Connection # type: ignore
110
107
 
111
108
 
112
- def get_client_info(): # for MySQLdb compatibility
113
- version = VERSION
114
- if VERSION[3] is None:
115
- version = VERSION[:3]
116
- return '.'.join(map(str, version))
109
+ def get_client_info() -> str: # for MySQLdb compatibility
110
+ from .. import __version__
111
+ return __version__
117
112
 
118
113
 
119
114
  # we include a doctored version_info here for MySQLdb compatibility
@@ -124,11 +119,11 @@ NULL = 'NULL'
124
119
  __version__ = get_client_info()
125
120
 
126
121
 
127
- def thread_safe():
122
+ def thread_safe() -> bool:
128
123
  return True # match MySQLdb.thread_safe()
129
124
 
130
125
 
131
- def install_as_MySQLdb():
126
+ def install_as_MySQLdb() -> None:
132
127
  """
133
128
  After this function is called, any application that imports MySQLdb or
134
129
  _mysql will unwittingly actually use pymysql.
@@ -169,7 +164,7 @@ __all__ = [
169
164
  'Warning',
170
165
  'apilevel',
171
166
  'connect',
172
- 'connections',
167
+ 'connection',
173
168
  'constants',
174
169
  'converters',
175
170
  'cursors',
@@ -4,7 +4,6 @@ Implements auth methods
4
4
  """
5
5
  from .err import OperationalError
6
6
 
7
-
8
7
  try:
9
8
  from cryptography.hazmat.backends import default_backend
10
9
  from cryptography.hazmat.primitives import serialization, hashes
@@ -17,8 +16,10 @@ except ImportError:
17
16
  from functools import partial
18
17
  import hashlib
19
18
 
19
+ from ..config import get_option
20
+
20
21
 
21
- DEBUG = False
22
+ DEBUG = get_option('debug.connection')
22
23
  SCRAMBLE_LENGTH = 20
23
24
  sha1_new = partial(hashlib.new, 'sha1')
24
25
 
@@ -28,7 +29,7 @@ sha1_new = partial(hashlib.new, 'sha1')
28
29
 
29
30
 
30
31
  def scramble_native_password(password, message):
31
- """Scramble used for mysql_native_password"""
32
+ """Scramble used for mysql_native_password."""
32
33
  if not password:
33
34
  return b''
34
35
 
@@ -76,9 +77,11 @@ def _scalar_clamp(s32):
76
77
 
77
78
 
78
79
  def ed25519_password(password, scramble):
79
- """Sign a random scramble with elliptic curve Ed25519.
80
+ """
81
+ Sign a random scramble with elliptic curve Ed25519.
80
82
 
81
83
  Secret and public key are derived from password.
84
+
82
85
  """
83
86
  # variable names based on rfc8032 section-5.1.6
84
87
  #
@@ -125,7 +128,8 @@ def _roundtrip(conn, send_data):
125
128
 
126
129
  def _xor_password(password, salt):
127
130
  # Trailing NUL character will be added in Auth Switch Request.
128
- # See https://github.com/mysql/mysql-server/blob/7d10c82196c8e45554f27c00681474a9fb86d137/sql/auth/sha2_password.cc#L939-L945
131
+ # See https://github.com/mysql/mysql-server/blob/
132
+ # 7d10c82196c8e45554f27c00681474a9fb86d137/sql/auth/sha2_password.cc#L939-L945
129
133
  salt = salt[:SCRAMBLE_LENGTH]
130
134
  password_bytes = bytearray(password)
131
135
  # salt = bytearray(salt) # for PY2 compat.
@@ -136,13 +140,16 @@ def _xor_password(password, salt):
136
140
 
137
141
 
138
142
  def sha2_rsa_encrypt(password, salt, public_key):
139
- """Encrypt password with salt and public_key.
143
+ """
144
+ Encrypt password with salt and public_key.
140
145
 
141
146
  Used for sha256_password and caching_sha2_password.
147
+
142
148
  """
143
149
  if not _have_cryptography:
144
150
  raise RuntimeError(
145
- "'cryptography' package is required for sha256_password or caching_sha2_password auth methods",
151
+ "'cryptography' package is required for sha256_password or "
152
+ 'caching_sha2_password auth methods',
146
153
  )
147
154
  message = _xor_password(password + b'\0', salt)
148
155
  rsa_key = serialization.load_pem_public_key(public_key, default_backend())
@@ -189,9 +196,11 @@ def sha256_password_auth(conn, pkt):
189
196
 
190
197
  def scramble_caching_sha2(password, nonce):
191
198
  # (bytes, bytes) -> bytes
192
- """Scramble algorithm used in cached_sha2_password fast path.
199
+ """
200
+ Scramble algorithm used in cached_sha2_password fast path.
193
201
 
194
202
  XOR(SHA256(password), SHA256(SHA256(SHA256(password)), nonce))
203
+
195
204
  """
196
205
  if not password:
197
206
  return b''
@@ -265,3 +274,25 @@ def caching_sha2_password_auth(conn, pkt):
265
274
 
266
275
  data = sha2_rsa_encrypt(conn.password, conn.salt, conn.server_public_key)
267
276
  pkt = _roundtrip(conn, data)
277
+
278
+
279
+ def gssapi_auth(data):
280
+ try:
281
+ import gssapi.raw
282
+ except ImportError:
283
+ raise ImportError(
284
+ 'The `gssapi` package must be '
285
+ 'installed for Kerberos authentication',
286
+ )
287
+
288
+ ctx = None
289
+ try:
290
+ ctx = gssapi.raw.init_sec_context(
291
+ gssapi.raw.import_name(data, gssapi.raw.NameType.user),
292
+ flags=[0], lifetime=0,
293
+ )
294
+ return ctx.token
295
+
296
+ finally:
297
+ if ctx is not None:
298
+ gssapi.raw.delete_sec_context(ctx.context)
@@ -1,14 +1,16 @@
1
- # type: ignore
1
+ from typing import Dict
2
+ from typing import Optional
2
3
 
3
4
  MBLENGTH = {8: 1, 33: 3, 88: 2, 91: 2}
4
5
 
5
6
 
6
7
  class Charset:
7
- def __init__(self, id, name, collation, is_default):
8
+
9
+ def __init__(self, id: int, name: str, collation: str, is_default: str):
8
10
  self.id, self.name, self.collation = id, name, collation
9
11
  self.is_default = is_default == 'Yes'
10
12
 
11
- def __repr__(self):
13
+ def __repr__(self) -> str:
12
14
  return 'Charset(id=%s, name=%r, collation=%r)' % (
13
15
  self.id,
14
16
  self.name,
@@ -16,7 +18,7 @@ class Charset:
16
18
  )
17
19
 
18
20
  @property
19
- def encoding(self):
21
+ def encoding(self) -> str:
20
22
  name = self.name
21
23
  if name in ('utf8mb4', 'utf8mb3'):
22
24
  return 'utf8'
@@ -29,40 +31,41 @@ class Charset:
29
31
  return name
30
32
 
31
33
  @property
32
- def is_binary(self):
34
+ def is_binary(self) -> bool:
33
35
  return self.id == 63
34
36
 
35
37
 
36
38
  class Charsets:
37
- def __init__(self):
38
- self._by_id = {}
39
- self._by_name = {}
40
39
 
41
- def add(self, c):
40
+ def __init__(self) -> None:
41
+ self._by_id: Dict[int, Charset] = {}
42
+ self._by_name: Dict[str, Charset] = {}
43
+
44
+ def add(self, c: Charset) -> None:
42
45
  self._by_id[c.id] = c
43
46
  if c.is_default:
44
47
  self._by_name[c.name] = c
45
48
 
46
- def by_id(self, id):
49
+ def by_id(self, id: int) -> Charset:
47
50
  return self._by_id[id]
48
51
 
49
- def by_name(self, name):
52
+ def by_name(self, name: str) -> Optional[Charset]:
50
53
  return self._by_name.get(name.lower())
51
54
 
52
55
 
53
56
  _charsets = Charsets()
54
- """
55
- Generated with:
56
-
57
- mysql -N -s -e "select id, character_set_name, collation_name, is_default
58
- from information_schema.collations order by id;" | python -c "import sys
59
- for l in sys.stdin.readlines():
60
- id, name, collation, is_default = l.split(chr(9))
61
- print '_charsets.add(Charset(%s, \'%s\', \'%s\', \'%s\'))' \
62
- % (id, name, collation, is_default.strip())
63
- "
64
-
65
- """
57
+
58
+ # Generated with:
59
+ #
60
+ # mysql -N -s -e "select id, character_set_name, collation_name, is_default
61
+ # from information_schema.collations order by id;" | python -c "import sys
62
+ # for l in sys.stdin.readlines():
63
+ # id, name, collation, is_default = l.split(chr(9))
64
+ # print '_charsets.add(Charset(%s, \'%s\', \'%s\', \'%s\'))' \
65
+ # % (id, name, collation, is_default.strip())
66
+ # "
67
+ #
68
+ #
66
69
  _charsets.add(Charset(1, 'big5', 'big5_chinese_ci', 'Yes'))
67
70
  _charsets.add(Charset(2, 'latin2', 'latin2_czech_cs', ''))
68
71
  _charsets.add(Charset(3, 'dec8', 'dec8_swedish_ci', 'Yes'))