MindsDB 25.8.3.0__py3-none-any.whl → 25.9.1.0__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 MindsDB might be problematic. Click here for more details.

Files changed (94) hide show
  1. mindsdb/__about__.py +1 -1
  2. mindsdb/__main__.py +2 -44
  3. mindsdb/api/a2a/__init__.py +52 -0
  4. mindsdb/api/a2a/agent.py +11 -12
  5. mindsdb/api/a2a/common/server/server.py +17 -36
  6. mindsdb/api/a2a/common/server/task_manager.py +14 -28
  7. mindsdb/api/a2a/task_manager.py +20 -21
  8. mindsdb/api/a2a/utils.py +1 -1
  9. mindsdb/api/common/middleware.py +106 -0
  10. mindsdb/api/http/initialize.py +13 -15
  11. mindsdb/api/http/namespaces/auth.py +6 -14
  12. mindsdb/api/http/namespaces/config.py +0 -2
  13. mindsdb/api/http/namespaces/default.py +74 -106
  14. mindsdb/api/http/start.py +25 -44
  15. mindsdb/api/litellm/start.py +11 -10
  16. mindsdb/api/mcp/__init__.py +165 -0
  17. mindsdb/api/mysql/mysql_proxy/mysql_proxy.py +33 -64
  18. mindsdb/api/postgres/postgres_proxy/postgres_proxy.py +86 -85
  19. mindsdb/integrations/handlers/crate_handler/crate_handler.py +3 -7
  20. mindsdb/integrations/handlers/derby_handler/derby_handler.py +32 -34
  21. mindsdb/integrations/handlers/documentdb_handler/requirements.txt +1 -0
  22. mindsdb/integrations/handlers/dummy_data_handler/dummy_data_handler.py +12 -13
  23. mindsdb/integrations/handlers/google_books_handler/google_books_handler.py +45 -44
  24. mindsdb/integrations/handlers/google_calendar_handler/google_calendar_handler.py +101 -95
  25. mindsdb/integrations/handlers/google_content_shopping_handler/google_content_shopping_handler.py +129 -129
  26. mindsdb/integrations/handlers/google_fit_handler/google_fit_handler.py +59 -43
  27. mindsdb/integrations/handlers/google_search_handler/google_search_handler.py +38 -39
  28. mindsdb/integrations/handlers/informix_handler/informix_handler.py +5 -18
  29. mindsdb/integrations/handlers/maxdb_handler/maxdb_handler.py +22 -28
  30. mindsdb/integrations/handlers/monetdb_handler/monetdb_handler.py +3 -7
  31. mindsdb/integrations/handlers/mongodb_handler/mongodb_handler.py +53 -67
  32. mindsdb/integrations/handlers/mongodb_handler/requirements.txt +1 -0
  33. mindsdb/{api/mongo/utilities → integrations/handlers/mongodb_handler/utils}/mongodb_ast.py +43 -68
  34. mindsdb/{api/mongo/utilities → integrations/handlers/mongodb_handler/utils}/mongodb_parser.py +17 -25
  35. mindsdb/{api/mongo/utilities → integrations/handlers/mongodb_handler/utils}/mongodb_query.py +10 -16
  36. mindsdb/integrations/handlers/mongodb_handler/utils/mongodb_render.py +43 -69
  37. mindsdb/integrations/libs/base.py +1 -1
  38. mindsdb/interfaces/agents/constants.py +1 -0
  39. mindsdb/interfaces/knowledge_base/controller.py +3 -1
  40. mindsdb/utilities/config.py +3 -155
  41. mindsdb/utilities/log.py +0 -25
  42. mindsdb/utilities/starters.py +0 -39
  43. {mindsdb-25.8.3.0.dist-info → mindsdb-25.9.1.0.dist-info}/METADATA +263 -261
  44. {mindsdb-25.8.3.0.dist-info → mindsdb-25.9.1.0.dist-info}/RECORD +47 -91
  45. mindsdb/api/a2a/__main__.py +0 -144
  46. mindsdb/api/a2a/run_a2a.py +0 -86
  47. mindsdb/api/common/check_auth.py +0 -42
  48. mindsdb/api/http/gunicorn_wrapper.py +0 -17
  49. mindsdb/api/mcp/start.py +0 -205
  50. mindsdb/api/mongo/__init__.py +0 -0
  51. mindsdb/api/mongo/classes/__init__.py +0 -5
  52. mindsdb/api/mongo/classes/query_sql.py +0 -19
  53. mindsdb/api/mongo/classes/responder.py +0 -45
  54. mindsdb/api/mongo/classes/responder_collection.py +0 -34
  55. mindsdb/api/mongo/classes/scram.py +0 -86
  56. mindsdb/api/mongo/classes/session.py +0 -23
  57. mindsdb/api/mongo/functions/__init__.py +0 -19
  58. mindsdb/api/mongo/responders/__init__.py +0 -73
  59. mindsdb/api/mongo/responders/add_shard.py +0 -13
  60. mindsdb/api/mongo/responders/aggregate.py +0 -90
  61. mindsdb/api/mongo/responders/buildinfo.py +0 -17
  62. mindsdb/api/mongo/responders/coll_stats.py +0 -63
  63. mindsdb/api/mongo/responders/company_id.py +0 -25
  64. mindsdb/api/mongo/responders/connection_status.py +0 -22
  65. mindsdb/api/mongo/responders/count.py +0 -21
  66. mindsdb/api/mongo/responders/db_stats.py +0 -32
  67. mindsdb/api/mongo/responders/delete.py +0 -105
  68. mindsdb/api/mongo/responders/describe.py +0 -23
  69. mindsdb/api/mongo/responders/end_sessions.py +0 -13
  70. mindsdb/api/mongo/responders/find.py +0 -175
  71. mindsdb/api/mongo/responders/get_cmd_line_opts.py +0 -18
  72. mindsdb/api/mongo/responders/get_free_monitoring_status.py +0 -14
  73. mindsdb/api/mongo/responders/get_parameter.py +0 -23
  74. mindsdb/api/mongo/responders/getlog.py +0 -14
  75. mindsdb/api/mongo/responders/host_info.py +0 -28
  76. mindsdb/api/mongo/responders/insert.py +0 -270
  77. mindsdb/api/mongo/responders/is_master.py +0 -20
  78. mindsdb/api/mongo/responders/is_master_lower.py +0 -13
  79. mindsdb/api/mongo/responders/list_collections.py +0 -55
  80. mindsdb/api/mongo/responders/list_databases.py +0 -37
  81. mindsdb/api/mongo/responders/list_indexes.py +0 -22
  82. mindsdb/api/mongo/responders/ping.py +0 -13
  83. mindsdb/api/mongo/responders/recv_chunk_start.py +0 -13
  84. mindsdb/api/mongo/responders/replsetgetstatus.py +0 -13
  85. mindsdb/api/mongo/responders/sasl_continue.py +0 -34
  86. mindsdb/api/mongo/responders/sasl_start.py +0 -33
  87. mindsdb/api/mongo/responders/update_range_deletions.py +0 -12
  88. mindsdb/api/mongo/responders/whatsmyuri.py +0 -18
  89. mindsdb/api/mongo/server.py +0 -388
  90. mindsdb/api/mongo/start.py +0 -15
  91. mindsdb/api/mongo/utilities/__init__.py +0 -0
  92. {mindsdb-25.8.3.0.dist-info → mindsdb-25.9.1.0.dist-info}/WHEEL +0 -0
  93. {mindsdb-25.8.3.0.dist-info → mindsdb-25.9.1.0.dist-info}/licenses/LICENSE +0 -0
  94. {mindsdb-25.8.3.0.dist-info → mindsdb-25.9.1.0.dist-info}/top_level.txt +0 -0
@@ -14,17 +14,38 @@ from mindsdb.api.executor.controllers import SessionController
14
14
  from mindsdb.api.postgres.postgres_proxy.executor import Executor
15
15
  from mindsdb.api.mysql.mysql_proxy.libs.constants.mysql import CHARSET_NUMBERS
16
16
  from mindsdb.api.executor.data_types.response_type import RESPONSE_TYPE
17
- from mindsdb.api.common.check_auth import check_auth
17
+ from mindsdb.api.common.middleware import check_auth
18
18
  from mindsdb.api.mysql.mysql_proxy.mysql_proxy import SQLAnswer
19
19
  from mindsdb.api.postgres.postgres_proxy.postgres_packets.errors import POSTGRES_SYNTAX_ERROR_CODE
20
20
  from mindsdb.api.postgres.postgres_proxy.postgres_packets.postgres_fields import GenericField, PostgresField
21
- from mindsdb.api.postgres.postgres_proxy.postgres_packets.postgres_message_formats import Terminate, \
22
- Query, AuthenticationClearTextPassword, AuthenticationOk, RowDescriptions, DataRow, CommandComplete, \
23
- ReadyForQuery, ConnectionFailure, ParameterStatus, Error, Execute, Bind, Parse, Sync, ParseComplete, \
24
- InvalidSQLStatementName, BindComplete, Describe, DataException, ParameterDescription
21
+ from mindsdb.api.postgres.postgres_proxy.postgres_packets.postgres_message_formats import (
22
+ Terminate,
23
+ Query,
24
+ AuthenticationClearTextPassword,
25
+ AuthenticationOk,
26
+ RowDescriptions,
27
+ DataRow,
28
+ CommandComplete,
29
+ ReadyForQuery,
30
+ ConnectionFailure,
31
+ ParameterStatus,
32
+ Error,
33
+ Execute,
34
+ Bind,
35
+ Parse,
36
+ Sync,
37
+ ParseComplete,
38
+ InvalidSQLStatementName,
39
+ BindComplete,
40
+ Describe,
41
+ DataException,
42
+ ParameterDescription,
43
+ )
25
44
  from mindsdb.api.postgres.postgres_proxy.postgres_packets.postgres_message import PostgresMessage
26
- from mindsdb.api.postgres.postgres_proxy.postgres_packets.postgres_packets import PostgresPacketReader, \
27
- PostgresPacketBuilder
45
+ from mindsdb.api.postgres.postgres_proxy.postgres_packets.postgres_packets import (
46
+ PostgresPacketReader,
47
+ PostgresPacketBuilder,
48
+ )
28
49
  from mindsdb.api.postgres.postgres_proxy.utilities import strip_null_byte
29
50
  from mindsdb.utilities.config import config
30
51
  from mindsdb.utilities.context import context as ctx
@@ -38,8 +59,8 @@ class PostgresProxyHandler(socketserver.StreamRequestHandler):
38
59
 
39
60
  def __init__(self, request, client_address, server):
40
61
  self.logger = log.getLogger(__name__)
41
- self.charset = 'utf8'
42
- self.charset_text_type = CHARSET_NUMBERS['utf8_general_ci']
62
+ self.charset = "utf8"
63
+ self.charset_text_type = CHARSET_NUMBERS["utf8_general_ci"]
43
64
  self.session = None
44
65
  self.client_capabilities = None
45
66
  self.user_parameters = None
@@ -48,17 +69,16 @@ class PostgresProxyHandler(socketserver.StreamRequestHandler):
48
69
  self.is_cloud = False
49
70
  self.named_portals = {}
50
71
  self.unnamed_portal = None
51
- self.transaction_status = b'I' # I: Idle, T: Transaction Block, E: Failed Transaction Block
72
+ self.transaction_status = b"I" # I: Idle, T: Transaction Block, E: Failed Transaction Block
52
73
  super().__init__(request, client_address, server)
53
74
 
54
75
  def handle(self) -> None:
55
-
56
76
  ctx.set_default()
57
77
  self.init_session()
58
- self.logger.debug('handle new incoming connection')
78
+ self.logger.debug("handle new incoming connection")
59
79
  cloud_connection = self.is_cloud_connection()
60
80
  if cloud_connection["is_cloud"]:
61
- ctx.company_id = cloud_connection.get('company_id')
81
+ ctx.company_id = cloud_connection.get("company_id")
62
82
  self.is_cloud = True
63
83
 
64
84
  self.message_map: Dict[Type[PostgresMessage], Callable[[Any], bool]] = {
@@ -68,7 +88,7 @@ class PostgresProxyHandler(socketserver.StreamRequestHandler):
68
88
  Bind: self.bind,
69
89
  Execute: self.execute,
70
90
  Describe: self.describe,
71
- Sync: self.sync
91
+ Sync: self.sync,
72
92
  }
73
93
  self.client_buffer = PostgresPacketReader(self.rfile)
74
94
  if self.is_cloud:
@@ -83,69 +103,59 @@ class PostgresProxyHandler(socketserver.StreamRequestHandler):
83
103
  self.main_loop()
84
104
 
85
105
  def is_cloud_connection(self):
86
- """ Determine source of connection. Must be call before handshake.
87
- Idea based on: real mysql connection does not send anything before server handshake, so
88
- socket should be in 'out' state. In opposite, clout connection sends '0000' right after
89
- connection. '0000' selected because in real mysql connection it should be length of package,
90
- and it can not be 0.
91
-
92
- Copied from mysql_proxy
93
- TODO: Extract method into common
94
- """
95
- is_cloud = config.get('cloud', False)
96
-
97
- if sys.platform != 'linux' or is_cloud is False:
98
- return {
99
- 'is_cloud': False
100
- }
106
+ """Determine source of connection. Must be call before handshake.
107
+ Idea based on: real mysql connection does not send anything before server handshake, so
108
+ socket should be in 'out' state. In opposite, clout connection sends '0000' right after
109
+ connection. '0000' selected because in real mysql connection it should be length of package,
110
+ and it can not be 0.
111
+
112
+ Copied from mysql_proxy
113
+ TODO: Extract method into common
114
+ """
115
+ is_cloud = config.get("cloud", False)
116
+
117
+ if sys.platform != "linux" or is_cloud is False:
118
+ return {"is_cloud": False}
101
119
 
102
120
  read_poller = select.poll()
103
121
  read_poller.register(self.request, select.POLLIN)
104
122
  events = read_poller.poll(30)
105
123
 
106
124
  if len(events) == 0:
107
- return {
108
- 'is_cloud': False
109
- }
125
+ return {"is_cloud": False}
110
126
 
111
127
  first_byte = self.request.recv(4, socket.MSG_PEEK)
112
- if first_byte == b'\x00\x00\x00\x00':
128
+ if first_byte == b"\x00\x00\x00\x00":
113
129
  self.request.recv(4)
114
130
  client_capabilities = self.request.recv(8)
115
- client_capabilities = struct.unpack('L', client_capabilities)[0]
131
+ client_capabilities = struct.unpack("L", client_capabilities)[0]
116
132
 
117
133
  company_id = self.request.recv(4)
118
- company_id = struct.unpack('I', company_id)[0]
134
+ company_id = struct.unpack("I", company_id)[0]
119
135
 
120
136
  user_class = self.request.recv(1)
121
- user_class = struct.unpack('B', user_class)[0]
137
+ user_class = struct.unpack("B", user_class)[0]
122
138
 
123
139
  database_name_len = self.request.recv(2)
124
- database_name_len = struct.unpack('H', database_name_len)[0]
140
+ database_name_len = struct.unpack("H", database_name_len)[0]
125
141
 
126
- database_name = ''
142
+ database_name = ""
127
143
  if database_name_len > 0:
128
144
  database_name = self.request.recv(database_name_len).decode()
129
145
 
130
146
  return {
131
- 'is_cloud': True,
132
- 'client_capabilities': client_capabilities,
133
- 'company_id': company_id,
134
- 'user_class': user_class,
135
- 'database': database_name
147
+ "is_cloud": True,
148
+ "client_capabilities": client_capabilities,
149
+ "company_id": company_id,
150
+ "user_class": user_class,
151
+ "database": database_name,
136
152
  }
137
153
 
138
- return {
139
- 'is_cloud': False
140
- }
154
+ return {"is_cloud": False}
141
155
 
142
156
  def parse(self, message: Parse):
143
157
  self.logger.info("Postgres_Proxy: Parsing")
144
- executor = Executor(
145
- session=self.session,
146
- proxy_server=self,
147
- charset=self.charset
148
- )
158
+ executor = Executor(session=self.session, proxy_server=self, charset=self.charset)
149
159
  # TODO: Remove comment if unneeded ot use session since we're storing in this proxy class per session anyway
150
160
  # stmt_id = self.session.register_stmt(executor)
151
161
  executor.stmt_prepare(sql=message.query)
@@ -179,7 +189,7 @@ class PostgresProxyHandler(socketserver.StreamRequestHandler):
179
189
 
180
190
  def describe(self, message: Describe):
181
191
  self.logger.info("Postgres_Proxy: Describing")
182
- if message.describe_type == b'P':
192
+ if message.describe_type == b"P":
183
193
  if message.name:
184
194
  describing = self.named_portals[message.name]
185
195
  elif self.unnamed_statement:
@@ -187,7 +197,7 @@ class PostgresProxyHandler(socketserver.StreamRequestHandler):
187
197
  else:
188
198
  self.send(InvalidSQLStatementName("Portal Does not Exist"))
189
199
  return True
190
- elif message.describe_type == b'S':
200
+ elif message.describe_type == b"S":
191
201
  if message.name:
192
202
  describing = self.named_statements[message.name]
193
203
  elif self.unnamed_statement:
@@ -227,8 +237,7 @@ class PostgresProxyHandler(socketserver.StreamRequestHandler):
227
237
  return True
228
238
 
229
239
  def init_session(self):
230
- self.logger.info('New connection [{ip}:{port}]'.format(
231
- ip=self.client_address[0], port=self.client_address[1]))
240
+ self.logger.info("New connection [{ip}:{port}]".format(ip=self.client_address[0], port=self.client_address[1]))
232
241
  self.logger.debug(self.__dict__)
233
242
 
234
243
  if self.server.connection_id >= 65025:
@@ -236,9 +245,9 @@ class PostgresProxyHandler(socketserver.StreamRequestHandler):
236
245
  self.server.connection_id += 1
237
246
  self.connection_id = self.server.connection_id
238
247
  self.session = SessionController()
239
- self.session.database = config.get('default_project')
248
+ self.session.database = config.get("default_project")
240
249
 
241
- if hasattr(self.server, 'salt') and isinstance(self.server.salt, str):
250
+ if hasattr(self.server, "salt") and isinstance(self.server.salt, str):
242
251
  self.salt = self.server.salt
243
252
  else:
244
253
  self.salt = base64.b64encode(os.urandom(15)).decode()
@@ -247,14 +256,10 @@ class PostgresProxyHandler(socketserver.StreamRequestHandler):
247
256
 
248
257
  self.current_transaction = None
249
258
 
250
- self.logger.debug('session salt: {salt}'.format(salt=self.salt))
259
+ self.logger.debug("session salt: {salt}".format(salt=self.salt))
251
260
 
252
261
  def process_query(self, sql):
253
- executor = Executor(
254
- session=self.session,
255
- proxy_server=self,
256
- charset=self.charset
257
- )
262
+ executor = Executor(session=self.session, proxy_server=self, charset=self.charset)
258
263
  self.logger.debug("processing query\n%s", sql)
259
264
  try:
260
265
  executor.query_execute(sql)
@@ -262,7 +267,7 @@ class PostgresProxyHandler(socketserver.StreamRequestHandler):
262
267
  return SQLAnswer(
263
268
  resp_type=RESPONSE_TYPE.ERROR,
264
269
  error_message=str(e).encode(self.get_encoding()),
265
- error_code=POSTGRES_SYNTAX_ERROR_CODE.encode(self.get_encoding())
270
+ error_code=POSTGRES_SYNTAX_ERROR_CODE.encode(self.get_encoding()),
266
271
  )
267
272
  return self.return_executor_data(executor)
268
273
 
@@ -277,7 +282,7 @@ class PostgresProxyHandler(socketserver.StreamRequestHandler):
277
282
  resp_type=RESPONSE_TYPE.TABLE,
278
283
  state_track=executor.state_track,
279
284
  result_set=executor.data,
280
- status=executor.server_status
285
+ status=executor.server_status,
281
286
  )
282
287
  return resp
283
288
 
@@ -295,7 +300,7 @@ class PostgresProxyHandler(socketserver.StreamRequestHandler):
295
300
  self.client_buffer.read_verify_ssl_request()
296
301
  # self.send(NoticeResponse()) -- Should Probably not send. Looks in protocol manual to be sent for warning
297
302
  self.logger.debug("Sending No to SSL Request")
298
- PostgresPacketBuilder().write_char(b'N', self.wfile)
303
+ PostgresPacketBuilder().write_char(b"N", self.wfile)
299
304
  self.user_parameters = self.client_buffer.read_startup_message()
300
305
 
301
306
  def authenticate(self, ask_for_password=False):
@@ -303,12 +308,12 @@ class PostgresProxyHandler(socketserver.StreamRequestHandler):
303
308
  self.send(AuthenticationClearTextPassword())
304
309
  password = self.client_buffer.read_authentication(encoding=self.charset)
305
310
  else:
306
- password = ''
307
- username = self.user_parameters[b'user'].decode(encoding=self.charset)
311
+ password = ""
312
+ username = self.user_parameters[b"user"].decode(encoding=self.charset)
308
313
  auth_data = self.server.check_auth(username, password, scramble_func, self.salt, ctx.company_id)
309
- if auth_data['success']:
314
+ if auth_data["success"]:
310
315
  self.logger.debug("Authentication succeeded")
311
- self.session.username = auth_data['username']
316
+ self.session.username = auth_data["username"]
312
317
  self.session.auth = True
313
318
  self.send(AuthenticationOk())
314
319
  return True
@@ -329,9 +334,9 @@ class PostgresProxyHandler(socketserver.StreamRequestHandler):
329
334
  def return_ok(self, sql, rows: int = 0):
330
335
  command = self.get_command(sql)
331
336
  if command == "BEGIN":
332
- self.transaction_status = b'T'
337
+ self.transaction_status = b"T"
333
338
  if command == "COMMIT":
334
- self.transaction_status = b'I'
339
+ self.transaction_status = b"I"
335
340
  if command == "CREATE":
336
341
  command = "SELECT"
337
342
  if command in ("INSERT", "DELETE", "UPDATE", "SELECT", "MOVE", "FETCH", "COPY"):
@@ -347,7 +352,7 @@ class PostgresProxyHandler(socketserver.StreamRequestHandler):
347
352
  if type(sql) == bytes:
348
353
  encoding = self.get_encoding()
349
354
  sql: str = sql.decode(encoding)
350
- return strip_null_byte(sql).strip(';')
355
+ return strip_null_byte(sql).strip(";")
351
356
 
352
357
  def return_table(self, sql_answer: SQLAnswer, row_descs=True):
353
358
  fields = self.to_postgres_fields(sql_answer.result_set.columns)
@@ -356,7 +361,7 @@ class PostgresProxyHandler(socketserver.StreamRequestHandler):
356
361
  self.send(RowDescriptions(fields=fields))
357
362
  self.send(DataRow(rows=rows))
358
363
  encoding = self.get_encoding()
359
- tag = ('SELECT %s' % str(len(rows))).encode(encoding)
364
+ tag = ("SELECT %s" % str(len(rows))).encode(encoding)
360
365
  self.send(CommandComplete(tag=tag))
361
366
  return True
362
367
 
@@ -389,11 +394,7 @@ class PostgresProxyHandler(socketserver.StreamRequestHandler):
389
394
  fields = []
390
395
  i = 0
391
396
  for column in columns:
392
- fields.append(GenericField(
393
- name=column['name'],
394
- object_id=column['type'].value,
395
- column_id=i
396
- ))
397
+ fields.append(GenericField(name=column["name"], object_id=column["type"].value, column_id=i))
397
398
  i += 1
398
399
  return fields
399
400
 
@@ -410,12 +411,12 @@ class PostgresProxyHandler(socketserver.StreamRequestHandler):
410
411
  column = json.dumps(column)
411
412
  if isinstance(column, datetime.date) or isinstance(column, datetime.datetime):
412
413
  try:
413
- column = datetime.datetime.strftime(column, '%Y-%m-%d')
414
+ column = datetime.datetime.strftime(column, "%Y-%m-%d")
414
415
  except ValueError:
415
416
  try:
416
- column = datetime.datetime.strftime(column, '%Y-%m-%dT%H:%M:%S')
417
+ column = datetime.datetime.strftime(column, "%Y-%m-%dT%H:%M:%S")
417
418
  except ValueError:
418
- column = datetime.datetime.strptime(column, '%Y-%m-%dT%H:%M:%S.%f')
419
+ column = datetime.datetime.strptime(column, "%Y-%m-%dT%H:%M:%S.%f")
419
420
  if isinstance(column, bool):
420
421
  if column:
421
422
  column = "true"
@@ -427,7 +428,7 @@ class PostgresProxyHandler(socketserver.StreamRequestHandler):
427
428
 
428
429
  def send_initial_data(self):
429
430
  server_encoding = self.charset.encode(self.charset)
430
- client_encoding = self.user_parameters.get(b'client_encoding', server_encoding)
431
+ client_encoding = self.user_parameters.get(b"client_encoding", server_encoding)
431
432
  # TODO: Send BackendKeyData Here (55.2.1)
432
433
  self.send(ParameterStatus(name=b"server_version", value=b"14.6"))
433
434
  self.send(ParameterStatus(name=b"server_encoding", value=server_encoding))
@@ -459,8 +460,8 @@ class PostgresProxyHandler(socketserver.StreamRequestHandler):
459
460
 
460
461
  @staticmethod
461
462
  def startProxy():
462
- host = config['api']['postgres']['host']
463
- port = int(config['api']['postgres']['port'])
463
+ host = config["api"]["postgres"]["host"]
464
+ port = int(config["api"]["postgres"]["port"])
464
465
  server = TcpServer((host, port), PostgresProxyHandler)
465
466
  server.connection_id = 0
466
467
  server.mindsdb_config = config
@@ -56,9 +56,7 @@ class CrateHandler(DatabaseHandler):
56
56
  if self.is_connected:
57
57
  return self.connection
58
58
 
59
- is_local = (
60
- self.host.startswith("localhost") or self.host == "127.0.0.1"
61
- )
59
+ is_local = self.host.startswith("localhost") or self.host == "127.0.0.1"
62
60
 
63
61
  try:
64
62
  # Build URL based on connection type
@@ -121,7 +119,7 @@ class CrateHandler(DatabaseHandler):
121
119
  """Receive raw query and act upon it somehow.
122
120
  Args:
123
121
  query (Any): query in native format (str for sql databases,
124
- dict for mongo, etc)
122
+ etc)
125
123
  Returns:
126
124
  HandlerResponse
127
125
  """
@@ -136,9 +134,7 @@ class CrateHandler(DatabaseHandler):
136
134
  result = cur.fetchall()
137
135
  response = Response(
138
136
  RESPONSE_TYPE.TABLE,
139
- data_frame=pd.DataFrame(
140
- result, columns=[x[0] for x in cur.description]
141
- ),
137
+ data_frame=pd.DataFrame(result, columns=[x[0] for x in cur.description]),
142
138
  )
143
139
  else:
144
140
  response = Response(RESPONSE_TYPE.OK)
@@ -6,7 +6,7 @@ from mindsdb_sql_parser import parse_sql
6
6
  from mindsdb.integrations.libs.response import (
7
7
  HandlerStatusResponse as StatusResponse,
8
8
  HandlerResponse as Response,
9
- RESPONSE_TYPE
9
+ RESPONSE_TYPE,
10
10
  )
11
11
  import pandas as pd
12
12
  import jaydebeapi as jdbcconnector
@@ -15,11 +15,10 @@ logger = log.getLogger(__name__)
15
15
 
16
16
 
17
17
  class DerbyHandler(DatabaseHandler):
18
-
19
- name = 'derby'
18
+ name = "derby"
20
19
 
21
20
  def __init__(self, name: str, connection_data: Optional[dict], **kwargs):
22
- """ Initialize the handler
21
+ """Initialize the handler
23
22
  Args:
24
23
  name (str): name of particular handler instance
25
24
  connection_data (dict): parameters for connecting to the database
@@ -29,16 +28,16 @@ class DerbyHandler(DatabaseHandler):
29
28
 
30
29
  self.kwargs = kwargs
31
30
  self.parser = parse_sql
32
- self.database = connection_data['database']
31
+ self.database = connection_data["database"]
33
32
  self.connection_config = connection_data
34
- self.host = connection_data['host']
35
- self.port = connection_data['port']
36
- self.schema = 'APP'
33
+ self.host = connection_data["host"]
34
+ self.port = connection_data["port"]
35
+ self.schema = "APP"
37
36
  self.connection = None
38
37
  self.is_connected = False
39
38
 
40
39
  def connect(self):
41
- """ Set up any connections required by the handler
40
+ """Set up any connections required by the handler
42
41
  Should return output of check_connection() method after attempting
43
42
  connection. Should switch self.is_connected.
44
43
  Returns:
@@ -47,10 +46,10 @@ class DerbyHandler(DatabaseHandler):
47
46
  if self.is_connected is True:
48
47
  return self.connection
49
48
 
50
- user = self.connection_config.get('user')
51
- password = self.connection_config.get('password')
52
- jdbc_class = self.connection_config.get('jdbcClass')
53
- jar_location = self.connection_config.get('jdbcJarLocation')
49
+ user = self.connection_config.get("user")
50
+ password = self.connection_config.get("password")
51
+ jdbc_class = self.connection_config.get("jdbcClass")
52
+ jar_location = self.connection_config.get("jdbcJarLocation")
54
53
 
55
54
  jdbc_url = "jdbc:derby://" + self.host + ":" + self.port + "/" + self.database + ";"
56
55
 
@@ -62,11 +61,17 @@ class DerbyHandler(DatabaseHandler):
62
61
 
63
62
  try:
64
63
  if user and password and jar_location:
65
- self.connection = jdbcconnector.connect(jclassname=jdbc_class, url=jdbc_url, driver_args=[user, password], jars=jar_location.split(","))
64
+ self.connection = jdbcconnector.connect(
65
+ jclassname=jdbc_class, url=jdbc_url, driver_args=[user, password], jars=jar_location.split(",")
66
+ )
66
67
  elif user and password:
67
- self.connection = jdbcconnector.connect(jclassname=jdbc_class, url=jdbc_url, driver_args=[user, password])
68
+ self.connection = jdbcconnector.connect(
69
+ jclassname=jdbc_class, url=jdbc_url, driver_args=[user, password]
70
+ )
68
71
  elif jar_location:
69
- self.connection = jdbcconnector.connect(jclassname=jdbc_class, url=jdbc_url, jars=jar_location.split(","))
72
+ self.connection = jdbcconnector.connect(
73
+ jclassname=jdbc_class, url=jdbc_url, jars=jar_location.split(",")
74
+ )
70
75
  else:
71
76
  self.connection = jdbcconnector.connect(jdbc_class, jdbc_url)
72
77
  except Exception as e:
@@ -75,7 +80,7 @@ class DerbyHandler(DatabaseHandler):
75
80
  return self.connection
76
81
 
77
82
  def disconnect(self):
78
- """ Close any existing connections
83
+ """Close any existing connections
79
84
  Should switch self.is_connected.
80
85
  """
81
86
  if self.is_connected is False:
@@ -89,7 +94,7 @@ class DerbyHandler(DatabaseHandler):
89
94
  return
90
95
 
91
96
  def check_connection(self) -> StatusResponse:
92
- """ Check connection to the handler
97
+ """Check connection to the handler
93
98
  Returns:
94
99
  HandlerStatusResponse
95
100
  """
@@ -100,7 +105,7 @@ class DerbyHandler(DatabaseHandler):
100
105
  self.connect()
101
106
  responseCode.success = True
102
107
  except Exception as e:
103
- logger.error(f'Error connecting to database {self.database}, {e}!')
108
+ logger.error(f"Error connecting to database {self.database}, {e}!")
104
109
  responseCode.error_message = str(e)
105
110
  finally:
106
111
  if responseCode.success is True and need_to_close:
@@ -114,7 +119,7 @@ class DerbyHandler(DatabaseHandler):
114
119
  """Receive raw query and act upon it somehow.
115
120
  Args:
116
121
  query (Any): query in native format (str for sql databases,
117
- dict for mongo, etc)
122
+ etc)
118
123
  Returns:
119
124
  HandlerResponse
120
125
  """
@@ -126,21 +131,14 @@ class DerbyHandler(DatabaseHandler):
126
131
  if cur.description:
127
132
  result = cur.fetchall()
128
133
  response = Response(
129
- RESPONSE_TYPE.TABLE,
130
- data_frame=pd.DataFrame(
131
- result,
132
- columns=[x[0] for x in cur.description]
133
- )
134
+ RESPONSE_TYPE.TABLE, data_frame=pd.DataFrame(result, columns=[x[0] for x in cur.description])
134
135
  )
135
136
  else:
136
137
  response = Response(RESPONSE_TYPE.OK)
137
138
  self.connection.commit()
138
139
  except Exception as e:
139
- logger.error(f'Error running query: {query} on {self.database}!')
140
- response = Response(
141
- RESPONSE_TYPE.ERROR,
142
- error_message=str(e)
143
- )
140
+ logger.error(f"Error running query: {query} on {self.database}!")
141
+ response = Response(RESPONSE_TYPE.ERROR, error_message=str(e))
144
142
  self.connection.rollback()
145
143
 
146
144
  if need_to_close is True:
@@ -173,12 +171,12 @@ class DerbyHandler(DatabaseHandler):
173
171
  Returns:
174
172
  Response: Names of the tables in the database.
175
173
  """
176
- query = f'''
177
- SELECT st.tablename FROM sys.systables st LEFT OUTER JOIN sys.sysschemas ss ON (st.schemaid = ss.schemaid) WHERE ss.schemaname ='{self.schema}' '''
174
+ query = f"""
175
+ SELECT st.tablename FROM sys.systables st LEFT OUTER JOIN sys.sysschemas ss ON (st.schemaid = ss.schemaid) WHERE ss.schemaname ='{self.schema}' """
178
176
 
179
177
  result = self.native_query(query)
180
178
  df = result.data_frame
181
- result.data_frame = df.rename(columns={df.columns[0]: 'table_name'})
179
+ result.data_frame = df.rename(columns={df.columns[0]: "table_name"})
182
180
  return result
183
181
 
184
182
  def get_columns(self, table_name: str) -> StatusResponse:
@@ -191,5 +189,5 @@ class DerbyHandler(DatabaseHandler):
191
189
  Response: Details of the table.
192
190
  """
193
191
 
194
- query = f''' SELECT COLUMNNAME FROM SYS.SYSCOLUMNS INNER JOIN SYS.SYSTABLES ON SYS.SYSCOLUMNS.REFERENCEID=SYS.SYSTABLES.TABLEID WHERE TABLENAME='{table_name}' '''
192
+ query = f""" SELECT COLUMNNAME FROM SYS.SYSCOLUMNS INNER JOIN SYS.SYSTABLES ON SYS.SYSCOLUMNS.REFERENCEID=SYS.SYSTABLES.TABLEID WHERE TABLENAME='{table_name}' """
195
193
  return self.native_query(query)
@@ -0,0 +1 @@
1
+ -r mindsdb/integrations/handlers/mongodb_handler/requirements.txt
@@ -11,22 +11,22 @@ from mindsdb.utilities.render.sqlalchemy_render import SqlalchemyRender
11
11
 
12
12
 
13
13
  class DummyHandler(DatabaseHandler):
14
- name = 'dummy_data'
14
+ name = "dummy_data"
15
15
 
16
16
  def __init__(self, **kwargs):
17
- super().__init__('dummy_data')
17
+ super().__init__("dummy_data")
18
18
  self.db_path = None
19
19
 
20
- args = kwargs.get('connection_data', {})
21
- if 'db_path' in args:
22
- self.db_path = args['db_path']
20
+ args = kwargs.get("connection_data", {})
21
+ if "db_path" in args:
22
+ self.db_path = args["db_path"]
23
23
 
24
24
  def connect(self):
25
25
  """Set up any connections required by the handler"""
26
26
  return self.db_path is not None
27
27
 
28
28
  def disconnect(self):
29
- """ Close any existing connections"""
29
+ """Close any existing connections"""
30
30
  return
31
31
 
32
32
  def check_connection(self) -> HandlerStatusResponse:
@@ -41,7 +41,7 @@ class DummyHandler(DatabaseHandler):
41
41
  """Receive raw query and act upon it somehow
42
42
 
43
43
  Args:
44
- query (Any): query in native format (str for sql databases, dict for mongo, etc)
44
+ query (Any): query in native format (str for sql databases, etc)
45
45
  params (Optional[List])
46
46
 
47
47
  Returns:
@@ -49,7 +49,7 @@ class DummyHandler(DatabaseHandler):
49
49
  """
50
50
  con = duckdb.connect(self.db_path)
51
51
  if params is not None:
52
- query = query.replace('%s', '?')
52
+ query = query.replace("%s", "?")
53
53
  cur = con.executemany(query, params)
54
54
  if cur.rowcount >= 0:
55
55
  result_df = cur.fetchdf()
@@ -71,7 +71,7 @@ class DummyHandler(DatabaseHandler):
71
71
  Returns:
72
72
  HandlerResponse
73
73
  """
74
- renderer = SqlalchemyRender('postgres')
74
+ renderer = SqlalchemyRender("postgres")
75
75
  query_str, params = renderer.get_exec_params(query, with_failback=True)
76
76
  return self.native_query(query_str, params)
77
77
 
@@ -81,10 +81,10 @@ class DummyHandler(DatabaseHandler):
81
81
  Returns:
82
82
  HandlerResponse: Names of the tables in the database
83
83
  """
84
- q = 'SHOW TABLES;'
84
+ q = "SHOW TABLES;"
85
85
  result = self.native_query(q)
86
86
  df = result.data_frame
87
- result.data_frame = df.rename(columns={df.columns[0]: 'table_name'})
87
+ result.data_frame = df.rename(columns={df.columns[0]: "table_name"})
88
88
  return result
89
89
 
90
90
  def get_columns(self, table_name: str) -> HandlerResponse:
@@ -96,11 +96,10 @@ class DummyHandler(DatabaseHandler):
96
96
  Returns:
97
97
  HandlerResponse: Details of the table.
98
98
  """
99
- query = f'DESCRIBE {table_name};'
99
+ query = f"DESCRIBE {table_name};"
100
100
  return self.native_query(query)
101
101
 
102
102
  def subscribe(self, stop_event, callback, table_name, columns=None, **kwargs):
103
-
104
103
  while True:
105
104
  if stop_event.is_set():
106
105
  return