13
13
# limitations under the License.
14
14
15
15
import asyncio
16
- from threading import Thread
17
- from typing import Any , Awaitable , Callable , Optional , TypeVar , Union
16
+ from warnings import warn
17
+ from typing import Any , Callable , Optional , Union
18
18
19
- from aiohttp import ClientSession
20
-
21
- from .async_client import AsyncToolboxClient
22
19
from .tools import ToolboxTool
20
+ from toolbox_core .sync_client import ToolboxSyncClient as ToolboxCoreSyncClient
23
21
24
- T = TypeVar ("T" )
25
22
26
23
27
24
class ToolboxClient :
28
- __session : Optional [ClientSession ] = None
29
- __loop : Optional [asyncio .AbstractEventLoop ] = None
30
- __thread : Optional [Thread ] = None
31
25
32
26
def __init__ (
33
27
self ,
@@ -39,51 +33,7 @@ def __init__(
39
33
Args:
40
34
url: The base URL of the Toolbox service.
41
35
"""
42
-
43
- # Running a loop in a background thread allows us to support async
44
- # methods from non-async environments.
45
- if ToolboxClient .__loop is None :
46
- loop = asyncio .new_event_loop ()
47
- thread = Thread (target = loop .run_forever , daemon = True )
48
- thread .start ()
49
- ToolboxClient .__thread = thread
50
- ToolboxClient .__loop = loop
51
-
52
- async def __start_session () -> None :
53
-
54
- # Use a default session if none is provided. This leverages connection
55
- # pooling for better performance by reusing a single session throughout
56
- # the application's lifetime.
57
- if ToolboxClient .__session is None :
58
- ToolboxClient .__session = ClientSession ()
59
-
60
- coro = __start_session ()
61
-
62
- asyncio .run_coroutine_threadsafe (coro , ToolboxClient .__loop ).result ()
63
-
64
- if not ToolboxClient .__session :
65
- raise ValueError ("Session cannot be None." )
66
- self .__async_client = AsyncToolboxClient (url , ToolboxClient .__session )
67
-
68
- def __run_as_sync (self , coro : Awaitable [T ]) -> T :
69
- """Run an async coroutine synchronously"""
70
- if not self .__loop :
71
- raise Exception (
72
- "Cannot call synchronous methods before the background loop is initialized."
73
- )
74
- return asyncio .run_coroutine_threadsafe (coro , self .__loop ).result ()
75
-
76
- async def __run_as_async (self , coro : Awaitable [T ]) -> T :
77
- """Run an async coroutine asynchronously"""
78
-
79
- # If a loop has not been provided, attempt to run in current thread.
80
- if not self .__loop :
81
- return await coro
82
-
83
- # Otherwise, run in the background thread.
84
- return await asyncio .wrap_future (
85
- asyncio .run_coroutine_threadsafe (coro , self .__loop )
86
- )
36
+ self .__core_sync_client = ToolboxCoreSyncClient (url = url )
87
37
88
38
async def aload_tool (
89
39
self ,
@@ -92,7 +42,6 @@ async def aload_tool(
92
42
auth_tokens : Optional [dict [str , Callable [[], str ]]] = None ,
93
43
auth_headers : Optional [dict [str , Callable [[], str ]]] = None ,
94
44
bound_params : dict [str , Union [Any , Callable [[], Any ]]] = {},
95
- strict : bool = True ,
96
45
) -> ToolboxTool :
97
46
"""
98
47
Loads the tool with the given tool name from the Toolbox service.
@@ -105,27 +54,42 @@ async def aload_tool(
105
54
auth_headers: Deprecated. Use `auth_token_getters` instead.
106
55
bound_params: An optional mapping of parameter names to their
107
56
bound values.
108
- strict: If True, raises a ValueError if any of the given bound
109
- parameters are missing from the schema or require
110
- authentication. If False, only issues a warning.
111
57
112
58
Returns:
113
59
A tool loaded from the Toolbox.
114
60
"""
115
- async_tool = await self .__run_as_async (
116
- self .__async_client .aload_tool (
117
- tool_name ,
118
- auth_token_getters ,
119
- auth_tokens ,
120
- auth_headers ,
121
- bound_params ,
122
- strict ,
123
- )
61
+ if auth_headers :
62
+ if auth_token_getters :
63
+ warn (
64
+ "Both `auth_token_getters` and `auth_headers` are provided. `auth_headers` is deprecated, and `auth_token_getters` will be used." ,
65
+ DeprecationWarning ,
66
+ )
67
+ else :
68
+ warn (
69
+ "Argument `auth_headers` is deprecated. Use `auth_token_getters` instead." ,
70
+ DeprecationWarning ,
71
+ )
72
+ auth_token_getters = auth_headers
73
+
74
+ if auth_tokens :
75
+ if auth_token_getters :
76
+ warn (
77
+ "Both `auth_token_getters` and `auth_tokens` are provided. `auth_tokens` is deprecated, and `auth_token_getters` will be used." ,
78
+ DeprecationWarning ,
79
+ )
80
+ else :
81
+ warn (
82
+ "Argument `auth_tokens` is deprecated. Use `auth_token_getters` instead." ,
83
+ DeprecationWarning ,
84
+ )
85
+ auth_token_getters = auth_tokens
86
+
87
+ core_tool = await self .__core_sync_client ._ToolboxSyncClient__async_client .load_tool (
88
+ name = tool_name ,
89
+ auth_token_getters = auth_token_getters ,
90
+ bound_params = bound_params
124
91
)
125
-
126
- if not self .__loop or not self .__thread :
127
- raise ValueError ("Background loop or thread cannot be None." )
128
- return ToolboxTool (async_tool , self .__loop , self .__thread )
92
+ return ToolboxTool (core_tool = core_tool )
129
93
130
94
async def aload_toolset (
131
95
self ,
@@ -134,7 +98,7 @@ async def aload_toolset(
134
98
auth_tokens : Optional [dict [str , Callable [[], str ]]] = None ,
135
99
auth_headers : Optional [dict [str , Callable [[], str ]]] = None ,
136
100
bound_params : dict [str , Union [Any , Callable [[], Any ]]] = {},
137
- strict : bool = True ,
101
+ strict : bool = False ,
138
102
) -> list [ToolboxTool ]:
139
103
"""
140
104
Loads tools from the Toolbox service, optionally filtered by toolset
@@ -149,30 +113,51 @@ async def aload_toolset(
149
113
auth_headers: Deprecated. Use `auth_token_getters` instead.
150
114
bound_params: An optional mapping of parameter names to their
151
115
bound values.
152
- strict: If True, raises a ValueError if any of the given bound
153
- parameters are missing from the schema or require
154
- authentication. If False, only issues a warning.
116
+ strict: If True, raises an error if *any* loaded tool instance fails
117
+ to utilize at least one provided parameter or auth token (if any
118
+ provided). If False (default), raises an error only if a
119
+ user-provided parameter or auth token cannot be applied to *any*
120
+ loaded tool across the set.
155
121
156
122
Returns:
157
123
A list of all tools loaded from the Toolbox.
158
124
"""
159
- async_tools = await self .__run_as_async (
160
- self .__async_client .aload_toolset (
161
- toolset_name ,
162
- auth_token_getters ,
163
- auth_tokens ,
164
- auth_headers ,
165
- bound_params ,
166
- strict ,
167
- )
125
+ if auth_headers :
126
+ if auth_token_getters :
127
+ warn (
128
+ "Both `auth_token_getters` and `auth_headers` are provided. `auth_headers` is deprecated, and `auth_token_getters` will be used." ,
129
+ DeprecationWarning ,
130
+ )
131
+ else :
132
+ warn (
133
+ "Argument `auth_headers` is deprecated. Use `auth_token_getters` instead." ,
134
+ DeprecationWarning ,
135
+ )
136
+ auth_token_getters = auth_headers
137
+
138
+ if auth_tokens :
139
+ if auth_token_getters :
140
+ warn (
141
+ "Both `auth_token_getters` and `auth_tokens` are provided. `auth_tokens` is deprecated, and `auth_token_getters` will be used." ,
142
+ DeprecationWarning ,
143
+ )
144
+ else :
145
+ warn (
146
+ "Argument `auth_tokens` is deprecated. Use `auth_token_getters` instead." ,
147
+ DeprecationWarning ,
148
+ )
149
+ auth_token_getters = auth_tokens
150
+
151
+ core_tools = await self .__core_sync_client ._ToolboxSyncClient__async_client .load_toolset (
152
+ name = toolset_name ,
153
+ auth_token_getters = auth_token_getters ,
154
+ bound_params = bound_params ,
155
+ strict = strict
168
156
)
169
157
170
- tools : list [ToolboxTool ] = []
171
-
172
- if not self .__loop or not self .__thread :
173
- raise ValueError ("Background loop or thread cannot be None." )
174
- for async_tool in async_tools :
175
- tools .append (ToolboxTool (async_tool , self .__loop , self .__thread ))
158
+ tools = []
159
+ for core_tool in core_tools :
160
+ tools .append (ToolboxTool (core_tool_instance = core_tool ))
176
161
return tools
177
162
178
163
def load_tool (
@@ -182,7 +167,6 @@ def load_tool(
182
167
auth_tokens : Optional [dict [str , Callable [[], str ]]] = None ,
183
168
auth_headers : Optional [dict [str , Callable [[], str ]]] = None ,
184
169
bound_params : dict [str , Union [Any , Callable [[], Any ]]] = {},
185
- strict : bool = True ,
186
170
) -> ToolboxTool :
187
171
"""
188
172
Loads the tool with the given tool name from the Toolbox service.
@@ -195,27 +179,42 @@ def load_tool(
195
179
auth_headers: Deprecated. Use `auth_token_getters` instead.
196
180
bound_params: An optional mapping of parameter names to their
197
181
bound values.
198
- strict: If True, raises a ValueError if any of the given bound
199
- parameters are missing from the schema or require
200
- authentication. If False, only issues a warning.
201
182
202
183
Returns:
203
184
A tool loaded from the Toolbox.
204
185
"""
205
- async_tool = self .__run_as_sync (
206
- self .__async_client .aload_tool (
207
- tool_name ,
208
- auth_token_getters ,
209
- auth_tokens ,
210
- auth_headers ,
211
- bound_params ,
212
- strict ,
213
- )
186
+ if auth_headers :
187
+ if auth_token_getters :
188
+ warn (
189
+ "Both `auth_token_getters` and `auth_headers` are provided. `auth_headers` is deprecated, and `auth_token_getters` will be used." ,
190
+ DeprecationWarning ,
191
+ )
192
+ else :
193
+ warn (
194
+ "Argument `auth_headers` is deprecated. Use `auth_token_getters` instead." ,
195
+ DeprecationWarning ,
196
+ )
197
+ auth_token_getters = auth_headers
198
+
199
+ if auth_tokens :
200
+ if auth_token_getters :
201
+ warn (
202
+ "Both `auth_token_getters` and `auth_tokens` are provided. `auth_tokens` is deprecated, and `auth_token_getters` will be used." ,
203
+ DeprecationWarning ,
204
+ )
205
+ else :
206
+ warn (
207
+ "Argument `auth_tokens` is deprecated. Use `auth_token_getters` instead." ,
208
+ DeprecationWarning ,
209
+ )
210
+ auth_token_getters = auth_tokens
211
+
212
+ core_tool = self .__core_sync_client .load_tool (
213
+ name = tool_name ,
214
+ auth_token_getters = auth_token_getters ,
215
+ bound_params = bound_params
214
216
)
215
-
216
- if not self .__loop or not self .__thread :
217
- raise ValueError ("Background loop or thread cannot be None." )
218
- return ToolboxTool (async_tool , self .__loop , self .__thread )
217
+ return ToolboxTool (core_tool = core_tool )
219
218
220
219
def load_toolset (
221
220
self ,
@@ -224,7 +223,7 @@ def load_toolset(
224
223
auth_tokens : Optional [dict [str , Callable [[], str ]]] = None ,
225
224
auth_headers : Optional [dict [str , Callable [[], str ]]] = None ,
226
225
bound_params : dict [str , Union [Any , Callable [[], Any ]]] = {},
227
- strict : bool = True ,
226
+ strict : bool = False ,
228
227
) -> list [ToolboxTool ]:
229
228
"""
230
229
Loads tools from the Toolbox service, optionally filtered by toolset
@@ -239,27 +238,49 @@ def load_toolset(
239
238
auth_headers: Deprecated. Use `auth_token_getters` instead.
240
239
bound_params: An optional mapping of parameter names to their
241
240
bound values.
242
- strict: If True, raises a ValueError if any of the given bound
243
- parameters are missing from the schema or require
244
- authentication. If False, only issues a warning.
241
+ strict: If True, raises an error if *any* loaded tool instance fails
242
+ to utilize at least one provided parameter or auth token (if any
243
+ provided). If False (default), raises an error only if a
244
+ user-provided parameter or auth token cannot be applied to *any*
245
+ loaded tool across the set.
245
246
246
247
Returns:
247
248
A list of all tools loaded from the Toolbox.
248
249
"""
249
- async_tools = self .__run_as_sync (
250
- self .__async_client .aload_toolset (
251
- toolset_name ,
252
- auth_token_getters ,
253
- auth_tokens ,
254
- auth_headers ,
255
- bound_params ,
256
- strict ,
257
- )
250
+ if auth_headers :
251
+ if auth_token_getters :
252
+ warn (
253
+ "Both `auth_token_getters` and `auth_headers` are provided. `auth_headers` is deprecated, and `auth_token_getters` will be used." ,
254
+ DeprecationWarning ,
255
+ )
256
+ else :
257
+ warn (
258
+ "Argument `auth_headers` is deprecated. Use `auth_token_getters` instead." ,
259
+ DeprecationWarning ,
260
+ )
261
+ auth_token_getters = auth_headers
262
+
263
+ if auth_tokens :
264
+ if auth_token_getters :
265
+ warn (
266
+ "Both `auth_token_getters` and `auth_tokens` are provided. `auth_tokens` is deprecated, and `auth_token_getters` will be used." ,
267
+ DeprecationWarning ,
268
+ )
269
+ else :
270
+ warn (
271
+ "Argument `auth_tokens` is deprecated. Use `auth_token_getters` instead." ,
272
+ DeprecationWarning ,
273
+ )
274
+ auth_token_getters = auth_tokens
275
+
276
+ core_tools = self .__core_sync_client .load_toolset (
277
+ name = toolset_name ,
278
+ auth_token_getters = auth_token_getters ,
279
+ bound_params = bound_params ,
280
+ strict = strict
258
281
)
259
282
260
- if not self .__loop or not self .__thread :
261
- raise ValueError ("Background loop or thread cannot be None." )
262
- tools : list [ToolboxTool ] = []
263
- for async_tool in async_tools :
264
- tools .append (ToolboxTool (async_tool , self .__loop , self .__thread ))
283
+ tools = []
284
+ for core_tool in core_tools :
285
+ tools .append (ToolboxTool (core_tool_instance = core_tool ))
265
286
return tools
0 commit comments