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.
- mindsdb/__about__.py +1 -1
- mindsdb/__main__.py +215 -185
- mindsdb/api/a2a/__init__.py +0 -0
- mindsdb/api/a2a/__main__.py +114 -0
- mindsdb/api/a2a/a2a_client.py +439 -0
- mindsdb/api/a2a/agent.py +308 -0
- mindsdb/api/a2a/common/__init__.py +0 -0
- mindsdb/api/a2a/common/client/__init__.py +4 -0
- mindsdb/api/a2a/common/client/card_resolver.py +21 -0
- mindsdb/api/a2a/common/client/client.py +86 -0
- mindsdb/api/a2a/common/server/__init__.py +4 -0
- mindsdb/api/a2a/common/server/server.py +164 -0
- mindsdb/api/a2a/common/server/task_manager.py +287 -0
- mindsdb/api/a2a/common/server/utils.py +28 -0
- mindsdb/api/a2a/common/types.py +365 -0
- mindsdb/api/a2a/constants.py +9 -0
- mindsdb/api/a2a/run_a2a.py +129 -0
- mindsdb/api/a2a/task_manager.py +594 -0
- mindsdb/api/executor/command_executor.py +49 -28
- mindsdb/api/executor/datahub/classes/response.py +5 -2
- mindsdb/api/executor/datahub/datanodes/information_schema_datanode.py +8 -0
- mindsdb/api/executor/datahub/datanodes/integration_datanode.py +39 -72
- mindsdb/api/executor/datahub/datanodes/system_tables.py +10 -13
- mindsdb/api/executor/planner/query_planner.py +14 -2
- mindsdb/api/executor/sql_query/result_set.py +185 -52
- mindsdb/api/executor/sql_query/sql_query.py +1 -1
- mindsdb/api/executor/sql_query/steps/apply_predictor_step.py +11 -13
- mindsdb/api/executor/sql_query/steps/fetch_dataframe.py +8 -10
- mindsdb/api/executor/sql_query/steps/fetch_dataframe_partition.py +5 -44
- mindsdb/api/executor/sql_query/steps/insert_step.py +24 -15
- mindsdb/api/executor/sql_query/steps/join_step.py +1 -1
- mindsdb/api/executor/sql_query/steps/project_step.py +1 -1
- mindsdb/api/executor/sql_query/steps/sql_steps.py +1 -1
- mindsdb/api/executor/sql_query/steps/subselect_step.py +4 -8
- mindsdb/api/executor/sql_query/steps/union_step.py +1 -3
- mindsdb/api/http/initialize.py +118 -85
- mindsdb/api/http/namespaces/analysis.py +17 -4
- mindsdb/api/http/namespaces/file.py +8 -2
- mindsdb/api/http/namespaces/sql.py +13 -27
- mindsdb/api/http/namespaces/tree.py +1 -1
- mindsdb/api/http/start.py +7 -2
- mindsdb/api/mcp/start.py +42 -5
- mindsdb/api/mysql/mysql_proxy/data_types/mysql_packet.py +0 -1
- mindsdb/api/mysql/mysql_proxy/data_types/mysql_packets/binary_resultset_row_package.py +52 -19
- mindsdb/api/mysql/mysql_proxy/executor/mysql_executor.py +8 -10
- mindsdb/api/mysql/mysql_proxy/libs/constants/mysql.py +54 -38
- mindsdb/api/mysql/mysql_proxy/mysql_proxy.py +86 -123
- mindsdb/api/mysql/mysql_proxy/utilities/dump.py +351 -0
- mindsdb/api/mysql/mysql_proxy/utilities/exceptions.py +0 -4
- mindsdb/api/postgres/postgres_proxy/executor/executor.py +1 -1
- mindsdb/api/postgres/postgres_proxy/postgres_packets/postgres_message_formats.py +2 -2
- mindsdb/api/postgres/postgres_proxy/postgres_proxy.py +5 -6
- mindsdb/integrations/handlers/altibase_handler/altibase_handler.py +26 -27
- mindsdb/integrations/handlers/altibase_handler/connection_args.py +13 -13
- mindsdb/integrations/handlers/altibase_handler/tests/test_altibase_handler.py +8 -8
- mindsdb/integrations/handlers/altibase_handler/tests/test_altibase_handler_dsn.py +13 -13
- mindsdb/integrations/handlers/anthropic_handler/__init__.py +2 -2
- mindsdb/integrations/handlers/anthropic_handler/anthropic_handler.py +1 -3
- mindsdb/integrations/handlers/aurora_handler/aurora_handler.py +1 -0
- mindsdb/integrations/handlers/autosklearn_handler/autosklearn_handler.py +1 -1
- mindsdb/integrations/handlers/autosklearn_handler/config.py +0 -1
- mindsdb/integrations/handlers/bigquery_handler/bigquery_handler.py +1 -1
- mindsdb/integrations/handlers/bigquery_handler/requirements.txt +1 -0
- mindsdb/integrations/handlers/bigquery_handler/tests/test_bigquery_handler.py +1 -1
- mindsdb/integrations/handlers/binance_handler/binance_handler.py +1 -0
- mindsdb/integrations/handlers/binance_handler/binance_tables.py +3 -4
- mindsdb/integrations/handlers/byom_handler/__init__.py +0 -1
- mindsdb/integrations/handlers/chromadb_handler/requirements.txt +1 -0
- mindsdb/integrations/handlers/ckan_handler/ckan_handler.py +3 -0
- mindsdb/integrations/handlers/clickhouse_handler/__init__.py +1 -1
- mindsdb/integrations/handlers/cloud_spanner_handler/tests/test_cloud_spanner_handler.py +0 -2
- mindsdb/integrations/handlers/cloud_sql_handler/cloud_sql_handler.py +0 -1
- mindsdb/integrations/handlers/cohere_handler/__init__.py +1 -1
- mindsdb/integrations/handlers/cohere_handler/cohere_handler.py +11 -13
- mindsdb/integrations/handlers/confluence_handler/confluence_tables.py +6 -0
- mindsdb/integrations/handlers/databend_handler/connection_args.py +1 -1
- mindsdb/integrations/handlers/databend_handler/databend_handler.py +4 -4
- mindsdb/integrations/handlers/databend_handler/tests/__init__.py +0 -1
- mindsdb/integrations/handlers/databend_handler/tests/test_databend_handler.py +1 -1
- mindsdb/integrations/handlers/derby_handler/connection_args.py +1 -1
- mindsdb/integrations/handlers/derby_handler/derby_handler.py +14 -22
- mindsdb/integrations/handlers/derby_handler/tests/test_derby_handler.py +6 -6
- mindsdb/integrations/handlers/discord_handler/discord_handler.py +5 -5
- mindsdb/integrations/handlers/discord_handler/discord_tables.py +3 -3
- mindsdb/integrations/handlers/discord_handler/tests/test_discord.py +5 -3
- mindsdb/integrations/handlers/dockerhub_handler/dockerhub.py +3 -3
- mindsdb/integrations/handlers/dockerhub_handler/dockerhub_handler.py +2 -2
- mindsdb/integrations/handlers/dockerhub_handler/dockerhub_tables.py +57 -54
- mindsdb/integrations/handlers/dremio_handler/__init__.py +2 -2
- mindsdb/integrations/handlers/druid_handler/__init__.py +1 -1
- mindsdb/integrations/handlers/druid_handler/druid_handler.py +2 -2
- mindsdb/integrations/handlers/edgelessdb_handler/tests/test_edgelessdb_handler.py +9 -9
- mindsdb/integrations/handlers/email_handler/email_client.py +1 -1
- mindsdb/integrations/handlers/email_handler/email_ingestor.py +1 -1
- mindsdb/integrations/handlers/email_handler/email_tables.py +0 -1
- mindsdb/integrations/handlers/email_handler/settings.py +0 -1
- mindsdb/integrations/handlers/eventstoredb_handler/eventstoredb_handler.py +2 -1
- mindsdb/integrations/handlers/firebird_handler/firebird_handler.py +1 -1
- mindsdb/integrations/handlers/flaml_handler/flaml_handler.py +9 -9
- mindsdb/integrations/handlers/frappe_handler/frappe_client.py +5 -5
- mindsdb/integrations/handlers/frappe_handler/frappe_handler.py +6 -5
- mindsdb/integrations/handlers/frappe_handler/frappe_tables.py +2 -2
- mindsdb/integrations/handlers/github_handler/connection_args.py +2 -2
- mindsdb/integrations/handlers/github_handler/github_handler.py +1 -8
- mindsdb/integrations/handlers/github_handler/github_tables.py +13 -24
- mindsdb/integrations/handlers/gitlab_handler/gitlab_handler.py +2 -1
- mindsdb/integrations/handlers/gitlab_handler/gitlab_tables.py +1 -4
- mindsdb/integrations/handlers/gmail_handler/gmail_handler.py +6 -13
- mindsdb/integrations/handlers/gmail_handler/requirements.txt +1 -0
- mindsdb/integrations/handlers/google_analytics_handler/requirements.txt +2 -1
- mindsdb/integrations/handlers/google_books_handler/google_books_handler.py +2 -1
- mindsdb/integrations/handlers/google_books_handler/google_books_tables.py +0 -3
- mindsdb/integrations/handlers/google_books_handler/requirements.txt +1 -1
- mindsdb/integrations/handlers/google_calendar_handler/google_calendar_handler.py +4 -4
- mindsdb/integrations/handlers/google_calendar_handler/google_calendar_tables.py +2 -6
- mindsdb/integrations/handlers/google_calendar_handler/requirements.txt +1 -0
- mindsdb/integrations/handlers/google_content_shopping_handler/google_content_shopping_handler.py +3 -2
- mindsdb/integrations/handlers/google_content_shopping_handler/google_content_shopping_tables.py +0 -3
- mindsdb/integrations/handlers/google_content_shopping_handler/requirements.txt +1 -1
- mindsdb/integrations/handlers/google_fit_handler/google_fit_handler.py +10 -12
- mindsdb/integrations/handlers/google_fit_handler/google_fit_tables.py +11 -13
- mindsdb/integrations/handlers/google_fit_handler/requirements.txt +2 -0
- mindsdb/integrations/handlers/google_search_handler/google_search_handler.py +2 -1
- mindsdb/integrations/handlers/google_search_handler/google_search_tables.py +0 -3
- mindsdb/integrations/handlers/google_search_handler/requirements.txt +1 -1
- mindsdb/integrations/handlers/groq_handler/__init__.py +3 -3
- mindsdb/integrations/handlers/hackernews_handler/hn_handler.py +5 -7
- mindsdb/integrations/handlers/hackernews_handler/hn_table.py +6 -7
- mindsdb/integrations/handlers/hive_handler/tests/test_hive_handler.py +1 -1
- mindsdb/integrations/handlers/hsqldb_handler/connection_args.py +6 -6
- mindsdb/integrations/handlers/hsqldb_handler/hsqldb_handler.py +4 -3
- mindsdb/integrations/handlers/huggingface_api_handler/exceptions.py +1 -1
- mindsdb/integrations/handlers/huggingface_api_handler/huggingface_api_handler.py +1 -8
- mindsdb/integrations/handlers/huggingface_handler/huggingface_handler.py +6 -6
- mindsdb/integrations/handlers/huggingface_handler/requirements.txt +1 -1
- mindsdb/integrations/handlers/huggingface_handler/requirements_cpu.txt +1 -1
- mindsdb/integrations/handlers/ignite_handler/ignite_handler.py +2 -1
- mindsdb/integrations/handlers/impala_handler/impala_handler.py +9 -12
- mindsdb/integrations/handlers/impala_handler/tests/test_impala_handler.py +11 -11
- mindsdb/integrations/handlers/influxdb_handler/influxdb_handler.py +10 -13
- mindsdb/integrations/handlers/influxdb_handler/influxdb_tables.py +20 -20
- mindsdb/integrations/handlers/informix_handler/__about__.py +8 -8
- mindsdb/integrations/handlers/informix_handler/__init__.py +12 -5
- mindsdb/integrations/handlers/informix_handler/informix_handler.py +99 -133
- mindsdb/integrations/handlers/informix_handler/tests/test_informix_handler.py +13 -11
- mindsdb/integrations/handlers/ingres_handler/__about__.py +0 -1
- mindsdb/integrations/handlers/ingres_handler/ingres_handler.py +1 -0
- mindsdb/integrations/handlers/jira_handler/jira_handler.archived.py +75 -0
- mindsdb/integrations/handlers/jira_handler/jira_handler.py +113 -38
- mindsdb/integrations/handlers/jira_handler/jira_tables.py +229 -0
- mindsdb/integrations/handlers/jira_handler/requirements.txt +1 -0
- mindsdb/integrations/handlers/kinetica_handler/__init__.py +0 -1
- mindsdb/integrations/handlers/langchain_handler/langchain_handler.py +4 -4
- mindsdb/integrations/handlers/langchain_handler/tools.py +9 -10
- mindsdb/integrations/handlers/leonardoai_handler/__init__.py +1 -1
- mindsdb/integrations/handlers/lightfm_handler/requirements.txt +1 -0
- mindsdb/integrations/handlers/lightwood_handler/functions.py +2 -2
- mindsdb/integrations/handlers/lightwood_handler/lightwood_handler.py +0 -3
- mindsdb/integrations/handlers/lightwood_handler/requirements.txt +4 -4
- mindsdb/integrations/handlers/lightwood_handler/tests/test_lightwood_handler.py +11 -11
- mindsdb/integrations/handlers/lindorm_handler/requirements.txt +1 -0
- mindsdb/integrations/handlers/llama_index_handler/llama_index_handler.py +4 -4
- mindsdb/integrations/handlers/llama_index_handler/settings.py +10 -9
- mindsdb/integrations/handlers/materialize_handler/tests/test_materialize_handler.py +8 -10
- mindsdb/integrations/handlers/matrixone_handler/matrixone_handler.py +4 -4
- mindsdb/integrations/handlers/matrixone_handler/tests/test_matrixone_handler.py +8 -9
- mindsdb/integrations/handlers/maxdb_handler/connection_args.py +25 -25
- mindsdb/integrations/handlers/maxdb_handler/maxdb_handler.py +1 -0
- mindsdb/integrations/handlers/mediawiki_handler/mediawiki_handler.py +3 -2
- mindsdb/integrations/handlers/mediawiki_handler/mediawiki_tables.py +1 -1
- mindsdb/integrations/handlers/mendeley_handler/__about__.py +1 -1
- mindsdb/integrations/handlers/mendeley_handler/__init__.py +2 -2
- mindsdb/integrations/handlers/mendeley_handler/mendeley_handler.py +48 -56
- mindsdb/integrations/handlers/mendeley_handler/mendeley_tables.py +24 -29
- mindsdb/integrations/handlers/mendeley_handler/tests/test_mendeley_handler.py +19 -17
- mindsdb/integrations/handlers/merlion_handler/merlion_handler.py +5 -4
- mindsdb/integrations/handlers/minds_endpoint_handler/__init__.py +3 -3
- mindsdb/integrations/handlers/mlflow_handler/mlflow_handler.py +58 -36
- mindsdb/integrations/handlers/monetdb_handler/__about__.py +8 -8
- mindsdb/integrations/handlers/monetdb_handler/__init__.py +15 -5
- mindsdb/integrations/handlers/monetdb_handler/connection_args.py +17 -18
- mindsdb/integrations/handlers/monetdb_handler/monetdb_handler.py +40 -57
- mindsdb/integrations/handlers/monetdb_handler/tests/test_monetdb_handler.py +7 -8
- mindsdb/integrations/handlers/monetdb_handler/utils/monet_get_id.py +13 -14
- mindsdb/integrations/handlers/monkeylearn_handler/__about__.py +1 -1
- mindsdb/integrations/handlers/monkeylearn_handler/__init__.py +1 -1
- mindsdb/integrations/handlers/monkeylearn_handler/monkeylearn_handler.py +2 -5
- mindsdb/integrations/handlers/ms_one_drive_handler/ms_graph_api_one_drive_client.py +1 -0
- mindsdb/integrations/handlers/ms_one_drive_handler/ms_one_drive_handler.py +1 -1
- mindsdb/integrations/handlers/ms_one_drive_handler/requirements.txt +2 -0
- mindsdb/integrations/handlers/ms_teams_handler/ms_graph_api_teams_client.py +23 -23
- mindsdb/integrations/handlers/ms_teams_handler/ms_teams_handler.py +3 -3
- mindsdb/integrations/handlers/ms_teams_handler/ms_teams_tables.py +10 -5
- mindsdb/integrations/handlers/ms_teams_handler/requirements.txt +3 -1
- mindsdb/integrations/handlers/mssql_handler/mssql_handler.py +73 -8
- mindsdb/integrations/handlers/mysql_handler/__about__.py +8 -8
- mindsdb/integrations/handlers/mysql_handler/__init__.py +15 -5
- mindsdb/integrations/handlers/mysql_handler/connection_args.py +43 -47
- mindsdb/integrations/handlers/mysql_handler/mysql_handler.py +101 -34
- mindsdb/integrations/handlers/mysql_handler/settings.py +15 -13
- mindsdb/integrations/handlers/neuralforecast_handler/neuralforecast_handler.py +1 -1
- mindsdb/integrations/handlers/newsapi_handler/newsapi_handler.py +1 -1
- mindsdb/integrations/handlers/newsapi_handler/tests/test_newsapi_handler.py +4 -4
- mindsdb/integrations/handlers/nuo_jdbc_handler/connection_args.py +2 -2
- mindsdb/integrations/handlers/nuo_jdbc_handler/nuo_jdbc_handler.py +28 -36
- mindsdb/integrations/handlers/nuo_jdbc_handler/tests/test_nuo_handler.py +5 -5
- mindsdb/integrations/handlers/oceanbase_handler/oceanbase_handler.py +0 -1
- mindsdb/integrations/handlers/oceanbase_handler/tests/test_oceanbase_handler.py +8 -10
- mindsdb/integrations/handlers/ollama_handler/ollama_handler.py +3 -3
- mindsdb/integrations/handlers/openai_handler/openai_handler.py +5 -4
- mindsdb/integrations/handlers/opengauss_handler/tests/test_opengauss_handler.py +1 -2
- mindsdb/integrations/handlers/openstreetmap_handler/__init__.py +7 -7
- mindsdb/integrations/handlers/oracle_handler/connection_args.py +6 -0
- mindsdb/integrations/handlers/oracle_handler/oracle_handler.py +77 -11
- mindsdb/integrations/handlers/orioledb_handler/tests/test_orioledb_handler.py +8 -10
- mindsdb/integrations/handlers/palm_handler/__about__.py +1 -1
- mindsdb/integrations/handlers/palm_handler/__init__.py +1 -1
- mindsdb/integrations/handlers/palm_handler/palm_handler.py +1 -3
- mindsdb/integrations/handlers/paypal_handler/paypal_handler.py +2 -2
- mindsdb/integrations/handlers/paypal_handler/paypal_tables.py +15 -14
- mindsdb/integrations/handlers/pgvector_handler/pgvector_handler.py +53 -10
- mindsdb/integrations/handlers/phoenix_handler/__init__.py +1 -1
- mindsdb/integrations/handlers/phoenix_handler/phoenix_handler.py +1 -0
- mindsdb/integrations/handlers/pinot_handler/__init__.py +1 -1
- mindsdb/integrations/handlers/pinot_handler/pinot_handler.py +3 -2
- mindsdb/integrations/handlers/plaid_handler/plaid_handler.py +13 -13
- mindsdb/integrations/handlers/plaid_handler/plaid_tables.py +10 -12
- mindsdb/integrations/handlers/plaid_handler/utils.py +4 -6
- mindsdb/integrations/handlers/planetscale_handler/planetscale_handler.py +1 -4
- mindsdb/integrations/handlers/portkey_handler/__init__.py +2 -2
- mindsdb/integrations/handlers/postgres_handler/postgres_handler.py +105 -24
- mindsdb/integrations/handlers/postgres_handler/tests/test_postgres_handler.py +11 -6
- mindsdb/integrations/handlers/questdb_handler/questdb_handler.py +1 -2
- mindsdb/integrations/handlers/questdb_handler/tests/test_questdb_handler.py +2 -3
- mindsdb/integrations/handlers/quickbooks_handler/quickbooks_handler.py +6 -8
- mindsdb/integrations/handlers/quickbooks_handler/quickbooks_table.py +10 -10
- mindsdb/integrations/handlers/rag_handler/ingest.py +2 -2
- mindsdb/integrations/handlers/rag_handler/rag_handler.py +1 -1
- mindsdb/integrations/handlers/rag_handler/settings.py +1 -1
- mindsdb/integrations/handlers/reddit_handler/reddit_handler.py +2 -7
- mindsdb/integrations/handlers/reddit_handler/reddit_tables.py +2 -3
- mindsdb/integrations/handlers/replicate_handler/replicate_handler.py +6 -6
- mindsdb/integrations/handlers/rocket_chat_handler/rocket_chat_handler.py +1 -2
- mindsdb/integrations/handlers/rocket_chat_handler/rocket_chat_tables.py +0 -3
- mindsdb/integrations/handlers/rockset_handler/connection_args.py +14 -14
- mindsdb/integrations/handlers/rockset_handler/tests/test_rockset_handler.py +1 -0
- mindsdb/integrations/handlers/scylla_handler/scylla_handler.py +6 -5
- mindsdb/integrations/handlers/sendinblue_handler/sendinblue_handler.py +2 -1
- mindsdb/integrations/handlers/sendinblue_handler/sendinblue_tables.py +16 -16
- mindsdb/integrations/handlers/sentence_transformers_handler/__init__.py +1 -1
- mindsdb/integrations/handlers/sheets_handler/connection_args.py +1 -1
- mindsdb/integrations/handlers/shopify_handler/shopify_handler.py +7 -6
- mindsdb/integrations/handlers/shopify_handler/shopify_tables.py +38 -41
- mindsdb/integrations/handlers/singlestore_handler/__about__.py +1 -1
- mindsdb/integrations/handlers/singlestore_handler/__init__.py +0 -1
- mindsdb/integrations/handlers/singlestore_handler/singlestore_handler.py +1 -0
- mindsdb/integrations/handlers/singlestore_handler/tests/test_singlestore_handler.py +3 -3
- mindsdb/integrations/handlers/slack_handler/__init__.py +3 -3
- mindsdb/integrations/handlers/snowflake_handler/requirements.txt +1 -1
- mindsdb/integrations/handlers/snowflake_handler/snowflake_handler.py +100 -6
- mindsdb/integrations/handlers/solr_handler/connection_args.py +7 -7
- mindsdb/integrations/handlers/solr_handler/solr_handler.py +2 -1
- mindsdb/integrations/handlers/solr_handler/tests/test_solr_handler.py +2 -1
- mindsdb/integrations/handlers/sqlany_handler/sqlany_handler.py +3 -2
- mindsdb/integrations/handlers/sqlite_handler/sqlite_handler.py +1 -0
- mindsdb/integrations/handlers/sqreamdb_handler/connection_args.py +1 -1
- mindsdb/integrations/handlers/sqreamdb_handler/sqreamdb_handler.py +15 -20
- mindsdb/integrations/handlers/sqreamdb_handler/tests/test_sqreamdb_handler.py +4 -4
- mindsdb/integrations/handlers/stabilityai_handler/__init__.py +1 -1
- mindsdb/integrations/handlers/starrocks_handler/starrocks_handler.py +0 -1
- mindsdb/integrations/handlers/starrocks_handler/tests/test_starrocks_handler.py +8 -10
- mindsdb/integrations/handlers/statsforecast_handler/statsforecast_handler.py +2 -2
- mindsdb/integrations/handlers/strava_handler/strava_handler.py +4 -8
- mindsdb/integrations/handlers/strava_handler/strava_tables.py +22 -30
- mindsdb/integrations/handlers/stripe_handler/stripe_handler.py +3 -2
- mindsdb/integrations/handlers/stripe_handler/stripe_tables.py +11 -27
- mindsdb/integrations/handlers/supabase_handler/tests/test_supabase_handler.py +1 -1
- mindsdb/integrations/handlers/surrealdb_handler/surrealdb_handler.py +4 -4
- mindsdb/integrations/handlers/tdengine_handler/tdengine_handler.py +25 -27
- mindsdb/integrations/handlers/tdengine_handler/tests/test_tdengine_handler.py +8 -8
- mindsdb/integrations/handlers/tidb_handler/tests/test_tidb_handler.py +1 -2
- mindsdb/integrations/handlers/timegpt_handler/timegpt_handler.py +5 -5
- mindsdb/integrations/handlers/tpot_handler/tpot_handler.py +21 -26
- mindsdb/integrations/handlers/trino_handler/trino_handler.py +14 -14
- mindsdb/integrations/handlers/twitter_handler/twitter_handler.py +2 -4
- mindsdb/integrations/handlers/unify_handler/tests/test_unify_handler.py +7 -8
- mindsdb/integrations/handlers/unify_handler/unify_handler.py +9 -9
- mindsdb/integrations/handlers/vertex_handler/requirements.txt +1 -0
- mindsdb/integrations/handlers/vertex_handler/vertex_client.py +1 -1
- mindsdb/integrations/handlers/vertica_handler/tests/test_vertica_handler.py +11 -11
- mindsdb/integrations/handlers/vertica_handler/vertica_handler.py +11 -14
- mindsdb/integrations/handlers/vitess_handler/tests/test_vitess_handler.py +9 -11
- mindsdb/integrations/handlers/vitess_handler/vitess_handler.py +0 -1
- mindsdb/integrations/handlers/web_handler/web_handler.py +1 -0
- mindsdb/integrations/handlers/whatsapp_handler/__init__.py +3 -3
- mindsdb/integrations/handlers/writer_handler/evaluate.py +1 -1
- mindsdb/integrations/handlers/writer_handler/settings.py +0 -1
- mindsdb/integrations/handlers/writer_handler/writer_handler.py +1 -0
- mindsdb/integrations/handlers/youtube_handler/requirements.txt +1 -0
- mindsdb/integrations/handlers/youtube_handler/youtube_handler.py +5 -5
- mindsdb/integrations/handlers/youtube_handler/youtube_tables.py +26 -27
- mindsdb/integrations/handlers/yugabyte_handler/tests/test_yugabyte_handler.py +3 -3
- mindsdb/integrations/handlers/yugabyte_handler/yugabyte_handler.py +0 -6
- mindsdb/integrations/libs/response.py +67 -52
- mindsdb/integrations/libs/vectordatabase_handler.py +6 -0
- mindsdb/integrations/utilities/files/file_reader.py +5 -2
- mindsdb/integrations/utilities/handler_utils.py +15 -3
- mindsdb/integrations/utilities/handlers/api_utilities/__init__.py +0 -1
- mindsdb/integrations/utilities/handlers/auth_utilities/__init__.py +0 -2
- mindsdb/integrations/utilities/utils.py +3 -3
- mindsdb/interfaces/agents/agents_controller.py +164 -1
- mindsdb/interfaces/agents/constants.py +29 -2
- mindsdb/interfaces/agents/langchain_agent.py +18 -8
- mindsdb/interfaces/agents/mindsdb_database_agent.py +101 -2
- mindsdb/interfaces/database/projects.py +1 -7
- mindsdb/interfaces/functions/controller.py +11 -14
- mindsdb/interfaces/functions/to_markdown.py +9 -124
- mindsdb/interfaces/knowledge_base/controller.py +47 -19
- mindsdb/interfaces/knowledge_base/preprocessing/document_preprocessor.py +41 -15
- mindsdb/interfaces/knowledge_base/preprocessing/json_chunker.py +434 -0
- mindsdb/interfaces/knowledge_base/preprocessing/models.py +54 -0
- mindsdb/interfaces/knowledge_base/utils.py +10 -15
- mindsdb/interfaces/model/model_controller.py +0 -2
- mindsdb/interfaces/query_context/context_controller.py +66 -10
- mindsdb/interfaces/skills/custom/text2sql/mindsdb_kb_tools.py +190 -0
- mindsdb/interfaces/skills/custom/text2sql/mindsdb_sql_toolkit.py +92 -0
- mindsdb/interfaces/skills/skill_tool.py +202 -57
- mindsdb/interfaces/skills/sql_agent.py +238 -28
- mindsdb/interfaces/storage/fs.py +1 -0
- mindsdb/interfaces/variables/__init__.py +0 -0
- mindsdb/interfaces/variables/variables_controller.py +97 -0
- mindsdb/migrations/env.py +5 -7
- mindsdb/migrations/migrate.py +47 -9
- mindsdb/migrations/versions/2025-05-21_9f150e4f9a05_checkpoint_1.py +360 -0
- mindsdb/utilities/config.py +333 -220
- mindsdb/utilities/context.py +1 -1
- mindsdb/utilities/functions.py +0 -36
- mindsdb/utilities/langfuse.py +19 -10
- mindsdb/utilities/otel/__init__.py +9 -193
- mindsdb/utilities/otel/metric_handlers/__init__.py +5 -1
- mindsdb/utilities/otel/prepare.py +198 -0
- mindsdb/utilities/sql.py +83 -0
- mindsdb/utilities/starters.py +13 -0
- {mindsdb-25.4.5.0.dist-info → mindsdb-25.5.4.0.dist-info}/METADATA +351 -338
- {mindsdb-25.4.5.0.dist-info → mindsdb-25.5.4.0.dist-info}/RECORD +348 -322
- {mindsdb-25.4.5.0.dist-info → mindsdb-25.5.4.0.dist-info}/WHEEL +1 -1
- mindsdb/api/mysql/mysql_proxy/classes/sql_statement_parser.py +0 -151
- mindsdb/integrations/handlers/monkeylearn_handler/requirements.txt +0 -1
- {mindsdb-25.4.5.0.dist-info → mindsdb-25.5.4.0.dist-info}/licenses/LICENSE +0 -0
- {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,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.
|
|
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 =
|
|
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__ =
|
|
2
|
-
__package_name__ =
|
|
3
|
-
__version__ =
|
|
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__ =
|
|
6
|
-
__github__ =
|
|
7
|
-
__pypi__ =
|
|
8
|
-
__license__ =
|
|
9
|
-
__copyright__ =
|
|
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 =
|
|
13
|
-
name =
|
|
14
|
+
title = "MySQL"
|
|
15
|
+
name = "mysql"
|
|
14
16
|
type = HANDLER_TYPE.DATA
|
|
15
|
-
icon_path =
|
|
17
|
+
icon_path = "icon.svg"
|
|
16
18
|
|
|
17
19
|
__all__ = [
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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=
|
|
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
|
-
"""
|
|
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(
|
|
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 =
|
|
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 =
|
|
48
|
-
self.connection_data = kwargs.get(
|
|
49
|
-
self.database = self.connection_data.get(
|
|
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
|
|
95
|
-
config[
|
|
167
|
+
if "conn_attrs" in self.connection_data:
|
|
168
|
+
config["conn_attrs"] = self.connection_data["conn_attrs"]
|
|
96
169
|
|
|
97
|
-
if
|
|
98
|
-
config[
|
|
170
|
+
if "connection_timeout" not in config:
|
|
171
|
+
config["connection_timeout"] = 10
|
|
99
172
|
|
|
100
|
-
ssl = self.connection_data.get(
|
|
173
|
+
ssl = self.connection_data.get("ssl")
|
|
101
174
|
if ssl is True:
|
|
102
|
-
ssl_ca = self.connection_data.get(
|
|
103
|
-
ssl_cert = self.connection_data.get(
|
|
104
|
-
ssl_key = self.connection_data.get(
|
|
105
|
-
config[
|
|
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
|
|
113
|
-
config[
|
|
114
|
-
if
|
|
115
|
-
config[
|
|
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(
|
|
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 =
|
|
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(
|
|
188
|
-
|
|
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(
|
|
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(
|
|
18
|
-
host = values.get(
|
|
19
|
-
user = values.get(
|
|
20
|
-
password = values.get(
|
|
21
|
-
database = values.get(
|
|
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(
|
|
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[
|
|
28
|
-
values[
|
|
29
|
-
values[
|
|
30
|
-
values[
|
|
31
|
-
values[
|
|
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(
|
|
36
|
+
values.pop("url", None)
|
|
35
37
|
|
|
36
38
|
return values
|
|
37
39
|
|
|
38
40
|
if not url:
|
|
39
|
-
for param in [
|
|
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
|
-
|
|
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"]
|