MindsDB 25.3.4.0__py3-none-any.whl → 25.3.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 +2 -2
- mindsdb/integrations/handlers/confluence_handler/confluence_api_client.py +164 -0
- mindsdb/integrations/handlers/confluence_handler/confluence_handler.py +54 -59
- mindsdb/integrations/handlers/confluence_handler/confluence_tables.py +753 -0
- mindsdb/integrations/handlers/confluence_handler/connection_args.py +8 -8
- mindsdb/integrations/handlers/langchain_handler/requirements.txt +1 -1
- mindsdb/integrations/handlers/lightwood_handler/requirements.txt +3 -3
- mindsdb/integrations/handlers/litellm_handler/requirements.txt +1 -1
- mindsdb/integrations/handlers/llama_index_handler/requirements.txt +1 -1
- mindsdb/integrations/handlers/mysql_handler/mysql_handler.py +2 -0
- mindsdb/integrations/handlers/ray_serve_handler/ray_serve_handler.py +18 -16
- mindsdb/integrations/handlers/snowflake_handler/snowflake_handler.py +26 -1
- {mindsdb-25.3.4.0.dist-info → mindsdb-25.3.4.1.dist-info}/METADATA +228 -231
- {mindsdb-25.3.4.0.dist-info → mindsdb-25.3.4.1.dist-info}/RECORD +17 -17
- {mindsdb-25.3.4.0.dist-info → mindsdb-25.3.4.1.dist-info}/WHEEL +1 -1
- mindsdb/integrations/handlers/confluence_handler/confluence_table.py +0 -193
- mindsdb/integrations/handlers/confluence_handler/requirements.txt +0 -1
- {mindsdb-25.3.4.0.dist-info → mindsdb-25.3.4.1.dist-info}/licenses/LICENSE +0 -0
- {mindsdb-25.3.4.0.dist-info → mindsdb-25.3.4.1.dist-info}/top_level.txt +0 -0
mindsdb/__about__.py
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
__title__ = 'MindsDB'
|
|
2
2
|
__package_name__ = 'mindsdb'
|
|
3
|
-
__version__ = '25.3.4.
|
|
3
|
+
__version__ = '25.3.4.1'
|
|
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'
|
|
7
7
|
__github__ = 'https://github.com/mindsdb/mindsdb'
|
|
8
8
|
__pypi__ = 'https://pypi.org/project/mindsdb/'
|
|
9
|
-
__license__ = '
|
|
9
|
+
__license__ = 'Elastic License 2.0'
|
|
10
10
|
__copyright__ = 'Copyright(c) 2018 MindsDB, Inc'
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
from typing import List
|
|
2
|
+
|
|
3
|
+
import requests
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ConfluenceAPIClient:
|
|
7
|
+
def __init__(self, url: str, username: str, password: str):
|
|
8
|
+
self.url = url
|
|
9
|
+
self.username = username
|
|
10
|
+
self.password = password
|
|
11
|
+
self.session = requests.Session()
|
|
12
|
+
self.session.auth = (self.username, self.password)
|
|
13
|
+
self.session.headers.update({"Accept": "application/json"})
|
|
14
|
+
|
|
15
|
+
def get_spaces(
|
|
16
|
+
self,
|
|
17
|
+
ids: List[int] = None,
|
|
18
|
+
keys: List[str] = None,
|
|
19
|
+
space_type: str = None,
|
|
20
|
+
status: str = None,
|
|
21
|
+
sort_condition: str = None,
|
|
22
|
+
limit: int = None,
|
|
23
|
+
):
|
|
24
|
+
url = f"{self.url}/wiki/api/v2/spaces"
|
|
25
|
+
params = {
|
|
26
|
+
"description-format": "view",
|
|
27
|
+
}
|
|
28
|
+
if ids:
|
|
29
|
+
params["ids"] = ids
|
|
30
|
+
if keys:
|
|
31
|
+
params["keys"] = keys
|
|
32
|
+
if space_type:
|
|
33
|
+
params["type"] = space_type
|
|
34
|
+
if status:
|
|
35
|
+
params["status"] = status
|
|
36
|
+
if sort_condition:
|
|
37
|
+
params["sort"] = sort_condition
|
|
38
|
+
if limit:
|
|
39
|
+
params["limit"] = limit
|
|
40
|
+
|
|
41
|
+
return self._paginate(url, params)
|
|
42
|
+
|
|
43
|
+
def get_pages(
|
|
44
|
+
self,
|
|
45
|
+
page_ids: List[int] = None,
|
|
46
|
+
space_ids: List[int] = None,
|
|
47
|
+
statuses: List[str] = None,
|
|
48
|
+
title: str = None,
|
|
49
|
+
sort_condition: str = None,
|
|
50
|
+
limit: int = None,
|
|
51
|
+
) -> List[dict]:
|
|
52
|
+
url = f"{self.url}/wiki/api/v2/pages"
|
|
53
|
+
params = {
|
|
54
|
+
"body-format": "storage",
|
|
55
|
+
}
|
|
56
|
+
if page_ids:
|
|
57
|
+
params["id"] = page_ids
|
|
58
|
+
if space_ids:
|
|
59
|
+
params["space-id"] = space_ids
|
|
60
|
+
if statuses:
|
|
61
|
+
params["status"] = statuses
|
|
62
|
+
if title:
|
|
63
|
+
params["title"] = title
|
|
64
|
+
if sort_condition:
|
|
65
|
+
params["sort"] = sort_condition
|
|
66
|
+
if limit:
|
|
67
|
+
params["limit"] = limit
|
|
68
|
+
|
|
69
|
+
return self._paginate(url, params)
|
|
70
|
+
|
|
71
|
+
def get_blogposts(
|
|
72
|
+
self,
|
|
73
|
+
post_ids: List[int] = None,
|
|
74
|
+
space_ids: List[str] = None,
|
|
75
|
+
statuses: List[str] = None,
|
|
76
|
+
title: str = None,
|
|
77
|
+
sort_condition: str = None,
|
|
78
|
+
limit: int = None,
|
|
79
|
+
) -> List[dict]:
|
|
80
|
+
url = f"{self.url}/wiki/api/v2/blogposts"
|
|
81
|
+
params = {
|
|
82
|
+
"body-format": "storage",
|
|
83
|
+
}
|
|
84
|
+
if post_ids:
|
|
85
|
+
params["id"] = post_ids
|
|
86
|
+
if space_ids:
|
|
87
|
+
params["space-id"] = space_ids
|
|
88
|
+
if statuses:
|
|
89
|
+
params["status"] = statuses
|
|
90
|
+
if title:
|
|
91
|
+
params["title"] = title
|
|
92
|
+
if sort_condition:
|
|
93
|
+
params["sort"] = sort_condition
|
|
94
|
+
if limit:
|
|
95
|
+
params["limit"] = limit
|
|
96
|
+
|
|
97
|
+
return self._paginate(url, params)
|
|
98
|
+
|
|
99
|
+
def get_whiteboard_by_id(self, whiteboard_id: int) -> dict:
|
|
100
|
+
url = f"{self.url}/wiki/api/v2/whiteboards/{whiteboard_id}"
|
|
101
|
+
|
|
102
|
+
return self._make_request("GET", url)
|
|
103
|
+
|
|
104
|
+
def get_database_by_id(self, database_id: int) -> dict:
|
|
105
|
+
url = f"{self.url}/wiki/api/v2/databases/{database_id}"
|
|
106
|
+
|
|
107
|
+
return self._make_request("GET", url)
|
|
108
|
+
|
|
109
|
+
def get_tasks(
|
|
110
|
+
self,
|
|
111
|
+
task_ids: List[int] = None,
|
|
112
|
+
space_ids: List[str] = None,
|
|
113
|
+
page_ids: List[str] = None,
|
|
114
|
+
blogpost_ids: List[str] = None,
|
|
115
|
+
created_by_ids: List[str] = None,
|
|
116
|
+
assigned_to_ids: List[str] = None,
|
|
117
|
+
completed_by_ids: List[str] = None,
|
|
118
|
+
status: str = None,
|
|
119
|
+
limit: int = None,
|
|
120
|
+
) -> List[dict]:
|
|
121
|
+
url = f"{self.url}/wiki/api/v2/tasks"
|
|
122
|
+
params = {
|
|
123
|
+
"body-format": "storage",
|
|
124
|
+
}
|
|
125
|
+
if task_ids:
|
|
126
|
+
params["id"] = task_ids
|
|
127
|
+
if space_ids:
|
|
128
|
+
params["space-id"] = space_ids
|
|
129
|
+
if page_ids:
|
|
130
|
+
params["page-id"] = page_ids
|
|
131
|
+
if blogpost_ids:
|
|
132
|
+
params["blogpost-id"] = blogpost_ids
|
|
133
|
+
if created_by_ids:
|
|
134
|
+
params["created-by"] = created_by_ids
|
|
135
|
+
if assigned_to_ids:
|
|
136
|
+
params["assigned-to"] = assigned_to_ids
|
|
137
|
+
if completed_by_ids:
|
|
138
|
+
params["completed-by"] = completed_by_ids
|
|
139
|
+
if status:
|
|
140
|
+
params["status"] = status
|
|
141
|
+
if limit:
|
|
142
|
+
params["limit"] = limit
|
|
143
|
+
|
|
144
|
+
return self._paginate(url, params)
|
|
145
|
+
|
|
146
|
+
def _paginate(self, url: str, params: dict = None) -> List[dict]:
|
|
147
|
+
results = []
|
|
148
|
+
response = self._make_request("GET", url, params)
|
|
149
|
+
results.extend(response["results"])
|
|
150
|
+
|
|
151
|
+
while response["_links"].get("next"):
|
|
152
|
+
params["cursor"] = response["_links"].get("next")
|
|
153
|
+
response = self._make_request("GET", url, params)
|
|
154
|
+
results.extend(response["results"])
|
|
155
|
+
|
|
156
|
+
return results
|
|
157
|
+
|
|
158
|
+
def _make_request(self, method: str, url: str, params: dict = None, data: dict = None) -> dict:
|
|
159
|
+
response = self.session.request(method, url, params=params, json=data)
|
|
160
|
+
|
|
161
|
+
if response.status_code != 200:
|
|
162
|
+
raise Exception(f"Request failed with status code {response.status_code}: {response.text}")
|
|
163
|
+
|
|
164
|
+
return response.json()
|
|
@@ -1,83 +1,92 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import Any, Dict
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
from
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
from mindsdb.integrations.handlers.confluence_handler.confluence_table import (
|
|
3
|
+
from mindsdb.integrations.handlers.confluence_handler.confluence_api_client import ConfluenceAPIClient
|
|
4
|
+
from mindsdb.integrations.handlers.confluence_handler.confluence_tables import (
|
|
5
|
+
ConfluenceBlogPostsTable,
|
|
6
|
+
ConfluenceDatabasesTable,
|
|
8
7
|
ConfluencePagesTable,
|
|
8
|
+
ConfluenceSpacesTable,
|
|
9
|
+
ConfluenceTasksTable,
|
|
10
|
+
ConfluenceWhiteboardsTable,
|
|
9
11
|
)
|
|
10
12
|
from mindsdb.integrations.libs.api_handler import APIHandler
|
|
11
13
|
from mindsdb.integrations.libs.response import (
|
|
12
14
|
HandlerStatusResponse as StatusResponse,
|
|
13
15
|
)
|
|
14
|
-
from mindsdb_sql_parser import parse_sql
|
|
15
16
|
from mindsdb.utilities import log
|
|
16
17
|
|
|
17
|
-
from atlassian import Confluence
|
|
18
|
-
from typing import Optional
|
|
19
|
-
import requests
|
|
20
18
|
|
|
21
19
|
logger = log.getLogger(__name__)
|
|
22
20
|
|
|
21
|
+
|
|
23
22
|
class ConfluenceHandler(APIHandler):
|
|
24
|
-
"""
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
----------
|
|
30
|
-
name : str
|
|
31
|
-
name of a handler instance
|
|
32
|
-
"""
|
|
33
|
-
super().__init__(name)
|
|
23
|
+
"""
|
|
24
|
+
This handler handles the connection and execution of SQL statements on Confluence.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
name = "confluence"
|
|
34
28
|
|
|
35
|
-
|
|
29
|
+
def __init__(self, name: str, connection_data: Dict, **kwargs: Any) -> None:
|
|
30
|
+
"""
|
|
31
|
+
Initializes the handler.
|
|
36
32
|
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
Args:
|
|
34
|
+
name (str): The name of the handler instance.
|
|
35
|
+
connection_data (Dict): The connection data required to connect to the Confluence API.
|
|
36
|
+
kwargs: Arbitrary keyword arguments.
|
|
37
|
+
"""
|
|
38
|
+
super().__init__(name)
|
|
39
39
|
self.connection_data = connection_data
|
|
40
40
|
self.kwargs = kwargs
|
|
41
|
+
|
|
41
42
|
self.connection = None
|
|
42
43
|
self.is_connected = False
|
|
44
|
+
self.thread_safe = True
|
|
43
45
|
|
|
44
|
-
|
|
45
|
-
self._register_table("pages",
|
|
46
|
+
self._register_table("spaces", ConfluenceSpacesTable(self))
|
|
47
|
+
self._register_table("pages", ConfluencePagesTable(self))
|
|
48
|
+
self._register_table("blogposts", ConfluenceBlogPostsTable(self))
|
|
49
|
+
self._register_table("whiteboards", ConfluenceWhiteboardsTable(self))
|
|
50
|
+
self._register_table("databases", ConfluenceDatabasesTable(self))
|
|
51
|
+
self._register_table("tasks", ConfluenceTasksTable(self))
|
|
46
52
|
|
|
47
|
-
def connect(self):
|
|
48
|
-
"""
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
connection
|
|
53
|
+
def connect(self) -> ConfluenceAPIClient:
|
|
54
|
+
"""
|
|
55
|
+
Establishes a connection to the Confluence API.
|
|
56
|
+
|
|
57
|
+
Raises:
|
|
58
|
+
ValueError: If the required connection parameters are not provided.
|
|
59
|
+
|
|
60
|
+
Returns:
|
|
61
|
+
atlassian.confluence.Confluence: A connection object to the Confluence API.
|
|
53
62
|
"""
|
|
54
63
|
if self.is_connected is True:
|
|
55
64
|
return self.connection
|
|
56
|
-
|
|
57
|
-
if not all(key in self.connection_data and self.connection_data.get(key) for key in ['
|
|
58
|
-
raise ValueError('Required parameters (
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
url=self.connection_data.get('
|
|
65
|
+
|
|
66
|
+
if not all(key in self.connection_data and self.connection_data.get(key) for key in ['api_base', 'username', 'password']):
|
|
67
|
+
raise ValueError('Required parameters (api_base, username, password) must be provided and should not be empty.')
|
|
68
|
+
|
|
69
|
+
self.connection = ConfluenceAPIClient(
|
|
70
|
+
url=self.connection_data.get('api_base'),
|
|
62
71
|
username=self.connection_data.get('username'),
|
|
63
72
|
password=self.connection_data.get('password'),
|
|
64
73
|
)
|
|
65
|
-
|
|
74
|
+
|
|
66
75
|
self.is_connected = True
|
|
67
76
|
return self.connection
|
|
68
77
|
|
|
69
78
|
def check_connection(self) -> StatusResponse:
|
|
70
|
-
"""
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
79
|
+
"""
|
|
80
|
+
Checks the status of the connection to the Confluence API.
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
StatusResponse: An object containing the success status and an error message if an error occurs.
|
|
75
84
|
"""
|
|
76
85
|
response = StatusResponse(False)
|
|
77
|
-
need_to_close = self.is_connected is False
|
|
78
86
|
|
|
79
87
|
try:
|
|
80
|
-
self.connect()
|
|
88
|
+
connection = self.connect()
|
|
89
|
+
connection.get_spaces(limit=1)
|
|
81
90
|
response.success = True
|
|
82
91
|
except Exception as e:
|
|
83
92
|
logger.error(f"Error connecting to Confluence API: {e}!")
|
|
@@ -86,17 +95,3 @@ class ConfluenceHandler(APIHandler):
|
|
|
86
95
|
self.is_connected = response.success
|
|
87
96
|
|
|
88
97
|
return response
|
|
89
|
-
|
|
90
|
-
def native_query(self, query: str) -> StatusResponse:
|
|
91
|
-
"""Receive and process a raw query.
|
|
92
|
-
Parameters
|
|
93
|
-
----------
|
|
94
|
-
query : str
|
|
95
|
-
query in a native format
|
|
96
|
-
Returns
|
|
97
|
-
-------
|
|
98
|
-
StatusResponse
|
|
99
|
-
Request status
|
|
100
|
-
"""
|
|
101
|
-
ast = parse_sql(query)
|
|
102
|
-
return self.query(ast)
|