MindsDB 25.7.3.0__py3-none-any.whl → 25.7.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/api/a2a/common/server/server.py +16 -6
- mindsdb/api/executor/command_executor.py +206 -135
- mindsdb/api/executor/datahub/datanodes/project_datanode.py +14 -3
- mindsdb/api/executor/planner/plan_join.py +3 -0
- mindsdb/api/executor/planner/plan_join_ts.py +117 -100
- mindsdb/api/executor/planner/query_planner.py +1 -0
- mindsdb/api/executor/sql_query/steps/apply_predictor_step.py +54 -85
- mindsdb/api/http/initialize.py +16 -43
- mindsdb/api/http/namespaces/agents.py +23 -20
- mindsdb/api/http/namespaces/chatbots.py +83 -120
- mindsdb/api/http/namespaces/file.py +1 -1
- mindsdb/api/http/namespaces/jobs.py +38 -60
- mindsdb/api/http/namespaces/tree.py +69 -61
- mindsdb/api/mcp/start.py +2 -0
- mindsdb/api/mysql/mysql_proxy/utilities/dump.py +3 -2
- mindsdb/integrations/handlers/autogluon_handler/requirements.txt +1 -1
- mindsdb/integrations/handlers/autosklearn_handler/requirements.txt +1 -1
- mindsdb/integrations/handlers/bigquery_handler/bigquery_handler.py +25 -5
- mindsdb/integrations/handlers/chromadb_handler/chromadb_handler.py +3 -3
- mindsdb/integrations/handlers/flaml_handler/requirements.txt +1 -1
- mindsdb/integrations/handlers/google_calendar_handler/google_calendar_tables.py +82 -73
- mindsdb/integrations/handlers/hubspot_handler/requirements.txt +1 -1
- mindsdb/integrations/handlers/langchain_handler/langchain_handler.py +83 -76
- mindsdb/integrations/handlers/lightwood_handler/requirements.txt +4 -4
- mindsdb/integrations/handlers/litellm_handler/litellm_handler.py +5 -2
- mindsdb/integrations/handlers/litellm_handler/settings.py +2 -1
- mindsdb/integrations/handlers/pgvector_handler/pgvector_handler.py +106 -90
- mindsdb/integrations/handlers/postgres_handler/postgres_handler.py +41 -39
- mindsdb/integrations/handlers/salesforce_handler/constants.py +208 -0
- mindsdb/integrations/handlers/salesforce_handler/salesforce_handler.py +141 -80
- mindsdb/integrations/handlers/salesforce_handler/salesforce_tables.py +0 -1
- mindsdb/integrations/handlers/tpot_handler/requirements.txt +1 -1
- mindsdb/integrations/handlers/web_handler/urlcrawl_helpers.py +32 -17
- mindsdb/integrations/handlers/web_handler/web_handler.py +19 -22
- mindsdb/integrations/libs/vectordatabase_handler.py +10 -1
- mindsdb/integrations/utilities/handler_utils.py +32 -12
- mindsdb/interfaces/agents/agents_controller.py +167 -108
- mindsdb/interfaces/agents/langchain_agent.py +10 -3
- mindsdb/interfaces/data_catalog/data_catalog_loader.py +4 -4
- mindsdb/interfaces/database/database.py +38 -13
- mindsdb/interfaces/database/integrations.py +20 -5
- mindsdb/interfaces/database/projects.py +63 -16
- mindsdb/interfaces/database/views.py +86 -60
- mindsdb/interfaces/jobs/jobs_controller.py +103 -110
- mindsdb/interfaces/knowledge_base/controller.py +26 -5
- mindsdb/interfaces/knowledge_base/evaluate.py +2 -1
- mindsdb/interfaces/knowledge_base/executor.py +24 -0
- mindsdb/interfaces/query_context/context_controller.py +100 -133
- mindsdb/interfaces/skills/skills_controller.py +18 -6
- mindsdb/interfaces/storage/db.py +40 -6
- mindsdb/interfaces/variables/variables_controller.py +8 -15
- mindsdb/utilities/config.py +3 -3
- mindsdb/utilities/functions.py +72 -60
- mindsdb/utilities/log.py +38 -6
- mindsdb/utilities/ps.py +7 -7
- {mindsdb-25.7.3.0.dist-info → mindsdb-25.7.4.0.dist-info}/METADATA +246 -247
- {mindsdb-25.7.3.0.dist-info → mindsdb-25.7.4.0.dist-info}/RECORD +61 -60
- {mindsdb-25.7.3.0.dist-info → mindsdb-25.7.4.0.dist-info}/WHEEL +0 -0
- {mindsdb-25.7.3.0.dist-info → mindsdb-25.7.4.0.dist-info}/licenses/LICENSE +0 -0
- {mindsdb-25.7.3.0.dist-info → mindsdb-25.7.4.0.dist-info}/top_level.txt +0 -0
|
@@ -94,14 +94,26 @@ class Project:
|
|
|
94
94
|
def drop_model(self, name: str):
|
|
95
95
|
ModelController().delete_model(name, project_name=self.name)
|
|
96
96
|
|
|
97
|
-
def drop_view(self, name: str):
|
|
98
|
-
|
|
97
|
+
def drop_view(self, name: str, strict_case: bool = False) -> None:
|
|
98
|
+
"""Remove a view with the specified name from the current project.
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
name (str): The name of the view to remove.
|
|
102
|
+
strict_case (bool, optional): If True, the view name is case-sensitive. Defaults to False.
|
|
103
|
+
|
|
104
|
+
Raises:
|
|
105
|
+
EntityNotExistsError: If the view does not exist.
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
None
|
|
109
|
+
"""
|
|
110
|
+
ViewController().delete(name, project_name=self.name, strict_case=strict_case)
|
|
99
111
|
|
|
100
112
|
def create_view(self, name: str, query: str):
|
|
101
113
|
ViewController().add(name, query=query, project_name=self.name)
|
|
102
114
|
|
|
103
|
-
def update_view(self, name: str, query: str):
|
|
104
|
-
ViewController().update(name, query=query, project_name=self.name)
|
|
115
|
+
def update_view(self, name: str, query: str, strict_case: bool = False):
|
|
116
|
+
ViewController().update(name, query=query, project_name=self.name, strict_case=strict_case)
|
|
105
117
|
|
|
106
118
|
def delete_view(self, name: str):
|
|
107
119
|
ViewController().delete(name, project_name=self.name)
|
|
@@ -279,18 +291,29 @@ class Project:
|
|
|
279
291
|
]
|
|
280
292
|
return data
|
|
281
293
|
|
|
282
|
-
def get_view(self, name):
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
.
|
|
294
|
+
def get_view(self, name: str, strict_case: bool = False) -> dict | None:
|
|
295
|
+
"""Get a view by name from the current project.
|
|
296
|
+
|
|
297
|
+
Args:
|
|
298
|
+
name (str): The name of the view to retrieve.
|
|
299
|
+
strict_case (bool, optional): If True, the view name is case-sensitive. Defaults to False.
|
|
300
|
+
|
|
301
|
+
Returns:
|
|
302
|
+
dict | None: A dictionary with view information if found, otherwise None.
|
|
303
|
+
"""
|
|
304
|
+
query = db.session.query(db.View).filter(
|
|
305
|
+
db.View.project_id == self.id,
|
|
306
|
+
db.View.company_id == ctx.company_id,
|
|
291
307
|
)
|
|
308
|
+
if strict_case:
|
|
309
|
+
query = query.filter(db.View.name == name)
|
|
310
|
+
else:
|
|
311
|
+
query = query.filter(sa.func.lower(db.View.name) == name.lower())
|
|
312
|
+
|
|
313
|
+
view_record = query.one_or_none()
|
|
314
|
+
|
|
292
315
|
if view_record is None:
|
|
293
|
-
return
|
|
316
|
+
return None
|
|
294
317
|
return {
|
|
295
318
|
"name": view_record.name,
|
|
296
319
|
"query": view_record.query,
|
|
@@ -385,8 +408,29 @@ class ProjectController:
|
|
|
385
408
|
return [Project.from_record(x) for x in records]
|
|
386
409
|
|
|
387
410
|
def get(
|
|
388
|
-
self,
|
|
411
|
+
self,
|
|
412
|
+
id: int | None = None,
|
|
413
|
+
name: str | None = None,
|
|
414
|
+
deleted: bool = False,
|
|
415
|
+
is_default: bool = False,
|
|
416
|
+
strict_case: bool = False,
|
|
389
417
|
) -> Project:
|
|
418
|
+
"""Get a project by id or name.
|
|
419
|
+
|
|
420
|
+
Args:
|
|
421
|
+
id (int | None, optional): The id of the project to retrieve. Cannot be used with 'name'.
|
|
422
|
+
name (str | None, optional): The name of the project to retrieve. Cannot be used with 'id'.
|
|
423
|
+
deleted (bool, optional): If True, include deleted projects. Defaults to False.
|
|
424
|
+
is_default (bool, optional): If True, only return the default project. Defaults to False.
|
|
425
|
+
strict_case (bool, optional): If True, the project name is case-sensitive. Defaults to False.
|
|
426
|
+
|
|
427
|
+
Raises:
|
|
428
|
+
ValueError: If both 'id' and 'name' are provided.
|
|
429
|
+
EntityNotExistsError: If the project is not found.
|
|
430
|
+
|
|
431
|
+
Returns:
|
|
432
|
+
Project: The project instance matching the given criteria.
|
|
433
|
+
"""
|
|
390
434
|
if id is not None and name is not None:
|
|
391
435
|
raise ValueError("Both 'id' and 'name' can't be provided at the same time")
|
|
392
436
|
|
|
@@ -396,7 +440,10 @@ class ProjectController:
|
|
|
396
440
|
if id is not None:
|
|
397
441
|
q = q.filter_by(id=id)
|
|
398
442
|
elif name is not None:
|
|
399
|
-
|
|
443
|
+
if strict_case:
|
|
444
|
+
q = q.filter((db.Project.name == name))
|
|
445
|
+
else:
|
|
446
|
+
q = q.filter((sa.func.lower(db.Project.name) == sa.func.lower(name)))
|
|
400
447
|
|
|
401
448
|
if deleted is True:
|
|
402
449
|
q = q.filter((db.Project.deleted_at != sa.null()))
|
|
@@ -12,64 +12,90 @@ class ViewController:
|
|
|
12
12
|
from mindsdb.interfaces.database.database import DatabaseController
|
|
13
13
|
|
|
14
14
|
database_controller = DatabaseController()
|
|
15
|
-
project_databases_dict = database_controller.get_dict(filter_type=
|
|
15
|
+
project_databases_dict = database_controller.get_dict(filter_type="project")
|
|
16
16
|
|
|
17
17
|
if project_name not in project_databases_dict:
|
|
18
|
-
raise EntityNotExistsError(
|
|
18
|
+
raise EntityNotExistsError("Can not find project", project_name)
|
|
19
19
|
|
|
20
|
-
project_id = project_databases_dict[project_name][
|
|
20
|
+
project_id = project_databases_dict[project_name]["id"]
|
|
21
21
|
view_record = (
|
|
22
22
|
db.session.query(db.View.id)
|
|
23
23
|
.filter(
|
|
24
|
-
func.lower(db.View.name) == name,
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
).first()
|
|
24
|
+
func.lower(db.View.name) == name, db.View.company_id == ctx.company_id, db.View.project_id == project_id
|
|
25
|
+
)
|
|
26
|
+
.first()
|
|
28
27
|
)
|
|
29
28
|
if view_record is not None:
|
|
30
|
-
raise EntityExistsError(
|
|
29
|
+
raise EntityExistsError("View already exists", name)
|
|
31
30
|
|
|
32
|
-
view_record = db.View(
|
|
33
|
-
name=name,
|
|
34
|
-
company_id=ctx.company_id,
|
|
35
|
-
query=query,
|
|
36
|
-
project_id=project_id
|
|
37
|
-
)
|
|
31
|
+
view_record = db.View(name=name, company_id=ctx.company_id, query=query, project_id=project_id)
|
|
38
32
|
db.session.add(view_record)
|
|
39
33
|
db.session.commit()
|
|
40
34
|
|
|
41
|
-
def update(self, name, query, project_name):
|
|
42
|
-
|
|
35
|
+
def update(self, name: str, query: str, project_name: str, strict_case: bool = False):
|
|
36
|
+
"""Update the SQL query of an existing view in the specified project.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
name (str): The name of the view to update.
|
|
40
|
+
query (str): The new SQL query for the view.
|
|
41
|
+
project_name (str): The name of the project containing the view.
|
|
42
|
+
strict_case (bool, optional): If True, the view name is case-sensitive. If False, the name comparison is case-insensitive. Defaults to False.
|
|
43
|
+
|
|
44
|
+
Raises:
|
|
45
|
+
EntityNotExistsError: If the view with the specified name does not exist in the given project.
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
None
|
|
49
|
+
"""
|
|
43
50
|
project_record = get_project_record(project_name)
|
|
44
51
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
52
|
+
q = db.session.query(db.View).filter(
|
|
53
|
+
db.View.company_id == ctx.company_id, db.View.project_id == project_record.id
|
|
54
|
+
)
|
|
55
|
+
if strict_case:
|
|
56
|
+
q = q.filter(db.View.name == name)
|
|
57
|
+
else:
|
|
58
|
+
q = q.filter(func.lower(db.View.name) == func.lower(name))
|
|
59
|
+
|
|
60
|
+
rec = q.first()
|
|
50
61
|
if rec is None:
|
|
51
|
-
raise EntityNotExistsError(
|
|
62
|
+
raise EntityNotExistsError("View not found", name)
|
|
52
63
|
rec.query = query
|
|
53
64
|
db.session.commit()
|
|
54
65
|
|
|
55
|
-
def delete(self, name, project_name):
|
|
56
|
-
name
|
|
66
|
+
def delete(self, name: str, project_name: str, strict_case: bool = False) -> None:
|
|
67
|
+
"""Remove a view with the specified name from the given project.
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
name (str): The name of the view to remove.
|
|
71
|
+
project_name (str): The name of the project containing the view.
|
|
72
|
+
strict_case (bool, optional): If True, the view name is case-sensitive. Defaults to False.
|
|
73
|
+
|
|
74
|
+
Raises:
|
|
75
|
+
EntityNotExistsError: If the view does not exist.
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
None
|
|
79
|
+
"""
|
|
57
80
|
project_record = get_project_record(project_name)
|
|
58
81
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
82
|
+
query = db.session.query(db.View).filter(
|
|
83
|
+
db.View.company_id == ctx.company_id, db.View.project_id == project_record.id
|
|
84
|
+
)
|
|
85
|
+
if strict_case:
|
|
86
|
+
query = query.filter(db.View.name == name)
|
|
87
|
+
else:
|
|
88
|
+
query = query.filter(func.lower(db.View.name) == func.lower(name))
|
|
89
|
+
|
|
90
|
+
record = query.first()
|
|
91
|
+
if record is None:
|
|
92
|
+
raise EntityNotExistsError("View not found", name)
|
|
93
|
+
db.session.delete(record)
|
|
67
94
|
db.session.commit()
|
|
68
95
|
|
|
69
|
-
query_context_controller.drop_query_context(
|
|
96
|
+
query_context_controller.drop_query_context("view", record.id)
|
|
70
97
|
|
|
71
98
|
def list(self, project_name):
|
|
72
|
-
|
|
73
99
|
project_names = {}
|
|
74
100
|
for project in get_project_records():
|
|
75
101
|
if project_name is not None and project.name != project_name:
|
|
@@ -77,49 +103,49 @@ class ViewController:
|
|
|
77
103
|
project_names[project.id] = project.name
|
|
78
104
|
|
|
79
105
|
query = db.session.query(db.View).filter(
|
|
80
|
-
db.View.company_id == ctx.company_id,
|
|
81
|
-
db.View.project_id.in_(list(project_names.keys()))
|
|
106
|
+
db.View.company_id == ctx.company_id, db.View.project_id.in_(list(project_names.keys()))
|
|
82
107
|
)
|
|
83
108
|
|
|
84
109
|
data = []
|
|
85
110
|
|
|
86
111
|
for record in query:
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
112
|
+
data.append(
|
|
113
|
+
{
|
|
114
|
+
"id": record.id,
|
|
115
|
+
"name": record.name,
|
|
116
|
+
"project": project_names[record.project_id],
|
|
117
|
+
"query": record.query,
|
|
118
|
+
}
|
|
119
|
+
)
|
|
94
120
|
|
|
95
121
|
return data
|
|
96
122
|
|
|
97
123
|
def _get_view_record_data(self, record):
|
|
98
|
-
return {
|
|
99
|
-
'id': record.id,
|
|
100
|
-
'name': record.name,
|
|
101
|
-
'query': record.query
|
|
102
|
-
}
|
|
124
|
+
return {"id": record.id, "name": record.name, "query": record.query}
|
|
103
125
|
|
|
104
126
|
def get(self, id=None, name=None, project_name=None):
|
|
105
127
|
project_record = get_project_record(project_name)
|
|
106
128
|
|
|
107
129
|
if id is not None:
|
|
108
|
-
records =
|
|
109
|
-
|
|
110
|
-
project_id=project_record.id,
|
|
111
|
-
|
|
112
|
-
)
|
|
130
|
+
records = (
|
|
131
|
+
db.session.query(db.View)
|
|
132
|
+
.filter_by(id=id, project_id=project_record.id, company_id=ctx.company_id)
|
|
133
|
+
.all()
|
|
134
|
+
)
|
|
113
135
|
elif name is not None:
|
|
114
|
-
records =
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
136
|
+
records = (
|
|
137
|
+
db.session.query(db.View)
|
|
138
|
+
.filter(
|
|
139
|
+
func.lower(db.View.name) == name.lower(),
|
|
140
|
+
db.View.project_id == project_record.id,
|
|
141
|
+
db.View.company_id == ctx.company_id,
|
|
142
|
+
)
|
|
143
|
+
.all()
|
|
144
|
+
)
|
|
119
145
|
if len(records) == 0:
|
|
120
146
|
if name is None:
|
|
121
|
-
name = f
|
|
122
|
-
raise EntityNotExistsError("Can't find view", f
|
|
147
|
+
name = f"id={id}"
|
|
148
|
+
raise EntityNotExistsError("Can't find view", f"{project_name}.{name}")
|
|
123
149
|
elif len(records) > 1:
|
|
124
150
|
raise Exception(f"There are multiple views with name/id: {name}/{id}")
|
|
125
151
|
record = records[0]
|