MindsDB 25.8.2.0__py3-none-any.whl → 25.9.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.
- mindsdb/__about__.py +1 -1
- mindsdb/__main__.py +5 -45
- mindsdb/api/a2a/__init__.py +52 -0
- mindsdb/api/a2a/agent.py +17 -28
- mindsdb/api/a2a/common/server/server.py +17 -36
- mindsdb/api/a2a/common/server/task_manager.py +14 -28
- mindsdb/api/a2a/common/types.py +3 -4
- mindsdb/api/a2a/task_manager.py +43 -55
- mindsdb/api/a2a/utils.py +63 -0
- mindsdb/api/common/middleware.py +106 -0
- mindsdb/api/http/initialize.py +13 -15
- mindsdb/api/http/namespaces/agents.py +6 -7
- mindsdb/api/http/namespaces/auth.py +6 -14
- mindsdb/api/http/namespaces/config.py +0 -2
- mindsdb/api/http/namespaces/default.py +74 -106
- mindsdb/api/http/start.py +25 -44
- mindsdb/api/litellm/start.py +11 -10
- mindsdb/api/mcp/__init__.py +165 -0
- mindsdb/api/mysql/mysql_proxy/mysql_proxy.py +33 -64
- mindsdb/api/postgres/postgres_proxy/postgres_proxy.py +86 -85
- mindsdb/integrations/handlers/crate_handler/crate_handler.py +3 -7
- mindsdb/integrations/handlers/derby_handler/derby_handler.py +32 -34
- mindsdb/integrations/handlers/documentdb_handler/requirements.txt +1 -0
- mindsdb/integrations/handlers/dummy_data_handler/dummy_data_handler.py +12 -13
- mindsdb/integrations/handlers/google_books_handler/google_books_handler.py +45 -44
- mindsdb/integrations/handlers/google_calendar_handler/google_calendar_handler.py +101 -95
- mindsdb/integrations/handlers/google_content_shopping_handler/google_content_shopping_handler.py +129 -129
- mindsdb/integrations/handlers/google_fit_handler/google_fit_handler.py +59 -43
- mindsdb/integrations/handlers/google_search_handler/google_search_handler.py +38 -39
- mindsdb/integrations/handlers/informix_handler/informix_handler.py +5 -18
- mindsdb/integrations/handlers/maxdb_handler/maxdb_handler.py +22 -28
- mindsdb/integrations/handlers/monetdb_handler/monetdb_handler.py +3 -7
- mindsdb/integrations/handlers/mongodb_handler/mongodb_handler.py +53 -67
- mindsdb/integrations/handlers/mongodb_handler/requirements.txt +1 -0
- mindsdb/{api/mongo/utilities → integrations/handlers/mongodb_handler/utils}/mongodb_ast.py +43 -68
- mindsdb/{api/mongo/utilities → integrations/handlers/mongodb_handler/utils}/mongodb_parser.py +17 -25
- mindsdb/{api/mongo/utilities → integrations/handlers/mongodb_handler/utils}/mongodb_query.py +10 -16
- mindsdb/integrations/handlers/mongodb_handler/utils/mongodb_render.py +43 -69
- mindsdb/integrations/libs/base.py +1 -1
- mindsdb/interfaces/agents/constants.py +17 -2
- mindsdb/interfaces/agents/langchain_agent.py +83 -18
- mindsdb/interfaces/knowledge_base/controller.py +3 -1
- mindsdb/interfaces/skills/custom/text2sql/mindsdb_sql_toolkit.py +7 -1
- mindsdb/interfaces/skills/skill_tool.py +7 -1
- mindsdb/interfaces/skills/sql_agent.py +6 -2
- mindsdb/utilities/config.py +3 -155
- mindsdb/utilities/fs.py +10 -4
- mindsdb/utilities/log.py +0 -25
- mindsdb/utilities/starters.py +0 -39
- {mindsdb-25.8.2.0.dist-info → mindsdb-25.9.1.0.dist-info}/METADATA +265 -263
- {mindsdb-25.8.2.0.dist-info → mindsdb-25.9.1.0.dist-info}/RECORD +54 -98
- mindsdb/api/a2a/__main__.py +0 -144
- mindsdb/api/a2a/run_a2a.py +0 -86
- mindsdb/api/common/check_auth.py +0 -42
- mindsdb/api/http/gunicorn_wrapper.py +0 -17
- mindsdb/api/mcp/start.py +0 -205
- mindsdb/api/mongo/__init__.py +0 -0
- mindsdb/api/mongo/classes/__init__.py +0 -5
- mindsdb/api/mongo/classes/query_sql.py +0 -19
- mindsdb/api/mongo/classes/responder.py +0 -45
- mindsdb/api/mongo/classes/responder_collection.py +0 -34
- mindsdb/api/mongo/classes/scram.py +0 -86
- mindsdb/api/mongo/classes/session.py +0 -23
- mindsdb/api/mongo/functions/__init__.py +0 -19
- mindsdb/api/mongo/responders/__init__.py +0 -73
- mindsdb/api/mongo/responders/add_shard.py +0 -13
- mindsdb/api/mongo/responders/aggregate.py +0 -90
- mindsdb/api/mongo/responders/buildinfo.py +0 -17
- mindsdb/api/mongo/responders/coll_stats.py +0 -63
- mindsdb/api/mongo/responders/company_id.py +0 -25
- mindsdb/api/mongo/responders/connection_status.py +0 -22
- mindsdb/api/mongo/responders/count.py +0 -21
- mindsdb/api/mongo/responders/db_stats.py +0 -32
- mindsdb/api/mongo/responders/delete.py +0 -105
- mindsdb/api/mongo/responders/describe.py +0 -23
- mindsdb/api/mongo/responders/end_sessions.py +0 -13
- mindsdb/api/mongo/responders/find.py +0 -175
- mindsdb/api/mongo/responders/get_cmd_line_opts.py +0 -18
- mindsdb/api/mongo/responders/get_free_monitoring_status.py +0 -14
- mindsdb/api/mongo/responders/get_parameter.py +0 -23
- mindsdb/api/mongo/responders/getlog.py +0 -14
- mindsdb/api/mongo/responders/host_info.py +0 -28
- mindsdb/api/mongo/responders/insert.py +0 -270
- mindsdb/api/mongo/responders/is_master.py +0 -20
- mindsdb/api/mongo/responders/is_master_lower.py +0 -13
- mindsdb/api/mongo/responders/list_collections.py +0 -55
- mindsdb/api/mongo/responders/list_databases.py +0 -37
- mindsdb/api/mongo/responders/list_indexes.py +0 -22
- mindsdb/api/mongo/responders/ping.py +0 -13
- mindsdb/api/mongo/responders/recv_chunk_start.py +0 -13
- mindsdb/api/mongo/responders/replsetgetstatus.py +0 -13
- mindsdb/api/mongo/responders/sasl_continue.py +0 -34
- mindsdb/api/mongo/responders/sasl_start.py +0 -33
- mindsdb/api/mongo/responders/update_range_deletions.py +0 -12
- mindsdb/api/mongo/responders/whatsmyuri.py +0 -18
- mindsdb/api/mongo/server.py +0 -388
- mindsdb/api/mongo/start.py +0 -15
- mindsdb/api/mongo/utilities/__init__.py +0 -0
- {mindsdb-25.8.2.0.dist-info → mindsdb-25.9.1.0.dist-info}/WHEEL +0 -0
- {mindsdb-25.8.2.0.dist-info → mindsdb-25.9.1.0.dist-info}/licenses/LICENSE +0 -0
- {mindsdb-25.8.2.0.dist-info → mindsdb-25.9.1.0.dist-info}/top_level.txt +0 -0
|
@@ -6,7 +6,7 @@ from mindsdb_sql_parser import parse_sql
|
|
|
6
6
|
from mindsdb.integrations.libs.response import (
|
|
7
7
|
HandlerStatusResponse as StatusResponse,
|
|
8
8
|
HandlerResponse as Response,
|
|
9
|
-
RESPONSE_TYPE
|
|
9
|
+
RESPONSE_TYPE,
|
|
10
10
|
)
|
|
11
11
|
import pandas as pd
|
|
12
12
|
import jaydebeapi as jdbcconnector
|
|
@@ -15,11 +15,10 @@ logger = log.getLogger(__name__)
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
class DerbyHandler(DatabaseHandler):
|
|
18
|
-
|
|
19
|
-
name = 'derby'
|
|
18
|
+
name = "derby"
|
|
20
19
|
|
|
21
20
|
def __init__(self, name: str, connection_data: Optional[dict], **kwargs):
|
|
22
|
-
"""
|
|
21
|
+
"""Initialize the handler
|
|
23
22
|
Args:
|
|
24
23
|
name (str): name of particular handler instance
|
|
25
24
|
connection_data (dict): parameters for connecting to the database
|
|
@@ -29,16 +28,16 @@ class DerbyHandler(DatabaseHandler):
|
|
|
29
28
|
|
|
30
29
|
self.kwargs = kwargs
|
|
31
30
|
self.parser = parse_sql
|
|
32
|
-
self.database = connection_data[
|
|
31
|
+
self.database = connection_data["database"]
|
|
33
32
|
self.connection_config = connection_data
|
|
34
|
-
self.host = connection_data[
|
|
35
|
-
self.port = connection_data[
|
|
36
|
-
self.schema =
|
|
33
|
+
self.host = connection_data["host"]
|
|
34
|
+
self.port = connection_data["port"]
|
|
35
|
+
self.schema = "APP"
|
|
37
36
|
self.connection = None
|
|
38
37
|
self.is_connected = False
|
|
39
38
|
|
|
40
39
|
def connect(self):
|
|
41
|
-
"""
|
|
40
|
+
"""Set up any connections required by the handler
|
|
42
41
|
Should return output of check_connection() method after attempting
|
|
43
42
|
connection. Should switch self.is_connected.
|
|
44
43
|
Returns:
|
|
@@ -47,10 +46,10 @@ class DerbyHandler(DatabaseHandler):
|
|
|
47
46
|
if self.is_connected is True:
|
|
48
47
|
return self.connection
|
|
49
48
|
|
|
50
|
-
user = self.connection_config.get(
|
|
51
|
-
password = self.connection_config.get(
|
|
52
|
-
jdbc_class = self.connection_config.get(
|
|
53
|
-
jar_location = self.connection_config.get(
|
|
49
|
+
user = self.connection_config.get("user")
|
|
50
|
+
password = self.connection_config.get("password")
|
|
51
|
+
jdbc_class = self.connection_config.get("jdbcClass")
|
|
52
|
+
jar_location = self.connection_config.get("jdbcJarLocation")
|
|
54
53
|
|
|
55
54
|
jdbc_url = "jdbc:derby://" + self.host + ":" + self.port + "/" + self.database + ";"
|
|
56
55
|
|
|
@@ -62,11 +61,17 @@ class DerbyHandler(DatabaseHandler):
|
|
|
62
61
|
|
|
63
62
|
try:
|
|
64
63
|
if user and password and jar_location:
|
|
65
|
-
self.connection = jdbcconnector.connect(
|
|
64
|
+
self.connection = jdbcconnector.connect(
|
|
65
|
+
jclassname=jdbc_class, url=jdbc_url, driver_args=[user, password], jars=jar_location.split(",")
|
|
66
|
+
)
|
|
66
67
|
elif user and password:
|
|
67
|
-
self.connection = jdbcconnector.connect(
|
|
68
|
+
self.connection = jdbcconnector.connect(
|
|
69
|
+
jclassname=jdbc_class, url=jdbc_url, driver_args=[user, password]
|
|
70
|
+
)
|
|
68
71
|
elif jar_location:
|
|
69
|
-
self.connection = jdbcconnector.connect(
|
|
72
|
+
self.connection = jdbcconnector.connect(
|
|
73
|
+
jclassname=jdbc_class, url=jdbc_url, jars=jar_location.split(",")
|
|
74
|
+
)
|
|
70
75
|
else:
|
|
71
76
|
self.connection = jdbcconnector.connect(jdbc_class, jdbc_url)
|
|
72
77
|
except Exception as e:
|
|
@@ -75,7 +80,7 @@ class DerbyHandler(DatabaseHandler):
|
|
|
75
80
|
return self.connection
|
|
76
81
|
|
|
77
82
|
def disconnect(self):
|
|
78
|
-
"""
|
|
83
|
+
"""Close any existing connections
|
|
79
84
|
Should switch self.is_connected.
|
|
80
85
|
"""
|
|
81
86
|
if self.is_connected is False:
|
|
@@ -89,7 +94,7 @@ class DerbyHandler(DatabaseHandler):
|
|
|
89
94
|
return
|
|
90
95
|
|
|
91
96
|
def check_connection(self) -> StatusResponse:
|
|
92
|
-
"""
|
|
97
|
+
"""Check connection to the handler
|
|
93
98
|
Returns:
|
|
94
99
|
HandlerStatusResponse
|
|
95
100
|
"""
|
|
@@ -100,7 +105,7 @@ class DerbyHandler(DatabaseHandler):
|
|
|
100
105
|
self.connect()
|
|
101
106
|
responseCode.success = True
|
|
102
107
|
except Exception as e:
|
|
103
|
-
logger.error(f
|
|
108
|
+
logger.error(f"Error connecting to database {self.database}, {e}!")
|
|
104
109
|
responseCode.error_message = str(e)
|
|
105
110
|
finally:
|
|
106
111
|
if responseCode.success is True and need_to_close:
|
|
@@ -114,7 +119,7 @@ class DerbyHandler(DatabaseHandler):
|
|
|
114
119
|
"""Receive raw query and act upon it somehow.
|
|
115
120
|
Args:
|
|
116
121
|
query (Any): query in native format (str for sql databases,
|
|
117
|
-
|
|
122
|
+
etc)
|
|
118
123
|
Returns:
|
|
119
124
|
HandlerResponse
|
|
120
125
|
"""
|
|
@@ -126,21 +131,14 @@ class DerbyHandler(DatabaseHandler):
|
|
|
126
131
|
if cur.description:
|
|
127
132
|
result = cur.fetchall()
|
|
128
133
|
response = Response(
|
|
129
|
-
RESPONSE_TYPE.TABLE,
|
|
130
|
-
data_frame=pd.DataFrame(
|
|
131
|
-
result,
|
|
132
|
-
columns=[x[0] for x in cur.description]
|
|
133
|
-
)
|
|
134
|
+
RESPONSE_TYPE.TABLE, data_frame=pd.DataFrame(result, columns=[x[0] for x in cur.description])
|
|
134
135
|
)
|
|
135
136
|
else:
|
|
136
137
|
response = Response(RESPONSE_TYPE.OK)
|
|
137
138
|
self.connection.commit()
|
|
138
139
|
except Exception as e:
|
|
139
|
-
logger.error(f
|
|
140
|
-
response = Response(
|
|
141
|
-
RESPONSE_TYPE.ERROR,
|
|
142
|
-
error_message=str(e)
|
|
143
|
-
)
|
|
140
|
+
logger.error(f"Error running query: {query} on {self.database}!")
|
|
141
|
+
response = Response(RESPONSE_TYPE.ERROR, error_message=str(e))
|
|
144
142
|
self.connection.rollback()
|
|
145
143
|
|
|
146
144
|
if need_to_close is True:
|
|
@@ -173,12 +171,12 @@ class DerbyHandler(DatabaseHandler):
|
|
|
173
171
|
Returns:
|
|
174
172
|
Response: Names of the tables in the database.
|
|
175
173
|
"""
|
|
176
|
-
query = f
|
|
177
|
-
SELECT st.tablename FROM sys.systables st LEFT OUTER JOIN sys.sysschemas ss ON (st.schemaid = ss.schemaid) WHERE ss.schemaname ='{self.schema}'
|
|
174
|
+
query = f"""
|
|
175
|
+
SELECT st.tablename FROM sys.systables st LEFT OUTER JOIN sys.sysschemas ss ON (st.schemaid = ss.schemaid) WHERE ss.schemaname ='{self.schema}' """
|
|
178
176
|
|
|
179
177
|
result = self.native_query(query)
|
|
180
178
|
df = result.data_frame
|
|
181
|
-
result.data_frame = df.rename(columns={df.columns[0]:
|
|
179
|
+
result.data_frame = df.rename(columns={df.columns[0]: "table_name"})
|
|
182
180
|
return result
|
|
183
181
|
|
|
184
182
|
def get_columns(self, table_name: str) -> StatusResponse:
|
|
@@ -191,5 +189,5 @@ class DerbyHandler(DatabaseHandler):
|
|
|
191
189
|
Response: Details of the table.
|
|
192
190
|
"""
|
|
193
191
|
|
|
194
|
-
query = f
|
|
192
|
+
query = f""" SELECT COLUMNNAME FROM SYS.SYSCOLUMNS INNER JOIN SYS.SYSTABLES ON SYS.SYSCOLUMNS.REFERENCEID=SYS.SYSTABLES.TABLEID WHERE TABLENAME='{table_name}' """
|
|
195
193
|
return self.native_query(query)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
-r mindsdb/integrations/handlers/mongodb_handler/requirements.txt
|
|
@@ -11,22 +11,22 @@ from mindsdb.utilities.render.sqlalchemy_render import SqlalchemyRender
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class DummyHandler(DatabaseHandler):
|
|
14
|
-
name =
|
|
14
|
+
name = "dummy_data"
|
|
15
15
|
|
|
16
16
|
def __init__(self, **kwargs):
|
|
17
|
-
super().__init__(
|
|
17
|
+
super().__init__("dummy_data")
|
|
18
18
|
self.db_path = None
|
|
19
19
|
|
|
20
|
-
args = kwargs.get(
|
|
21
|
-
if
|
|
22
|
-
self.db_path = args[
|
|
20
|
+
args = kwargs.get("connection_data", {})
|
|
21
|
+
if "db_path" in args:
|
|
22
|
+
self.db_path = args["db_path"]
|
|
23
23
|
|
|
24
24
|
def connect(self):
|
|
25
25
|
"""Set up any connections required by the handler"""
|
|
26
26
|
return self.db_path is not None
|
|
27
27
|
|
|
28
28
|
def disconnect(self):
|
|
29
|
-
"""
|
|
29
|
+
"""Close any existing connections"""
|
|
30
30
|
return
|
|
31
31
|
|
|
32
32
|
def check_connection(self) -> HandlerStatusResponse:
|
|
@@ -41,7 +41,7 @@ class DummyHandler(DatabaseHandler):
|
|
|
41
41
|
"""Receive raw query and act upon it somehow
|
|
42
42
|
|
|
43
43
|
Args:
|
|
44
|
-
query (Any): query in native format (str for sql databases,
|
|
44
|
+
query (Any): query in native format (str for sql databases, etc)
|
|
45
45
|
params (Optional[List])
|
|
46
46
|
|
|
47
47
|
Returns:
|
|
@@ -49,7 +49,7 @@ class DummyHandler(DatabaseHandler):
|
|
|
49
49
|
"""
|
|
50
50
|
con = duckdb.connect(self.db_path)
|
|
51
51
|
if params is not None:
|
|
52
|
-
query = query.replace(
|
|
52
|
+
query = query.replace("%s", "?")
|
|
53
53
|
cur = con.executemany(query, params)
|
|
54
54
|
if cur.rowcount >= 0:
|
|
55
55
|
result_df = cur.fetchdf()
|
|
@@ -71,7 +71,7 @@ class DummyHandler(DatabaseHandler):
|
|
|
71
71
|
Returns:
|
|
72
72
|
HandlerResponse
|
|
73
73
|
"""
|
|
74
|
-
renderer = SqlalchemyRender(
|
|
74
|
+
renderer = SqlalchemyRender("postgres")
|
|
75
75
|
query_str, params = renderer.get_exec_params(query, with_failback=True)
|
|
76
76
|
return self.native_query(query_str, params)
|
|
77
77
|
|
|
@@ -81,10 +81,10 @@ class DummyHandler(DatabaseHandler):
|
|
|
81
81
|
Returns:
|
|
82
82
|
HandlerResponse: Names of the tables in the database
|
|
83
83
|
"""
|
|
84
|
-
q =
|
|
84
|
+
q = "SHOW TABLES;"
|
|
85
85
|
result = self.native_query(q)
|
|
86
86
|
df = result.data_frame
|
|
87
|
-
result.data_frame = df.rename(columns={df.columns[0]:
|
|
87
|
+
result.data_frame = df.rename(columns={df.columns[0]: "table_name"})
|
|
88
88
|
return result
|
|
89
89
|
|
|
90
90
|
def get_columns(self, table_name: str) -> HandlerResponse:
|
|
@@ -96,11 +96,10 @@ class DummyHandler(DatabaseHandler):
|
|
|
96
96
|
Returns:
|
|
97
97
|
HandlerResponse: Details of the table.
|
|
98
98
|
"""
|
|
99
|
-
query = f
|
|
99
|
+
query = f"DESCRIBE {table_name};"
|
|
100
100
|
return self.native_query(query)
|
|
101
101
|
|
|
102
102
|
def subscribe(self, stop_event, callback, table_name, columns=None, **kwargs):
|
|
103
|
-
|
|
104
103
|
while True:
|
|
105
104
|
if stop_event.is_set():
|
|
106
105
|
return
|
|
@@ -19,9 +19,10 @@ logger = log.getLogger(__name__)
|
|
|
19
19
|
|
|
20
20
|
class GoogleBooksHandler(APIHandler):
|
|
21
21
|
"""
|
|
22
|
-
|
|
22
|
+
A class for handling connections and interactions with the Google Books API.
|
|
23
23
|
"""
|
|
24
|
-
|
|
24
|
+
|
|
25
|
+
name = "google_books"
|
|
25
26
|
|
|
26
27
|
def __init__(self, name: str, **kwargs):
|
|
27
28
|
"""
|
|
@@ -33,18 +34,18 @@ class GoogleBooksHandler(APIHandler):
|
|
|
33
34
|
super().__init__(name)
|
|
34
35
|
self.token = None
|
|
35
36
|
self.service = None
|
|
36
|
-
self.connection_data = kwargs.get(
|
|
37
|
-
self.credentials_file = self.connection_data.get(
|
|
37
|
+
self.connection_data = kwargs.get("connection_data", {})
|
|
38
|
+
self.credentials_file = self.connection_data.get("credentials", None)
|
|
38
39
|
self.credentials = None
|
|
39
|
-
self.scopes = [
|
|
40
|
+
self.scopes = ["https://www.googleapis.com/auth/books"]
|
|
40
41
|
self.is_connected = False
|
|
41
42
|
self.connection = None
|
|
42
43
|
bookshelves = BookshelvesTable(self)
|
|
43
44
|
self.bookshelves = bookshelves
|
|
44
|
-
self._register_table(
|
|
45
|
+
self._register_table("bookshelves", bookshelves)
|
|
45
46
|
volumes = VolumesTable(self)
|
|
46
47
|
self.volumes = volumes
|
|
47
|
-
self._register_table(
|
|
48
|
+
self._register_table("volumes", volumes)
|
|
48
49
|
|
|
49
50
|
def connect(self):
|
|
50
51
|
"""
|
|
@@ -58,18 +59,19 @@ class GoogleBooksHandler(APIHandler):
|
|
|
58
59
|
if self.is_connected is True:
|
|
59
60
|
return self.service
|
|
60
61
|
if self.credentials_file:
|
|
61
|
-
if os.path.exists(
|
|
62
|
-
self.credentials = Credentials.from_authorized_user_file(
|
|
62
|
+
if os.path.exists("token_books.json"):
|
|
63
|
+
self.credentials = Credentials.from_authorized_user_file("token_books.json", self.scopes)
|
|
63
64
|
if not self.credentials or not self.credentials.valid:
|
|
64
65
|
if self.credentials and self.credentials.expired and self.credentials.refresh_token:
|
|
65
66
|
self.credentials.refresh(Request())
|
|
66
67
|
else:
|
|
67
68
|
self.credentials = service_account.Credentials.from_service_account_file(
|
|
68
|
-
self.credentials_file, scopes=self.scopes
|
|
69
|
+
self.credentials_file, scopes=self.scopes
|
|
70
|
+
)
|
|
69
71
|
# Save the credentials for the next run
|
|
70
|
-
with open(
|
|
72
|
+
with open("token_books.json", "w") as token:
|
|
71
73
|
token.write(self.credentials.to_json())
|
|
72
|
-
self.service = build(
|
|
74
|
+
self.service = build("books", "v1", credentials=self.credentials)
|
|
73
75
|
return self.service
|
|
74
76
|
|
|
75
77
|
def check_connection(self) -> StatusResponse:
|
|
@@ -85,7 +87,7 @@ class GoogleBooksHandler(APIHandler):
|
|
|
85
87
|
self.connect()
|
|
86
88
|
response.success = True
|
|
87
89
|
except Exception as e:
|
|
88
|
-
logger.error(f
|
|
90
|
+
logger.error(f"Error connecting to Google Books API: {e}!")
|
|
89
91
|
response.error_message = e
|
|
90
92
|
|
|
91
93
|
self.is_connected = response.success
|
|
@@ -96,7 +98,7 @@ class GoogleBooksHandler(APIHandler):
|
|
|
96
98
|
Receive raw query and act upon it somehow.
|
|
97
99
|
Args:
|
|
98
100
|
query (Any): query in native format (str for sql databases,
|
|
99
|
-
|
|
101
|
+
api's json etc)
|
|
100
102
|
Returns:
|
|
101
103
|
HandlerResponse
|
|
102
104
|
"""
|
|
@@ -104,10 +106,7 @@ class GoogleBooksHandler(APIHandler):
|
|
|
104
106
|
|
|
105
107
|
df = self.call_application_api(method_name, params)
|
|
106
108
|
|
|
107
|
-
return Response(
|
|
108
|
-
RESPONSE_TYPE.TABLE,
|
|
109
|
-
data_frame=df
|
|
110
|
-
)
|
|
109
|
+
return Response(RESPONSE_TYPE.TABLE, data_frame=df)
|
|
111
110
|
|
|
112
111
|
def get_bookshelves(self, params: dict = None) -> DataFrame:
|
|
113
112
|
"""
|
|
@@ -120,35 +119,39 @@ class GoogleBooksHandler(APIHandler):
|
|
|
120
119
|
service = self.connect()
|
|
121
120
|
minShelf = None
|
|
122
121
|
maxShelf = None
|
|
123
|
-
if params[
|
|
124
|
-
shelf = int(params[
|
|
125
|
-
if params[
|
|
126
|
-
df =
|
|
127
|
-
|
|
122
|
+
if params["shelf"]:
|
|
123
|
+
shelf = int(params["shelf"])
|
|
124
|
+
if params["source"]:
|
|
125
|
+
df = (
|
|
126
|
+
service.mylibrary()
|
|
127
|
+
.bookshelves()
|
|
128
|
+
.get(shelf=shelf, userid=params["userid"], source=params["source"])
|
|
129
|
+
.execute()
|
|
130
|
+
)
|
|
128
131
|
else:
|
|
129
|
-
df = service.mylibrary().bookshelves().get(shelf=shelf, userid=params[
|
|
132
|
+
df = service.mylibrary().bookshelves().get(shelf=shelf, userid=params["userid"]).execute()
|
|
130
133
|
|
|
131
134
|
df = pd.DataFrame(df, columns=self.bookshelves.get_columns())
|
|
132
135
|
return df
|
|
133
|
-
elif not params[
|
|
134
|
-
minShelf = int(params[
|
|
135
|
-
maxShelf = int(params[
|
|
136
|
-
elif not params[
|
|
137
|
-
minShelf = int(params[
|
|
138
|
-
maxShelf = int(params[
|
|
139
|
-
elif params[
|
|
140
|
-
minShelf = int(params[
|
|
141
|
-
maxShelf = int(params[
|
|
136
|
+
elif not params["minShelf"] and params["maxShelf"]:
|
|
137
|
+
minShelf = int(params["maxShelf"]) - 10
|
|
138
|
+
maxShelf = int(params["maxShelf"])
|
|
139
|
+
elif not params["maxShelf"] and params["minShelf"]:
|
|
140
|
+
minShelf = int(params["minShelf"])
|
|
141
|
+
maxShelf = int(params["minShelf"]) + 10
|
|
142
|
+
elif params["maxShelf"] and params["minShelf"]:
|
|
143
|
+
minShelf = int(params["minShelf"])
|
|
144
|
+
maxShelf = int(params["maxShelf"])
|
|
142
145
|
|
|
143
146
|
args = {
|
|
144
|
-
key: value for key, value in params.items() if key not in [
|
|
147
|
+
key: value for key, value in params.items() if key not in ["minShelf", "maxShelf"] and value is not None
|
|
145
148
|
}
|
|
146
|
-
bookshelves = service.bookshelves().list(userid=params[
|
|
149
|
+
bookshelves = service.bookshelves().list(userid=params["userid"], **args).execute()
|
|
147
150
|
|
|
148
|
-
df = pd.DataFrame(bookshelves[
|
|
151
|
+
df = pd.DataFrame(bookshelves["items"], columns=self.bookshelves.get_columns())
|
|
149
152
|
if minShelf is not None or maxShelf is not None:
|
|
150
153
|
# Drop bookshelves that are not in the id range
|
|
151
|
-
df = df.drop(df[(df[
|
|
154
|
+
df = df.drop(df[(df["id"] < minShelf) | (df["id"] > maxShelf)].index)
|
|
152
155
|
|
|
153
156
|
return df
|
|
154
157
|
|
|
@@ -161,11 +164,9 @@ class GoogleBooksHandler(APIHandler):
|
|
|
161
164
|
DataFrame
|
|
162
165
|
"""
|
|
163
166
|
service = self.connect()
|
|
164
|
-
args = {
|
|
165
|
-
key: value for key, value in params.items() if value is not None
|
|
166
|
-
}
|
|
167
|
+
args = {key: value for key, value in params.items() if value is not None}
|
|
167
168
|
volumes = service.volumes().list(**args).execute()
|
|
168
|
-
df = pd.DataFrame(volumes[
|
|
169
|
+
df = pd.DataFrame(volumes["items"], columns=self.volumes.get_columns())
|
|
169
170
|
return df
|
|
170
171
|
|
|
171
172
|
def call_application_api(self, method_name: str = None, params: dict = None) -> DataFrame:
|
|
@@ -177,9 +178,9 @@ class GoogleBooksHandler(APIHandler):
|
|
|
177
178
|
Returns:
|
|
178
179
|
DataFrame
|
|
179
180
|
"""
|
|
180
|
-
if method_name ==
|
|
181
|
+
if method_name == "get_bookshelves":
|
|
181
182
|
return self.get_bookshelves(params)
|
|
182
|
-
elif method_name ==
|
|
183
|
+
elif method_name == "get_volumes":
|
|
183
184
|
return self.get_volumes(params)
|
|
184
185
|
else:
|
|
185
|
-
raise NotImplementedError(f
|
|
186
|
+
raise NotImplementedError(f"Unknown method {method_name}")
|