MindsDB 25.4.5.0__py3-none-any.whl → 25.5.4.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 (350) hide show
  1. mindsdb/__about__.py +1 -1
  2. mindsdb/__main__.py +215 -185
  3. mindsdb/api/a2a/__init__.py +0 -0
  4. mindsdb/api/a2a/__main__.py +114 -0
  5. mindsdb/api/a2a/a2a_client.py +439 -0
  6. mindsdb/api/a2a/agent.py +308 -0
  7. mindsdb/api/a2a/common/__init__.py +0 -0
  8. mindsdb/api/a2a/common/client/__init__.py +4 -0
  9. mindsdb/api/a2a/common/client/card_resolver.py +21 -0
  10. mindsdb/api/a2a/common/client/client.py +86 -0
  11. mindsdb/api/a2a/common/server/__init__.py +4 -0
  12. mindsdb/api/a2a/common/server/server.py +164 -0
  13. mindsdb/api/a2a/common/server/task_manager.py +287 -0
  14. mindsdb/api/a2a/common/server/utils.py +28 -0
  15. mindsdb/api/a2a/common/types.py +365 -0
  16. mindsdb/api/a2a/constants.py +9 -0
  17. mindsdb/api/a2a/run_a2a.py +129 -0
  18. mindsdb/api/a2a/task_manager.py +594 -0
  19. mindsdb/api/executor/command_executor.py +49 -28
  20. mindsdb/api/executor/datahub/classes/response.py +5 -2
  21. mindsdb/api/executor/datahub/datanodes/information_schema_datanode.py +8 -0
  22. mindsdb/api/executor/datahub/datanodes/integration_datanode.py +39 -72
  23. mindsdb/api/executor/datahub/datanodes/system_tables.py +10 -13
  24. mindsdb/api/executor/planner/query_planner.py +14 -2
  25. mindsdb/api/executor/sql_query/result_set.py +185 -52
  26. mindsdb/api/executor/sql_query/sql_query.py +1 -1
  27. mindsdb/api/executor/sql_query/steps/apply_predictor_step.py +11 -13
  28. mindsdb/api/executor/sql_query/steps/fetch_dataframe.py +8 -10
  29. mindsdb/api/executor/sql_query/steps/fetch_dataframe_partition.py +5 -44
  30. mindsdb/api/executor/sql_query/steps/insert_step.py +24 -15
  31. mindsdb/api/executor/sql_query/steps/join_step.py +1 -1
  32. mindsdb/api/executor/sql_query/steps/project_step.py +1 -1
  33. mindsdb/api/executor/sql_query/steps/sql_steps.py +1 -1
  34. mindsdb/api/executor/sql_query/steps/subselect_step.py +4 -8
  35. mindsdb/api/executor/sql_query/steps/union_step.py +1 -3
  36. mindsdb/api/http/initialize.py +118 -85
  37. mindsdb/api/http/namespaces/analysis.py +17 -4
  38. mindsdb/api/http/namespaces/file.py +8 -2
  39. mindsdb/api/http/namespaces/sql.py +13 -27
  40. mindsdb/api/http/namespaces/tree.py +1 -1
  41. mindsdb/api/http/start.py +7 -2
  42. mindsdb/api/mcp/start.py +42 -5
  43. mindsdb/api/mysql/mysql_proxy/data_types/mysql_packet.py +0 -1
  44. mindsdb/api/mysql/mysql_proxy/data_types/mysql_packets/binary_resultset_row_package.py +52 -19
  45. mindsdb/api/mysql/mysql_proxy/executor/mysql_executor.py +8 -10
  46. mindsdb/api/mysql/mysql_proxy/libs/constants/mysql.py +54 -38
  47. mindsdb/api/mysql/mysql_proxy/mysql_proxy.py +86 -123
  48. mindsdb/api/mysql/mysql_proxy/utilities/dump.py +351 -0
  49. mindsdb/api/mysql/mysql_proxy/utilities/exceptions.py +0 -4
  50. mindsdb/api/postgres/postgres_proxy/executor/executor.py +1 -1
  51. mindsdb/api/postgres/postgres_proxy/postgres_packets/postgres_message_formats.py +2 -2
  52. mindsdb/api/postgres/postgres_proxy/postgres_proxy.py +5 -6
  53. mindsdb/integrations/handlers/altibase_handler/altibase_handler.py +26 -27
  54. mindsdb/integrations/handlers/altibase_handler/connection_args.py +13 -13
  55. mindsdb/integrations/handlers/altibase_handler/tests/test_altibase_handler.py +8 -8
  56. mindsdb/integrations/handlers/altibase_handler/tests/test_altibase_handler_dsn.py +13 -13
  57. mindsdb/integrations/handlers/anthropic_handler/__init__.py +2 -2
  58. mindsdb/integrations/handlers/anthropic_handler/anthropic_handler.py +1 -3
  59. mindsdb/integrations/handlers/aurora_handler/aurora_handler.py +1 -0
  60. mindsdb/integrations/handlers/autosklearn_handler/autosklearn_handler.py +1 -1
  61. mindsdb/integrations/handlers/autosklearn_handler/config.py +0 -1
  62. mindsdb/integrations/handlers/bigquery_handler/bigquery_handler.py +1 -1
  63. mindsdb/integrations/handlers/bigquery_handler/requirements.txt +1 -0
  64. mindsdb/integrations/handlers/bigquery_handler/tests/test_bigquery_handler.py +1 -1
  65. mindsdb/integrations/handlers/binance_handler/binance_handler.py +1 -0
  66. mindsdb/integrations/handlers/binance_handler/binance_tables.py +3 -4
  67. mindsdb/integrations/handlers/byom_handler/__init__.py +0 -1
  68. mindsdb/integrations/handlers/chromadb_handler/requirements.txt +1 -0
  69. mindsdb/integrations/handlers/ckan_handler/ckan_handler.py +3 -0
  70. mindsdb/integrations/handlers/clickhouse_handler/__init__.py +1 -1
  71. mindsdb/integrations/handlers/cloud_spanner_handler/tests/test_cloud_spanner_handler.py +0 -2
  72. mindsdb/integrations/handlers/cloud_sql_handler/cloud_sql_handler.py +0 -1
  73. mindsdb/integrations/handlers/cohere_handler/__init__.py +1 -1
  74. mindsdb/integrations/handlers/cohere_handler/cohere_handler.py +11 -13
  75. mindsdb/integrations/handlers/confluence_handler/confluence_tables.py +6 -0
  76. mindsdb/integrations/handlers/databend_handler/connection_args.py +1 -1
  77. mindsdb/integrations/handlers/databend_handler/databend_handler.py +4 -4
  78. mindsdb/integrations/handlers/databend_handler/tests/__init__.py +0 -1
  79. mindsdb/integrations/handlers/databend_handler/tests/test_databend_handler.py +1 -1
  80. mindsdb/integrations/handlers/derby_handler/connection_args.py +1 -1
  81. mindsdb/integrations/handlers/derby_handler/derby_handler.py +14 -22
  82. mindsdb/integrations/handlers/derby_handler/tests/test_derby_handler.py +6 -6
  83. mindsdb/integrations/handlers/discord_handler/discord_handler.py +5 -5
  84. mindsdb/integrations/handlers/discord_handler/discord_tables.py +3 -3
  85. mindsdb/integrations/handlers/discord_handler/tests/test_discord.py +5 -3
  86. mindsdb/integrations/handlers/dockerhub_handler/dockerhub.py +3 -3
  87. mindsdb/integrations/handlers/dockerhub_handler/dockerhub_handler.py +2 -2
  88. mindsdb/integrations/handlers/dockerhub_handler/dockerhub_tables.py +57 -54
  89. mindsdb/integrations/handlers/dremio_handler/__init__.py +2 -2
  90. mindsdb/integrations/handlers/druid_handler/__init__.py +1 -1
  91. mindsdb/integrations/handlers/druid_handler/druid_handler.py +2 -2
  92. mindsdb/integrations/handlers/edgelessdb_handler/tests/test_edgelessdb_handler.py +9 -9
  93. mindsdb/integrations/handlers/email_handler/email_client.py +1 -1
  94. mindsdb/integrations/handlers/email_handler/email_ingestor.py +1 -1
  95. mindsdb/integrations/handlers/email_handler/email_tables.py +0 -1
  96. mindsdb/integrations/handlers/email_handler/settings.py +0 -1
  97. mindsdb/integrations/handlers/eventstoredb_handler/eventstoredb_handler.py +2 -1
  98. mindsdb/integrations/handlers/firebird_handler/firebird_handler.py +1 -1
  99. mindsdb/integrations/handlers/flaml_handler/flaml_handler.py +9 -9
  100. mindsdb/integrations/handlers/frappe_handler/frappe_client.py +5 -5
  101. mindsdb/integrations/handlers/frappe_handler/frappe_handler.py +6 -5
  102. mindsdb/integrations/handlers/frappe_handler/frappe_tables.py +2 -2
  103. mindsdb/integrations/handlers/github_handler/connection_args.py +2 -2
  104. mindsdb/integrations/handlers/github_handler/github_handler.py +1 -8
  105. mindsdb/integrations/handlers/github_handler/github_tables.py +13 -24
  106. mindsdb/integrations/handlers/gitlab_handler/gitlab_handler.py +2 -1
  107. mindsdb/integrations/handlers/gitlab_handler/gitlab_tables.py +1 -4
  108. mindsdb/integrations/handlers/gmail_handler/gmail_handler.py +6 -13
  109. mindsdb/integrations/handlers/gmail_handler/requirements.txt +1 -0
  110. mindsdb/integrations/handlers/google_analytics_handler/requirements.txt +2 -1
  111. mindsdb/integrations/handlers/google_books_handler/google_books_handler.py +2 -1
  112. mindsdb/integrations/handlers/google_books_handler/google_books_tables.py +0 -3
  113. mindsdb/integrations/handlers/google_books_handler/requirements.txt +1 -1
  114. mindsdb/integrations/handlers/google_calendar_handler/google_calendar_handler.py +4 -4
  115. mindsdb/integrations/handlers/google_calendar_handler/google_calendar_tables.py +2 -6
  116. mindsdb/integrations/handlers/google_calendar_handler/requirements.txt +1 -0
  117. mindsdb/integrations/handlers/google_content_shopping_handler/google_content_shopping_handler.py +3 -2
  118. mindsdb/integrations/handlers/google_content_shopping_handler/google_content_shopping_tables.py +0 -3
  119. mindsdb/integrations/handlers/google_content_shopping_handler/requirements.txt +1 -1
  120. mindsdb/integrations/handlers/google_fit_handler/google_fit_handler.py +10 -12
  121. mindsdb/integrations/handlers/google_fit_handler/google_fit_tables.py +11 -13
  122. mindsdb/integrations/handlers/google_fit_handler/requirements.txt +2 -0
  123. mindsdb/integrations/handlers/google_search_handler/google_search_handler.py +2 -1
  124. mindsdb/integrations/handlers/google_search_handler/google_search_tables.py +0 -3
  125. mindsdb/integrations/handlers/google_search_handler/requirements.txt +1 -1
  126. mindsdb/integrations/handlers/groq_handler/__init__.py +3 -3
  127. mindsdb/integrations/handlers/hackernews_handler/hn_handler.py +5 -7
  128. mindsdb/integrations/handlers/hackernews_handler/hn_table.py +6 -7
  129. mindsdb/integrations/handlers/hive_handler/tests/test_hive_handler.py +1 -1
  130. mindsdb/integrations/handlers/hsqldb_handler/connection_args.py +6 -6
  131. mindsdb/integrations/handlers/hsqldb_handler/hsqldb_handler.py +4 -3
  132. mindsdb/integrations/handlers/huggingface_api_handler/exceptions.py +1 -1
  133. mindsdb/integrations/handlers/huggingface_api_handler/huggingface_api_handler.py +1 -8
  134. mindsdb/integrations/handlers/huggingface_handler/huggingface_handler.py +6 -6
  135. mindsdb/integrations/handlers/huggingface_handler/requirements.txt +1 -1
  136. mindsdb/integrations/handlers/huggingface_handler/requirements_cpu.txt +1 -1
  137. mindsdb/integrations/handlers/ignite_handler/ignite_handler.py +2 -1
  138. mindsdb/integrations/handlers/impala_handler/impala_handler.py +9 -12
  139. mindsdb/integrations/handlers/impala_handler/tests/test_impala_handler.py +11 -11
  140. mindsdb/integrations/handlers/influxdb_handler/influxdb_handler.py +10 -13
  141. mindsdb/integrations/handlers/influxdb_handler/influxdb_tables.py +20 -20
  142. mindsdb/integrations/handlers/informix_handler/__about__.py +8 -8
  143. mindsdb/integrations/handlers/informix_handler/__init__.py +12 -5
  144. mindsdb/integrations/handlers/informix_handler/informix_handler.py +99 -133
  145. mindsdb/integrations/handlers/informix_handler/tests/test_informix_handler.py +13 -11
  146. mindsdb/integrations/handlers/ingres_handler/__about__.py +0 -1
  147. mindsdb/integrations/handlers/ingres_handler/ingres_handler.py +1 -0
  148. mindsdb/integrations/handlers/jira_handler/jira_handler.archived.py +75 -0
  149. mindsdb/integrations/handlers/jira_handler/jira_handler.py +113 -38
  150. mindsdb/integrations/handlers/jira_handler/jira_tables.py +229 -0
  151. mindsdb/integrations/handlers/jira_handler/requirements.txt +1 -0
  152. mindsdb/integrations/handlers/kinetica_handler/__init__.py +0 -1
  153. mindsdb/integrations/handlers/langchain_handler/langchain_handler.py +4 -4
  154. mindsdb/integrations/handlers/langchain_handler/tools.py +9 -10
  155. mindsdb/integrations/handlers/leonardoai_handler/__init__.py +1 -1
  156. mindsdb/integrations/handlers/lightfm_handler/requirements.txt +1 -0
  157. mindsdb/integrations/handlers/lightwood_handler/functions.py +2 -2
  158. mindsdb/integrations/handlers/lightwood_handler/lightwood_handler.py +0 -3
  159. mindsdb/integrations/handlers/lightwood_handler/requirements.txt +4 -4
  160. mindsdb/integrations/handlers/lightwood_handler/tests/test_lightwood_handler.py +11 -11
  161. mindsdb/integrations/handlers/lindorm_handler/requirements.txt +1 -0
  162. mindsdb/integrations/handlers/llama_index_handler/llama_index_handler.py +4 -4
  163. mindsdb/integrations/handlers/llama_index_handler/settings.py +10 -9
  164. mindsdb/integrations/handlers/materialize_handler/tests/test_materialize_handler.py +8 -10
  165. mindsdb/integrations/handlers/matrixone_handler/matrixone_handler.py +4 -4
  166. mindsdb/integrations/handlers/matrixone_handler/tests/test_matrixone_handler.py +8 -9
  167. mindsdb/integrations/handlers/maxdb_handler/connection_args.py +25 -25
  168. mindsdb/integrations/handlers/maxdb_handler/maxdb_handler.py +1 -0
  169. mindsdb/integrations/handlers/mediawiki_handler/mediawiki_handler.py +3 -2
  170. mindsdb/integrations/handlers/mediawiki_handler/mediawiki_tables.py +1 -1
  171. mindsdb/integrations/handlers/mendeley_handler/__about__.py +1 -1
  172. mindsdb/integrations/handlers/mendeley_handler/__init__.py +2 -2
  173. mindsdb/integrations/handlers/mendeley_handler/mendeley_handler.py +48 -56
  174. mindsdb/integrations/handlers/mendeley_handler/mendeley_tables.py +24 -29
  175. mindsdb/integrations/handlers/mendeley_handler/tests/test_mendeley_handler.py +19 -17
  176. mindsdb/integrations/handlers/merlion_handler/merlion_handler.py +5 -4
  177. mindsdb/integrations/handlers/minds_endpoint_handler/__init__.py +3 -3
  178. mindsdb/integrations/handlers/mlflow_handler/mlflow_handler.py +58 -36
  179. mindsdb/integrations/handlers/monetdb_handler/__about__.py +8 -8
  180. mindsdb/integrations/handlers/monetdb_handler/__init__.py +15 -5
  181. mindsdb/integrations/handlers/monetdb_handler/connection_args.py +17 -18
  182. mindsdb/integrations/handlers/monetdb_handler/monetdb_handler.py +40 -57
  183. mindsdb/integrations/handlers/monetdb_handler/tests/test_monetdb_handler.py +7 -8
  184. mindsdb/integrations/handlers/monetdb_handler/utils/monet_get_id.py +13 -14
  185. mindsdb/integrations/handlers/monkeylearn_handler/__about__.py +1 -1
  186. mindsdb/integrations/handlers/monkeylearn_handler/__init__.py +1 -1
  187. mindsdb/integrations/handlers/monkeylearn_handler/monkeylearn_handler.py +2 -5
  188. mindsdb/integrations/handlers/ms_one_drive_handler/ms_graph_api_one_drive_client.py +1 -0
  189. mindsdb/integrations/handlers/ms_one_drive_handler/ms_one_drive_handler.py +1 -1
  190. mindsdb/integrations/handlers/ms_one_drive_handler/requirements.txt +2 -0
  191. mindsdb/integrations/handlers/ms_teams_handler/ms_graph_api_teams_client.py +23 -23
  192. mindsdb/integrations/handlers/ms_teams_handler/ms_teams_handler.py +3 -3
  193. mindsdb/integrations/handlers/ms_teams_handler/ms_teams_tables.py +10 -5
  194. mindsdb/integrations/handlers/ms_teams_handler/requirements.txt +3 -1
  195. mindsdb/integrations/handlers/mssql_handler/mssql_handler.py +73 -8
  196. mindsdb/integrations/handlers/mysql_handler/__about__.py +8 -8
  197. mindsdb/integrations/handlers/mysql_handler/__init__.py +15 -5
  198. mindsdb/integrations/handlers/mysql_handler/connection_args.py +43 -47
  199. mindsdb/integrations/handlers/mysql_handler/mysql_handler.py +101 -34
  200. mindsdb/integrations/handlers/mysql_handler/settings.py +15 -13
  201. mindsdb/integrations/handlers/neuralforecast_handler/neuralforecast_handler.py +1 -1
  202. mindsdb/integrations/handlers/newsapi_handler/newsapi_handler.py +1 -1
  203. mindsdb/integrations/handlers/newsapi_handler/tests/test_newsapi_handler.py +4 -4
  204. mindsdb/integrations/handlers/nuo_jdbc_handler/connection_args.py +2 -2
  205. mindsdb/integrations/handlers/nuo_jdbc_handler/nuo_jdbc_handler.py +28 -36
  206. mindsdb/integrations/handlers/nuo_jdbc_handler/tests/test_nuo_handler.py +5 -5
  207. mindsdb/integrations/handlers/oceanbase_handler/oceanbase_handler.py +0 -1
  208. mindsdb/integrations/handlers/oceanbase_handler/tests/test_oceanbase_handler.py +8 -10
  209. mindsdb/integrations/handlers/ollama_handler/ollama_handler.py +3 -3
  210. mindsdb/integrations/handlers/openai_handler/openai_handler.py +5 -4
  211. mindsdb/integrations/handlers/opengauss_handler/tests/test_opengauss_handler.py +1 -2
  212. mindsdb/integrations/handlers/openstreetmap_handler/__init__.py +7 -7
  213. mindsdb/integrations/handlers/oracle_handler/connection_args.py +6 -0
  214. mindsdb/integrations/handlers/oracle_handler/oracle_handler.py +77 -11
  215. mindsdb/integrations/handlers/orioledb_handler/tests/test_orioledb_handler.py +8 -10
  216. mindsdb/integrations/handlers/palm_handler/__about__.py +1 -1
  217. mindsdb/integrations/handlers/palm_handler/__init__.py +1 -1
  218. mindsdb/integrations/handlers/palm_handler/palm_handler.py +1 -3
  219. mindsdb/integrations/handlers/paypal_handler/paypal_handler.py +2 -2
  220. mindsdb/integrations/handlers/paypal_handler/paypal_tables.py +15 -14
  221. mindsdb/integrations/handlers/pgvector_handler/pgvector_handler.py +53 -10
  222. mindsdb/integrations/handlers/phoenix_handler/__init__.py +1 -1
  223. mindsdb/integrations/handlers/phoenix_handler/phoenix_handler.py +1 -0
  224. mindsdb/integrations/handlers/pinot_handler/__init__.py +1 -1
  225. mindsdb/integrations/handlers/pinot_handler/pinot_handler.py +3 -2
  226. mindsdb/integrations/handlers/plaid_handler/plaid_handler.py +13 -13
  227. mindsdb/integrations/handlers/plaid_handler/plaid_tables.py +10 -12
  228. mindsdb/integrations/handlers/plaid_handler/utils.py +4 -6
  229. mindsdb/integrations/handlers/planetscale_handler/planetscale_handler.py +1 -4
  230. mindsdb/integrations/handlers/portkey_handler/__init__.py +2 -2
  231. mindsdb/integrations/handlers/postgres_handler/postgres_handler.py +105 -24
  232. mindsdb/integrations/handlers/postgres_handler/tests/test_postgres_handler.py +11 -6
  233. mindsdb/integrations/handlers/questdb_handler/questdb_handler.py +1 -2
  234. mindsdb/integrations/handlers/questdb_handler/tests/test_questdb_handler.py +2 -3
  235. mindsdb/integrations/handlers/quickbooks_handler/quickbooks_handler.py +6 -8
  236. mindsdb/integrations/handlers/quickbooks_handler/quickbooks_table.py +10 -10
  237. mindsdb/integrations/handlers/rag_handler/ingest.py +2 -2
  238. mindsdb/integrations/handlers/rag_handler/rag_handler.py +1 -1
  239. mindsdb/integrations/handlers/rag_handler/settings.py +1 -1
  240. mindsdb/integrations/handlers/reddit_handler/reddit_handler.py +2 -7
  241. mindsdb/integrations/handlers/reddit_handler/reddit_tables.py +2 -3
  242. mindsdb/integrations/handlers/replicate_handler/replicate_handler.py +6 -6
  243. mindsdb/integrations/handlers/rocket_chat_handler/rocket_chat_handler.py +1 -2
  244. mindsdb/integrations/handlers/rocket_chat_handler/rocket_chat_tables.py +0 -3
  245. mindsdb/integrations/handlers/rockset_handler/connection_args.py +14 -14
  246. mindsdb/integrations/handlers/rockset_handler/tests/test_rockset_handler.py +1 -0
  247. mindsdb/integrations/handlers/scylla_handler/scylla_handler.py +6 -5
  248. mindsdb/integrations/handlers/sendinblue_handler/sendinblue_handler.py +2 -1
  249. mindsdb/integrations/handlers/sendinblue_handler/sendinblue_tables.py +16 -16
  250. mindsdb/integrations/handlers/sentence_transformers_handler/__init__.py +1 -1
  251. mindsdb/integrations/handlers/sheets_handler/connection_args.py +1 -1
  252. mindsdb/integrations/handlers/shopify_handler/shopify_handler.py +7 -6
  253. mindsdb/integrations/handlers/shopify_handler/shopify_tables.py +38 -41
  254. mindsdb/integrations/handlers/singlestore_handler/__about__.py +1 -1
  255. mindsdb/integrations/handlers/singlestore_handler/__init__.py +0 -1
  256. mindsdb/integrations/handlers/singlestore_handler/singlestore_handler.py +1 -0
  257. mindsdb/integrations/handlers/singlestore_handler/tests/test_singlestore_handler.py +3 -3
  258. mindsdb/integrations/handlers/slack_handler/__init__.py +3 -3
  259. mindsdb/integrations/handlers/snowflake_handler/requirements.txt +1 -1
  260. mindsdb/integrations/handlers/snowflake_handler/snowflake_handler.py +100 -6
  261. mindsdb/integrations/handlers/solr_handler/connection_args.py +7 -7
  262. mindsdb/integrations/handlers/solr_handler/solr_handler.py +2 -1
  263. mindsdb/integrations/handlers/solr_handler/tests/test_solr_handler.py +2 -1
  264. mindsdb/integrations/handlers/sqlany_handler/sqlany_handler.py +3 -2
  265. mindsdb/integrations/handlers/sqlite_handler/sqlite_handler.py +1 -0
  266. mindsdb/integrations/handlers/sqreamdb_handler/connection_args.py +1 -1
  267. mindsdb/integrations/handlers/sqreamdb_handler/sqreamdb_handler.py +15 -20
  268. mindsdb/integrations/handlers/sqreamdb_handler/tests/test_sqreamdb_handler.py +4 -4
  269. mindsdb/integrations/handlers/stabilityai_handler/__init__.py +1 -1
  270. mindsdb/integrations/handlers/starrocks_handler/starrocks_handler.py +0 -1
  271. mindsdb/integrations/handlers/starrocks_handler/tests/test_starrocks_handler.py +8 -10
  272. mindsdb/integrations/handlers/statsforecast_handler/statsforecast_handler.py +2 -2
  273. mindsdb/integrations/handlers/strava_handler/strava_handler.py +4 -8
  274. mindsdb/integrations/handlers/strava_handler/strava_tables.py +22 -30
  275. mindsdb/integrations/handlers/stripe_handler/stripe_handler.py +3 -2
  276. mindsdb/integrations/handlers/stripe_handler/stripe_tables.py +11 -27
  277. mindsdb/integrations/handlers/supabase_handler/tests/test_supabase_handler.py +1 -1
  278. mindsdb/integrations/handlers/surrealdb_handler/surrealdb_handler.py +4 -4
  279. mindsdb/integrations/handlers/tdengine_handler/tdengine_handler.py +25 -27
  280. mindsdb/integrations/handlers/tdengine_handler/tests/test_tdengine_handler.py +8 -8
  281. mindsdb/integrations/handlers/tidb_handler/tests/test_tidb_handler.py +1 -2
  282. mindsdb/integrations/handlers/timegpt_handler/timegpt_handler.py +5 -5
  283. mindsdb/integrations/handlers/tpot_handler/tpot_handler.py +21 -26
  284. mindsdb/integrations/handlers/trino_handler/trino_handler.py +14 -14
  285. mindsdb/integrations/handlers/twitter_handler/twitter_handler.py +2 -4
  286. mindsdb/integrations/handlers/unify_handler/tests/test_unify_handler.py +7 -8
  287. mindsdb/integrations/handlers/unify_handler/unify_handler.py +9 -9
  288. mindsdb/integrations/handlers/vertex_handler/requirements.txt +1 -0
  289. mindsdb/integrations/handlers/vertex_handler/vertex_client.py +1 -1
  290. mindsdb/integrations/handlers/vertica_handler/tests/test_vertica_handler.py +11 -11
  291. mindsdb/integrations/handlers/vertica_handler/vertica_handler.py +11 -14
  292. mindsdb/integrations/handlers/vitess_handler/tests/test_vitess_handler.py +9 -11
  293. mindsdb/integrations/handlers/vitess_handler/vitess_handler.py +0 -1
  294. mindsdb/integrations/handlers/web_handler/web_handler.py +1 -0
  295. mindsdb/integrations/handlers/whatsapp_handler/__init__.py +3 -3
  296. mindsdb/integrations/handlers/writer_handler/evaluate.py +1 -1
  297. mindsdb/integrations/handlers/writer_handler/settings.py +0 -1
  298. mindsdb/integrations/handlers/writer_handler/writer_handler.py +1 -0
  299. mindsdb/integrations/handlers/youtube_handler/requirements.txt +1 -0
  300. mindsdb/integrations/handlers/youtube_handler/youtube_handler.py +5 -5
  301. mindsdb/integrations/handlers/youtube_handler/youtube_tables.py +26 -27
  302. mindsdb/integrations/handlers/yugabyte_handler/tests/test_yugabyte_handler.py +3 -3
  303. mindsdb/integrations/handlers/yugabyte_handler/yugabyte_handler.py +0 -6
  304. mindsdb/integrations/libs/response.py +67 -52
  305. mindsdb/integrations/libs/vectordatabase_handler.py +6 -0
  306. mindsdb/integrations/utilities/files/file_reader.py +5 -2
  307. mindsdb/integrations/utilities/handler_utils.py +15 -3
  308. mindsdb/integrations/utilities/handlers/api_utilities/__init__.py +0 -1
  309. mindsdb/integrations/utilities/handlers/auth_utilities/__init__.py +0 -2
  310. mindsdb/integrations/utilities/utils.py +3 -3
  311. mindsdb/interfaces/agents/agents_controller.py +164 -1
  312. mindsdb/interfaces/agents/constants.py +29 -2
  313. mindsdb/interfaces/agents/langchain_agent.py +18 -8
  314. mindsdb/interfaces/agents/mindsdb_database_agent.py +101 -2
  315. mindsdb/interfaces/database/projects.py +1 -7
  316. mindsdb/interfaces/functions/controller.py +11 -14
  317. mindsdb/interfaces/functions/to_markdown.py +9 -124
  318. mindsdb/interfaces/knowledge_base/controller.py +47 -19
  319. mindsdb/interfaces/knowledge_base/preprocessing/document_preprocessor.py +41 -15
  320. mindsdb/interfaces/knowledge_base/preprocessing/json_chunker.py +434 -0
  321. mindsdb/interfaces/knowledge_base/preprocessing/models.py +54 -0
  322. mindsdb/interfaces/knowledge_base/utils.py +10 -15
  323. mindsdb/interfaces/model/model_controller.py +0 -2
  324. mindsdb/interfaces/query_context/context_controller.py +66 -10
  325. mindsdb/interfaces/skills/custom/text2sql/mindsdb_kb_tools.py +190 -0
  326. mindsdb/interfaces/skills/custom/text2sql/mindsdb_sql_toolkit.py +92 -0
  327. mindsdb/interfaces/skills/skill_tool.py +202 -57
  328. mindsdb/interfaces/skills/sql_agent.py +238 -28
  329. mindsdb/interfaces/storage/fs.py +1 -0
  330. mindsdb/interfaces/variables/__init__.py +0 -0
  331. mindsdb/interfaces/variables/variables_controller.py +97 -0
  332. mindsdb/migrations/env.py +5 -7
  333. mindsdb/migrations/migrate.py +47 -9
  334. mindsdb/migrations/versions/2025-05-21_9f150e4f9a05_checkpoint_1.py +360 -0
  335. mindsdb/utilities/config.py +333 -220
  336. mindsdb/utilities/context.py +1 -1
  337. mindsdb/utilities/functions.py +0 -36
  338. mindsdb/utilities/langfuse.py +19 -10
  339. mindsdb/utilities/otel/__init__.py +9 -193
  340. mindsdb/utilities/otel/metric_handlers/__init__.py +5 -1
  341. mindsdb/utilities/otel/prepare.py +198 -0
  342. mindsdb/utilities/sql.py +83 -0
  343. mindsdb/utilities/starters.py +13 -0
  344. {mindsdb-25.4.5.0.dist-info → mindsdb-25.5.4.0.dist-info}/METADATA +351 -338
  345. {mindsdb-25.4.5.0.dist-info → mindsdb-25.5.4.0.dist-info}/RECORD +348 -322
  346. {mindsdb-25.4.5.0.dist-info → mindsdb-25.5.4.0.dist-info}/WHEEL +1 -1
  347. mindsdb/api/mysql/mysql_proxy/classes/sql_statement_parser.py +0 -151
  348. mindsdb/integrations/handlers/monkeylearn_handler/requirements.txt +0 -1
  349. {mindsdb-25.4.5.0.dist-info → mindsdb-25.5.4.0.dist-info}/licenses/LICENSE +0 -0
  350. {mindsdb-25.4.5.0.dist-info → mindsdb-25.5.4.0.dist-info}/top_level.txt +0 -0
@@ -15,6 +15,7 @@ class TeamsTable(APIResource):
15
15
  """
16
16
  The table abstraction for the 'teams' resource of the Microsoft Graph API.
17
17
  """
18
+
18
19
  def list(
19
20
  self,
20
21
  conditions: List[FilterCondition] = None,
@@ -67,6 +68,7 @@ class ChannelsTable(APIResource):
67
68
  """
68
69
  The table abstraction for the 'channels' resource of the Microsoft Graph API.
69
70
  """
71
+
70
72
  def list(
71
73
  self,
72
74
  conditions: List[FilterCondition] = None,
@@ -146,6 +148,7 @@ class ChannelMessagesTable(APIResource):
146
148
  """
147
149
  The table abstraction for the 'channel messages' resource of the Microsoft Graph API.
148
150
  """
151
+
149
152
  def list(
150
153
  self,
151
154
  conditions: List[FilterCondition] = None,
@@ -206,7 +209,7 @@ class ChannelMessagesTable(APIResource):
206
209
 
207
210
  if not group_id or not channel_id:
208
211
  raise ValueError("The 'channelIdentity_teamId' and 'channelIdentity_channelId' columns are required.")
209
-
212
+
210
213
  messages = client.get_channel_messages(group_id, channel_id, message_ids)
211
214
 
212
215
  messages_df = pd.json_normalize(messages, sep="_")
@@ -247,12 +250,13 @@ class ChannelMessagesTable(APIResource):
247
250
  "channelIdentity_teamId",
248
251
  "channelIdentity_channelId",
249
252
  ]
250
-
253
+
251
254
 
252
255
  class ChatsTable(APIResource):
253
256
  """
254
257
  The table abstraction for the 'chats' resource of the Microsoft Graph API.
255
258
  """
259
+
256
260
  def list(
257
261
  self,
258
262
  conditions: List[FilterCondition] = None,
@@ -312,12 +316,13 @@ class ChatsTable(APIResource):
312
316
  "webUrl",
313
317
  "isHiddenForAllMembers"
314
318
  ]
315
-
319
+
316
320
 
317
321
  class ChatMessagesTable(APIResource):
318
322
  """
319
323
  The table abstraction for the 'chat messages' resource of the Microsoft Graph API.
320
324
  """
325
+
321
326
  def list(
322
327
  self,
323
328
  conditions: List[FilterCondition] = None,
@@ -367,7 +372,7 @@ class ChatMessagesTable(APIResource):
367
372
 
368
373
  if not chat_id:
369
374
  raise ValueError("The 'chatId' column is required.")
370
-
375
+
371
376
  messages = client.get_chat_messages(chat_id, message_ids)
372
377
 
373
378
  messages_df = pd.json_normalize(messages, sep="_")
@@ -405,4 +410,4 @@ class ChatMessagesTable(APIResource):
405
410
  "from_user_userIdentityType",
406
411
  "body_contentType",
407
412
  "body_content",
408
- ]
413
+ ]
@@ -1,2 +1,4 @@
1
1
  botframework-connector
2
- botbuilder-schema
2
+ botbuilder-schema
3
+ msal
4
+ -r mindsdb/integrations/utilities/handlers/auth_utilities/microsoft/requirements.txt
@@ -1,6 +1,10 @@
1
+ from typing import Any
2
+ import datetime
3
+
1
4
  import pymssql
2
5
  from pymssql import OperationalError
3
6
  import pandas as pd
7
+ from pandas.api import types as pd_types
4
8
 
5
9
  from mindsdb_sql_parser import parse_sql
6
10
  from mindsdb_sql_parser.ast.base import ASTNode
@@ -46,10 +50,77 @@ def _map_type(mssql_type_text: str) -> MYSQL_DATA_TYPE:
46
50
  if internal_type_name in db_types_list:
47
51
  return mysql_data_type
48
52
 
49
- logger.warning(f"MSSQL handler type mapping: unknown type: {internal_type_name}, use VARCHAR as fallback.")
53
+ logger.debug(f"MSSQL handler type mapping: unknown type: {internal_type_name}, use VARCHAR as fallback.")
50
54
  return MYSQL_DATA_TYPE.VARCHAR
51
55
 
52
56
 
57
+ def _make_table_response(result: list[dict[str, Any]], cursor: pymssql.Cursor) -> Response:
58
+ """Build response from result and cursor.
59
+
60
+ Args:
61
+ result (list[dict[str, Any]]): result of the query.
62
+ cursor (pymssql.Cursor): cursor object.
63
+
64
+ Returns:
65
+ Response: response object.
66
+ """
67
+ description: list[tuple[Any]] = cursor.description
68
+ mysql_types: list[MYSQL_DATA_TYPE] = []
69
+
70
+ data_frame = pd.DataFrame(
71
+ result,
72
+ columns=[x[0] for x in cursor.description]
73
+ )
74
+
75
+ for column in description:
76
+ column_name = column[0]
77
+ column_type = column[1]
78
+ column_dtype = data_frame[column_name].dtype
79
+ match column_type:
80
+ case pymssql.NUMBER:
81
+ if pd_types.is_integer_dtype(column_dtype):
82
+ mysql_types.append(MYSQL_DATA_TYPE.INT)
83
+ elif pd_types.is_float_dtype(column_dtype):
84
+ mysql_types.append(MYSQL_DATA_TYPE.FLOAT)
85
+ elif pd_types.is_bool_dtype(column_dtype):
86
+ # it is 'bit' type
87
+ mysql_types.append(MYSQL_DATA_TYPE.TINYINT)
88
+ else:
89
+ mysql_types.append(MYSQL_DATA_TYPE.DOUBLE)
90
+ case pymssql.DECIMAL:
91
+ mysql_types.append(MYSQL_DATA_TYPE.DECIMAL)
92
+ case pymssql.STRING:
93
+ mysql_types.append(MYSQL_DATA_TYPE.TEXT)
94
+ case pymssql.DATETIME:
95
+ mysql_types.append(MYSQL_DATA_TYPE.DATETIME)
96
+ case pymssql.BINARY:
97
+ # DATE and TIME types returned as 'BINARY' type, and dataframe type is 'object', so it is not possible
98
+ # to infer correct mysql type for them
99
+ if pd_types.is_datetime64_any_dtype(column_dtype):
100
+ # pymssql return datetimes as 'binary' type
101
+ # if timezone is present, then it is datetime.timezone
102
+ series = data_frame[column_name]
103
+ if (
104
+ series.dt.tz is not None
105
+ and isinstance(series.dt.tz, datetime.timezone)
106
+ and series.dt.tz != datetime.timezone.utc
107
+ ):
108
+ series = series.dt.tz_convert('UTC')
109
+ data_frame[column_name] = series.dt.tz_localize(None)
110
+ mysql_types.append(MYSQL_DATA_TYPE.DATETIME)
111
+ else:
112
+ mysql_types.append(MYSQL_DATA_TYPE.BINARY)
113
+ case _:
114
+ logger.warning(f"Unknown type: {column_type}, use TEXT as fallback.")
115
+ mysql_types.append(MYSQL_DATA_TYPE.TEXT)
116
+
117
+ return Response(
118
+ RESPONSE_TYPE.TABLE,
119
+ data_frame=data_frame,
120
+ mysql_types=mysql_types
121
+ )
122
+
123
+
53
124
  class SqlServerHandler(DatabaseHandler):
54
125
  """
55
126
  This handler handles connection and execution of the Microsoft SQL Server statements.
@@ -169,13 +240,7 @@ class SqlServerHandler(DatabaseHandler):
169
240
  cur.execute(query)
170
241
  if cur.description:
171
242
  result = cur.fetchall()
172
- response = Response(
173
- RESPONSE_TYPE.TABLE,
174
- data_frame=pd.DataFrame(
175
- result,
176
- columns=[x[0] for x in cur.description]
177
- )
178
- )
243
+ response = _make_table_response(result, cur)
179
244
  else:
180
245
  response = Response(RESPONSE_TYPE.OK, affected_rows=cur.rowcount)
181
246
  connection.commit()
@@ -1,9 +1,9 @@
1
- __title__ = 'MindsDB MySQL handler'
2
- __package_name__ = 'mindsdb_mysql_handler'
3
- __version__ = '0.0.1'
1
+ __title__ = "MindsDB MySQL handler"
2
+ __package_name__ = "mindsdb_mysql_handler"
3
+ __version__ = "0.0.1"
4
4
  __description__ = "MindsDB handler for MySQL"
5
- __author__ = 'MindsDB Inc'
6
- __github__ = 'https://github.com/mindsdb/mindsdb'
7
- __pypi__ = 'https://pypi.org/project/mindsdb/'
8
- __license__ = 'MIT'
9
- __copyright__ = 'Copyright 2022- mindsdb'
5
+ __author__ = "MindsDB Inc"
6
+ __github__ = "https://github.com/mindsdb/mindsdb"
7
+ __pypi__ = "https://pypi.org/project/mindsdb/"
8
+ __license__ = "MIT"
9
+ __copyright__ = "Copyright 2022- mindsdb"
@@ -2,19 +2,29 @@ from mindsdb.integrations.libs.const import HANDLER_TYPE
2
2
 
3
3
  from .__about__ import __version__ as version, __description__ as description
4
4
  from .connection_args import connection_args, connection_args_example
5
+
5
6
  try:
6
7
  from .mysql_handler import MySQLHandler as Handler
8
+
7
9
  import_error = None
8
10
  except Exception as e:
9
11
  Handler = None
10
12
  import_error = e
11
13
 
12
- title = 'MySQL'
13
- name = 'mysql'
14
+ title = "MySQL"
15
+ name = "mysql"
14
16
  type = HANDLER_TYPE.DATA
15
- icon_path = 'icon.svg'
17
+ icon_path = "icon.svg"
16
18
 
17
19
  __all__ = [
18
- 'Handler', 'version', 'name', 'type', 'title', 'description',
19
- 'connection_args', 'connection_args_example', 'import_error', 'icon_path'
20
+ "Handler",
21
+ "version",
22
+ "name",
23
+ "type",
24
+ "title",
25
+ "description",
26
+ "connection_args",
27
+ "connection_args_example",
28
+ "import_error",
29
+ "icon_path",
20
30
  ]
@@ -5,72 +5,68 @@ from mindsdb.integrations.libs.const import HANDLER_CONNECTION_ARG_TYPE as ARG_T
5
5
 
6
6
  connection_args = OrderedDict(
7
7
  url={
8
- 'type': ARG_TYPE.STR,
9
- 'description': 'The URI-Like connection string to the MySQL server. If provided, it will override the other connection arguments.',
10
- 'required': False,
11
- 'label': 'URL'
8
+ "type": ARG_TYPE.STR,
9
+ "description": "The URI-Like connection string to the MySQL server. If provided, it will override the other connection arguments.",
10
+ "required": False,
11
+ "label": "URL",
12
12
  },
13
13
  user={
14
- 'type': ARG_TYPE.STR,
15
- 'description': 'The user name used to authenticate with the MySQL server.',
16
- 'required': True,
17
- 'label': 'User'
14
+ "type": ARG_TYPE.STR,
15
+ "description": "The user name used to authenticate with the MySQL server.",
16
+ "required": True,
17
+ "label": "User",
18
18
  },
19
19
  password={
20
- 'type': ARG_TYPE.PWD,
21
- 'description': 'The password to authenticate the user with the MySQL server.',
22
- 'required': True,
23
- 'label': 'Password',
24
- 'secret': True
20
+ "type": ARG_TYPE.PWD,
21
+ "description": "The password to authenticate the user with the MySQL server.",
22
+ "required": True,
23
+ "label": "Password",
24
+ "secret": True,
25
25
  },
26
26
  database={
27
- 'type': ARG_TYPE.STR,
28
- 'description': 'The database name to use when connecting with the MySQL server.',
29
- 'required': True,
30
- 'label': 'Database'
27
+ "type": ARG_TYPE.STR,
28
+ "description": "The database name to use when connecting with the MySQL server.",
29
+ "required": True,
30
+ "label": "Database",
31
31
  },
32
32
  host={
33
- 'type': ARG_TYPE.STR,
34
- 'description': 'The host name or IP address of the MySQL server. NOTE: use \'127.0.0.1\' instead of \'localhost\' to connect to local server.',
35
- 'required': True,
36
- 'label': 'Host'
33
+ "type": ARG_TYPE.STR,
34
+ "description": "The host name or IP address of the MySQL server. NOTE: use '127.0.0.1' instead of 'localhost' to connect to local server.",
35
+ "required": True,
36
+ "label": "Host",
37
37
  },
38
38
  port={
39
- 'type': ARG_TYPE.INT,
40
- 'description': 'The TCP/IP port of the MySQL server. Must be an integer.',
41
- 'required': True,
42
- 'label': 'Port'
39
+ "type": ARG_TYPE.INT,
40
+ "description": "The TCP/IP port of the MySQL server. Must be an integer.",
41
+ "required": True,
42
+ "label": "Port",
43
43
  },
44
44
  ssl={
45
- 'type': ARG_TYPE.BOOL,
46
- 'description': 'Set it to True to enable ssl.',
47
- 'required': False,
48
- 'label': 'ssl'
45
+ "type": ARG_TYPE.BOOL,
46
+ "description": "Set it to True to enable ssl.",
47
+ "required": False,
48
+ "label": "ssl",
49
49
  },
50
50
  ssl_ca={
51
- 'type': ARG_TYPE.PATH,
52
- 'description': 'Path or URL of the Certificate Authority (CA) certificate file',
53
- 'required': False,
54
- 'label': 'ssl_ca'
51
+ "type": ARG_TYPE.PATH,
52
+ "description": "Path or URL of the Certificate Authority (CA) certificate file",
53
+ "required": False,
54
+ "label": "ssl_ca",
55
55
  },
56
56
  ssl_cert={
57
- 'type': ARG_TYPE.PATH,
58
- 'description': 'Path name or URL of the server public key certificate file',
59
- 'required': False,
60
- 'label': 'ssl_cert'
57
+ "type": ARG_TYPE.PATH,
58
+ "description": "Path name or URL of the server public key certificate file",
59
+ "required": False,
60
+ "label": "ssl_cert",
61
61
  },
62
62
  ssl_key={
63
- 'type': ARG_TYPE.PATH,
64
- 'description': 'The path name or URL of the server private key file',
65
- 'required': False,
66
- 'label': 'ssl_key',
67
- }
63
+ "type": ARG_TYPE.PATH,
64
+ "description": "The path name or URL of the server private key file",
65
+ "required": False,
66
+ "label": "ssl_key",
67
+ },
68
68
  )
69
69
 
70
70
  connection_args_example = OrderedDict(
71
- host='127.0.0.1',
72
- port=3306,
73
- user='root',
74
- password='password',
75
- database='database'
71
+ host="127.0.0.1", port=3306, user="root", password="password", database="database"
76
72
  )
@@ -10,16 +10,17 @@ from mindsdb.integrations.libs.base import DatabaseHandler
10
10
  from mindsdb.integrations.libs.response import (
11
11
  HandlerStatusResponse as StatusResponse,
12
12
  HandlerResponse as Response,
13
- RESPONSE_TYPE
13
+ RESPONSE_TYPE,
14
14
  )
15
15
  from mindsdb.integrations.handlers.mysql_handler.settings import ConnectionConfig
16
16
  from mindsdb.api.mysql.mysql_proxy.libs.constants.mysql import MYSQL_DATA_TYPE
17
+ from mindsdb.api.mysql.mysql_proxy.libs.constants.mysql import C_TYPES, DATA_C_TYPE_MAP
17
18
 
18
19
  logger = log.getLogger(__name__)
19
20
 
20
21
 
21
22
  def _map_type(mysql_type_text: str) -> MYSQL_DATA_TYPE:
22
- """ Map MySQL text types names to MySQL types as enum.
23
+ """Map MySQL text types names to MySQL types as enum.
23
24
 
24
25
  Args:
25
26
  mysql_type_text (str): The name of the MySQL type to map.
@@ -30,23 +31,95 @@ def _map_type(mysql_type_text: str) -> MYSQL_DATA_TYPE:
30
31
  try:
31
32
  return MYSQL_DATA_TYPE(mysql_type_text.upper())
32
33
  except Exception:
33
- logger.warning(f'MySQL handler: unknown type: {mysql_type_text}, use TEXT as fallback.')
34
+ logger.warning(
35
+ f"MySQL handler: unknown type: {mysql_type_text}, use TEXT as fallback."
36
+ )
34
37
  return MYSQL_DATA_TYPE.TEXT
35
38
 
36
39
 
40
+ def _make_table_response(result: list[dict], cursor: mysql.connector.cursor.MySQLCursor) -> Response:
41
+ """Build response from result and cursor.
42
+
43
+ Args:
44
+ result (list[dict]): result of the query.
45
+ cursor (mysql.connector.cursor.MySQLCursor): cursor object.
46
+
47
+ Returns:
48
+ Response: response object.
49
+ """
50
+ description = cursor.description
51
+ reverse_c_type_map = {v.code: k for k, v in DATA_C_TYPE_MAP.items() if v.code != C_TYPES.MYSQL_TYPE_BLOB}
52
+ mysql_types: list[MYSQL_DATA_TYPE] = []
53
+ for col in description:
54
+ type_int = col[1]
55
+ if isinstance(type_int, int) is False:
56
+ mysql_types.append(MYSQL_DATA_TYPE.TEXT)
57
+ continue
58
+
59
+ if type_int == C_TYPES.MYSQL_TYPE_TINY:
60
+ # There are 3 types that returns as TINYINT: TINYINT, BOOL, BOOLEAN.
61
+ mysql_types.append(MYSQL_DATA_TYPE.TINYINT)
62
+ continue
63
+
64
+ if type_int in reverse_c_type_map:
65
+ mysql_types.append(reverse_c_type_map[type_int])
66
+ continue
67
+
68
+ if type_int != C_TYPES.MYSQL_TYPE_BLOB:
69
+ raise ValueError(f'Unknown MySQL type id={type_int} in column {col[0]}')
70
+
71
+ # region determine text/blob type by flags
72
+ # Unfortunately, there is no way to determine particular type of text/blob column by flags.
73
+ # Subtype have to be determined by 8-s element of description tuple, but mysql.conector
74
+ # return the same value for all text types (TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT), and for
75
+ # all blob types (TINYBLOB, BLOB, MEDIUMBLOB, LONGBLOB).
76
+ if col[7] == 16: # and col[8] == 45
77
+ mysql_types.append(MYSQL_DATA_TYPE.TEXT)
78
+ elif col[7] == 144: # and col[8] == 63
79
+ mysql_types.append(MYSQL_DATA_TYPE.BLOB)
80
+ else:
81
+ logger.debug(f'MySQL handler: unknown type code {col[7]}, use TEXT as fallback.')
82
+ mysql_types.append(MYSQL_DATA_TYPE.TEXT)
83
+ # endregion
84
+
85
+ # region cast int and bool to nullable types
86
+ serieses = []
87
+ for i, mysql_type in enumerate(mysql_types):
88
+ expected_dtype = None
89
+ column_name = description[i][0]
90
+ if mysql_type in (
91
+ MYSQL_DATA_TYPE.SMALLINT, MYSQL_DATA_TYPE.INT, MYSQL_DATA_TYPE.MEDIUMINT,
92
+ MYSQL_DATA_TYPE.BIGINT, MYSQL_DATA_TYPE.TINYINT
93
+ ):
94
+ expected_dtype = 'Int64'
95
+ elif mysql_type in (MYSQL_DATA_TYPE.BOOL, MYSQL_DATA_TYPE.BOOLEAN):
96
+ expected_dtype = 'boolean'
97
+ serieses.append(pd.Series([row[column_name] for row in result], dtype=expected_dtype, name=description[i][0]))
98
+ df = pd.concat(serieses, axis=1, copy=False)
99
+ # endregion
100
+
101
+ response = Response(
102
+ RESPONSE_TYPE.TABLE,
103
+ df,
104
+ affected_rows=cursor.rowcount,
105
+ mysql_types=mysql_types
106
+ )
107
+ return response
108
+
109
+
37
110
  class MySQLHandler(DatabaseHandler):
38
111
  """
39
112
  This handler handles connection and execution of the MySQL statements.
40
113
  """
41
114
 
42
- name = 'mysql'
115
+ name = "mysql"
43
116
 
44
117
  def __init__(self, name, **kwargs):
45
118
  super().__init__(name)
46
119
  self.parser = parse_sql
47
- self.dialect = 'mysql'
48
- self.connection_data = kwargs.get('connection_data', {})
49
- self.database = self.connection_data.get('database')
120
+ self.dialect = "mysql"
121
+ self.connection_data = kwargs.get("connection_data", {})
122
+ self.database = self.connection_data.get("database")
50
123
 
51
124
  self.connection = None
52
125
 
@@ -91,28 +164,28 @@ class MySQLHandler(DatabaseHandler):
91
164
  if self.is_connected and self.connection.is_connected():
92
165
  return self.connection
93
166
  config = self._unpack_config()
94
- if 'conn_attrs' in self.connection_data:
95
- config['conn_attrs'] = self.connection_data['conn_attrs']
167
+ if "conn_attrs" in self.connection_data:
168
+ config["conn_attrs"] = self.connection_data["conn_attrs"]
96
169
 
97
- if 'connection_timeout' not in config:
98
- config['connection_timeout'] = 10
170
+ if "connection_timeout" not in config:
171
+ config["connection_timeout"] = 10
99
172
 
100
- ssl = self.connection_data.get('ssl')
173
+ ssl = self.connection_data.get("ssl")
101
174
  if ssl is True:
102
- ssl_ca = self.connection_data.get('ssl_ca')
103
- ssl_cert = self.connection_data.get('ssl_cert')
104
- ssl_key = self.connection_data.get('ssl_key')
105
- config['client_flags'] = [mysql.connector.constants.ClientFlag.SSL]
175
+ ssl_ca = self.connection_data.get("ssl_ca")
176
+ ssl_cert = self.connection_data.get("ssl_cert")
177
+ ssl_key = self.connection_data.get("ssl_key")
178
+ config["client_flags"] = [mysql.connector.constants.ClientFlag.SSL]
106
179
  if ssl_ca is not None:
107
180
  config["ssl_ca"] = ssl_ca
108
181
  if ssl_cert is not None:
109
182
  config["ssl_cert"] = ssl_cert
110
183
  if ssl_key is not None:
111
184
  config["ssl_key"] = ssl_key
112
- if 'collation' not in config:
113
- config['collation'] = 'utf8mb4_general_ci'
114
- if 'use_pure' not in config:
115
- config['use_pure'] = True
185
+ if "collation" not in config:
186
+ config["collation"] = "utf8mb4_general_ci"
187
+ if "use_pure" not in config:
188
+ config["use_pure"] = True
116
189
  try:
117
190
  connection = mysql.connector.connect(**config)
118
191
  connection.autocommit = True
@@ -146,7 +219,9 @@ class MySQLHandler(DatabaseHandler):
146
219
  connection = self.connect()
147
220
  result.success = connection.is_connected()
148
221
  except mysql.connector.Error as e:
149
- logger.error(f'Error connecting to MySQL {self.connection_data["database"]}, {e}!')
222
+ logger.error(
223
+ f'Error connecting to MySQL {self.connection_data["database"]}, {e}!'
224
+ )
150
225
  result.error_message = str(e)
151
226
 
152
227
  if result.success and need_to_close:
@@ -173,22 +248,14 @@ class MySQLHandler(DatabaseHandler):
173
248
  cur.execute(query)
174
249
  if cur.with_rows:
175
250
  result = cur.fetchall()
176
- response = Response(
177
- RESPONSE_TYPE.TABLE,
178
- pd.DataFrame(
179
- result,
180
- columns=[x[0] for x in cur.description]
181
- ),
182
- affected_rows=cur.rowcount
183
- )
251
+ response = _make_table_response(result, cur)
184
252
  else:
185
253
  response = Response(RESPONSE_TYPE.OK, affected_rows=cur.rowcount)
186
254
  except mysql.connector.Error as e:
187
- logger.error(f'Error running query: {query} on {self.connection_data["database"]}!')
188
- response = Response(
189
- RESPONSE_TYPE.ERROR,
190
- error_message=str(e)
255
+ logger.error(
256
+ f'Error running query: {query} on {self.connection_data["database"]}!'
191
257
  )
258
+ response = Response(RESPONSE_TYPE.ERROR, error_message=str(e))
192
259
  if connection is not None and connection.is_connected():
193
260
  connection.rollback()
194
261
 
@@ -201,7 +268,7 @@ class MySQLHandler(DatabaseHandler):
201
268
  """
202
269
  Retrieve the data from the SQL statement.
203
270
  """
204
- renderer = SqlalchemyRender('mysql')
271
+ renderer = SqlalchemyRender("mysql")
205
272
  query_str = renderer.get_string(query, with_failback=True)
206
273
  return self.native_query(query_str)
207
274
 
@@ -14,29 +14,31 @@ class ConnectionConfig(BaseModel):
14
14
  @model_validator(mode="before")
15
15
  def check_db_params(cls, values):
16
16
  """Ensures either URL is provided or all individual parameters are provided."""
17
- url = values.get('url')
18
- host = values.get('host')
19
- user = values.get('user')
20
- password = values.get('password')
21
- database = values.get('database')
17
+ url = values.get("url")
18
+ host = values.get("host")
19
+ user = values.get("user")
20
+ password = values.get("password")
21
+ database = values.get("database")
22
22
  if not url and not (host and user and password and database):
23
- raise ValueError("Either a valid URL or required parameters (host, user, password, database) must be provided.")
23
+ raise ValueError(
24
+ "Either a valid URL or required parameters (host, user, password, database) must be provided."
25
+ )
24
26
 
25
27
  if url:
26
28
  parsed = urlparse(url)
27
- values['host'] = parsed.hostname or host
28
- values['port'] = parsed.port if parsed.port is not None else 3306
29
- values['user'] = parsed.username or user
30
- values['password'] = parsed.password or password
31
- values['database'] = parsed.path[1:] if parsed.path else database
29
+ values["host"] = parsed.hostname or host
30
+ values["port"] = parsed.port if parsed.port is not None else 3306
31
+ values["user"] = parsed.username or user
32
+ values["password"] = parsed.password or password
33
+ values["database"] = parsed.path[1:] if parsed.path else database
32
34
 
33
35
  # mysql connector raise error if url is provided
34
- values.pop('url', None)
36
+ values.pop("url", None)
35
37
 
36
38
  return values
37
39
 
38
40
  if not url:
39
- for param in ['host', 'user', 'password', 'database']:
41
+ for param in ["host", "user", "password", "database"]:
40
42
  if not values.get(param):
41
43
  raise ValueError(f"{param} is required when URL is not provided.")
42
44
  return values
@@ -41,7 +41,7 @@ class NeuralForecastHandler(BaseMLEngine):
41
41
  time_settings = args["timeseries_settings"]
42
42
  using_args = args["using"]
43
43
  assert time_settings["is_timeseries"], "Specify time series settings in your query"
44
- ###### store model args and time series settings in the model folder
44
+ # store model args and time series settings in the model folder
45
45
  model_args = {}
46
46
  model_args["target"] = target
47
47
  model_args["horizon"] = time_settings["horizon"]
@@ -194,7 +194,7 @@ class NewsAPIHandler(APIHandler):
194
194
  try:
195
195
  result = self.api.get_everything(**params)
196
196
  except Exception as e:
197
- raise RuntimeError(f"API call failed: {e}")
197
+ raise RuntimeError(f"API call failed: {e}")
198
198
  articles = result["articles"]
199
199
  for article in articles:
200
200
  article["source_id"] = article["source"]["id"]