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
mindsdb/__about__.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
__title__ = 'MindsDB'
|
|
2
2
|
__package_name__ = 'mindsdb'
|
|
3
|
-
__version__ = '25.4.
|
|
3
|
+
__version__ = '25.5.4.0'
|
|
4
4
|
__description__ = "MindsDB's AI SQL Server enables developers to build AI tools that need access to real-time data to perform their tasks"
|
|
5
5
|
__email__ = "jorge@mindsdb.com"
|
|
6
6
|
__author__ = 'MindsDB Inc'
|
mindsdb/__main__.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import gc
|
|
2
|
+
gc.disable()
|
|
1
3
|
import os
|
|
2
4
|
import sys
|
|
3
5
|
import time
|
|
@@ -12,7 +14,7 @@ from enum import Enum
|
|
|
12
14
|
from dataclasses import dataclass, field
|
|
13
15
|
from typing import Callable, Optional, Tuple, List
|
|
14
16
|
|
|
15
|
-
from
|
|
17
|
+
from sqlalchemy import func
|
|
16
18
|
from sqlalchemy.orm.attributes import flag_modified
|
|
17
19
|
|
|
18
20
|
from mindsdb.utilities import log
|
|
@@ -22,17 +24,20 @@ logger.debug("Starting MindsDB...")
|
|
|
22
24
|
|
|
23
25
|
from mindsdb.__about__ import __version__ as mindsdb_version
|
|
24
26
|
from mindsdb.utilities.config import config
|
|
25
|
-
from mindsdb.utilities.exception import EntityNotExistsError
|
|
26
27
|
from mindsdb.utilities.starters import (
|
|
27
|
-
start_http,
|
|
28
|
-
|
|
28
|
+
start_http,
|
|
29
|
+
start_mysql,
|
|
30
|
+
start_mongo,
|
|
31
|
+
start_postgres,
|
|
32
|
+
start_ml_task_queue,
|
|
33
|
+
start_scheduler,
|
|
34
|
+
start_tasks,
|
|
35
|
+
start_mcp,
|
|
36
|
+
start_litellm,
|
|
37
|
+
start_a2a,
|
|
29
38
|
)
|
|
30
39
|
from mindsdb.utilities.ps import is_pid_listen_port, get_child_pids
|
|
31
|
-
from mindsdb.utilities.functions import get_versions_where_predictors_become_obsolete
|
|
32
|
-
from mindsdb.interfaces.database.integrations import integration_controller
|
|
33
|
-
from mindsdb.interfaces.database.projects import ProjectController
|
|
34
40
|
import mindsdb.interfaces.storage.db as db
|
|
35
|
-
from mindsdb.integrations.utilities.install import install_dependencies
|
|
36
41
|
from mindsdb.utilities.fs import clean_process_marks, clean_unlinked_process_marks
|
|
37
42
|
from mindsdb.utilities.context import context as ctx
|
|
38
43
|
from mindsdb.utilities.auth import register_oauth_client, get_aws_meta_data
|
|
@@ -43,23 +48,26 @@ try:
|
|
|
43
48
|
except Exception:
|
|
44
49
|
import multiprocessing as mp
|
|
45
50
|
try:
|
|
46
|
-
mp.set_start_method(
|
|
51
|
+
mp.set_start_method("spawn")
|
|
47
52
|
except RuntimeError:
|
|
48
|
-
logger.info(
|
|
53
|
+
logger.info("Torch multiprocessing context already set, ignoring...")
|
|
54
|
+
|
|
55
|
+
gc.enable()
|
|
49
56
|
|
|
50
57
|
_stop_event = threading.Event()
|
|
51
58
|
|
|
52
59
|
|
|
53
60
|
class TrunkProcessEnum(Enum):
|
|
54
|
-
HTTP =
|
|
55
|
-
MYSQL =
|
|
56
|
-
MONGODB =
|
|
57
|
-
POSTGRES =
|
|
58
|
-
JOBS =
|
|
59
|
-
TASKS =
|
|
60
|
-
ML_TASK_QUEUE =
|
|
61
|
-
MCP =
|
|
62
|
-
LITELLM =
|
|
61
|
+
HTTP = "http"
|
|
62
|
+
MYSQL = "mysql"
|
|
63
|
+
MONGODB = "mongodb"
|
|
64
|
+
POSTGRES = "postgres"
|
|
65
|
+
JOBS = "jobs"
|
|
66
|
+
TASKS = "tasks"
|
|
67
|
+
ML_TASK_QUEUE = "ml_task_queue"
|
|
68
|
+
MCP = "mcp"
|
|
69
|
+
LITELLM = "litellm"
|
|
70
|
+
A2A = "a2a"
|
|
63
71
|
|
|
64
72
|
@classmethod
|
|
65
73
|
def _missing_(cls, value):
|
|
@@ -97,7 +105,8 @@ class TrunkProcessData:
|
|
|
97
105
|
self._restarts_time.append(current_time_seconds)
|
|
98
106
|
if self.max_restart_interval_seconds > 0:
|
|
99
107
|
self._restarts_time = [
|
|
100
|
-
x
|
|
108
|
+
x
|
|
109
|
+
for x in self._restarts_time
|
|
101
110
|
if x >= (current_time_seconds - self.max_restart_interval_seconds)
|
|
102
111
|
]
|
|
103
112
|
if len(self._restarts_time) > self.max_restart_count:
|
|
@@ -114,12 +123,17 @@ class TrunkProcessData:
|
|
|
114
123
|
"""
|
|
115
124
|
if config.is_cloud:
|
|
116
125
|
return False
|
|
117
|
-
if sys.platform in (
|
|
118
|
-
return
|
|
126
|
+
if sys.platform in ("linux", "darwin"):
|
|
127
|
+
return (
|
|
128
|
+
self.restart_on_failure
|
|
129
|
+
and self.process.exitcode == -signal.SIGKILL.value
|
|
130
|
+
)
|
|
119
131
|
else:
|
|
120
132
|
if self.max_restart_count == 0:
|
|
121
133
|
# to prevent infinity restarts, max_restart_count should be > 0
|
|
122
|
-
logger.warning(
|
|
134
|
+
logger.warning(
|
|
135
|
+
"In the current OS, it is not possible to use `max_restart_count=0`"
|
|
136
|
+
)
|
|
123
137
|
return False
|
|
124
138
|
return self.restart_on_failure
|
|
125
139
|
|
|
@@ -160,22 +174,25 @@ def set_error_model_status_by_pids(unexisting_pids: List[int]):
|
|
|
160
174
|
db.session.query(db.Predictor)
|
|
161
175
|
.filter(
|
|
162
176
|
db.Predictor.deleted_at.is_(None),
|
|
163
|
-
db.Predictor.status.not_in(
|
|
164
|
-
db.PREDICTOR_STATUS.COMPLETE,
|
|
165
|
-
|
|
166
|
-
])
|
|
177
|
+
db.Predictor.status.not_in(
|
|
178
|
+
[db.PREDICTOR_STATUS.COMPLETE, db.PREDICTOR_STATUS.ERROR]
|
|
179
|
+
),
|
|
167
180
|
)
|
|
168
181
|
.all()
|
|
169
182
|
)
|
|
170
183
|
for predictor_record in predictor_records:
|
|
171
|
-
predictor_process_id = (predictor_record.training_metadata or {}).get(
|
|
184
|
+
predictor_process_id = (predictor_record.training_metadata or {}).get(
|
|
185
|
+
"process_id"
|
|
186
|
+
)
|
|
172
187
|
if predictor_process_id in unexisting_pids:
|
|
173
188
|
predictor_record.status = db.PREDICTOR_STATUS.ERROR
|
|
174
189
|
if isinstance(predictor_record.data, dict) is False:
|
|
175
190
|
predictor_record.data = {}
|
|
176
|
-
if
|
|
177
|
-
predictor_record.data[
|
|
178
|
-
|
|
191
|
+
if "error" not in predictor_record.data:
|
|
192
|
+
predictor_record.data["error"] = (
|
|
193
|
+
"The training process was terminated for unknown reasons"
|
|
194
|
+
)
|
|
195
|
+
flag_modified(predictor_record, "data")
|
|
179
196
|
db.session.commit()
|
|
180
197
|
|
|
181
198
|
|
|
@@ -187,10 +204,9 @@ def set_error_model_status_for_unfinished():
|
|
|
187
204
|
db.session.query(db.Predictor)
|
|
188
205
|
.filter(
|
|
189
206
|
db.Predictor.deleted_at.is_(None),
|
|
190
|
-
db.Predictor.status.not_in(
|
|
191
|
-
db.PREDICTOR_STATUS.COMPLETE,
|
|
192
|
-
|
|
193
|
-
])
|
|
207
|
+
db.Predictor.status.not_in(
|
|
208
|
+
[db.PREDICTOR_STATUS.COMPLETE, db.PREDICTOR_STATUS.ERROR]
|
|
209
|
+
),
|
|
194
210
|
)
|
|
195
211
|
.all()
|
|
196
212
|
)
|
|
@@ -198,34 +214,131 @@ def set_error_model_status_for_unfinished():
|
|
|
198
214
|
predictor_record.status = db.PREDICTOR_STATUS.ERROR
|
|
199
215
|
if isinstance(predictor_record.data, dict) is False:
|
|
200
216
|
predictor_record.data = {}
|
|
201
|
-
if
|
|
202
|
-
predictor_record.data[
|
|
203
|
-
flag_modified(predictor_record,
|
|
217
|
+
if "error" not in predictor_record.data:
|
|
218
|
+
predictor_record.data["error"] = "Unknown error"
|
|
219
|
+
flag_modified(predictor_record, "data")
|
|
204
220
|
db.session.commit()
|
|
205
221
|
|
|
206
222
|
|
|
207
223
|
def do_clean_process_marks():
|
|
208
|
-
"""delete unexisting 'process marks'
|
|
209
|
-
"""
|
|
224
|
+
"""delete unexisting 'process marks'"""
|
|
210
225
|
while _stop_event.wait(timeout=5) is False:
|
|
211
226
|
unexisting_pids = clean_unlinked_process_marks()
|
|
212
227
|
if not config.is_cloud and len(unexisting_pids) > 0:
|
|
213
228
|
set_error_model_status_by_pids(unexisting_pids)
|
|
214
229
|
|
|
215
230
|
|
|
216
|
-
|
|
231
|
+
def create_permanent_integrations():
|
|
232
|
+
"""
|
|
233
|
+
Create permanent integrations, for now only the 'files' integration.
|
|
234
|
+
NOTE: this is intentional to avoid importing integration_controller
|
|
235
|
+
"""
|
|
236
|
+
integration_name = "files"
|
|
237
|
+
existing = (
|
|
238
|
+
db.session.query(db.Integration)
|
|
239
|
+
.filter_by(name=integration_name, company_id=None)
|
|
240
|
+
.first()
|
|
241
|
+
)
|
|
242
|
+
if existing is None:
|
|
243
|
+
integration_record = db.Integration(
|
|
244
|
+
name=integration_name,
|
|
245
|
+
data={},
|
|
246
|
+
engine=integration_name,
|
|
247
|
+
company_id=None,
|
|
248
|
+
)
|
|
249
|
+
db.session.add(integration_record)
|
|
250
|
+
try:
|
|
251
|
+
db.session.commit()
|
|
252
|
+
except Exception as e:
|
|
253
|
+
logger.error(
|
|
254
|
+
f"Failed to commit permanent integration {integration_name}: {e}"
|
|
255
|
+
)
|
|
256
|
+
db.session.rollback()
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
def validate_default_project() -> None:
|
|
260
|
+
"""Handle 'default_project' config option.
|
|
261
|
+
Project with the name specified in 'default_project' must exists and be marked with
|
|
262
|
+
'is_default' metadata. If it is not possible, then terminate the process with error.
|
|
263
|
+
Note: this can be done using 'project_controller', but we want to save init time and used RAM.
|
|
264
|
+
"""
|
|
265
|
+
new_default_project_name = config.get("default_project")
|
|
266
|
+
logger.debug(f"Checking if default project {new_default_project_name} exists")
|
|
267
|
+
filter_company_id = ctx.company_id if ctx.company_id is not None else 0
|
|
268
|
+
|
|
269
|
+
current_default_project: db.Project | None = db.Project.query.filter(
|
|
270
|
+
db.Project.company_id == filter_company_id,
|
|
271
|
+
db.Project.metadata_["is_default"].as_boolean() == True, # noqa
|
|
272
|
+
).first()
|
|
273
|
+
|
|
274
|
+
if current_default_project is None:
|
|
275
|
+
# Legacy: If the default project does not exist, mark the new one as default.
|
|
276
|
+
existing_project = db.Project.query.filter(
|
|
277
|
+
db.Project.company_id == filter_company_id,
|
|
278
|
+
func.lower(db.Project.name) == func.lower(new_default_project_name),
|
|
279
|
+
).first()
|
|
280
|
+
if existing_project is None:
|
|
281
|
+
logger.critical(
|
|
282
|
+
f"A project with the name '{new_default_project_name}' does not exist"
|
|
283
|
+
)
|
|
284
|
+
sys.exit(1)
|
|
285
|
+
|
|
286
|
+
existing_project.metadata_ = {"is_default": True}
|
|
287
|
+
flag_modified(existing_project, "metadata_")
|
|
288
|
+
db.session.commit()
|
|
289
|
+
elif current_default_project.name != new_default_project_name:
|
|
290
|
+
# If the default project exists, but the name is different, update the name.
|
|
291
|
+
existing_project = db.Project.query.filter(
|
|
292
|
+
db.Project.company_id == filter_company_id,
|
|
293
|
+
func.lower(db.Project.name) == func.lower(new_default_project_name),
|
|
294
|
+
).first()
|
|
295
|
+
if existing_project is not None:
|
|
296
|
+
logger.critical(
|
|
297
|
+
f"A project with the name '{new_default_project_name}' already exists"
|
|
298
|
+
)
|
|
299
|
+
sys.exit(1)
|
|
300
|
+
current_default_project.name = new_default_project_name
|
|
301
|
+
db.session.commit()
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
def start_process(trunc_process_data: TrunkProcessData) -> None:
|
|
305
|
+
"""Start a process.
|
|
306
|
+
|
|
307
|
+
Args:
|
|
308
|
+
trunc_process_data (TrunkProcessData): The data of the process to start.
|
|
309
|
+
"""
|
|
310
|
+
mp_ctx = mp.get_context("spawn")
|
|
311
|
+
logger.info(f"{trunc_process_data.name} API: starting...")
|
|
312
|
+
try:
|
|
313
|
+
trunc_process_data.process = mp_ctx.Process(
|
|
314
|
+
target=trunc_process_data.entrypoint,
|
|
315
|
+
args=trunc_process_data.args,
|
|
316
|
+
name=trunc_process_data.name,
|
|
317
|
+
)
|
|
318
|
+
trunc_process_data.process.start()
|
|
319
|
+
except Exception as e:
|
|
320
|
+
logger.error(
|
|
321
|
+
f"Failed to start {trunc_process_data.name} API with exception {e}\n{traceback.format_exc()}"
|
|
322
|
+
)
|
|
323
|
+
close_api_gracefully(trunc_processes_struct)
|
|
324
|
+
raise e
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
if __name__ == "__main__":
|
|
328
|
+
mp.freeze_support()
|
|
217
329
|
# warn if less than 1Gb of free RAM
|
|
218
330
|
if psutil.virtual_memory().available < (1 << 30):
|
|
219
331
|
logger.warning(
|
|
220
|
-
|
|
221
|
-
+
|
|
332
|
+
"The system is running low on memory. "
|
|
333
|
+
+ "This may impact the stability and performance of the program."
|
|
222
334
|
)
|
|
223
335
|
|
|
224
336
|
ctx.set_default()
|
|
225
337
|
|
|
226
338
|
# ---- CHECK SYSTEM ----
|
|
227
339
|
if not (sys.version_info[0] >= 3 and sys.version_info[1] >= 10):
|
|
228
|
-
print(
|
|
340
|
+
print(
|
|
341
|
+
"""
|
|
229
342
|
MindsDB requires Python >= 3.10 to run
|
|
230
343
|
|
|
231
344
|
Once you have supported Python version installed you can start mindsdb as follows:
|
|
@@ -241,11 +354,12 @@ if __name__ == '__main__':
|
|
|
241
354
|
python3 -m mindsdb
|
|
242
355
|
|
|
243
356
|
More instructions in https://docs.mindsdb.com
|
|
244
|
-
"""
|
|
357
|
+
"""
|
|
358
|
+
)
|
|
245
359
|
exit(1)
|
|
246
360
|
|
|
247
361
|
if config.cmd_args.version:
|
|
248
|
-
print(f
|
|
362
|
+
print(f"MindsDB {mindsdb_version}")
|
|
249
363
|
sys.exit(0)
|
|
250
364
|
|
|
251
365
|
config.raise_warnings(logger=logger)
|
|
@@ -254,23 +368,23 @@ if __name__ == '__main__':
|
|
|
254
368
|
if os.environ.get("FLASK_SECRET_KEY") is None:
|
|
255
369
|
os.environ["FLASK_SECRET_KEY"] = secrets.token_hex(32)
|
|
256
370
|
|
|
257
|
-
if os.environ.get(
|
|
371
|
+
if os.environ.get("ARROW_DEFAULT_MEMORY_POOL") is None:
|
|
258
372
|
try:
|
|
259
373
|
"""It seems like snowflake handler have memory issue that related to pyarrow. Memory usage keep growing with
|
|
260
374
|
requests. This is related to 'memory pool' that is 'mimalloc' by default: it is fastest but use a lot of ram
|
|
261
375
|
"""
|
|
262
376
|
import pyarrow as pa
|
|
377
|
+
|
|
263
378
|
try:
|
|
264
379
|
pa.jemalloc_memory_pool()
|
|
265
|
-
os.environ[
|
|
380
|
+
os.environ["ARROW_DEFAULT_MEMORY_POOL"] = "jemalloc"
|
|
266
381
|
except NotImplementedError:
|
|
267
382
|
pa.system_memory_pool()
|
|
268
|
-
os.environ[
|
|
383
|
+
os.environ["ARROW_DEFAULT_MEMORY_POOL"] = "system"
|
|
269
384
|
except Exception:
|
|
270
385
|
pass
|
|
271
386
|
|
|
272
387
|
db.init()
|
|
273
|
-
mp.freeze_support()
|
|
274
388
|
|
|
275
389
|
environment = config["environment"]
|
|
276
390
|
if environment == "aws_marketplace":
|
|
@@ -281,87 +395,18 @@ if __name__ == '__main__':
|
|
|
281
395
|
elif environment != "local":
|
|
282
396
|
try:
|
|
283
397
|
aws_meta_data = get_aws_meta_data()
|
|
284
|
-
config.update({
|
|
285
|
-
'aws_meta_data': aws_meta_data
|
|
286
|
-
})
|
|
398
|
+
config.update({"aws_meta_data": aws_meta_data})
|
|
287
399
|
except Exception:
|
|
288
400
|
pass
|
|
289
401
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
if not is_cloud:
|
|
293
|
-
logger.debug("Applying database migrations")
|
|
294
|
-
try:
|
|
295
|
-
from mindsdb.migrations import migrate
|
|
296
|
-
migrate.migrate_to_head()
|
|
297
|
-
except Exception as e:
|
|
298
|
-
logger.error(f"Error! Something went wrong during DB migrations: {e}")
|
|
299
|
-
|
|
300
|
-
logger.debug(f"Checking if default project {config.get('default_project')} exists")
|
|
301
|
-
project_controller = ProjectController()
|
|
302
|
-
|
|
303
|
-
try:
|
|
304
|
-
current_default_project = project_controller.get(is_default=True)
|
|
305
|
-
except EntityNotExistsError:
|
|
306
|
-
# In previous versions, the default project could be deleted. This is no longer possible.
|
|
307
|
-
current_default_project = None
|
|
308
|
-
|
|
309
|
-
if current_default_project:
|
|
310
|
-
if current_default_project.record.name != config.get('default_project'):
|
|
311
|
-
try:
|
|
312
|
-
project_controller.get(name=config.get('default_project'))
|
|
313
|
-
log.critical(f"A project with the name '{config.get('default_project')}' already exists")
|
|
314
|
-
sys.exit(1)
|
|
315
|
-
except EntityNotExistsError:
|
|
316
|
-
pass
|
|
317
|
-
project_controller.update(current_default_project.record.id, new_name=config.get('default_project'))
|
|
318
|
-
|
|
319
|
-
# Legacy: If the default project does not exist, mark the new one as default.
|
|
320
|
-
else:
|
|
321
|
-
try:
|
|
322
|
-
project_controller.get(name=config.get('default_project'))
|
|
323
|
-
except EntityNotExistsError:
|
|
324
|
-
log.critical(
|
|
325
|
-
f"A project with the name '{config.get('default_project')}' does not exist"
|
|
326
|
-
)
|
|
327
|
-
raise
|
|
328
|
-
|
|
329
|
-
project_controller.update(
|
|
330
|
-
name=config.get('default_project'),
|
|
331
|
-
new_metadata={
|
|
332
|
-
"is_default": True
|
|
333
|
-
}
|
|
334
|
-
)
|
|
335
|
-
|
|
336
|
-
apis = os.getenv('MINDSDB_APIS') or config.cmd_args.api
|
|
402
|
+
apis = os.getenv("MINDSDB_APIS") or config.cmd_args.api
|
|
337
403
|
|
|
338
404
|
if apis is None: # If "--api" option is not specified, start the default APIs
|
|
339
405
|
api_arr = [TrunkProcessEnum.HTTP, TrunkProcessEnum.MYSQL]
|
|
340
406
|
elif apis == "": # If "--api=" (blank) is specified, don't start any APIs
|
|
341
407
|
api_arr = []
|
|
342
408
|
else: # The user has provided a list of APIs to start
|
|
343
|
-
api_arr = [TrunkProcessEnum(name) for name in apis.split(
|
|
344
|
-
|
|
345
|
-
if config.cmd_args.install_handlers is not None:
|
|
346
|
-
handlers_list = [s.strip() for s in config.cmd_args.install_handlers.split(",")]
|
|
347
|
-
# import_meta = handler_meta.get('import', {})
|
|
348
|
-
for handler_name, handler_meta in integration_controller.get_handlers_import_status().items():
|
|
349
|
-
if handler_name not in handlers_list:
|
|
350
|
-
continue
|
|
351
|
-
import_meta = handler_meta.get("import", {})
|
|
352
|
-
if import_meta.get("success") is True:
|
|
353
|
-
logger.info(f"{'{0: <18}'.format(handler_name)} - already installed")
|
|
354
|
-
continue
|
|
355
|
-
result = install_dependencies(import_meta.get("dependencies", []))
|
|
356
|
-
if result.get("success") is True:
|
|
357
|
-
logger.info(
|
|
358
|
-
f"{'{0: <18}'.format(handler_name)} - successfully installed"
|
|
359
|
-
)
|
|
360
|
-
else:
|
|
361
|
-
logger.info(
|
|
362
|
-
f"{'{0: <18}'.format(handler_name)} - error during dependencies installation: {result.get('error_message', 'unknown error')}"
|
|
363
|
-
)
|
|
364
|
-
sys.exit(0)
|
|
409
|
+
api_arr = [TrunkProcessEnum(name) for name in apis.split(",")]
|
|
365
410
|
|
|
366
411
|
logger.info(f"Version: {mindsdb_version}")
|
|
367
412
|
logger.info(f"Configuration file: {config.config_path or 'absent'}")
|
|
@@ -370,50 +415,32 @@ if __name__ == '__main__':
|
|
|
370
415
|
logger.debug(f"System config: {config.auto_config}")
|
|
371
416
|
logger.debug(f"Env config: {config.env_config}")
|
|
372
417
|
|
|
418
|
+
is_cloud = config.is_cloud
|
|
373
419
|
unexisting_pids = clean_unlinked_process_marks()
|
|
374
420
|
if not is_cloud:
|
|
421
|
+
logger.debug("Applying database migrations")
|
|
422
|
+
try:
|
|
423
|
+
from mindsdb.migrations import migrate
|
|
424
|
+
|
|
425
|
+
migrate.migrate_to_head()
|
|
426
|
+
except Exception as e:
|
|
427
|
+
logger.error(f"Error! Something went wrong during DB migrations: {e}")
|
|
428
|
+
|
|
429
|
+
validate_default_project()
|
|
430
|
+
|
|
375
431
|
if len(unexisting_pids) > 0:
|
|
376
432
|
set_error_model_status_by_pids(unexisting_pids)
|
|
377
433
|
set_error_model_status_for_unfinished()
|
|
378
|
-
|
|
379
|
-
integration_controller.create_permanent_integrations()
|
|
380
|
-
|
|
381
|
-
# region Mark old predictors as outdated
|
|
382
|
-
is_modified = False
|
|
383
|
-
predictor_records = (
|
|
384
|
-
db.session.query(db.Predictor)
|
|
385
|
-
.filter(db.Predictor.deleted_at.is_(None))
|
|
386
|
-
.all()
|
|
387
|
-
)
|
|
388
|
-
if len(predictor_records) > 0:
|
|
389
|
-
(
|
|
390
|
-
sucess,
|
|
391
|
-
compatible_versions,
|
|
392
|
-
) = get_versions_where_predictors_become_obsolete()
|
|
393
|
-
if sucess is True:
|
|
394
|
-
compatible_versions = [version.parse(x) for x in compatible_versions]
|
|
395
|
-
mindsdb_version_parsed = version.parse(mindsdb_version)
|
|
396
|
-
compatible_versions = [x for x in compatible_versions if x <= mindsdb_version_parsed]
|
|
397
|
-
if len(compatible_versions) > 0:
|
|
398
|
-
last_compatible_version = compatible_versions[-1]
|
|
399
|
-
for predictor_record in predictor_records:
|
|
400
|
-
if (
|
|
401
|
-
isinstance(predictor_record.mindsdb_version, str)
|
|
402
|
-
and version.parse(predictor_record.mindsdb_version) < last_compatible_version
|
|
403
|
-
):
|
|
404
|
-
predictor_record.update_status = "available"
|
|
405
|
-
is_modified = True
|
|
406
|
-
if is_modified is True:
|
|
407
|
-
db.session.commit()
|
|
408
|
-
# endregion
|
|
434
|
+
create_permanent_integrations()
|
|
409
435
|
|
|
410
436
|
clean_process_marks()
|
|
411
437
|
|
|
412
438
|
# Get config values for APIs
|
|
413
|
-
http_api_config = config.get(
|
|
414
|
-
mysql_api_config = config.get(
|
|
415
|
-
mcp_api_config = config.get(
|
|
416
|
-
litellm_api_config = config.get(
|
|
439
|
+
http_api_config = config.get("api", {}).get("http", {})
|
|
440
|
+
mysql_api_config = config.get("api", {}).get("mysql", {})
|
|
441
|
+
mcp_api_config = config.get("api", {}).get("mcp", {})
|
|
442
|
+
litellm_api_config = config.get("api", {}).get("litellm", {})
|
|
443
|
+
a2a_api_config = config.get("a2a", {})
|
|
417
444
|
trunc_processes_struct = {
|
|
418
445
|
TrunkProcessEnum.HTTP: TrunkProcessData(
|
|
419
446
|
name=TrunkProcessEnum.HTTP.value,
|
|
@@ -469,6 +496,7 @@ if __name__ == '__main__':
|
|
|
469
496
|
entrypoint=start_mcp,
|
|
470
497
|
port=mcp_api_config.get('port', 47337),
|
|
471
498
|
args=(config.cmd_args.verbose,),
|
|
499
|
+
need_to_run=mcp_api_config.get('need_to_run', False),
|
|
472
500
|
restart_on_failure=mcp_api_config.get('restart_on_failure', False),
|
|
473
501
|
max_restart_count=mcp_api_config.get('max_restart_count', TrunkProcessData.max_restart_count),
|
|
474
502
|
max_restart_interval_seconds=mcp_api_config.get(
|
|
@@ -485,6 +513,20 @@ if __name__ == '__main__':
|
|
|
485
513
|
max_restart_interval_seconds=litellm_api_config.get(
|
|
486
514
|
'max_restart_interval_seconds', TrunkProcessData.max_restart_interval_seconds
|
|
487
515
|
)
|
|
516
|
+
),
|
|
517
|
+
TrunkProcessEnum.A2A: TrunkProcessData(
|
|
518
|
+
name=TrunkProcessEnum.A2A.value,
|
|
519
|
+
entrypoint=start_a2a,
|
|
520
|
+
port=a2a_api_config.get('port', 8001),
|
|
521
|
+
args=(config.cmd_args.verbose,),
|
|
522
|
+
need_to_run=a2a_api_config.get('enabled', False),
|
|
523
|
+
restart_on_failure=a2a_api_config.get('restart_on_failure', True),
|
|
524
|
+
max_restart_count=a2a_api_config.get(
|
|
525
|
+
'max_restart_count', TrunkProcessData.max_restart_count
|
|
526
|
+
),
|
|
527
|
+
max_restart_interval_seconds=a2a_api_config.get(
|
|
528
|
+
'max_restart_interval_seconds', TrunkProcessData.max_restart_interval_seconds
|
|
529
|
+
)
|
|
488
530
|
)
|
|
489
531
|
}
|
|
490
532
|
|
|
@@ -494,35 +536,20 @@ if __name__ == '__main__':
|
|
|
494
536
|
else:
|
|
495
537
|
logger.error(f"ERROR: {api_enum} API is not a valid api in config")
|
|
496
538
|
|
|
497
|
-
if config[
|
|
539
|
+
if config["jobs"]["disable"] is False:
|
|
498
540
|
trunc_processes_struct[TrunkProcessEnum.JOBS].need_to_run = True
|
|
499
541
|
|
|
500
|
-
if config[
|
|
542
|
+
if config["tasks"]["disable"] is False:
|
|
501
543
|
trunc_processes_struct[TrunkProcessEnum.TASKS].need_to_run = True
|
|
502
544
|
|
|
503
545
|
if config.cmd_args.ml_task_queue_consumer is True:
|
|
504
546
|
trunc_processes_struct[TrunkProcessEnum.ML_TASK_QUEUE].need_to_run = True
|
|
505
547
|
|
|
506
|
-
def start_process(trunc_process_data):
|
|
507
|
-
# TODO this 'ctx' is eclipsing 'context' class imported as 'ctx'
|
|
508
|
-
ctx = mp.get_context("spawn")
|
|
509
|
-
logger.info(f"{trunc_process_data.name} API: starting...")
|
|
510
|
-
try:
|
|
511
|
-
trunc_process_data.process = ctx.Process(
|
|
512
|
-
target=trunc_process_data.entrypoint,
|
|
513
|
-
args=trunc_process_data.args,
|
|
514
|
-
name=trunc_process_data.name
|
|
515
|
-
)
|
|
516
|
-
trunc_process_data.process.start()
|
|
517
|
-
except Exception as e:
|
|
518
|
-
logger.error(
|
|
519
|
-
f"Failed to start {trunc_process_data.name} API with exception {e}\n{traceback.format_exc()}"
|
|
520
|
-
)
|
|
521
|
-
close_api_gracefully(trunc_processes_struct)
|
|
522
|
-
raise e
|
|
523
|
-
|
|
524
548
|
for trunc_process_data in trunc_processes_struct.values():
|
|
525
|
-
if
|
|
549
|
+
if (
|
|
550
|
+
trunc_process_data.started is True
|
|
551
|
+
or trunc_process_data.need_to_run is False
|
|
552
|
+
):
|
|
526
553
|
continue
|
|
527
554
|
start_process(trunc_process_data)
|
|
528
555
|
|
|
@@ -542,10 +569,11 @@ if __name__ == '__main__':
|
|
|
542
569
|
wait_api_start(
|
|
543
570
|
trunc_process_data.name,
|
|
544
571
|
trunc_process_data.process.pid,
|
|
545
|
-
trunc_process_data.port
|
|
572
|
+
trunc_process_data.port,
|
|
546
573
|
)
|
|
547
574
|
for trunc_process_data in trunc_processes_struct.values()
|
|
548
|
-
if trunc_process_data.port is not None
|
|
575
|
+
if trunc_process_data.port is not None
|
|
576
|
+
and trunc_process_data.need_to_run is True
|
|
549
577
|
]
|
|
550
578
|
for future in asyncio.as_completed(futures):
|
|
551
579
|
api_name, port, started = await future
|
|
@@ -568,7 +596,9 @@ if __name__ == '__main__':
|
|
|
568
596
|
finally:
|
|
569
597
|
if trunc_process_data.should_restart:
|
|
570
598
|
if trunc_process_data.request_restart_attempt():
|
|
571
|
-
logger.warning(
|
|
599
|
+
logger.warning(
|
|
600
|
+
f"{trunc_process_data.name} API: stopped unexpectedly, restarting"
|
|
601
|
+
)
|
|
572
602
|
trunc_process_data.process = None
|
|
573
603
|
if trunc_process_data.name == TrunkProcessEnum.HTTP.value:
|
|
574
604
|
# do not open GUI on HTTP API restart
|
|
@@ -577,7 +607,7 @@ if __name__ == '__main__':
|
|
|
577
607
|
api_name, port, started = await wait_api_start(
|
|
578
608
|
trunc_process_data.name,
|
|
579
609
|
trunc_process_data.process.pid,
|
|
580
|
-
trunc_process_data.port
|
|
610
|
+
trunc_process_data.port,
|
|
581
611
|
)
|
|
582
612
|
if started:
|
|
583
613
|
logger.info(f"{api_name} API: started on {port}")
|
|
@@ -587,7 +617,7 @@ if __name__ == '__main__':
|
|
|
587
617
|
finish = True
|
|
588
618
|
logger.error(
|
|
589
619
|
f'The "{trunc_process_data.name}" process could not restart after failure. '
|
|
590
|
-
|
|
620
|
+
"There will be no further attempts to restart."
|
|
591
621
|
)
|
|
592
622
|
else:
|
|
593
623
|
finish = True
|
|
@@ -600,13 +630,13 @@ if __name__ == '__main__':
|
|
|
600
630
|
for trunc_process_data in trunc_processes_struct.values()
|
|
601
631
|
if trunc_process_data.need_to_run is True
|
|
602
632
|
],
|
|
603
|
-
return_exceptions=False
|
|
633
|
+
return_exceptions=False,
|
|
604
634
|
)
|
|
605
635
|
|
|
606
636
|
ioloop = asyncio.new_event_loop()
|
|
607
637
|
ioloop.run_until_complete(wait_apis_start())
|
|
608
638
|
|
|
609
|
-
threading.Thread(target=do_clean_process_marks, name=
|
|
639
|
+
threading.Thread(target=do_clean_process_marks, name="clean_process_marks").start()
|
|
610
640
|
|
|
611
641
|
ioloop.run_until_complete(gather_apis())
|
|
612
642
|
ioloop.close()
|
|
File without changes
|