MindsDB 25.5.3.0__py3-none-any.whl → 25.5.4.1__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 +8 -8
- mindsdb/__main__.py +127 -79
- mindsdb/api/a2a/__init__.py +0 -0
- mindsdb/api/a2a/__main__.py +144 -0
- mindsdb/api/a2a/agent.py +308 -0
- mindsdb/api/a2a/common/__init__.py +0 -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 +86 -0
- mindsdb/api/a2a/task_manager.py +560 -0
- mindsdb/api/executor/command_executor.py +185 -309
- 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/config.py +61 -86
- 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/byom_handler/requirements.txt +1 -2
- 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/lancedb_handler/requirements.txt +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/litellm_handler/litellm_handler.py +37 -20
- 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/llm/config.py +13 -0
- mindsdb/integrations/libs/llm/utils.py +37 -65
- 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/rag/rerankers/base_reranker.py +230 -227
- mindsdb/integrations/utilities/utils.py +3 -3
- mindsdb/interfaces/agents/agents_controller.py +164 -1
- mindsdb/interfaces/agents/constants.py +32 -13
- mindsdb/interfaces/agents/langchain_agent.py +106 -95
- mindsdb/interfaces/agents/mindsdb_database_agent.py +101 -2
- mindsdb/interfaces/knowledge_base/controller.py +250 -216
- 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 +287 -216
- mindsdb/utilities/starters.py +13 -0
- {mindsdb-25.5.3.0.dist-info → mindsdb-25.5.4.1.dist-info}/METADATA +646 -698
- {mindsdb-25.5.3.0.dist-info → mindsdb-25.5.4.1.dist-info}/RECORD +312 -295
- {mindsdb-25.5.3.0.dist-info → mindsdb-25.5.4.1.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.1.dist-info}/licenses/LICENSE +0 -0
- {mindsdb-25.5.3.0.dist-info → mindsdb-25.5.4.1.dist-info}/top_level.txt +0 -0
|
@@ -8,7 +8,7 @@ from mindsdb.integrations.utilities.query_traversal import query_traversal
|
|
|
8
8
|
from mindsdb.interfaces.query_context.context_controller import RunningQuery
|
|
9
9
|
from mindsdb.api.executor.sql_query.result_set import ResultSet
|
|
10
10
|
from mindsdb.utilities import log
|
|
11
|
-
from mindsdb.utilities.config import
|
|
11
|
+
from mindsdb.utilities.config import config
|
|
12
12
|
from mindsdb.utilities.partitioning import get_max_thread_count, split_data_frame
|
|
13
13
|
from mindsdb.api.executor.sql_query.steps.fetch_dataframe import get_table_alias, get_fill_param_fnc
|
|
14
14
|
from mindsdb.utilities.context_executor import ContextThreadPoolExecutor
|
|
@@ -64,8 +64,6 @@ class FetchDataframePartitionCall(BaseStepCall):
|
|
|
64
64
|
self.current_step_num = step.step_num
|
|
65
65
|
self.substeps = step.steps
|
|
66
66
|
|
|
67
|
-
config = Config()
|
|
68
|
-
|
|
69
67
|
# ml task queue enabled?
|
|
70
68
|
use_threads, thread_count = False, None
|
|
71
69
|
if config['ml_task_queue']['type'] == 'redis':
|
|
@@ -95,21 +93,8 @@ class FetchDataframePartitionCall(BaseStepCall):
|
|
|
95
93
|
"""
|
|
96
94
|
|
|
97
95
|
results = []
|
|
98
|
-
while True:
|
|
99
|
-
|
|
100
|
-
# fetch batch
|
|
101
|
-
query2 = run_query.get_partition_query(self.current_step_num, query)
|
|
102
|
-
response = self.dn.query(
|
|
103
|
-
query=query2,
|
|
104
|
-
session=self.session
|
|
105
|
-
)
|
|
106
|
-
df = response.data_frame
|
|
107
|
-
|
|
108
|
-
if df is None or len(df) == 0:
|
|
109
|
-
break
|
|
110
96
|
|
|
111
|
-
|
|
112
|
-
max_track_value = run_query.get_max_track_value(df)
|
|
97
|
+
for df in run_query.get_partitions(self.dn, self, query):
|
|
113
98
|
try:
|
|
114
99
|
sub_data = self.exec_sub_steps(df)
|
|
115
100
|
results.append(sub_data)
|
|
@@ -119,8 +104,6 @@ class FetchDataframePartitionCall(BaseStepCall):
|
|
|
119
104
|
else:
|
|
120
105
|
raise e
|
|
121
106
|
|
|
122
|
-
run_query.set_progress(df, max_track_value)
|
|
123
|
-
|
|
124
107
|
return self.concat_results(results)
|
|
125
108
|
|
|
126
109
|
def concat_results(self, results: List[ResultSet]) -> ResultSet:
|
|
@@ -135,7 +118,7 @@ class FetchDataframePartitionCall(BaseStepCall):
|
|
|
135
118
|
|
|
136
119
|
data = ResultSet()
|
|
137
120
|
if len(df_list) > 0:
|
|
138
|
-
data.from_df_cols(pd.concat(df_list), col_names)
|
|
121
|
+
data = ResultSet.from_df_cols(pd.concat(df_list), col_names)
|
|
139
122
|
|
|
140
123
|
return data
|
|
141
124
|
|
|
@@ -147,10 +130,7 @@ class FetchDataframePartitionCall(BaseStepCall):
|
|
|
147
130
|
- substep are executed using result of previos step (like it is all fetched data is available)
|
|
148
131
|
- the final result is returned and used outside to concatenate with results of other's batches
|
|
149
132
|
"""
|
|
150
|
-
|
|
151
|
-
input_data = ResultSet()
|
|
152
|
-
|
|
153
|
-
input_data.from_df(
|
|
133
|
+
input_data = ResultSet.from_df(
|
|
154
134
|
df,
|
|
155
135
|
table_name=self.table_alias[1],
|
|
156
136
|
table_alias=self.table_alias[2],
|
|
@@ -191,22 +171,7 @@ class FetchDataframePartitionCall(BaseStepCall):
|
|
|
191
171
|
|
|
192
172
|
with ContextThreadPoolExecutor(max_workers=thread_count) as executor:
|
|
193
173
|
|
|
194
|
-
|
|
195
|
-
# fetch batch
|
|
196
|
-
query2 = run_query.get_partition_query(self.current_step_num, query)
|
|
197
|
-
response = self.dn.query(
|
|
198
|
-
query=query2,
|
|
199
|
-
session=self.session
|
|
200
|
-
)
|
|
201
|
-
df = response.data_frame
|
|
202
|
-
|
|
203
|
-
if df is None or len(df) == 0:
|
|
204
|
-
# TODO detect circles: data handler ignores condition and output is repeated
|
|
205
|
-
|
|
206
|
-
# exit & stop workers
|
|
207
|
-
break
|
|
208
|
-
|
|
209
|
-
max_track_value = run_query.get_max_track_value(df)
|
|
174
|
+
for df in run_query.get_partitions(self.dn, self, query):
|
|
210
175
|
|
|
211
176
|
# split into chunks and send to workers
|
|
212
177
|
futures = []
|
|
@@ -225,9 +190,5 @@ class FetchDataframePartitionCall(BaseStepCall):
|
|
|
225
190
|
if self.sql_query.stop_event is not None and self.sql_query.stop_event.is_set():
|
|
226
191
|
executor.shutdown()
|
|
227
192
|
raise RuntimeError('Query is interrupted')
|
|
228
|
-
# TODO
|
|
229
|
-
# 1. get next batch without updating track_value:
|
|
230
|
-
# it allows to keep queue_in filled with data between fetching batches
|
|
231
|
-
run_query.set_progress(df, max_track_value)
|
|
232
193
|
|
|
233
194
|
return self.concat_results(results)
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
from mindsdb_sql_parser.ast import (
|
|
2
2
|
Identifier,
|
|
3
3
|
)
|
|
4
|
+
|
|
4
5
|
from mindsdb.api.executor.planner.steps import (
|
|
5
6
|
SaveToTable,
|
|
6
7
|
InsertToTable,
|
|
7
8
|
CreateTableStep
|
|
8
9
|
)
|
|
9
|
-
|
|
10
10
|
from mindsdb.api.executor.sql_query.result_set import ResultSet, Column
|
|
11
11
|
from mindsdb.api.executor.exceptions import (
|
|
12
12
|
NotSupportedYet,
|
|
13
13
|
LogicError
|
|
14
14
|
)
|
|
15
|
+
from mindsdb.integrations.libs.response import INF_SCHEMA_COLUMNS_NAMES
|
|
15
16
|
|
|
16
17
|
from .base import BaseStepCall
|
|
17
18
|
|
|
@@ -30,12 +31,32 @@ class InsertToTableCall(BaseStepCall):
|
|
|
30
31
|
if step.is_replace:
|
|
31
32
|
is_replace = True
|
|
32
33
|
|
|
34
|
+
if len(step.table.parts) > 1:
|
|
35
|
+
integration_name = step.table.parts[0]
|
|
36
|
+
table_name = Identifier(parts=step.table.parts[1:])
|
|
37
|
+
else:
|
|
38
|
+
integration_name = self.context['database']
|
|
39
|
+
table_name = step.table
|
|
40
|
+
|
|
41
|
+
dn = self.session.datahub.get(integration_name)
|
|
42
|
+
|
|
43
|
+
if hasattr(dn, 'create_table') is False:
|
|
44
|
+
raise NotSupportedYet(f"Creating table in '{integration_name}' is not supported")
|
|
45
|
+
|
|
33
46
|
if step.dataframe is not None:
|
|
34
47
|
data = self.steps_data[step.dataframe.result.step_num]
|
|
35
48
|
elif step.query is not None:
|
|
36
49
|
data = ResultSet()
|
|
37
|
-
|
|
38
|
-
|
|
50
|
+
if step.query.columns is None:
|
|
51
|
+
# Is query like: INSERT INTO table VALUES (...)
|
|
52
|
+
table_columns_df = dn.get_table_columns_df(str(table_name))
|
|
53
|
+
columns_names = table_columns_df[INF_SCHEMA_COLUMNS_NAMES.COLUMN_NAME].to_list()
|
|
54
|
+
for column_name in columns_names:
|
|
55
|
+
data.add_column(Column(name=column_name))
|
|
56
|
+
else:
|
|
57
|
+
# Is query like: INSERT INTO table (column_name, ...) VALUES (...)
|
|
58
|
+
for col in step.query.columns:
|
|
59
|
+
data.add_column(Column(name=col.name))
|
|
39
60
|
|
|
40
61
|
records = []
|
|
41
62
|
for row in step.query.values:
|
|
@@ -53,18 +74,6 @@ class InsertToTableCall(BaseStepCall):
|
|
|
53
74
|
else:
|
|
54
75
|
raise LogicError(f'Data not found for insert: {step}')
|
|
55
76
|
|
|
56
|
-
if len(step.table.parts) > 1:
|
|
57
|
-
integration_name = step.table.parts[0]
|
|
58
|
-
table_name = Identifier(parts=step.table.parts[1:])
|
|
59
|
-
else:
|
|
60
|
-
integration_name = self.context['database']
|
|
61
|
-
table_name = step.table
|
|
62
|
-
|
|
63
|
-
dn = self.session.datahub.get(integration_name)
|
|
64
|
-
|
|
65
|
-
if hasattr(dn, 'create_table') is False:
|
|
66
|
-
raise NotSupportedYet(f"Creating table in '{integration_name}' is not supported")
|
|
67
|
-
|
|
68
77
|
# del 'service' columns
|
|
69
78
|
for col in data.find_columns('__mindsdb_row_id'):
|
|
70
79
|
data.del_column(col)
|
|
@@ -101,7 +101,7 @@ class JoinStepCall(BaseStepCall):
|
|
|
101
101
|
resp_df.replace({np.nan: None}, inplace=True)
|
|
102
102
|
|
|
103
103
|
names_a.update(names_b)
|
|
104
|
-
data = ResultSet
|
|
104
|
+
data = ResultSet.from_df_cols(df=resp_df, columns_dict=names_a)
|
|
105
105
|
|
|
106
106
|
for col in data.find_columns('__mindsdb_row_id'):
|
|
107
107
|
data.del_column(col)
|
|
@@ -55,7 +55,7 @@ class SubSelectStepCall(BaseStepCall):
|
|
|
55
55
|
|
|
56
56
|
for col_name in query_cols:
|
|
57
57
|
if col_name not in result_cols:
|
|
58
|
-
result.add_column(Column(col_name))
|
|
58
|
+
result.add_column(Column(name=col_name))
|
|
59
59
|
|
|
60
60
|
# inject previous step values
|
|
61
61
|
if isinstance(query, Select):
|
|
@@ -69,12 +69,10 @@ class SubSelectStepCall(BaseStepCall):
|
|
|
69
69
|
df = result.to_df()
|
|
70
70
|
res = query_df(df, query, session=self.session)
|
|
71
71
|
|
|
72
|
-
result2 = ResultSet()
|
|
73
72
|
# get database from first column
|
|
74
73
|
database = result.columns[0].database
|
|
75
|
-
result2.from_df(res, database, table_name)
|
|
76
74
|
|
|
77
|
-
return
|
|
75
|
+
return ResultSet.from_df(res, database, table_name)
|
|
78
76
|
|
|
79
77
|
|
|
80
78
|
class QueryStepCall(BaseStepCall):
|
|
@@ -86,7 +84,7 @@ class QueryStepCall(BaseStepCall):
|
|
|
86
84
|
|
|
87
85
|
if step.from_table is not None:
|
|
88
86
|
if isinstance(step.from_table, pd.DataFrame):
|
|
89
|
-
result_set = ResultSet
|
|
87
|
+
result_set = ResultSet.from_df(step.from_table)
|
|
90
88
|
else:
|
|
91
89
|
result_set = self.steps_data[step.from_table.step_num]
|
|
92
90
|
else:
|
|
@@ -208,6 +206,4 @@ class QueryStepCall(BaseStepCall):
|
|
|
208
206
|
query.from_table = Identifier('df_table')
|
|
209
207
|
res = query_df(df, query, session=self.session)
|
|
210
208
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
return data
|
|
209
|
+
return ResultSet.from_df_cols(df=res, columns_dict=col_names, strict=False)
|
mindsdb/api/http/initialize.py
CHANGED
|
@@ -4,9 +4,11 @@ import mimetypes
|
|
|
4
4
|
import threading
|
|
5
5
|
import traceback
|
|
6
6
|
import webbrowser
|
|
7
|
+
|
|
7
8
|
from pathlib import Path
|
|
8
9
|
from http import HTTPStatus
|
|
9
10
|
|
|
11
|
+
|
|
10
12
|
import requests
|
|
11
13
|
from flask import Flask, url_for, make_response, request, send_from_directory
|
|
12
14
|
from flask.json import dumps
|
|
@@ -68,7 +70,9 @@ try:
|
|
|
68
70
|
from opentelemetry.instrumentation.flask import FlaskInstrumentor
|
|
69
71
|
from opentelemetry.instrumentation.requests import RequestsInstrumentor
|
|
70
72
|
except ImportError:
|
|
71
|
-
logger.debug(
|
|
73
|
+
logger.debug(
|
|
74
|
+
"OpenTelemetry is not avaiable. Please run `pip install -r requirements/requirements-opentelemetry.txt` to use it."
|
|
75
|
+
)
|
|
72
76
|
FlaskInstrumentor = _NoOpFlaskInstrumentor
|
|
73
77
|
RequestsInstrumentor = _NoOpRequestsInstrumentor
|
|
74
78
|
|
|
@@ -78,6 +82,7 @@ class Swagger_Api(Api):
|
|
|
78
82
|
This is a modification of the base Flask Restplus Api class due to the issue described here
|
|
79
83
|
https://github.com/noirbizarre/flask-restplus/issues/223
|
|
80
84
|
"""
|
|
85
|
+
|
|
81
86
|
@property
|
|
82
87
|
def specs_url(self):
|
|
83
88
|
return url_for(self.endpoint("specs"), _external=False)
|
|
@@ -92,7 +97,10 @@ def custom_output_json(data, code, headers=None):
|
|
|
92
97
|
def get_last_compatible_gui_version() -> Version:
|
|
93
98
|
logger.debug("Getting last compatible frontend..")
|
|
94
99
|
try:
|
|
95
|
-
res = requests.get(
|
|
100
|
+
res = requests.get(
|
|
101
|
+
"https://mindsdb-web-builds.s3.amazonaws.com/compatible-config.json",
|
|
102
|
+
timeout=5,
|
|
103
|
+
)
|
|
96
104
|
except (ConnectionError, requests.exceptions.ConnectionError) as e:
|
|
97
105
|
logger.error(f"Is no connection. {e}")
|
|
98
106
|
return False
|
|
@@ -118,13 +126,16 @@ def get_last_compatible_gui_version() -> Version:
|
|
|
118
126
|
gui_versions = {}
|
|
119
127
|
max_mindsdb_lv = None
|
|
120
128
|
max_gui_lv = None
|
|
121
|
-
for el in versions[
|
|
122
|
-
if el[
|
|
123
|
-
gui_lv = parse_version(el[
|
|
129
|
+
for el in versions["mindsdb"]:
|
|
130
|
+
if el["mindsdb_version"] is None:
|
|
131
|
+
gui_lv = parse_version(el["gui_version"])
|
|
124
132
|
else:
|
|
125
|
-
mindsdb_lv = parse_version(el[
|
|
126
|
-
gui_lv = parse_version(el[
|
|
127
|
-
if
|
|
133
|
+
mindsdb_lv = parse_version(el["mindsdb_version"])
|
|
134
|
+
gui_lv = parse_version(el["gui_version"])
|
|
135
|
+
if (
|
|
136
|
+
mindsdb_lv.base_version not in gui_versions
|
|
137
|
+
or gui_lv > gui_versions[mindsdb_lv.base_version]
|
|
138
|
+
):
|
|
128
139
|
gui_versions[mindsdb_lv.base_version] = gui_lv
|
|
129
140
|
if max_mindsdb_lv is None or max_mindsdb_lv < mindsdb_lv:
|
|
130
141
|
max_mindsdb_lv = mindsdb_lv
|
|
@@ -139,7 +150,11 @@ def get_last_compatible_gui_version() -> Version:
|
|
|
139
150
|
elif current_mindsdb_lv > all_mindsdb_lv[-1]:
|
|
140
151
|
gui_version_lv = max_gui_lv
|
|
141
152
|
else:
|
|
142
|
-
lower_versions = {
|
|
153
|
+
lower_versions = {
|
|
154
|
+
key: value
|
|
155
|
+
for key, value in gui_versions.items()
|
|
156
|
+
if parse_version(key) < current_mindsdb_lv
|
|
157
|
+
}
|
|
143
158
|
if len(lower_versions) == 0:
|
|
144
159
|
gui_version_lv = gui_versions[all_mindsdb_lv[0].base_version]
|
|
145
160
|
else:
|
|
@@ -156,12 +171,12 @@ def get_last_compatible_gui_version() -> Version:
|
|
|
156
171
|
def get_current_gui_version() -> Version:
|
|
157
172
|
logger.debug("Getting current frontend version..")
|
|
158
173
|
config = Config()
|
|
159
|
-
static_path = Path(config[
|
|
160
|
-
version_txt_path = static_path.joinpath(
|
|
174
|
+
static_path = Path(config["paths"]["static"])
|
|
175
|
+
version_txt_path = static_path.joinpath("version.txt")
|
|
161
176
|
|
|
162
177
|
current_gui_version = None
|
|
163
178
|
if version_txt_path.is_file():
|
|
164
|
-
with open(version_txt_path,
|
|
179
|
+
with open(version_txt_path, "rt") as f:
|
|
165
180
|
current_gui_version = f.readline()
|
|
166
181
|
|
|
167
182
|
current_gui_lv = (
|
|
@@ -177,7 +192,7 @@ def initialize_static():
|
|
|
177
192
|
config = Config()
|
|
178
193
|
last_gui_version_lv = get_last_compatible_gui_version()
|
|
179
194
|
current_gui_version_lv = get_current_gui_version()
|
|
180
|
-
required_gui_version = config[
|
|
195
|
+
required_gui_version = config["gui"].get("version")
|
|
181
196
|
|
|
182
197
|
if required_gui_version is not None:
|
|
183
198
|
required_gui_version_lv = parse_version(required_gui_version)
|
|
@@ -193,7 +208,10 @@ def initialize_static():
|
|
|
193
208
|
return False
|
|
194
209
|
|
|
195
210
|
# ignore versions like '23.9.2.2'
|
|
196
|
-
if
|
|
211
|
+
if (
|
|
212
|
+
current_gui_version_lv is not None
|
|
213
|
+
and len(current_gui_version_lv.release) < 3
|
|
214
|
+
):
|
|
197
215
|
if current_gui_version_lv == last_gui_version_lv:
|
|
198
216
|
return True
|
|
199
217
|
logger.debug("Updating gui..")
|
|
@@ -204,37 +222,40 @@ def initialize_static():
|
|
|
204
222
|
|
|
205
223
|
|
|
206
224
|
def initialize_app(config, no_studio):
|
|
207
|
-
static_root = config[
|
|
225
|
+
static_root = config["paths"]["static"]
|
|
208
226
|
logger.debug(f"Static route: {static_root}")
|
|
209
|
-
gui_exists = Path(static_root).joinpath(
|
|
227
|
+
gui_exists = Path(static_root).joinpath("index.html").is_file()
|
|
210
228
|
logger.debug(f"Does GUI already exist.. {'YES' if gui_exists else 'NO'}")
|
|
211
229
|
init_static_thread = None
|
|
212
|
-
if (
|
|
213
|
-
|
|
214
|
-
and (
|
|
215
|
-
config['gui']['autoupdate'] is True
|
|
216
|
-
or gui_exists is False
|
|
217
|
-
)
|
|
230
|
+
if no_studio is False and (
|
|
231
|
+
config["gui"]["autoupdate"] is True or gui_exists is False
|
|
218
232
|
):
|
|
219
|
-
init_static_thread = threading.Thread(
|
|
233
|
+
init_static_thread = threading.Thread(
|
|
234
|
+
target=initialize_static, name="initialize_static"
|
|
235
|
+
)
|
|
220
236
|
init_static_thread.start()
|
|
221
237
|
|
|
238
|
+
# Wait for static initialization.
|
|
239
|
+
if not no_studio and init_static_thread is not None:
|
|
240
|
+
init_static_thread.join()
|
|
241
|
+
|
|
222
242
|
app, api = initialize_flask(config, init_static_thread, no_studio)
|
|
223
243
|
Compress(app)
|
|
244
|
+
|
|
224
245
|
initialize_interfaces(app)
|
|
225
246
|
|
|
226
247
|
if os.path.isabs(static_root) is False:
|
|
227
248
|
static_root = os.path.join(os.getcwd(), static_root)
|
|
228
249
|
static_root = Path(static_root)
|
|
229
250
|
|
|
230
|
-
@app.route(
|
|
231
|
-
@app.route(
|
|
251
|
+
@app.route("/", defaults={"path": ""}, methods=["GET"])
|
|
252
|
+
@app.route("/<path:path>", methods=["GET"])
|
|
232
253
|
def root_index(path):
|
|
233
|
-
if path.startswith(
|
|
254
|
+
if path.startswith("api/"):
|
|
234
255
|
return http_error(
|
|
235
256
|
HTTPStatus.NOT_FOUND,
|
|
236
|
-
|
|
237
|
-
|
|
257
|
+
"Not found",
|
|
258
|
+
"The endpoint you are trying to access does not exist on the server.",
|
|
238
259
|
)
|
|
239
260
|
|
|
240
261
|
# Normalize the path.
|
|
@@ -244,14 +265,14 @@ def initialize_app(config, no_studio):
|
|
|
244
265
|
if not full_path.startswith(str(static_root)):
|
|
245
266
|
return http_error(
|
|
246
267
|
HTTPStatus.FORBIDDEN,
|
|
247
|
-
|
|
248
|
-
|
|
268
|
+
"Forbidden",
|
|
269
|
+
"You are not allowed to access the requested resource.",
|
|
249
270
|
)
|
|
250
271
|
|
|
251
272
|
if os.path.isfile(full_path):
|
|
252
273
|
return send_from_directory(static_root, path)
|
|
253
274
|
else:
|
|
254
|
-
return send_from_directory(static_root,
|
|
275
|
+
return send_from_directory(static_root, "index.html")
|
|
255
276
|
|
|
256
277
|
protected_namespaces = [
|
|
257
278
|
tab_ns,
|
|
@@ -270,7 +291,7 @@ def initialize_app(config, no_studio):
|
|
|
270
291
|
skills_ns,
|
|
271
292
|
agents_ns,
|
|
272
293
|
jobs_ns,
|
|
273
|
-
knowledge_bases_ns
|
|
294
|
+
knowledge_bases_ns,
|
|
274
295
|
]
|
|
275
296
|
|
|
276
297
|
for ns in protected_namespaces:
|
|
@@ -285,20 +306,20 @@ def initialize_app(config, no_studio):
|
|
|
285
306
|
# pass through HTTP errors
|
|
286
307
|
# NOTE flask_restx require 'message', also it modyfies 'application/problem+json' to 'application/json'
|
|
287
308
|
if isinstance(e, HTTPException):
|
|
288
|
-
return (
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
309
|
+
return (
|
|
310
|
+
{"title": e.name, "detail": e.description, "message": e.description},
|
|
311
|
+
e.code,
|
|
312
|
+
{"Content-Type": "application/problem+json"},
|
|
313
|
+
)
|
|
314
|
+
return (
|
|
315
|
+
{
|
|
316
|
+
"title": getattr(type(e), "__name__") or "Unknown error",
|
|
317
|
+
"detail": str(e),
|
|
318
|
+
"message": str(e),
|
|
319
|
+
},
|
|
320
|
+
500,
|
|
321
|
+
{"Content-Type": "application/problem+json"},
|
|
322
|
+
)
|
|
302
323
|
|
|
303
324
|
@app.teardown_appcontext
|
|
304
325
|
def remove_session(*args, **kwargs):
|
|
@@ -312,31 +333,34 @@ def initialize_app(config, no_studio):
|
|
|
312
333
|
|
|
313
334
|
# region routes where auth is required
|
|
314
335
|
if (
|
|
315
|
-
config[
|
|
316
|
-
and any(
|
|
336
|
+
config["auth"]["http_auth_enabled"] is True
|
|
337
|
+
and any(
|
|
338
|
+
request.path.startswith(f"/api{ns.path}") for ns in protected_namespaces
|
|
339
|
+
)
|
|
317
340
|
and check_auth() is False
|
|
318
341
|
):
|
|
319
342
|
return http_error(
|
|
320
|
-
HTTPStatus.UNAUTHORIZED,
|
|
321
|
-
|
|
343
|
+
HTTPStatus.UNAUTHORIZED,
|
|
344
|
+
"Unauthorized",
|
|
345
|
+
"Authorization is required to complete the request",
|
|
322
346
|
)
|
|
323
347
|
# endregion
|
|
324
348
|
|
|
325
|
-
company_id = request.headers.get(
|
|
326
|
-
user_class = request.headers.get(
|
|
349
|
+
company_id = request.headers.get("company-id")
|
|
350
|
+
user_class = request.headers.get("user-class")
|
|
327
351
|
|
|
328
352
|
try:
|
|
329
|
-
email_confirmed = int(request.headers.get(
|
|
353
|
+
email_confirmed = int(request.headers.get("email-confirmed", 1))
|
|
330
354
|
except Exception:
|
|
331
355
|
email_confirmed = 1
|
|
332
356
|
|
|
333
357
|
try:
|
|
334
|
-
user_id = int(request.headers.get(
|
|
358
|
+
user_id = int(request.headers.get("user-id", 0))
|
|
335
359
|
except Exception:
|
|
336
360
|
user_id = 0
|
|
337
361
|
|
|
338
362
|
try:
|
|
339
|
-
session_id = request.cookies.get(
|
|
363
|
+
session_id = request.cookies.get("session")
|
|
340
364
|
except Exception:
|
|
341
365
|
session_id = "unknown"
|
|
342
366
|
|
|
@@ -366,10 +390,6 @@ def initialize_app(config, no_studio):
|
|
|
366
390
|
ctx.user_class = user_class
|
|
367
391
|
ctx.email_confirmed = email_confirmed
|
|
368
392
|
|
|
369
|
-
# Wait for static initialization.
|
|
370
|
-
if not no_studio and init_static_thread is not None:
|
|
371
|
-
init_static_thread.join()
|
|
372
|
-
|
|
373
393
|
logger.debug("Done initializing app.")
|
|
374
394
|
return app
|
|
375
395
|
|
|
@@ -377,13 +397,13 @@ def initialize_app(config, no_studio):
|
|
|
377
397
|
def initialize_flask(config, init_static_thread, no_studio):
|
|
378
398
|
logger.debug("Initializing flask..")
|
|
379
399
|
# region required for windows https://github.com/mindsdb/mindsdb/issues/2526
|
|
380
|
-
mimetypes.add_type(
|
|
381
|
-
mimetypes.add_type(
|
|
400
|
+
mimetypes.add_type("text/css", ".css")
|
|
401
|
+
mimetypes.add_type("text/javascript", ".js")
|
|
382
402
|
# endregion
|
|
383
403
|
|
|
384
404
|
kwargs = {}
|
|
385
405
|
if no_studio is not True:
|
|
386
|
-
static_path = os.path.join(config[
|
|
406
|
+
static_path = os.path.join(config["paths"]["static"], "static/")
|
|
387
407
|
if os.path.isabs(static_path) is False:
|
|
388
408
|
static_path = os.path.join(os.getcwd(), static_path)
|
|
389
409
|
kwargs["static_url_path"] = "/static"
|
|
@@ -397,35 +417,31 @@ def initialize_flask(config, init_static_thread, no_studio):
|
|
|
397
417
|
FlaskInstrumentor().instrument_app(app)
|
|
398
418
|
RequestsInstrumentor().instrument()
|
|
399
419
|
|
|
400
|
-
app.config[
|
|
401
|
-
app.config[
|
|
402
|
-
app.config[
|
|
403
|
-
|
|
404
|
-
|
|
420
|
+
app.config["SECRET_KEY"] = os.environ.get("FLASK_SECRET_KEY", secrets.token_hex(32))
|
|
421
|
+
app.config["SESSION_COOKIE_NAME"] = "session"
|
|
422
|
+
app.config["PERMANENT_SESSION_LIFETIME"] = config["auth"][
|
|
423
|
+
"http_permanent_session_lifetime"
|
|
424
|
+
]
|
|
425
|
+
app.config["SEND_FILE_MAX_AGE_DEFAULT"] = 60
|
|
426
|
+
app.config["SWAGGER_HOST"] = "http://localhost:8000/mindsdb"
|
|
405
427
|
app.json = CustomJSONProvider()
|
|
406
428
|
|
|
407
|
-
authorizations = {
|
|
408
|
-
'apikey': {
|
|
409
|
-
'type': 'session',
|
|
410
|
-
'in': 'query',
|
|
411
|
-
'name': 'session'
|
|
412
|
-
}
|
|
413
|
-
}
|
|
429
|
+
authorizations = {"apikey": {"type": "session", "in": "query", "name": "session"}}
|
|
414
430
|
|
|
415
431
|
logger.debug("Creating swagger API..")
|
|
416
432
|
api = Swagger_Api(
|
|
417
433
|
app,
|
|
418
434
|
authorizations=authorizations,
|
|
419
|
-
security=[
|
|
420
|
-
url_prefix=
|
|
421
|
-
prefix=
|
|
422
|
-
doc=
|
|
435
|
+
security=["apikey"],
|
|
436
|
+
url_prefix=":8000",
|
|
437
|
+
prefix="/api",
|
|
438
|
+
doc="/doc/",
|
|
423
439
|
)
|
|
424
440
|
|
|
425
|
-
api.representations[
|
|
441
|
+
api.representations["application/json"] = custom_output_json
|
|
426
442
|
|
|
427
|
-
port = config[
|
|
428
|
-
host = config[
|
|
443
|
+
port = config["api"]["http"]["port"]
|
|
444
|
+
host = config["api"]["http"]["host"]
|
|
429
445
|
|
|
430
446
|
# NOTE rewrite it, that hotfix to see GUI link
|
|
431
447
|
if not no_studio:
|
|
@@ -438,9 +454,9 @@ def initialize_flask(config, init_static_thread, no_studio):
|
|
|
438
454
|
pid = os.getpid()
|
|
439
455
|
thread = threading.Thread(
|
|
440
456
|
target=_open_webbrowser,
|
|
441
|
-
args=(url, pid, port, init_static_thread, config[
|
|
457
|
+
args=(url, pid, port, init_static_thread, config["paths"]["static"]),
|
|
442
458
|
daemon=True,
|
|
443
|
-
name=
|
|
459
|
+
name="open_webbrowser",
|
|
444
460
|
)
|
|
445
461
|
thread.start()
|
|
446
462
|
|
|
@@ -77,8 +77,8 @@ class QueryAnalysis(Resource):
|
|
|
77
77
|
if result.type != SQL_RESPONSE_TYPE.TABLE:
|
|
78
78
|
return http_error(500, "Error", "Query does not return data")
|
|
79
79
|
|
|
80
|
-
column_names = [
|
|
81
|
-
df =
|
|
80
|
+
column_names = [column.name for column in result.result_set.columns]
|
|
81
|
+
df = result.result_set.to_df()
|
|
82
82
|
try:
|
|
83
83
|
analysis = analyze_df(df)
|
|
84
84
|
except ImportError:
|
|
@@ -95,7 +95,7 @@ class QueryAnalysis(Resource):
|
|
|
95
95
|
return {
|
|
96
96
|
"analysis": analysis,
|
|
97
97
|
"column_names": column_names,
|
|
98
|
-
"row_count": len(result.
|
|
98
|
+
"row_count": len(result.result_set),
|
|
99
99
|
"timestamp": time.time(),
|
|
100
100
|
"tables": query_tables,
|
|
101
101
|
}
|