MindsDB 25.2.3.0__py3-none-any.whl → 25.3.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of MindsDB might be problematic. Click here for more details.

Files changed (86) hide show
  1. mindsdb/__about__.py +1 -1
  2. mindsdb/__main__.py +16 -11
  3. mindsdb/api/executor/command_executor.py +1 -1
  4. mindsdb/api/executor/datahub/datanodes/system_tables.py +10 -2
  5. mindsdb/api/executor/planner/query_planner.py +6 -2
  6. mindsdb/api/executor/sql_query/steps/prepare_steps.py +2 -1
  7. mindsdb/api/http/initialize.py +8 -5
  8. mindsdb/api/http/namespaces/agents.py +0 -7
  9. mindsdb/api/http/namespaces/config.py +0 -48
  10. mindsdb/api/http/namespaces/knowledge_bases.py +1 -1
  11. mindsdb/api/http/namespaces/util.py +0 -28
  12. mindsdb/api/mongo/classes/query_sql.py +2 -1
  13. mindsdb/api/mongo/responders/aggregate.py +2 -2
  14. mindsdb/api/mongo/responders/coll_stats.py +3 -2
  15. mindsdb/api/mongo/responders/db_stats.py +2 -1
  16. mindsdb/api/mongo/responders/insert.py +4 -2
  17. mindsdb/api/mysql/mysql_proxy/classes/fake_mysql_proxy/fake_mysql_proxy.py +2 -1
  18. mindsdb/api/mysql/mysql_proxy/mysql_proxy.py +5 -4
  19. mindsdb/api/postgres/postgres_proxy/postgres_proxy.py +2 -4
  20. mindsdb/integrations/handlers/anyscale_endpoints_handler/requirements.txt +0 -1
  21. mindsdb/integrations/handlers/autosklearn_handler/autosklearn_handler.py +1 -1
  22. mindsdb/integrations/handlers/dspy_handler/requirements.txt +0 -1
  23. mindsdb/integrations/handlers/gmail_handler/connection_args.py +2 -2
  24. mindsdb/integrations/handlers/gmail_handler/gmail_handler.py +19 -66
  25. mindsdb/integrations/handlers/gmail_handler/requirements.txt +0 -1
  26. mindsdb/integrations/handlers/google_calendar_handler/connection_args.py +15 -0
  27. mindsdb/integrations/handlers/google_calendar_handler/google_calendar_handler.py +31 -41
  28. mindsdb/integrations/handlers/google_calendar_handler/requirements.txt +0 -2
  29. mindsdb/integrations/handlers/langchain_embedding_handler/requirements.txt +0 -1
  30. mindsdb/integrations/handlers/langchain_handler/requirements.txt +0 -1
  31. mindsdb/integrations/handlers/llama_index_handler/requirements.txt +0 -1
  32. mindsdb/integrations/handlers/openai_handler/constants.py +3 -1
  33. mindsdb/integrations/handlers/openai_handler/requirements.txt +0 -1
  34. mindsdb/integrations/handlers/rag_handler/requirements.txt +0 -1
  35. mindsdb/integrations/handlers/ray_serve_handler/ray_serve_handler.py +33 -8
  36. mindsdb/integrations/handlers/web_handler/urlcrawl_helpers.py +3 -2
  37. mindsdb/integrations/handlers/web_handler/web_handler.py +42 -33
  38. mindsdb/integrations/handlers/youtube_handler/__init__.py +2 -0
  39. mindsdb/integrations/handlers/youtube_handler/connection_args.py +32 -0
  40. mindsdb/integrations/handlers/youtube_handler/youtube_handler.py +2 -38
  41. mindsdb/integrations/libs/llm/utils.py +7 -1
  42. mindsdb/integrations/libs/process_cache.py +2 -2
  43. mindsdb/integrations/utilities/handlers/auth_utilities/google/google_user_oauth_utilities.py +29 -38
  44. mindsdb/integrations/utilities/pydantic_utils.py +208 -0
  45. mindsdb/integrations/utilities/rag/chains/local_context_summarizer_chain.py +227 -0
  46. mindsdb/integrations/utilities/rag/pipelines/rag.py +11 -4
  47. mindsdb/integrations/utilities/rag/retrievers/sql_retriever.py +800 -135
  48. mindsdb/integrations/utilities/rag/settings.py +390 -152
  49. mindsdb/integrations/utilities/sql_utils.py +2 -1
  50. mindsdb/interfaces/agents/agents_controller.py +14 -10
  51. mindsdb/interfaces/agents/callback_handlers.py +52 -5
  52. mindsdb/interfaces/agents/langchain_agent.py +5 -3
  53. mindsdb/interfaces/agents/mindsdb_chat_model.py +4 -2
  54. mindsdb/interfaces/chatbot/chatbot_controller.py +9 -8
  55. mindsdb/interfaces/database/database.py +3 -2
  56. mindsdb/interfaces/database/integrations.py +1 -1
  57. mindsdb/interfaces/database/projects.py +28 -2
  58. mindsdb/interfaces/jobs/jobs_controller.py +4 -1
  59. mindsdb/interfaces/jobs/scheduler.py +1 -1
  60. mindsdb/interfaces/knowledge_base/preprocessing/constants.py +2 -2
  61. mindsdb/interfaces/model/model_controller.py +5 -2
  62. mindsdb/interfaces/skills/retrieval_tool.py +128 -39
  63. mindsdb/interfaces/skills/skill_tool.py +7 -7
  64. mindsdb/interfaces/skills/skills_controller.py +10 -6
  65. mindsdb/interfaces/skills/sql_agent.py +6 -1
  66. mindsdb/interfaces/storage/db.py +14 -12
  67. mindsdb/interfaces/storage/json.py +59 -0
  68. mindsdb/interfaces/storage/model_fs.py +85 -3
  69. mindsdb/interfaces/triggers/triggers_controller.py +2 -1
  70. mindsdb/migrations/versions/2022-10-14_43c52d23845a_projects.py +17 -3
  71. mindsdb/migrations/versions/2025-02-10_6ab9903fc59a_del_log_table.py +33 -0
  72. mindsdb/migrations/versions/2025-02-14_4521dafe89ab_added_encrypted_content_to_json_storage.py +29 -0
  73. mindsdb/migrations/versions/2025-02-19_11347c213b36_added_metadata_to_projects.py +41 -0
  74. mindsdb/utilities/config.py +6 -1
  75. mindsdb/utilities/functions.py +11 -0
  76. mindsdb/utilities/log.py +17 -2
  77. mindsdb/utilities/ml_task_queue/consumer.py +4 -2
  78. mindsdb/utilities/render/sqlalchemy_render.py +4 -0
  79. {MindsDB-25.2.3.0.dist-info → mindsdb-25.3.1.0.dist-info}/METADATA +226 -247
  80. {MindsDB-25.2.3.0.dist-info → mindsdb-25.3.1.0.dist-info}/RECORD +83 -80
  81. {MindsDB-25.2.3.0.dist-info → mindsdb-25.3.1.0.dist-info}/WHEEL +1 -1
  82. mindsdb/integrations/handlers/gmail_handler/utils.py +0 -45
  83. mindsdb/utilities/log_controller.py +0 -39
  84. mindsdb/utilities/telemetry.py +0 -44
  85. {MindsDB-25.2.3.0.dist-info → mindsdb-25.3.1.0.dist-info}/LICENSE +0 -0
  86. {MindsDB-25.2.3.0.dist-info → mindsdb-25.3.1.0.dist-info}/top_level.txt +0 -0
@@ -7,6 +7,7 @@ from mindsdb_sql_parser import ast
7
7
  from mindsdb_sql_parser.ast.base import ASTNode
8
8
 
9
9
  from mindsdb.integrations.utilities.query_traversal import query_traversal
10
+ from mindsdb.utilities.config import config
10
11
 
11
12
 
12
13
  class FilterOperator(Enum):
@@ -74,7 +75,7 @@ def make_sql_session():
74
75
  from mindsdb.api.executor.controllers.session_controller import SessionController
75
76
 
76
77
  sql_session = SessionController()
77
- sql_session.database = 'mindsdb'
78
+ sql_session.database = config.get('default_project')
78
79
  return sql_session
79
80
 
80
81
 
@@ -13,12 +13,16 @@ from mindsdb.interfaces.database.projects import ProjectController
13
13
  from mindsdb.interfaces.model.functions import PredictorRecordNotFound
14
14
  from mindsdb.interfaces.model.model_controller import ModelController
15
15
  from mindsdb.interfaces.skills.skills_controller import SkillsController
16
+ from mindsdb.utilities.config import config
16
17
  from mindsdb.utilities.exception import EntityExistsError, EntityNotExistsError
17
18
 
18
19
  from .constants import ASSISTANT_COLUMN, SUPPORTED_PROVIDERS, PROVIDER_TO_MODELS
19
20
  from .langchain_agent import get_llm_provider
20
21
 
21
22
 
23
+ default_project = config.get('default_project')
24
+
25
+
22
26
  class AgentsController:
23
27
  '''Handles CRUD operations at the database level for Agents'''
24
28
 
@@ -70,7 +74,7 @@ class AgentsController:
70
74
 
71
75
  return model, provider
72
76
 
73
- def get_agent(self, agent_name: str, project_name: str = 'mindsdb') -> Optional[db.Agents]:
77
+ def get_agent(self, agent_name: str, project_name: str = default_project) -> Optional[db.Agents]:
74
78
  '''
75
79
  Gets an agent by name.
76
80
 
@@ -91,7 +95,7 @@ class AgentsController:
91
95
  ).first()
92
96
  return agent
93
97
 
94
- def get_agent_by_id(self, id: int, project_name: str = 'mindsdb') -> db.Agents:
98
+ def get_agent_by_id(self, id: int, project_name: str = default_project) -> db.Agents:
95
99
  '''
96
100
  Gets an agent by id.
97
101
 
@@ -162,7 +166,7 @@ class AgentsController:
162
166
  ValueError: Agent with given name already exists, or skill/model with given name does not exist.
163
167
  '''
164
168
  if project_name is None:
165
- project_name = 'mindsdb'
169
+ project_name = default_project
166
170
  project = self.project_controller.get(name=project_name)
167
171
 
168
172
  agent = self.get_agent(name, project_name)
@@ -208,7 +212,7 @@ class AgentsController:
208
212
  def update_agent(
209
213
  self,
210
214
  agent_name: str,
211
- project_name: str = 'mindsdb',
215
+ project_name: str = default_project,
212
216
  name: str = None,
213
217
  model_name: str = None,
214
218
  skills_to_add: List[Union[str, dict]] = None,
@@ -256,9 +260,9 @@ class AgentsController:
256
260
  if (
257
261
  is_demo and (
258
262
  (name is not None and name != agent_name)
259
- or (model_name or provider)
260
- or (len(skills_to_add) > 0 or len(skills_to_remove) > 0 or len(skills_to_rewrite) > 0)
261
- or (isinstance(params, dict) and len(params) > 1 and 'prompt_template' not in params)
263
+ or (model_name is not None and existing_agent.model_name != model_name)
264
+ or (provider is not None and existing_agent.provider != provider)
265
+ or (isinstance(params, dict) and len(params) > 0 and 'prompt_template' not in params)
262
266
  )
263
267
  ):
264
268
  raise ValueError("It is forbidden to change properties of the demo object")
@@ -347,7 +351,7 @@ class AgentsController:
347
351
 
348
352
  return existing_agent
349
353
 
350
- def delete_agent(self, agent_name: str, project_name: str = 'mindsdb'):
354
+ def delete_agent(self, agent_name: str, project_name: str = default_project):
351
355
  '''
352
356
  Deletes an agent by name.
353
357
 
@@ -371,7 +375,7 @@ class AgentsController:
371
375
  self,
372
376
  agent: db.Agents,
373
377
  messages: List[Dict[str, str]],
374
- project_name: str = 'mindsdb',
378
+ project_name: str = default_project,
375
379
  tools: List[BaseTool] = None,
376
380
  stream: bool = False) -> Union[Iterator[object], pd.DataFrame]:
377
381
  """
@@ -412,7 +416,7 @@ class AgentsController:
412
416
  self,
413
417
  agent: db.Agents,
414
418
  messages: List[Dict[str, str]],
415
- project_name: str = 'mindsdb',
419
+ project_name: str = default_project,
416
420
  tools: List[BaseTool] = None) -> Iterator[object]:
417
421
  '''
418
422
  Queries an agent to get a stream of completion chunks.
@@ -1,9 +1,13 @@
1
- from typing import Any, Dict, List, Union
1
+ import io
2
2
  import logging
3
+ import contextlib
4
+ from typing import Any, Dict, List, Union, Callable
5
+
3
6
  from langchain_core.agents import AgentAction, AgentFinish
4
7
  from langchain_core.callbacks.base import BaseCallbackHandler
5
8
  from langchain_core.messages.base import BaseMessage
6
9
  from langchain_core.outputs import LLMResult
10
+ from langchain_core.callbacks import StdOutCallbackHandler
7
11
 
8
12
 
9
13
  class ContextCaptureCallback(BaseCallbackHandler):
@@ -20,14 +24,49 @@ class ContextCaptureCallback(BaseCallbackHandler):
20
24
  return self.context
21
25
 
22
26
 
27
+ class VerboseLogCallbackHandler(StdOutCallbackHandler):
28
+ def __init__(self, logger: logging.Logger, verbose: bool):
29
+ self.logger = logger
30
+ self.verbose = verbose
31
+ super().__init__()
32
+
33
+ def __call(self, method: Callable, *args: List[Any], **kwargs: Any) -> Any:
34
+ if self.verbose is False:
35
+ return
36
+ f = io.StringIO()
37
+ with contextlib.redirect_stdout(f):
38
+ method(*args, **kwargs)
39
+ output = f.getvalue()
40
+ self.logger.info(output)
41
+
42
+ def on_chain_start(self, *args: List[Any], **kwargs: Any) -> None:
43
+ self.__call(super().on_chain_start, *args, **kwargs)
44
+
45
+ def on_chain_end(self, *args: List[Any], **kwargs: Any) -> None:
46
+ self.__call(super().on_chain_end, *args, **kwargs)
47
+
48
+ def on_agent_action(self, *args: List[Any], **kwargs: Any) -> None:
49
+ self.__call(super().on_agent_action, *args, **kwargs)
50
+
51
+ def on_tool_end(self, *args: List[Any], **kwargs: Any) -> None:
52
+ self.__call(super().on_tool_end, *args, **kwargs)
53
+
54
+ def on_text(self, *args: List[Any], **kwargs: Any) -> None:
55
+ self.__call(super().on_text, *args, **kwargs)
56
+
57
+ def on_agent_finish(self, *args: List[Any], **kwargs: Any) -> None:
58
+ self.__call(super().on_agent_finish, *args, **kwargs)
59
+
60
+
23
61
  class LogCallbackHandler(BaseCallbackHandler):
24
62
  '''Langchain callback handler that logs agent and chain executions.'''
25
63
 
26
- def __init__(self, logger: logging.Logger):
64
+ def __init__(self, logger: logging.Logger, verbose: bool = True):
27
65
  logger.setLevel('DEBUG')
28
66
  self.logger = logger
29
67
  self._num_running_chains = 0
30
68
  self.generated_sql = None
69
+ self.verbose_log_handler = VerboseLogCallbackHandler(logger, verbose)
31
70
 
32
71
  def on_llm_start(
33
72
  self, serialized: Dict[str, Any], prompts: List[str], **kwargs: Any
@@ -36,6 +75,7 @@ class LogCallbackHandler(BaseCallbackHandler):
36
75
  self.logger.debug('LLM started with prompts:')
37
76
  for prompt in prompts:
38
77
  self.logger.debug(prompt[:50])
78
+ self.verbose_log_handler.on_llm_start(serialized, prompts, **kwargs)
39
79
 
40
80
  def on_chat_model_start(
41
81
  self,
@@ -46,7 +86,7 @@ class LogCallbackHandler(BaseCallbackHandler):
46
86
  self.logger.debug('Chat model started with messages:')
47
87
  for message_list in messages:
48
88
  for message in message_list:
49
- self.logger.debug(message.pretty_print())
89
+ self.logger.debug(message.pretty_repr())
50
90
 
51
91
  def on_llm_new_token(self, token: str, **kwargs: Any) -> Any:
52
92
  '''Run on new LLM token. Only available when streaming is enabled.'''
@@ -72,6 +112,8 @@ class LogCallbackHandler(BaseCallbackHandler):
72
112
  self._num_running_chains))
73
113
  self.logger.debug('Inputs: {}'.format(inputs))
74
114
 
115
+ self.verbose_log_handler.on_chain_start(serialized=serialized, inputs=inputs, **kwargs)
116
+
75
117
  def on_chain_end(self, outputs: Dict[str, Any], **kwargs: Any) -> Any:
76
118
  '''Run when chain ends running.'''
77
119
  self._num_running_chains -= 1
@@ -79,6 +121,8 @@ class LogCallbackHandler(BaseCallbackHandler):
79
121
  self._num_running_chains))
80
122
  self.logger.debug('Outputs: {}'.format(outputs))
81
123
 
124
+ self.verbose_log_handler.on_chain_end(outputs=outputs, **kwargs)
125
+
82
126
  def on_chain_error(
83
127
  self, error: Union[Exception, KeyboardInterrupt], **kwargs: Any
84
128
  ) -> Any:
@@ -96,7 +140,7 @@ class LogCallbackHandler(BaseCallbackHandler):
96
140
 
97
141
  def on_tool_end(self, output: str, **kwargs: Any) -> Any:
98
142
  '''Run when tool ends running.'''
99
- pass
143
+ self.verbose_log_handler.on_tool_end(output=output, **kwargs)
100
144
 
101
145
  def on_tool_error(
102
146
  self, error: Union[Exception, KeyboardInterrupt], **kwargs: Any
@@ -106,7 +150,7 @@ class LogCallbackHandler(BaseCallbackHandler):
106
150
 
107
151
  def on_text(self, text: str, **kwargs: Any) -> Any:
108
152
  '''Run on arbitrary text.'''
109
- pass
153
+ self.verbose_log_handler.on_text(text=text, **kwargs)
110
154
 
111
155
  def on_agent_action(self, action: AgentAction, **kwargs: Any) -> Any:
112
156
  '''Run on agent action.'''
@@ -124,7 +168,10 @@ class LogCallbackHandler(BaseCallbackHandler):
124
168
  # fix for mistral
125
169
  action.tool = action.tool.replace('\\', '')
126
170
 
171
+ self.verbose_log_handler.on_agent_action(action=action, **kwargs)
172
+
127
173
  def on_agent_finish(self, finish: AgentFinish, **kwargs: Any) -> Any:
128
174
  '''Run on agent end.'''
129
175
  self.logger.debug('Agent finished with return values:')
130
176
  self.logger.debug(str(finish.return_values))
177
+ self.verbose_log_handler.on_agent_finish(finish=finish, **kwargs)
@@ -400,7 +400,7 @@ class LangchainAgent:
400
400
  "max_iterations", args.get("max_iterations", DEFAULT_MAX_ITERATIONS)
401
401
  ),
402
402
  memory=memory,
403
- verbose=args.get("verbose", args.get("verbose", True)),
403
+ verbose=args.get("verbose", args.get("verbose", False))
404
404
  )
405
405
  return agent_executor
406
406
 
@@ -435,7 +435,7 @@ class LangchainAgent:
435
435
  all_callbacks = []
436
436
 
437
437
  if self.log_callback_handler is None:
438
- self.log_callback_handler = LogCallbackHandler(logger)
438
+ self.log_callback_handler = LogCallbackHandler(logger, verbose=args.get("verbose", True))
439
439
 
440
440
  all_callbacks.append(self.log_callback_handler)
441
441
 
@@ -599,7 +599,9 @@ AI: {response}"""
599
599
  agent_executor_finished_event.set()
600
600
 
601
601
  # Enqueue Langchain agent streaming chunks in a separate thread to not block event chunks.
602
- executor_stream_thread = threading.Thread(target=stream_worker, daemon=True, args=(ctx.dump(),))
602
+ executor_stream_thread = threading.Thread(
603
+ target=stream_worker, daemon=True, args=(ctx.dump(),), name='LangchainAgent.stream_worker'
604
+ )
603
605
  executor_stream_thread.start()
604
606
 
605
607
  while not agent_executor_finished_event.is_set():
@@ -31,8 +31,10 @@ from langchain_core.outputs import (
31
31
  from pydantic import model_validator
32
32
 
33
33
  from mindsdb.interfaces.agents.constants import USER_COLUMN
34
+ from mindsdb.utilities.config import config
34
35
 
35
36
  logger = logging.getLogger(__name__)
37
+ default_project = config.get('default_project')
36
38
 
37
39
 
38
40
  def _convert_message_to_dict(message: BaseMessage) -> dict:
@@ -63,7 +65,7 @@ class ChatMindsdb(BaseChatModel):
63
65
  """A chat model that uses the Mindsdb"""
64
66
 
65
67
  model_name: str
66
- project_name: Optional[str] = 'mindsdb'
68
+ project_name: Optional[str] = default_project
67
69
  model_info: Optional[dict] = None
68
70
  project_datanode: Optional[Any] = None
69
71
 
@@ -139,7 +141,7 @@ class ChatMindsdb(BaseChatModel):
139
141
  from mindsdb.api.executor.controllers import SessionController
140
142
 
141
143
  session = SessionController()
142
- session.database = 'mindsdb'
144
+ session.database = default_project
143
145
 
144
146
  values['model_info'] = session.model_controller.get_model(model_name, project_name=project_name)
145
147
 
@@ -9,7 +9,10 @@ from mindsdb.interfaces.model.functions import get_project_records
9
9
  from mindsdb.utilities.context import context as ctx
10
10
 
11
11
  from mindsdb.api.executor.controllers.session_controller import SessionController
12
- from mindsdb.utilities.config import Config
12
+ from mindsdb.utilities.config import config
13
+
14
+
15
+ default_project = config.get('default_project')
13
16
 
14
17
 
15
18
  class ChatBotController:
@@ -25,7 +28,7 @@ class ChatBotController:
25
28
  self.project_controller = project_controller
26
29
  self.agents_controller = agents_controller
27
30
 
28
- def get_chatbot(self, chatbot_name: str, project_name: str = 'mindsdb') -> dict:
31
+ def get_chatbot(self, chatbot_name: str, project_name: str = default_project) -> dict:
29
32
  '''
30
33
  Gets a chatbot by name.
31
34
 
@@ -118,7 +121,7 @@ class ChatBotController:
118
121
 
119
122
  return bot_obj
120
123
 
121
- def get_chatbots(self, project_name: str = 'mindsdb') -> List[dict]:
124
+ def get_chatbots(self, project_name: str = default_project) -> List[dict]:
122
125
  '''
123
126
  Gets all chatbots in a project.
124
127
 
@@ -199,14 +202,12 @@ class ChatBotController:
199
202
  bot (db.ChatBots): The created chatbot
200
203
  '''
201
204
 
202
- config = Config()
203
-
204
205
  is_cloud = config.get('cloud', False)
205
206
  if is_cloud and ctx.user_class == 0:
206
207
  raise Exception("You can't create chatbot")
207
208
 
208
209
  if project_name is None:
209
- project_name = 'mindsdb'
210
+ project_name = default_project
210
211
  project = self.project_controller.get(name=project_name)
211
212
 
212
213
  bot = self.get_chatbot(name, project_name)
@@ -260,7 +261,7 @@ class ChatBotController:
260
261
  def update_chatbot(
261
262
  self,
262
263
  chatbot_name: str,
263
- project_name: str = 'mindsdb',
264
+ project_name: str = default_project,
264
265
  name: str = None,
265
266
  model_name: str = None,
266
267
  agent_name: str = None,
@@ -338,7 +339,7 @@ class ChatBotController:
338
339
 
339
340
  return existing_chatbot_rec
340
341
 
341
- def delete_chatbot(self, chatbot_name: str, project_name: str = 'mindsdb'):
342
+ def delete_chatbot(self, chatbot_name: str, project_name: str = default_project):
342
343
  '''
343
344
  Deletes a chatbot by name.
344
345
 
@@ -3,6 +3,7 @@ from collections import OrderedDict
3
3
 
4
4
  from mindsdb.interfaces.database.projects import ProjectController
5
5
  import mindsdb.utilities.profiler as profiler
6
+ from mindsdb.utilities.config import config
6
7
  from mindsdb.utilities.exception import EntityNotExistsError
7
8
  from mindsdb.interfaces.database.log import LogDBController
8
9
 
@@ -58,7 +59,7 @@ class DatabaseController:
58
59
  'id': x.id,
59
60
  'engine': None,
60
61
  'visible': True,
61
- 'deletable': x.name.lower() != 'mindsdb'
62
+ 'deletable': x.name.lower() != config.get('default_project')
62
63
  })
63
64
  for key, value in integrations.items():
64
65
  db_type = value.get('type', 'data')
@@ -106,7 +107,7 @@ class DatabaseController:
106
107
  }
107
108
 
108
109
  def exists(self, db_name: str) -> bool:
109
- return db_name in self.get_dict()
110
+ return db_name.lower() in self.get_dict()
110
111
 
111
112
  def get_project(self, name: str):
112
113
  return self.project_controller.get(name=name)
@@ -64,7 +64,7 @@ class HandlersCache:
64
64
  ):
65
65
  return
66
66
  self._stop_event.clear()
67
- self.cleaner_thread = threading.Thread(target=self._clean)
67
+ self.cleaner_thread = threading.Thread(target=self._clean, name='HandlersCache.clean')
68
68
  self.cleaner_thread.daemon = True
69
69
  self.cleaner_thread.start()
70
70
 
@@ -4,6 +4,7 @@ from typing import List, Optional
4
4
  from collections import OrderedDict
5
5
 
6
6
  import sqlalchemy as sa
7
+ from sqlalchemy.orm.attributes import flag_modified
7
8
  import numpy as np
8
9
 
9
10
  from mindsdb_sql_parser.ast.base import ASTNode
@@ -30,6 +31,7 @@ class Project:
30
31
  p.name = db_record.name
31
32
  p.company_id = ctx.company_id
32
33
  p.id = db_record.id
34
+ p.metadata = db_record.metadata_
33
35
  return p
34
36
 
35
37
  def create(self, name: str):
@@ -405,9 +407,9 @@ class ProjectController:
405
407
 
406
408
  return [Project.from_record(x) for x in records]
407
409
 
408
- def get(self, id: Optional[int] = None, name: Optional[str] = None, deleted: bool = False) -> Project:
410
+ def get(self, id: Optional[int] = None, name: Optional[str] = None, deleted: bool = False, is_default: bool = False) -> Project:
409
411
  if id is not None and name is not None:
410
- raise ValueError("Both 'id' and 'name' is None")
412
+ raise ValueError("Both 'id' and 'name' can't be provided at the same time")
411
413
 
412
414
  company_id = ctx.company_id if ctx.company_id is not None else 0
413
415
  q = db.Project.query.filter_by(company_id=company_id)
@@ -424,6 +426,9 @@ class ProjectController:
424
426
  else:
425
427
  q = q.filter_by(deleted_at=sa.null())
426
428
 
429
+ if is_default:
430
+ q = q.filter(db.Project.metadata_['is_default'].as_boolean() == is_default)
431
+
427
432
  record = q.first()
428
433
 
429
434
  if record is None:
@@ -434,3 +439,24 @@ class ProjectController:
434
439
  project = Project()
435
440
  project.create(name=name)
436
441
  return project
442
+
443
+ def update(self, id: Optional[int] = None, name: Optional[str] = None, new_name: str = None, new_metadata: dict = None) -> Project:
444
+ if id is not None and name is not None:
445
+ raise ValueError("Both 'id' and 'name' can't be provided at the same time")
446
+
447
+ if id is not None:
448
+ project = self.get(id=id)
449
+ else:
450
+ project = self.get(name=name)
451
+
452
+ if new_name is not None:
453
+ project.name = new_name
454
+ project.record.name = new_name
455
+
456
+ if new_metadata is not None:
457
+ project.metadata = new_metadata
458
+ project.record.metadata = new_metadata
459
+ flag_modified(project.record, 'metadata_')
460
+
461
+ db.session.commit()
462
+ return project
@@ -9,6 +9,7 @@ from mindsdb_sql_parser import parse_sql, ParsingException
9
9
  from mindsdb_sql_parser.ast.mindsdb import CreateJob
10
10
  from mindsdb_sql_parser.ast import Select, Star, Identifier, BinaryOperation, Constant
11
11
 
12
+ from mindsdb.utilities.config import config
12
13
  from mindsdb.utilities.context import context as ctx
13
14
  from mindsdb.utilities.exception import EntityNotExistsError, EntityExistsError
14
15
  from mindsdb.interfaces.storage import db
@@ -20,6 +21,8 @@ from mindsdb.utilities import log
20
21
 
21
22
  logger = log.getLogger(__name__)
22
23
 
24
+ default_project = config.get('default_project')
25
+
23
26
 
24
27
  def split_sql(sql):
25
28
  # split sql by ';' ignoring delimiter in quotes
@@ -199,7 +202,7 @@ class JobsController:
199
202
  """
200
203
 
201
204
  if project_name is None:
202
- project_name = 'mindsdb'
205
+ project_name = default_project
203
206
 
204
207
  start_at = None
205
208
  if query.start_str is not None:
@@ -44,7 +44,7 @@ class Scheduler:
44
44
  self.q_in = queue.Queue()
45
45
  self.q_out = queue.Queue()
46
46
  self.work_thread = threading.Thread(
47
- target=execute_async, args=(self.q_in, self.q_out)
47
+ target=execute_async, args=(self.q_in, self.q_out), name='Scheduler.execute_async'
48
48
  )
49
49
  self.work_thread.start()
50
50
 
@@ -6,8 +6,8 @@ DEFAULT_MARKDOWN_HEADERS = [
6
6
  ]
7
7
 
8
8
  # Limits for web crawling
9
- DEFAULT_CRAWL_DEPTH = 1
10
- DEFAULT_WEB_CRAWL_LIMIT = 100
9
+ DEFAULT_CRAWL_DEPTH = None
10
+ DEFAULT_WEB_CRAWL_LIMIT = 1
11
11
  DEFAULT_WEB_FILTERS = []
12
12
 
13
13
  DEFAULT_CONTEXT_DOCUMENT_LIMIT = 50
@@ -19,6 +19,7 @@ from mindsdb.interfaces.model.functions import (
19
19
  )
20
20
  from mindsdb.interfaces.storage.json import get_json_storage
21
21
  from mindsdb.interfaces.storage.model_fs import ModelStorage
22
+ from mindsdb.utilities.config import config
22
23
  from mindsdb.utilities.context import context as ctx
23
24
  from mindsdb.utilities.functions import resolve_model_identifier
24
25
  import mindsdb.utilities.profiler as profiler
@@ -29,6 +30,8 @@ logger = log.getLogger(__name__)
29
30
 
30
31
  IS_PY36 = sys.version_info[1] <= 6
31
32
 
33
+ default_project = config.get('default_project')
34
+
32
35
 
33
36
  def delete_model_storage(model_id, ctx_dump):
34
37
  try:
@@ -149,7 +152,7 @@ class ModelController():
149
152
  models.append(model_data)
150
153
  return models
151
154
 
152
- def delete_model(self, model_name: str, project_name: str = 'mindsdb', version=None):
155
+ def delete_model(self, model_name: str, project_name: str = default_project, version=None):
153
156
  from mindsdb.interfaces.database.database import DatabaseController
154
157
 
155
158
  project_record = get_project_record(func.lower(project_name))
@@ -344,7 +347,7 @@ class ModelController():
344
347
  def prepare_finetune_statement(self, statement, database_controller):
345
348
  project_name, model_name, model_version = resolve_model_identifier(statement.name)
346
349
  if project_name is None:
347
- project_name = 'mindsdb'
350
+ project_name = default_project
348
351
  data_integration_ref, fetch_data_query = self._get_data_integration_ref(statement, database_controller)
349
352
 
350
353
  set_active = True