MindsDB 25.5.3.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 +127 -79
- 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 +47 -27
- mindsdb/api/executor/datahub/classes/response.py +5 -2
- mindsdb/api/executor/datahub/datanodes/integration_datanode.py +39 -72
- mindsdb/api/executor/planner/query_planner.py +10 -1
- 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 +9 -12
- 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 +99 -83
- mindsdb/api/http/namespaces/analysis.py +3 -3
- mindsdb/api/http/namespaces/file.py +8 -2
- mindsdb/api/http/namespaces/sql.py +13 -27
- 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 +82 -115
- mindsdb/api/mysql/mysql_proxy/utilities/dump.py +351 -0
- mindsdb/api/postgres/postgres_proxy/executor/executor.py +1 -1
- 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/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/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/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_calendar_handler/google_calendar_handler.py +4 -4
- mindsdb/integrations/handlers/google_calendar_handler/google_calendar_tables.py +2 -6
- 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_fit_handler/google_fit_handler.py +10 -12
- mindsdb/integrations/handlers/google_fit_handler/google_fit_tables.py +11 -13
- 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/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.py +4 -4
- mindsdb/integrations/handlers/jira_handler/jira_tables.py +9 -9
- 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/lightwood_handler/functions.py +2 -2
- mindsdb/integrations/handlers/lightwood_handler/lightwood_handler.py +0 -1
- mindsdb/integrations/handlers/lightwood_handler/tests/test_lightwood_handler.py +11 -11
- 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_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/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/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/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/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/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/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 +15 -0
- mindsdb/interfaces/agents/langchain_agent.py +16 -4
- mindsdb/interfaces/agents/mindsdb_database_agent.py +101 -2
- mindsdb/interfaces/knowledge_base/controller.py +25 -0
- mindsdb/interfaces/knowledge_base/preprocessing/document_preprocessor.py +13 -10
- mindsdb/interfaces/knowledge_base/preprocessing/json_chunker.py +434 -0
- mindsdb/interfaces/knowledge_base/preprocessing/models.py +54 -0
- 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 +205 -17
- 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 -7
- mindsdb/migrations/versions/2025-05-21_9f150e4f9a05_checkpoint_1.py +360 -0
- mindsdb/utilities/config.py +331 -219
- mindsdb/utilities/starters.py +13 -0
- {mindsdb-25.5.3.0.dist-info → mindsdb-25.5.4.0.dist-info}/METADATA +641 -695
- {mindsdb-25.5.3.0.dist-info → mindsdb-25.5.4.0.dist-info}/RECORD +309 -288
- {mindsdb-25.5.3.0.dist-info → mindsdb-25.5.4.0.dist-info}/WHEEL +1 -1
- mindsdb/integrations/handlers/monkeylearn_handler/requirements.txt +0 -1
- {mindsdb-25.5.3.0.dist-info → mindsdb-25.5.4.0.dist-info}/licenses/LICENSE +0 -0
- {mindsdb-25.5.3.0.dist-info → mindsdb-25.5.4.0.dist-info}/top_level.txt +0 -0
|
@@ -8,14 +8,14 @@ class VerticaHandlerTest(unittest.TestCase):
|
|
|
8
8
|
def setUpClass(cls):
|
|
9
9
|
cls.kwargs = {
|
|
10
10
|
"connection_data": {
|
|
11
|
-
"host":'127.0.0.1',
|
|
12
|
-
"port":5433,
|
|
13
|
-
"user":'dbadmin',
|
|
14
|
-
"password":'',
|
|
15
|
-
"database":'VMart',
|
|
16
|
-
"schema_name":'public'
|
|
11
|
+
"host": '127.0.0.1',
|
|
12
|
+
"port": 5433,
|
|
13
|
+
"user": 'dbadmin',
|
|
14
|
+
"password": '',
|
|
15
|
+
"database": 'VMart',
|
|
16
|
+
"schema_name": 'public'
|
|
17
17
|
}
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
}
|
|
20
20
|
cls.handler = VerticaHandler('test_vertica_handler', cls.kwargs)
|
|
21
21
|
|
|
@@ -24,21 +24,21 @@ class VerticaHandlerTest(unittest.TestCase):
|
|
|
24
24
|
|
|
25
25
|
def test_1_connect(self):
|
|
26
26
|
assert self.handler.connect()
|
|
27
|
-
|
|
27
|
+
|
|
28
28
|
def test_2_create_table(self):
|
|
29
29
|
query = "CREATE Table TEST(id Number(1),Name Varchar(33))"
|
|
30
30
|
result = self.handler.query(query)
|
|
31
|
-
assert result.type is not RESPONSE_TYPE.ERROR
|
|
31
|
+
assert result.type is not RESPONSE_TYPE.ERROR
|
|
32
32
|
|
|
33
33
|
def test_3_insert(self):
|
|
34
34
|
query = "INSERT INTO TEST (1,'lOVe yOU)"
|
|
35
35
|
result = self.handler.query(query)
|
|
36
|
-
assert result.type is not RESPONSE_TYPE.ERROR
|
|
36
|
+
assert result.type is not RESPONSE_TYPE.ERROR
|
|
37
37
|
|
|
38
38
|
def test_4_native_query_select(self):
|
|
39
39
|
query = "SELECT * FROM TEST;"
|
|
40
40
|
result = self.handler.query(query)
|
|
41
|
-
assert result.type is RESPONSE_TYPE.TABLE
|
|
41
|
+
assert result.type is RESPONSE_TYPE.TABLE
|
|
42
42
|
|
|
43
43
|
def test_5_get_tables(self):
|
|
44
44
|
tables = self.handler.get_tables()
|
|
@@ -30,7 +30,7 @@ class VerticaHandler(DatabaseHandler):
|
|
|
30
30
|
|
|
31
31
|
def __init__(self, name, connection_data: Optional[dict], **kwargs):
|
|
32
32
|
super().__init__(name)
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
self.parser = parse_sql
|
|
35
35
|
self.dialect = 'vertica'
|
|
36
36
|
self.kwargs = kwargs
|
|
@@ -40,7 +40,6 @@ class VerticaHandler(DatabaseHandler):
|
|
|
40
40
|
self.connection = None
|
|
41
41
|
self.is_connected = False
|
|
42
42
|
|
|
43
|
-
|
|
44
43
|
def connect(self):
|
|
45
44
|
if self.is_connected is True:
|
|
46
45
|
return self.connection
|
|
@@ -66,7 +65,7 @@ class VerticaHandler(DatabaseHandler):
|
|
|
66
65
|
return
|
|
67
66
|
|
|
68
67
|
def check_connection(self) -> StatusResponse:
|
|
69
|
-
|
|
68
|
+
|
|
70
69
|
result = StatusResponse(False)
|
|
71
70
|
need_to_close = self.is_connected is False
|
|
72
71
|
|
|
@@ -96,10 +95,10 @@ class VerticaHandler(DatabaseHandler):
|
|
|
96
95
|
connection = self.connect()
|
|
97
96
|
with connection.cursor() as cur:
|
|
98
97
|
try:
|
|
99
|
-
e=cur.execute(query)
|
|
98
|
+
e = cur.execute(query)
|
|
100
99
|
result = e.fetchall()
|
|
101
100
|
if e.rowcount != -1:
|
|
102
|
-
|
|
101
|
+
|
|
103
102
|
response = Response(
|
|
104
103
|
RESPONSE_TYPE.TABLE,
|
|
105
104
|
pd.DataFrame(
|
|
@@ -135,26 +134,24 @@ class VerticaHandler(DatabaseHandler):
|
|
|
135
134
|
"""
|
|
136
135
|
Get a list with all of the tabels in VERTICA
|
|
137
136
|
"""
|
|
138
|
-
q = f'''SELECT
|
|
137
|
+
q = f'''SELECT
|
|
139
138
|
TABLE_NAME,
|
|
140
139
|
TABLE_SCHEMA
|
|
141
|
-
from v_catalog.tables
|
|
142
|
-
WHERE table_schema='{self.schema_name}'
|
|
140
|
+
from v_catalog.tables
|
|
141
|
+
WHERE table_schema='{self.schema_name}'
|
|
143
142
|
order by
|
|
144
143
|
table_name;'''
|
|
145
144
|
|
|
146
|
-
|
|
147
145
|
return self.native_query(q)
|
|
148
146
|
|
|
149
147
|
def get_columns(self, table_name) -> Response:
|
|
150
148
|
"""
|
|
151
149
|
Show details about the table
|
|
152
150
|
"""
|
|
153
|
-
q = f'''SELECT
|
|
154
|
-
column_name ,
|
|
155
|
-
data_type
|
|
156
|
-
FROM v_catalog.columns
|
|
151
|
+
q = f'''SELECT
|
|
152
|
+
column_name ,
|
|
153
|
+
data_type
|
|
154
|
+
FROM v_catalog.columns
|
|
157
155
|
WHERE table_name='{table_name}';'''
|
|
158
156
|
|
|
159
|
-
|
|
160
157
|
return self.native_query(q)
|
|
@@ -2,13 +2,14 @@ import unittest
|
|
|
2
2
|
from mindsdb.integrations.handlers.vitess_handler.vitess_handler import VitessHandler
|
|
3
3
|
from mindsdb.integrations.libs.response import RESPONSE_TYPE
|
|
4
4
|
|
|
5
|
+
|
|
5
6
|
class VitessHandlerTest(unittest.TestCase):
|
|
6
7
|
@classmethod
|
|
7
8
|
def setUpClass(cls):
|
|
8
9
|
cls.kwargs = {
|
|
9
10
|
"connection_data": {
|
|
10
11
|
"host": "localhost",
|
|
11
|
-
"port": 33577
|
|
12
|
+
"port": 33577,
|
|
12
13
|
"user": "root",
|
|
13
14
|
"password": "",
|
|
14
15
|
"database": "vitess",
|
|
@@ -21,36 +22,33 @@ class VitessHandlerTest(unittest.TestCase):
|
|
|
21
22
|
|
|
22
23
|
def test_1_connect(self):
|
|
23
24
|
assert self.handler.connect()
|
|
24
|
-
|
|
25
|
+
|
|
25
26
|
def test_2_create_table(self):
|
|
26
27
|
query = "CREATE Table IF NOT EXISTS Lover(name varchar(101));"
|
|
27
28
|
result = self.handler.query(query)
|
|
28
|
-
assert result.type is not RESPONSE_TYPE.ERROR
|
|
29
|
+
assert result.type is not RESPONSE_TYPE.ERROR
|
|
29
30
|
|
|
30
31
|
def test_3_insert(self):
|
|
31
32
|
query = "INSERT INTO LOVER VALUES('Shiv Shakti');"
|
|
32
33
|
result = self.handler.query(query)
|
|
33
|
-
assert result.type is not RESPONSE_TYPE.ERROR
|
|
34
|
+
assert result.type is not RESPONSE_TYPE.ERROR
|
|
34
35
|
|
|
35
36
|
def test_4_native_query_select(self):
|
|
36
37
|
query = "SELECT * FROM LOVER;"
|
|
37
38
|
result = self.handler.query(query)
|
|
38
|
-
assert result.type is RESPONSE_TYPE.TABLE
|
|
39
|
+
assert result.type is RESPONSE_TYPE.TABLE
|
|
39
40
|
|
|
40
41
|
def test_5_get_tables(self):
|
|
41
42
|
tables = self.handler.get_tables()
|
|
42
|
-
assert tables.type is
|
|
43
|
+
assert tables.type is RESPONSE_TYPE.TABLE
|
|
43
44
|
|
|
44
45
|
def test_6_get_columns(self):
|
|
45
46
|
columns = self.handler.get_columns('LOVER')
|
|
46
|
-
|
|
47
|
+
|
|
47
48
|
query = "DROP Table IF EXISTS Lover;"
|
|
48
|
-
|
|
49
|
+
self.handler.query(query)
|
|
49
50
|
assert columns.type is not RESPONSE_TYPE.ERROR
|
|
50
51
|
|
|
51
52
|
|
|
52
53
|
if __name__ == '__main__':
|
|
53
54
|
unittest.main()
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
@@ -10,7 +10,7 @@ try:
|
|
|
10
10
|
except Exception as e:
|
|
11
11
|
Handler = None
|
|
12
12
|
import_error = e
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
title = 'WhatsApp'
|
|
15
15
|
name = 'whatsapp'
|
|
16
16
|
type = HANDLER_TYPE.DATA
|
|
@@ -21,8 +21,8 @@ __all__ = [
|
|
|
21
21
|
'version',
|
|
22
22
|
'name',
|
|
23
23
|
'type',
|
|
24
|
-
'title',
|
|
24
|
+
'title',
|
|
25
25
|
'description',
|
|
26
26
|
'import_error',
|
|
27
27
|
'icon_path'
|
|
28
|
-
]
|
|
28
|
+
]
|
|
@@ -2,7 +2,6 @@ from typing import List, Union
|
|
|
2
2
|
from pydantic import BaseModel, Extra, field_validator
|
|
3
3
|
|
|
4
4
|
from mindsdb.integrations.handlers.rag_handler.settings import (
|
|
5
|
-
DEFAULT_EMBEDDINGS_MODEL,
|
|
6
5
|
RAGBaseParameters,
|
|
7
6
|
)
|
|
8
7
|
from langchain_core.callbacks import StreamingStdOutCallbackHandler
|
|
@@ -14,12 +14,12 @@ from mindsdb.utilities.config import Config
|
|
|
14
14
|
|
|
15
15
|
from googleapiclient.discovery import build
|
|
16
16
|
|
|
17
|
-
from mindsdb.integrations.utilities.handlers.auth_utilities import GoogleUserOAuth2Manager
|
|
17
|
+
from mindsdb.integrations.utilities.handlers.auth_utilities.google import GoogleUserOAuth2Manager
|
|
18
18
|
|
|
19
19
|
DEFAULT_SCOPES = [
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
'https://www.googleapis.com/auth/youtube',
|
|
21
|
+
'https://www.googleapis.com/auth/youtube.force-ssl',
|
|
22
|
+
'https://www.googleapis.com/auth/youtubepartner'
|
|
23
23
|
]
|
|
24
24
|
|
|
25
25
|
logger = log.getLogger(__name__)
|
|
@@ -81,7 +81,7 @@ class YoutubeHandler(APIHandler):
|
|
|
81
81
|
"""
|
|
82
82
|
if self.is_connected is True:
|
|
83
83
|
return self.connection
|
|
84
|
-
|
|
84
|
+
|
|
85
85
|
google_oauth2_manager = GoogleUserOAuth2Manager(self.handler_storage, self.scopes, self.credentials_file, self.credentials_url, self.connection_data.get('code'))
|
|
86
86
|
creds = google_oauth2_manager.get_oauth2_credentials()
|
|
87
87
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from typing import List
|
|
2
2
|
|
|
3
3
|
from mindsdb.integrations.libs.api_handler import APITable
|
|
4
|
-
from mindsdb.integrations.utilities.sql_utils import extract_comparison_conditions
|
|
5
4
|
from mindsdb.utilities import log
|
|
6
5
|
|
|
7
6
|
from mindsdb_sql_parser import ast
|
|
@@ -61,21 +60,21 @@ class YoutubeCommentsTable(APITable):
|
|
|
61
60
|
|
|
62
61
|
if not video_id and not channel_id:
|
|
63
62
|
raise ValueError("Either video_id or channel_id has to be present in where clause.")
|
|
64
|
-
|
|
63
|
+
|
|
65
64
|
comments_df = self.get_comments(video_id=video_id, channel_id=channel_id)
|
|
66
65
|
|
|
67
66
|
select_statement_executor = SELECTQueryExecutor(
|
|
68
|
-
comments_df,
|
|
69
|
-
selected_columns,
|
|
70
|
-
[where_condition for where_condition in where_conditions if where_condition[1] not in ['video_id', 'channel_id']],
|
|
71
|
-
order_by_conditions,
|
|
67
|
+
comments_df,
|
|
68
|
+
selected_columns,
|
|
69
|
+
[where_condition for where_condition in where_conditions if where_condition[1] not in ['video_id', 'channel_id']],
|
|
70
|
+
order_by_conditions,
|
|
72
71
|
result_limit if query.limit else None
|
|
73
72
|
)
|
|
74
73
|
|
|
75
74
|
comments_df = select_statement_executor.execute_query()
|
|
76
75
|
|
|
77
76
|
return comments_df
|
|
78
|
-
|
|
77
|
+
|
|
79
78
|
def insert(self, query: ast.Insert) -> None:
|
|
80
79
|
"""Inserts data into the YouTube POST /commentThreads API endpoint.
|
|
81
80
|
|
|
@@ -93,7 +92,7 @@ class YoutubeCommentsTable(APITable):
|
|
|
93
92
|
ValueError
|
|
94
93
|
If the query contains an unsupported condition
|
|
95
94
|
"""
|
|
96
|
-
|
|
95
|
+
|
|
97
96
|
insert_query_parser = INSERTQueryParser(query, self.get_columns())
|
|
98
97
|
|
|
99
98
|
values_to_insert = insert_query_parser.parse_query()
|
|
@@ -101,13 +100,13 @@ class YoutubeCommentsTable(APITable):
|
|
|
101
100
|
for value in values_to_insert:
|
|
102
101
|
if not value.get('comment_id'):
|
|
103
102
|
if not value.get('comment'):
|
|
104
|
-
raise ValueError(
|
|
103
|
+
raise ValueError("comment is mandatory for inserting a top-level comment.")
|
|
105
104
|
else:
|
|
106
105
|
self.insert_comment(video_id=value['video_id'], text=value['comment'])
|
|
107
106
|
|
|
108
107
|
else:
|
|
109
108
|
if not value.get('reply'):
|
|
110
|
-
raise ValueError(
|
|
109
|
+
raise ValueError("reply is mandatory for inserting a reply.")
|
|
111
110
|
else:
|
|
112
111
|
self.insert_comment(comment_id=value['comment_id'], text=value['reply'])
|
|
113
112
|
|
|
@@ -178,7 +177,7 @@ class YoutubeCommentsTable(APITable):
|
|
|
178
177
|
replies = []
|
|
179
178
|
if 'replies' in comment:
|
|
180
179
|
for reply in comment["replies"]["comments"]:
|
|
181
|
-
replies.append(
|
|
180
|
+
replies.append(
|
|
182
181
|
{
|
|
183
182
|
"reply_author": reply["snippet"]["authorDisplayName"],
|
|
184
183
|
"user_id": reply["snippet"]["authorChannelId"]["value"],
|
|
@@ -225,7 +224,7 @@ class YoutubeCommentsTable(APITable):
|
|
|
225
224
|
|
|
226
225
|
youtube_comments_df = pd.json_normalize(data, 'replies', ['comment_id', 'channel_id', 'video_id', 'user_id', 'display_name', 'comment', "published_at", "updated_at"], record_prefix='replies.')
|
|
227
226
|
youtube_comments_df = youtube_comments_df.rename(columns={'replies.user_id': 'reply_user_id', 'replies.reply_author': 'reply_author', 'replies.reply': 'reply'})
|
|
228
|
-
|
|
227
|
+
|
|
229
228
|
# check if DataFrame is empty
|
|
230
229
|
if youtube_comments_df.empty:
|
|
231
230
|
return youtube_comments_df
|
|
@@ -262,10 +261,10 @@ class YoutubeChannelsTable(APITable):
|
|
|
262
261
|
channel_df = self.get_channel_details(channel_id)
|
|
263
262
|
|
|
264
263
|
select_statement_executor = SELECTQueryExecutor(
|
|
265
|
-
channel_df,
|
|
266
|
-
selected_columns,
|
|
267
|
-
[where_condition for where_condition in where_conditions if where_condition[1] == 'channel_id'],
|
|
268
|
-
order_by_conditions,
|
|
264
|
+
channel_df,
|
|
265
|
+
selected_columns,
|
|
266
|
+
[where_condition for where_condition in where_conditions if where_condition[1] == 'channel_id'],
|
|
267
|
+
order_by_conditions,
|
|
269
268
|
result_limit if query.limit else None
|
|
270
269
|
)
|
|
271
270
|
|
|
@@ -325,7 +324,7 @@ class YoutubeVideosTable(APITable):
|
|
|
325
324
|
video_id = arg2
|
|
326
325
|
else:
|
|
327
326
|
raise NotImplementedError("Only '=' operator is supported for video_id column.")
|
|
328
|
-
|
|
327
|
+
|
|
329
328
|
elif arg1 == "channel_id":
|
|
330
329
|
if op == "=":
|
|
331
330
|
channel_id = arg2
|
|
@@ -334,24 +333,24 @@ class YoutubeVideosTable(APITable):
|
|
|
334
333
|
|
|
335
334
|
if not video_id and not channel_id:
|
|
336
335
|
raise ValueError("Either video_id or channel_id has to be present in where clause.")
|
|
337
|
-
|
|
336
|
+
|
|
338
337
|
if video_id:
|
|
339
338
|
video_df = self.get_videos_by_video_ids([video_id])
|
|
340
339
|
else:
|
|
341
340
|
video_df = self.get_videos_by_channel_id(channel_id)
|
|
342
341
|
|
|
343
342
|
select_statement_executor = SELECTQueryExecutor(
|
|
344
|
-
video_df,
|
|
345
|
-
selected_columns,
|
|
346
|
-
[where_condition for where_condition in where_conditions if where_condition[1] not in ['video_id', 'channel_id']],
|
|
347
|
-
order_by_conditions,
|
|
343
|
+
video_df,
|
|
344
|
+
selected_columns,
|
|
345
|
+
[where_condition for where_condition in where_conditions if where_condition[1] not in ['video_id', 'channel_id']],
|
|
346
|
+
order_by_conditions,
|
|
348
347
|
result_limit if query.limit else None
|
|
349
348
|
)
|
|
350
349
|
|
|
351
350
|
video_df = select_statement_executor.execute_query()
|
|
352
351
|
|
|
353
352
|
return video_df
|
|
354
|
-
|
|
353
|
+
|
|
355
354
|
def get_videos_by_channel_id(self, channel_id):
|
|
356
355
|
video_ids = []
|
|
357
356
|
resource = (
|
|
@@ -389,7 +388,7 @@ class YoutubeVideosTable(APITable):
|
|
|
389
388
|
# loop over 50 video ids at a time
|
|
390
389
|
# an invalid request error is caused otherwise
|
|
391
390
|
for i in range(0, len(video_ids), 50):
|
|
392
|
-
resource = self.handler.connect().videos().list(part="statistics,snippet,contentDetails", id=",".join(video_ids[i:i+50])).execute()
|
|
391
|
+
resource = self.handler.connect().videos().list(part="statistics,snippet,contentDetails", id=",".join(video_ids[i:i + 50])).execute()
|
|
393
392
|
for item in resource["items"]:
|
|
394
393
|
data.append(
|
|
395
394
|
{
|
|
@@ -418,15 +417,15 @@ class YoutubeVideosTable(APITable):
|
|
|
418
417
|
except Exception as e:
|
|
419
418
|
logger.error(f"Encountered an error while fetching transcripts for video ${video_id}: ${e}"),
|
|
420
419
|
return "Transcript not available for this video"
|
|
421
|
-
|
|
420
|
+
|
|
422
421
|
def parse_duration(self, video_id, duration):
|
|
423
422
|
try:
|
|
424
|
-
parsed_duration = re.search(
|
|
423
|
+
parsed_duration = re.search(r"PT(\d+H)?(\d+M)?(\d+S)", duration).groups()
|
|
425
424
|
duration_str = ""
|
|
426
425
|
for d in parsed_duration:
|
|
427
426
|
if d:
|
|
428
427
|
duration_str += f"{d[:-1]}:"
|
|
429
|
-
|
|
428
|
+
|
|
430
429
|
return duration_str.strip(":")
|
|
431
430
|
except Exception as e:
|
|
432
431
|
logger.error(f"Encountered an error while parsing duration for video ${video_id}: ${e}"),
|
|
@@ -35,7 +35,7 @@ class YugabyteHandlerTest(unittest.TestCase):
|
|
|
35
35
|
def test_4_get_tables(self):
|
|
36
36
|
tables = self.handler.get_tables()
|
|
37
37
|
assert tables.type is not RESPONSE_TYPE.ERROR
|
|
38
|
-
|
|
38
|
+
|
|
39
39
|
def test_5_select_query(self):
|
|
40
40
|
query = "SELECT * FROM PREM;"
|
|
41
41
|
result = self.handler.native_query(query)
|
|
@@ -44,6 +44,6 @@ class YugabyteHandlerTest(unittest.TestCase):
|
|
|
44
44
|
def test_6_check_connection(self):
|
|
45
45
|
self.handler.check_connection()
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
|
|
48
48
|
if __name__ == '__main__':
|
|
49
|
-
unittest.main()
|
|
49
|
+
unittest.main()
|
|
@@ -1,10 +1,4 @@
|
|
|
1
1
|
from collections import OrderedDict
|
|
2
|
-
from typing import Optional
|
|
3
|
-
|
|
4
|
-
from mindsdb_sql_parser import parse_sql
|
|
5
|
-
from mindsdb_sql_parser.ast.base import ASTNode
|
|
6
|
-
from mindsdb.utilities.render.sqlalchemy_render import SqlalchemyRender
|
|
7
|
-
from pandas import DataFrame
|
|
8
2
|
|
|
9
3
|
from mindsdb.integrations.handlers.postgres_handler.postgres_handler import (
|
|
10
4
|
PostgresHandler,
|
|
@@ -6,6 +6,7 @@ import pandas
|
|
|
6
6
|
|
|
7
7
|
from mindsdb.utilities import log
|
|
8
8
|
from mindsdb.api.executor.data_types.response_type import RESPONSE_TYPE
|
|
9
|
+
from mindsdb.api.mysql.mysql_proxy.libs.constants.mysql import MYSQL_DATA_TYPE
|
|
9
10
|
from mindsdb_sql_parser.ast import ASTNode
|
|
10
11
|
|
|
11
12
|
|
|
@@ -18,29 +19,32 @@ class _INFORMATION_SCHEMA_COLUMNS_NAMES:
|
|
|
18
19
|
These column names match the standard INFORMATION_SCHEMA.COLUMNS structure
|
|
19
20
|
used in SQL databases to describe table metadata.
|
|
20
21
|
"""
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
22
|
+
|
|
23
|
+
COLUMN_NAME: str = "COLUMN_NAME"
|
|
24
|
+
DATA_TYPE: str = "DATA_TYPE"
|
|
25
|
+
ORDINAL_POSITION: str = "ORDINAL_POSITION"
|
|
26
|
+
COLUMN_DEFAULT: str = "COLUMN_DEFAULT"
|
|
27
|
+
IS_NULLABLE: str = "IS_NULLABLE"
|
|
28
|
+
CHARACTER_MAXIMUM_LENGTH: str = "CHARACTER_MAXIMUM_LENGTH"
|
|
29
|
+
CHARACTER_OCTET_LENGTH: str = "CHARACTER_OCTET_LENGTH"
|
|
30
|
+
NUMERIC_PRECISION: str = "NUMERIC_PRECISION"
|
|
31
|
+
NUMERIC_SCALE: str = "NUMERIC_SCALE"
|
|
32
|
+
DATETIME_PRECISION: str = "DATETIME_PRECISION"
|
|
33
|
+
CHARACTER_SET_NAME: str = "CHARACTER_SET_NAME"
|
|
34
|
+
COLLATION_NAME: str = "COLLATION_NAME"
|
|
35
|
+
MYSQL_DATA_TYPE: str = "MYSQL_DATA_TYPE"
|
|
34
36
|
|
|
35
37
|
|
|
36
38
|
INF_SCHEMA_COLUMNS_NAMES = _INFORMATION_SCHEMA_COLUMNS_NAMES()
|
|
37
39
|
INF_SCHEMA_COLUMNS_NAMES_SET = set(f.name for f in fields(INF_SCHEMA_COLUMNS_NAMES))
|
|
38
40
|
|
|
39
41
|
|
|
40
|
-
|
|
41
42
|
class HandlerResponse:
|
|
42
|
-
def __init__(
|
|
43
|
-
|
|
43
|
+
def __init__(
|
|
44
|
+
self, resp_type: RESPONSE_TYPE, data_frame: pandas.DataFrame = None, query: ASTNode = 0,
|
|
45
|
+
error_code: int = 0, error_message: str | None = None, affected_rows: int | None = None,
|
|
46
|
+
mysql_types: list[MYSQL_DATA_TYPE] | None = None
|
|
47
|
+
) -> None:
|
|
44
48
|
self.resp_type = resp_type
|
|
45
49
|
self.query = query
|
|
46
50
|
self.data_frame = data_frame
|
|
@@ -49,6 +53,7 @@ class HandlerResponse:
|
|
|
49
53
|
self.affected_rows = affected_rows
|
|
50
54
|
if isinstance(self.affected_rows, int) is False or self.affected_rows < 0:
|
|
51
55
|
self.affected_rows = 0
|
|
56
|
+
self.mysql_types = mysql_types
|
|
52
57
|
|
|
53
58
|
@property
|
|
54
59
|
def type(self):
|
|
@@ -66,7 +71,9 @@ class HandlerResponse:
|
|
|
66
71
|
f"Cannot convert {self.resp_type} to {RESPONSE_TYPE.COLUMNS_TABLE}, "
|
|
67
72
|
f"the error is: {self.error_message}"
|
|
68
73
|
)
|
|
69
|
-
raise ValueError(
|
|
74
|
+
raise ValueError(
|
|
75
|
+
f"Cannot convert {self.resp_type} to {RESPONSE_TYPE.COLUMNS_TABLE}"
|
|
76
|
+
)
|
|
70
77
|
|
|
71
78
|
self.data_frame.columns = [name.upper() for name in self.data_frame.columns]
|
|
72
79
|
self.data_frame[INF_SCHEMA_COLUMNS_NAMES.MYSQL_DATA_TYPE] = self.data_frame[
|
|
@@ -77,24 +84,26 @@ class HandlerResponse:
|
|
|
77
84
|
current_columns_set = set(self.data_frame.columns)
|
|
78
85
|
if INF_SCHEMA_COLUMNS_NAMES_SET != current_columns_set:
|
|
79
86
|
raise ValueError(
|
|
80
|
-
f
|
|
87
|
+
f"Columns set for INFORMATION_SCHEMA.COLUMNS is wrong: {list(current_columns_set)}"
|
|
81
88
|
)
|
|
82
89
|
# endregion
|
|
83
90
|
|
|
84
|
-
self.data_frame = self.data_frame.astype(
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
91
|
+
self.data_frame = self.data_frame.astype(
|
|
92
|
+
{
|
|
93
|
+
INF_SCHEMA_COLUMNS_NAMES.COLUMN_NAME: "string",
|
|
94
|
+
INF_SCHEMA_COLUMNS_NAMES.DATA_TYPE: "string",
|
|
95
|
+
INF_SCHEMA_COLUMNS_NAMES.ORDINAL_POSITION: "Int32",
|
|
96
|
+
INF_SCHEMA_COLUMNS_NAMES.COLUMN_DEFAULT: "string",
|
|
97
|
+
INF_SCHEMA_COLUMNS_NAMES.IS_NULLABLE: "string",
|
|
98
|
+
INF_SCHEMA_COLUMNS_NAMES.CHARACTER_MAXIMUM_LENGTH: "Int32",
|
|
99
|
+
INF_SCHEMA_COLUMNS_NAMES.CHARACTER_OCTET_LENGTH: "Int32",
|
|
100
|
+
INF_SCHEMA_COLUMNS_NAMES.NUMERIC_PRECISION: "Int32",
|
|
101
|
+
INF_SCHEMA_COLUMNS_NAMES.NUMERIC_SCALE: "Int32",
|
|
102
|
+
INF_SCHEMA_COLUMNS_NAMES.DATETIME_PRECISION: "Int32",
|
|
103
|
+
INF_SCHEMA_COLUMNS_NAMES.CHARACTER_SET_NAME: "string",
|
|
104
|
+
INF_SCHEMA_COLUMNS_NAMES.COLLATION_NAME: "string",
|
|
105
|
+
}
|
|
106
|
+
)
|
|
98
107
|
self.data_frame.replace([numpy.NaN, pandas.NA], None, inplace=True)
|
|
99
108
|
|
|
100
109
|
self.resp_type = RESPONSE_TYPE.COLUMNS_TABLE
|
|
@@ -103,33 +112,39 @@ class HandlerResponse:
|
|
|
103
112
|
try:
|
|
104
113
|
data = None
|
|
105
114
|
if self.data_frame is not None:
|
|
106
|
-
data = self.data_frame.to_json(
|
|
115
|
+
data = self.data_frame.to_json(
|
|
116
|
+
orient="split", index=False, date_format="iso"
|
|
117
|
+
)
|
|
107
118
|
except Exception as e:
|
|
108
119
|
logger.error("%s.to_json: error - %s", self.__class__.__name__, e)
|
|
109
120
|
data = None
|
|
110
|
-
return
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
121
|
+
return {
|
|
122
|
+
"type": self.resp_type,
|
|
123
|
+
"query": self.query,
|
|
124
|
+
"data_frame": data,
|
|
125
|
+
"error_code": self.error_code,
|
|
126
|
+
"error": self.error_message,
|
|
127
|
+
}
|
|
115
128
|
|
|
116
129
|
def __repr__(self):
|
|
117
|
-
return "%s: resp_type=%s, query=%s, data_frame
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
130
|
+
return "%s: resp_type=%s, query=%s, data_frame=\n%s\nerr_code=%s, error=%s, affected_rows=%s" % (
|
|
131
|
+
self.__class__.__name__,
|
|
132
|
+
self.resp_type,
|
|
133
|
+
self.query,
|
|
134
|
+
self.data_frame,
|
|
135
|
+
self.error_code,
|
|
136
|
+
self.error_message,
|
|
137
|
+
self.affected_rows,
|
|
138
|
+
)
|
|
126
139
|
|
|
127
140
|
|
|
128
141
|
class HandlerStatusResponse:
|
|
129
|
-
def __init__(
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
142
|
+
def __init__(
|
|
143
|
+
self,
|
|
144
|
+
success: bool = True,
|
|
145
|
+
error_message: str = None,
|
|
146
|
+
redirect_url: str = None,
|
|
147
|
+
copy_storage: str = None,
|
|
133
148
|
) -> None:
|
|
134
149
|
self.success = success
|
|
135
150
|
self.error_message = error_message
|
|
@@ -139,7 +154,7 @@ class HandlerStatusResponse:
|
|
|
139
154
|
def to_json(self):
|
|
140
155
|
data = {"success": self.success, "error": self.error_message}
|
|
141
156
|
if self.redirect_url is not None:
|
|
142
|
-
data[
|
|
157
|
+
data["redirect_url"] = self.redirect_url
|
|
143
158
|
return data
|
|
144
159
|
|
|
145
160
|
def __repr__(self):
|
|
@@ -553,3 +553,9 @@ class VectorStoreHandler(BaseHandler):
|
|
|
553
553
|
df(pd.DataFrame): Hybrid search result, sorted by hybrid search rank
|
|
554
554
|
'''
|
|
555
555
|
raise NotImplementedError(f'Hybrid search not supported for VectorStoreHandler {self.name}')
|
|
556
|
+
|
|
557
|
+
def create_index(self, *args, **kwargs):
|
|
558
|
+
"""
|
|
559
|
+
Create an index on the specified table.
|
|
560
|
+
"""
|
|
561
|
+
raise NotImplementedError(f'create_index not supported for VectorStoreHandler {self.name}')
|