solidworks-mcp-python 1.5.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.
- solidworks_mcp/__init__.py +57 -0
- solidworks_mcp/adapters/__init__.py +40 -0
- solidworks_mcp/adapters/base.py +1882 -0
- solidworks_mcp/adapters/circuit_breaker.py +2052 -0
- solidworks_mcp/adapters/com_executor.py +252 -0
- solidworks_mcp/adapters/complexity_analyzer.py +272 -0
- solidworks_mcp/adapters/connection_pool.py +1884 -0
- solidworks_mcp/adapters/factory.py +366 -0
- solidworks_mcp/adapters/intelligent_router.py +218 -0
- solidworks_mcp/adapters/mock_adapter.py +4016 -0
- solidworks_mcp/adapters/pywin32_adapter.py +2842 -0
- solidworks_mcp/adapters/solidworks/__init__.py +17 -0
- solidworks_mcp/adapters/solidworks/bitmap.py +180 -0
- solidworks_mcp/adapters/solidworks/com_utils.py +56 -0
- solidworks_mcp/adapters/solidworks/dimension_layout.py +753 -0
- solidworks_mcp/adapters/solidworks/documentation.py +1476 -0
- solidworks_mcp/adapters/solidworks/drawing_standard.py +1993 -0
- solidworks_mcp/adapters/solidworks/face_selection.py +392 -0
- solidworks_mcp/adapters/solidworks/features.py +3362 -0
- solidworks_mcp/adapters/solidworks/io.py +3649 -0
- solidworks_mcp/adapters/solidworks/rebuild_diagnostics.py +269 -0
- solidworks_mcp/adapters/solidworks/rebuild_inspector.py +146 -0
- solidworks_mcp/adapters/solidworks/selection.py +308 -0
- solidworks_mcp/adapters/solidworks/sketch.py +2545 -0
- solidworks_mcp/adapters/sw_feature_errors.py +66 -0
- solidworks_mcp/adapters/sw_type_info.py +317 -0
- solidworks_mcp/adapters/vba_adapter.py +318 -0
- solidworks_mcp/adapters/vba_macro_executor.py +215 -0
- solidworks_mcp/agents/__init__.py +68 -0
- solidworks_mcp/agents/design_knowledge/assembly_patterns.md +127 -0
- solidworks_mcp/agents/design_knowledge/hinges.md +118 -0
- solidworks_mcp/agents/design_knowledge/snap_fits.md +93 -0
- solidworks_mcp/agents/design_knowledge/solidworks_basics.md +3 -0
- solidworks_mcp/agents/design_knowledge/tolerancing.md +128 -0
- solidworks_mcp/agents/harness.py +216 -0
- solidworks_mcp/agents/history_db.py +1508 -0
- solidworks_mcp/agents/retrieval_index.py +164 -0
- solidworks_mcp/agents/schemas.py +165 -0
- solidworks_mcp/agents/smoke_test.py +285 -0
- solidworks_mcp/agents/soc_exporter.py +650 -0
- solidworks_mcp/agents/soc_pickup.py +332 -0
- solidworks_mcp/agents/soc_rewind.py +221 -0
- solidworks_mcp/agents/vector_rag.py +665 -0
- solidworks_mcp/cache/__init__.py +5 -0
- solidworks_mcp/cache/response_cache.py +164 -0
- solidworks_mcp/config.py +729 -0
- solidworks_mcp/exceptions.py +37 -0
- solidworks_mcp/security/__init__.py +68 -0
- solidworks_mcp/security/auth.py +128 -0
- solidworks_mcp/security/cors.py +27 -0
- solidworks_mcp/security/rate_limiting.py +90 -0
- solidworks_mcp/security/runtime.py +155 -0
- solidworks_mcp/server.py +777 -0
- solidworks_mcp/server_cli_fixed.py +120 -0
- solidworks_mcp/setup/__init__.py +1 -0
- solidworks_mcp/setup/cli.py +399 -0
- solidworks_mcp/setup/clients.py +157 -0
- solidworks_mcp/setup/config_file.py +230 -0
- solidworks_mcp/setup/handshake.py +202 -0
- solidworks_mcp/setup/launcher.py +102 -0
- solidworks_mcp/setup/legacy.py +100 -0
- solidworks_mcp/setup/registration.py +193 -0
- solidworks_mcp/setup/solidworks.py +49 -0
- solidworks_mcp/tools/__init__.py +64 -0
- solidworks_mcp/tools/analysis.py +723 -0
- solidworks_mcp/tools/automation.py +578 -0
- solidworks_mcp/tools/docs_discovery.py +1476 -0
- solidworks_mcp/tools/drawing.py +1015 -0
- solidworks_mcp/tools/drawing_analysis.py +456 -0
- solidworks_mcp/tools/drawing_automation.py +627 -0
- solidworks_mcp/tools/engineering_data.py +466 -0
- solidworks_mcp/tools/error_classifier.py +232 -0
- solidworks_mcp/tools/export.py +833 -0
- solidworks_mcp/tools/file_facts.py +40 -0
- solidworks_mcp/tools/file_management.py +1473 -0
- solidworks_mcp/tools/input_compat.py +17 -0
- solidworks_mcp/tools/macro_recording.py +464 -0
- solidworks_mcp/tools/modeling.py +2360 -0
- solidworks_mcp/tools/sketching.py +1422 -0
- solidworks_mcp/tools/template_management.py +367 -0
- solidworks_mcp/tools/tool_boundary.py +280 -0
- solidworks_mcp/tools/vba_generation.py +1145 -0
- solidworks_mcp/ui/__init__.py +9 -0
- solidworks_mcp/ui/local_llm.py +725 -0
- solidworks_mcp/ui/routers/__init__.py +10 -0
- solidworks_mcp/ui/routers/checkpoint.py +24 -0
- solidworks_mcp/ui/routers/docs.py +47 -0
- solidworks_mcp/ui/routers/llm.py +83 -0
- solidworks_mcp/ui/routers/local_model.py +69 -0
- solidworks_mcp/ui/routers/model.py +75 -0
- solidworks_mcp/ui/routers/preview.py +38 -0
- solidworks_mcp/ui/routers/session.py +161 -0
- solidworks_mcp/ui/routers/viewer.py +154 -0
- solidworks_mcp/ui/schemas.py +502 -0
- solidworks_mcp/ui/server.py +298 -0
- solidworks_mcp/ui/service.py +481 -0
- solidworks_mcp/ui/services/__init__.py +136 -0
- solidworks_mcp/ui/services/_utils.py +958 -0
- solidworks_mcp/ui/services/checkpoint_service.py +1110 -0
- solidworks_mcp/ui/services/docs_service.py +282 -0
- solidworks_mcp/ui/services/llm_service.py +956 -0
- solidworks_mcp/ui/services/model_service.py +459 -0
- solidworks_mcp/ui/services/parameter_repair_service.py +314 -0
- solidworks_mcp/ui/services/preview_service.py +489 -0
- solidworks_mcp/ui/services/session_service.py +1389 -0
- solidworks_mcp/utils/__init__.py +9 -0
- solidworks_mcp/utils/feature_tree_classifier.py +342 -0
- solidworks_mcp/utils/logging.py +76 -0
- solidworks_mcp/utils/validation.py +77 -0
- solidworks_mcp/version.py +8 -0
- solidworks_mcp_python-1.5.0.dist-info/METADATA +410 -0
- solidworks_mcp_python-1.5.0.dist-info/RECORD +115 -0
- solidworks_mcp_python-1.5.0.dist-info/WHEEL +4 -0
- solidworks_mcp_python-1.5.0.dist-info/entry_points.txt +3 -0
- solidworks_mcp_python-1.5.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,1884 @@
|
|
|
1
|
+
"""Connection pool adapter for managing multiple SolidWorks connections.
|
|
2
|
+
|
|
3
|
+
Provides connection pooling capabilities to allow parallel SolidWorks operations when
|
|
4
|
+
multiple instances are available.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import asyncio
|
|
8
|
+
import time
|
|
9
|
+
from collections.abc import Awaitable, Callable
|
|
10
|
+
from datetime import datetime
|
|
11
|
+
from typing import Any, TypeVar, cast
|
|
12
|
+
|
|
13
|
+
from loguru import logger
|
|
14
|
+
|
|
15
|
+
from .base import (
|
|
16
|
+
AdapterHealth,
|
|
17
|
+
AdapterResult,
|
|
18
|
+
AdapterResultStatus,
|
|
19
|
+
ExtrusionParameters,
|
|
20
|
+
LoftParameters,
|
|
21
|
+
MassProperties,
|
|
22
|
+
RevolveParameters,
|
|
23
|
+
SolidWorksAdapter,
|
|
24
|
+
SolidWorksFeature,
|
|
25
|
+
SolidWorksModel,
|
|
26
|
+
SweepParameters,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
T = TypeVar("T")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class ConnectionPoolAdapter(SolidWorksAdapter):
|
|
33
|
+
"""Connection pool wrapper for SolidWorks adapters.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
adapter_factory (Callable[[], SolidWorksAdapter] | None): Factory callable used to
|
|
37
|
+
create adapter instances.
|
|
38
|
+
Defaults to None.
|
|
39
|
+
pool_size (int): Number of adapters to maintain in the pool. Defaults to 3.
|
|
40
|
+
max_retries (int): Maximum number of retry attempts. Defaults to 3.
|
|
41
|
+
create_connection (Callable[[], SolidWorksAdapter] | None): Factory callable used to
|
|
42
|
+
create a connection.
|
|
43
|
+
Defaults to None.
|
|
44
|
+
max_size (int | None): Maximum number of items allowed in the pool. Defaults to
|
|
45
|
+
None.
|
|
46
|
+
timeout (float | None): Maximum time to wait in seconds. Defaults to None.
|
|
47
|
+
config (dict[str, object] | None): Configuration values for the operation. Defaults
|
|
48
|
+
to None.
|
|
49
|
+
|
|
50
|
+
Attributes:
|
|
51
|
+
_lock (Any): The lock value.
|
|
52
|
+
adapter_factory (Any): The adapter factory value.
|
|
53
|
+
max_retries (Any): The max retries value.
|
|
54
|
+
pool_initialized (Any): The pool initialized value.
|
|
55
|
+
pool_size (Any): The pool size value.
|
|
56
|
+
timeout (Any): The timeout value.
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
def __init__(
|
|
60
|
+
self,
|
|
61
|
+
adapter_factory: Callable[[], SolidWorksAdapter] | None = None,
|
|
62
|
+
pool_size: int = 3,
|
|
63
|
+
max_retries: int = 3,
|
|
64
|
+
create_connection: Callable[[], SolidWorksAdapter] | None = None,
|
|
65
|
+
max_size: int | None = None,
|
|
66
|
+
timeout: float | None = None,
|
|
67
|
+
config: dict[str, object] | None = None,
|
|
68
|
+
) -> None:
|
|
69
|
+
"""Initialize the connection pool adapter.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
adapter_factory (Callable[[], SolidWorksAdapter] | None): Factory callable used to
|
|
73
|
+
create adapter instances.
|
|
74
|
+
Defaults to None.
|
|
75
|
+
pool_size (int): Number of adapters to maintain in the pool. Defaults to 3.
|
|
76
|
+
max_retries (int): Maximum number of retry attempts. Defaults to 3.
|
|
77
|
+
create_connection (Callable[[], SolidWorksAdapter] | None): Factory callable used to
|
|
78
|
+
create a connection.
|
|
79
|
+
Defaults to None.
|
|
80
|
+
max_size (int | None): Maximum number of items allowed in the pool. Defaults to
|
|
81
|
+
None.
|
|
82
|
+
timeout (float | None): Maximum time to wait in seconds. Defaults to None.
|
|
83
|
+
config (dict[str, object] | None): Configuration values for the operation. Defaults
|
|
84
|
+
to None.
|
|
85
|
+
|
|
86
|
+
Returns:
|
|
87
|
+
None: None.
|
|
88
|
+
"""
|
|
89
|
+
if adapter_factory is None and create_connection is not None:
|
|
90
|
+
adapter_factory = create_connection
|
|
91
|
+
if max_size is not None:
|
|
92
|
+
pool_size = max_size
|
|
93
|
+
if adapter_factory is None:
|
|
94
|
+
from .mock_adapter import MockSolidWorksAdapter
|
|
95
|
+
|
|
96
|
+
def adapter_factory() -> MockSolidWorksAdapter:
|
|
97
|
+
"""Provide adapter factory support for the connection pool adapter.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
MockSolidWorksAdapter: The result produced by the operation.
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
return MockSolidWorksAdapter(config or {})
|
|
104
|
+
|
|
105
|
+
super().__init__(config)
|
|
106
|
+
self.adapter_factory = adapter_factory
|
|
107
|
+
self.pool_size = pool_size
|
|
108
|
+
self.max_retries = max_retries
|
|
109
|
+
|
|
110
|
+
self.pool: list[SolidWorksAdapter] = []
|
|
111
|
+
self.available_adapters: asyncio.Queue[SolidWorksAdapter] = asyncio.Queue()
|
|
112
|
+
self.pool_initialized = False
|
|
113
|
+
self._lock = asyncio.Lock()
|
|
114
|
+
self.timeout = timeout if timeout is not None else 30.0
|
|
115
|
+
|
|
116
|
+
async def _attempt_async(
|
|
117
|
+
self, operation: Callable[[], Awaitable[T]], default: T | None = None
|
|
118
|
+
) -> T | None:
|
|
119
|
+
"""Run an async operation and return default on failure.
|
|
120
|
+
|
|
121
|
+
Args:
|
|
122
|
+
operation (Callable[[], Awaitable[T]]): Callable object executed by the helper.
|
|
123
|
+
default (T | None): Fallback value returned when the operation fails. Defaults to
|
|
124
|
+
None.
|
|
125
|
+
|
|
126
|
+
Returns:
|
|
127
|
+
T | None: The result produced by the operation.
|
|
128
|
+
"""
|
|
129
|
+
try:
|
|
130
|
+
return await operation()
|
|
131
|
+
except Exception:
|
|
132
|
+
return default
|
|
133
|
+
|
|
134
|
+
async def _attempt_async_with_error(
|
|
135
|
+
self, operation: Callable[[], Awaitable[T]]
|
|
136
|
+
) -> tuple[T | None, Exception | None]:
|
|
137
|
+
"""Run an async operation and return (result, error).
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
operation (Callable[[], Awaitable[T]]): Callable object executed by the helper.
|
|
141
|
+
|
|
142
|
+
Returns:
|
|
143
|
+
tuple[T | None, Exception | None]: A tuple containing the resulting values.
|
|
144
|
+
"""
|
|
145
|
+
try:
|
|
146
|
+
return await operation(), None
|
|
147
|
+
except Exception as exc:
|
|
148
|
+
return None, exc
|
|
149
|
+
|
|
150
|
+
def _attempt_sync(
|
|
151
|
+
self, operation: Callable[[], T], default: T | None = None
|
|
152
|
+
) -> T | None:
|
|
153
|
+
"""Run a sync operation and return default on failure.
|
|
154
|
+
|
|
155
|
+
Args:
|
|
156
|
+
operation (Callable[[], T]): Callable object executed by the helper.
|
|
157
|
+
default (T | None): Fallback value returned when the operation fails. Defaults to
|
|
158
|
+
None.
|
|
159
|
+
|
|
160
|
+
Returns:
|
|
161
|
+
T | None: The result produced by the operation.
|
|
162
|
+
"""
|
|
163
|
+
try:
|
|
164
|
+
return operation()
|
|
165
|
+
except Exception:
|
|
166
|
+
return default
|
|
167
|
+
|
|
168
|
+
async def _invoke_with_optional_args(
|
|
169
|
+
self,
|
|
170
|
+
adapter: SolidWorksAdapter,
|
|
171
|
+
method_name: str,
|
|
172
|
+
*args: object,
|
|
173
|
+
) -> object:
|
|
174
|
+
"""Invoke adapter method with args, retrying without args on signature mismatch.
|
|
175
|
+
|
|
176
|
+
Args:
|
|
177
|
+
adapter (SolidWorksAdapter): Adapter instance used for the operation.
|
|
178
|
+
method_name (str): Name of the method to invoke.
|
|
179
|
+
*args (object): Additional positional arguments forwarded to the call.
|
|
180
|
+
|
|
181
|
+
Returns:
|
|
182
|
+
object: The result produced by the operation.
|
|
183
|
+
"""
|
|
184
|
+
method = getattr(adapter, method_name)
|
|
185
|
+
try:
|
|
186
|
+
return await method(*args)
|
|
187
|
+
except TypeError:
|
|
188
|
+
return await method()
|
|
189
|
+
|
|
190
|
+
async def _replace_failed_adapter(self) -> Exception | None:
|
|
191
|
+
"""Create, connect, and return a replacement adapter.
|
|
192
|
+
|
|
193
|
+
Returns None on success, or the captured exception on failure.
|
|
194
|
+
|
|
195
|
+
Returns:
|
|
196
|
+
Exception | None: The result produced by the operation.
|
|
197
|
+
"""
|
|
198
|
+
try:
|
|
199
|
+
new_adapter = self.adapter_factory()
|
|
200
|
+
await new_adapter.connect()
|
|
201
|
+
await self._return_adapter(new_adapter)
|
|
202
|
+
return None
|
|
203
|
+
except Exception as exc:
|
|
204
|
+
return exc
|
|
205
|
+
|
|
206
|
+
@property
|
|
207
|
+
def size(self) -> int:
|
|
208
|
+
"""Provide size support for the connection pool adapter.
|
|
209
|
+
|
|
210
|
+
Returns:
|
|
211
|
+
int: The computed numeric result.
|
|
212
|
+
"""
|
|
213
|
+
return len(self.pool)
|
|
214
|
+
|
|
215
|
+
@property
|
|
216
|
+
def active_connections(self) -> int:
|
|
217
|
+
"""Provide active connections support for the connection pool adapter.
|
|
218
|
+
|
|
219
|
+
Returns:
|
|
220
|
+
int: The computed numeric result.
|
|
221
|
+
"""
|
|
222
|
+
return max(0, len(self.pool) - self.available_adapters.qsize())
|
|
223
|
+
|
|
224
|
+
async def acquire(self) -> SolidWorksAdapter:
|
|
225
|
+
"""Provide acquire support for the connection pool adapter.
|
|
226
|
+
|
|
227
|
+
Returns:
|
|
228
|
+
SolidWorksAdapter: The result produced by the operation.
|
|
229
|
+
"""
|
|
230
|
+
return await self._get_adapter(timeout=self.timeout)
|
|
231
|
+
|
|
232
|
+
async def release(self, adapter: SolidWorksAdapter) -> None:
|
|
233
|
+
"""Provide release support for the connection pool adapter.
|
|
234
|
+
|
|
235
|
+
Args:
|
|
236
|
+
adapter (SolidWorksAdapter): Adapter instance used for the operation.
|
|
237
|
+
|
|
238
|
+
Returns:
|
|
239
|
+
None: None.
|
|
240
|
+
"""
|
|
241
|
+
await self._return_adapter(adapter)
|
|
242
|
+
|
|
243
|
+
async def cleanup(self) -> None:
|
|
244
|
+
"""Provide cleanup support for the connection pool adapter.
|
|
245
|
+
|
|
246
|
+
Returns:
|
|
247
|
+
None: None.
|
|
248
|
+
"""
|
|
249
|
+
await self.disconnect()
|
|
250
|
+
|
|
251
|
+
async def _initialize_pool(self) -> None:
|
|
252
|
+
"""Initialize the connection pool.
|
|
253
|
+
|
|
254
|
+
Returns:
|
|
255
|
+
None: None.
|
|
256
|
+
"""
|
|
257
|
+
if self.pool_initialized:
|
|
258
|
+
return
|
|
259
|
+
|
|
260
|
+
async with self._lock:
|
|
261
|
+
if self.pool_initialized:
|
|
262
|
+
return # type: ignore[unreachable] # double-check locking pattern
|
|
263
|
+
|
|
264
|
+
logger.info(f"Initializing connection pool with {self.pool_size} adapters")
|
|
265
|
+
|
|
266
|
+
for i in range(self.pool_size):
|
|
267
|
+
try:
|
|
268
|
+
adapter = self.adapter_factory()
|
|
269
|
+
await adapter.connect()
|
|
270
|
+
self.pool.append(adapter)
|
|
271
|
+
await self.available_adapters.put(adapter)
|
|
272
|
+
logger.debug(f"Initialized adapter {i + 1}/{self.pool_size}")
|
|
273
|
+
except Exception as e:
|
|
274
|
+
logger.warning(f"Failed to initialize adapter {i + 1}: {e}")
|
|
275
|
+
|
|
276
|
+
self.pool_initialized = True
|
|
277
|
+
logger.info(f"Connection pool initialized with {len(self.pool)} adapters")
|
|
278
|
+
|
|
279
|
+
async def _get_adapter(self, timeout: float = 30.0) -> SolidWorksAdapter:
|
|
280
|
+
"""Get an available adapter from the pool.
|
|
281
|
+
|
|
282
|
+
Args:
|
|
283
|
+
timeout (float): Maximum time to wait in seconds. Defaults to 30.0.
|
|
284
|
+
|
|
285
|
+
Returns:
|
|
286
|
+
SolidWorksAdapter: The result produced by the operation.
|
|
287
|
+
|
|
288
|
+
Raises:
|
|
289
|
+
Exception: If the operation cannot be completed.
|
|
290
|
+
"""
|
|
291
|
+
await self._initialize_pool()
|
|
292
|
+
|
|
293
|
+
try:
|
|
294
|
+
adapter = await asyncio.wait_for(
|
|
295
|
+
self.available_adapters.get(), timeout=timeout
|
|
296
|
+
)
|
|
297
|
+
return adapter
|
|
298
|
+
except TimeoutError as err:
|
|
299
|
+
raise Exception(f"No adapter available within {timeout} seconds") from err
|
|
300
|
+
|
|
301
|
+
async def _return_adapter(self, adapter: SolidWorksAdapter) -> None:
|
|
302
|
+
"""Return an adapter to the pool.
|
|
303
|
+
|
|
304
|
+
Args:
|
|
305
|
+
adapter (SolidWorksAdapter): Adapter instance used for the operation.
|
|
306
|
+
|
|
307
|
+
Returns:
|
|
308
|
+
None: None.
|
|
309
|
+
"""
|
|
310
|
+
await self.available_adapters.put(adapter)
|
|
311
|
+
|
|
312
|
+
async def _execute_with_pool(
|
|
313
|
+
self,
|
|
314
|
+
operation_name: str,
|
|
315
|
+
operation: Callable[[SolidWorksAdapter], Awaitable[AdapterResult[T]]],
|
|
316
|
+
) -> AdapterResult[T]:
|
|
317
|
+
"""Build internal execute with pool.
|
|
318
|
+
|
|
319
|
+
Args:
|
|
320
|
+
operation_name (str): The operation name value.
|
|
321
|
+
operation (Callable[[SolidWorksAdapter], Awaitable[AdapterResult[T]]]): Callable
|
|
322
|
+
object
|
|
323
|
+
executed by
|
|
324
|
+
the helper.
|
|
325
|
+
|
|
326
|
+
Returns:
|
|
327
|
+
AdapterResult[T]: The result produced by the operation.
|
|
328
|
+
"""
|
|
329
|
+
retries = 0
|
|
330
|
+
last_error = None
|
|
331
|
+
|
|
332
|
+
while retries <= self.max_retries:
|
|
333
|
+
adapter = None
|
|
334
|
+
try:
|
|
335
|
+
adapter = await self._get_adapter()
|
|
336
|
+
result = await operation(adapter)
|
|
337
|
+
|
|
338
|
+
# Return adapter to pool
|
|
339
|
+
await self._return_adapter(adapter)
|
|
340
|
+
|
|
341
|
+
return result
|
|
342
|
+
|
|
343
|
+
except Exception as e:
|
|
344
|
+
last_error = e
|
|
345
|
+
retries += 1
|
|
346
|
+
|
|
347
|
+
logger.warning(
|
|
348
|
+
f"Operation {operation_name} failed (attempt {retries}): {e}"
|
|
349
|
+
)
|
|
350
|
+
|
|
351
|
+
if adapter:
|
|
352
|
+
# Don't return failed adapter to pool, create a new one
|
|
353
|
+
from .base import SolidWorksAdapter
|
|
354
|
+
|
|
355
|
+
typed_adapter: SolidWorksAdapter = adapter
|
|
356
|
+
await self._attempt_async(lambda a=typed_adapter: a.disconnect()) # type: ignore[misc]
|
|
357
|
+
|
|
358
|
+
replacement_error = await self._attempt_async(
|
|
359
|
+
self._replace_failed_adapter
|
|
360
|
+
)
|
|
361
|
+
if replacement_error is not None:
|
|
362
|
+
logger.error(
|
|
363
|
+
f"Failed to create replacement adapter: {replacement_error}"
|
|
364
|
+
)
|
|
365
|
+
|
|
366
|
+
if retries <= self.max_retries:
|
|
367
|
+
await asyncio.sleep(1.0 * retries) # Exponential backoff
|
|
368
|
+
|
|
369
|
+
# All retries exhausted
|
|
370
|
+
return AdapterResult(
|
|
371
|
+
status=AdapterResultStatus.ERROR,
|
|
372
|
+
error=f"Operation {operation_name} failed after {self.max_retries} retries: {last_error}",
|
|
373
|
+
)
|
|
374
|
+
|
|
375
|
+
# Adapter interface implementation
|
|
376
|
+
|
|
377
|
+
async def connect(self) -> None:
|
|
378
|
+
"""Initialize the connection pool.
|
|
379
|
+
|
|
380
|
+
Returns:
|
|
381
|
+
None: None.
|
|
382
|
+
"""
|
|
383
|
+
await self._initialize_pool()
|
|
384
|
+
|
|
385
|
+
async def disconnect(self) -> None:
|
|
386
|
+
"""Disconnect all adapters in the pool.
|
|
387
|
+
|
|
388
|
+
Returns:
|
|
389
|
+
None: None.
|
|
390
|
+
"""
|
|
391
|
+
for adapter in self.pool:
|
|
392
|
+
from .base import SolidWorksAdapter
|
|
393
|
+
|
|
394
|
+
typed_adapter: SolidWorksAdapter = adapter
|
|
395
|
+
_, error = await self._attempt_async_with_error(
|
|
396
|
+
lambda a=typed_adapter: a.disconnect() # type: ignore[misc]
|
|
397
|
+
)
|
|
398
|
+
if error is not None:
|
|
399
|
+
logger.warning(f"Error disconnecting adapter: {error}")
|
|
400
|
+
|
|
401
|
+
self.pool.clear()
|
|
402
|
+
|
|
403
|
+
# Clear the queue
|
|
404
|
+
while not self.available_adapters.empty():
|
|
405
|
+
try:
|
|
406
|
+
self.available_adapters.get_nowait()
|
|
407
|
+
except asyncio.QueueEmpty:
|
|
408
|
+
break
|
|
409
|
+
|
|
410
|
+
self.pool_initialized = False
|
|
411
|
+
|
|
412
|
+
def is_connected(self) -> bool:
|
|
413
|
+
"""Check if pool is initialized.
|
|
414
|
+
|
|
415
|
+
Returns:
|
|
416
|
+
bool: True if connected, otherwise False.
|
|
417
|
+
"""
|
|
418
|
+
return self.pool_initialized and len(self.pool) > 0
|
|
419
|
+
|
|
420
|
+
async def health_check(self) -> AdapterHealth:
|
|
421
|
+
"""Get health status of the connection pool.
|
|
422
|
+
|
|
423
|
+
Returns:
|
|
424
|
+
AdapterHealth: The result produced by the operation.
|
|
425
|
+
"""
|
|
426
|
+
healthy_count = 0
|
|
427
|
+
total_response_time = 0
|
|
428
|
+
|
|
429
|
+
if not self.pool_initialized:
|
|
430
|
+
return AdapterHealth(
|
|
431
|
+
healthy=False,
|
|
432
|
+
last_check=datetime.now(),
|
|
433
|
+
error_count=0,
|
|
434
|
+
success_count=0,
|
|
435
|
+
average_response_time=0,
|
|
436
|
+
connection_status="pool_not_initialized",
|
|
437
|
+
metrics={
|
|
438
|
+
"pool_size": 0,
|
|
439
|
+
"available_adapters": 0,
|
|
440
|
+
"healthy_adapters": 0,
|
|
441
|
+
},
|
|
442
|
+
)
|
|
443
|
+
|
|
444
|
+
# Check health of all adapters
|
|
445
|
+
for adapter in self.pool:
|
|
446
|
+
from .base import SolidWorksAdapter
|
|
447
|
+
|
|
448
|
+
typed_adapter: SolidWorksAdapter = adapter
|
|
449
|
+
health = await self._attempt_async(lambda a=typed_adapter: a.health_check()) # type: ignore[misc]
|
|
450
|
+
if not health:
|
|
451
|
+
continue
|
|
452
|
+
if health.healthy:
|
|
453
|
+
healthy_count += 1
|
|
454
|
+
total_response_time += health.average_response_time
|
|
455
|
+
|
|
456
|
+
avg_response_time = total_response_time / len(self.pool) if self.pool else 0
|
|
457
|
+
|
|
458
|
+
return AdapterHealth(
|
|
459
|
+
healthy=healthy_count > 0,
|
|
460
|
+
last_check=datetime.now(),
|
|
461
|
+
error_count=len(self.pool) - healthy_count,
|
|
462
|
+
success_count=healthy_count,
|
|
463
|
+
average_response_time=avg_response_time,
|
|
464
|
+
connection_status="pooled",
|
|
465
|
+
metrics={
|
|
466
|
+
"pool_size": len(self.pool),
|
|
467
|
+
"available_adapters": self.available_adapters.qsize(),
|
|
468
|
+
"healthy_adapters": healthy_count,
|
|
469
|
+
},
|
|
470
|
+
)
|
|
471
|
+
|
|
472
|
+
# Model operations
|
|
473
|
+
|
|
474
|
+
async def open_model(self, file_path: str) -> AdapterResult[SolidWorksModel]:
|
|
475
|
+
"""Open model using pool.
|
|
476
|
+
|
|
477
|
+
Args:
|
|
478
|
+
file_path (str): Path to the target file.
|
|
479
|
+
|
|
480
|
+
Returns:
|
|
481
|
+
AdapterResult[SolidWorksModel]: The result produced by the operation.
|
|
482
|
+
"""
|
|
483
|
+
return await self._execute_with_pool(
|
|
484
|
+
"open_model", lambda adapter: adapter.open_model(file_path)
|
|
485
|
+
)
|
|
486
|
+
|
|
487
|
+
async def close_model(self, save: bool = False) -> AdapterResult[None]:
|
|
488
|
+
"""Close model using pool.
|
|
489
|
+
|
|
490
|
+
Args:
|
|
491
|
+
save (bool): The save value. Defaults to False.
|
|
492
|
+
|
|
493
|
+
Returns:
|
|
494
|
+
AdapterResult[None]: The result produced by the operation.
|
|
495
|
+
"""
|
|
496
|
+
return await self._execute_with_pool(
|
|
497
|
+
"close_model", lambda adapter: adapter.close_model(save)
|
|
498
|
+
)
|
|
499
|
+
|
|
500
|
+
async def save_file(self, file_path: str | None = None) -> AdapterResult[None]:
|
|
501
|
+
"""Save model using pool.
|
|
502
|
+
|
|
503
|
+
Args:
|
|
504
|
+
file_path (str | None): Path to the target file. Defaults to None.
|
|
505
|
+
|
|
506
|
+
Returns:
|
|
507
|
+
AdapterResult[None]: The result produced by the operation.
|
|
508
|
+
"""
|
|
509
|
+
return await self._execute_with_pool(
|
|
510
|
+
"save_file", lambda adapter: adapter.save_file(file_path)
|
|
511
|
+
)
|
|
512
|
+
|
|
513
|
+
async def create_part(
|
|
514
|
+
self,
|
|
515
|
+
name: str | None = None,
|
|
516
|
+
units: str | None = None,
|
|
517
|
+
template: str | None = None,
|
|
518
|
+
) -> AdapterResult[SolidWorksModel]:
|
|
519
|
+
"""Create part using pool.
|
|
520
|
+
|
|
521
|
+
Args:
|
|
522
|
+
name (str | None): The name value. Defaults to None.
|
|
523
|
+
units (str | None): The units value. Defaults to None.
|
|
524
|
+
template (str | None): Template file path. Defaults to None.
|
|
525
|
+
|
|
526
|
+
Returns:
|
|
527
|
+
AdapterResult[SolidWorksModel]: The result produced by the operation.
|
|
528
|
+
"""
|
|
529
|
+
|
|
530
|
+
async def _op(adapter: SolidWorksAdapter) -> AdapterResult[SolidWorksModel]:
|
|
531
|
+
"""Build internal op.
|
|
532
|
+
|
|
533
|
+
Args:
|
|
534
|
+
adapter (SolidWorksAdapter): Adapter instance used for the operation.
|
|
535
|
+
|
|
536
|
+
Returns:
|
|
537
|
+
AdapterResult[SolidWorksModel]: The result produced by the operation.
|
|
538
|
+
"""
|
|
539
|
+
if template is not None:
|
|
540
|
+
# No zero-arg retry: dropping the template would silently
|
|
541
|
+
# build the document from a different one.
|
|
542
|
+
return await adapter.create_part(name, units, template)
|
|
543
|
+
if name is None and units is None:
|
|
544
|
+
return await adapter.create_part()
|
|
545
|
+
result = await self._invoke_with_optional_args(
|
|
546
|
+
adapter, "create_part", name, units
|
|
547
|
+
)
|
|
548
|
+
return cast(AdapterResult[SolidWorksModel], result)
|
|
549
|
+
|
|
550
|
+
return await self._execute_with_pool("create_part", _op)
|
|
551
|
+
|
|
552
|
+
async def create_assembly(
|
|
553
|
+
self, name: str | None = None, template: str | None = None
|
|
554
|
+
) -> AdapterResult[SolidWorksModel]:
|
|
555
|
+
"""Create assembly using pool.
|
|
556
|
+
|
|
557
|
+
Args:
|
|
558
|
+
name (str | None): The name value. Defaults to None.
|
|
559
|
+
template (str | None): Template file path. Defaults to None.
|
|
560
|
+
|
|
561
|
+
Returns:
|
|
562
|
+
AdapterResult[SolidWorksModel]: The result produced by the operation.
|
|
563
|
+
"""
|
|
564
|
+
|
|
565
|
+
async def _op(adapter: SolidWorksAdapter) -> AdapterResult[SolidWorksModel]:
|
|
566
|
+
"""Build internal op.
|
|
567
|
+
|
|
568
|
+
Args:
|
|
569
|
+
adapter (SolidWorksAdapter): Adapter instance used for the operation.
|
|
570
|
+
|
|
571
|
+
Returns:
|
|
572
|
+
AdapterResult[SolidWorksModel]: The result produced by the operation.
|
|
573
|
+
"""
|
|
574
|
+
if template is not None:
|
|
575
|
+
return await adapter.create_assembly(name, template)
|
|
576
|
+
if name is None:
|
|
577
|
+
return await adapter.create_assembly()
|
|
578
|
+
result = await self._invoke_with_optional_args(
|
|
579
|
+
adapter, "create_assembly", name
|
|
580
|
+
)
|
|
581
|
+
return cast(AdapterResult[SolidWorksModel], result)
|
|
582
|
+
|
|
583
|
+
return await self._execute_with_pool("create_assembly", _op)
|
|
584
|
+
|
|
585
|
+
async def create_drawing(
|
|
586
|
+
self, name: str | None = None, template: str | None = None
|
|
587
|
+
) -> AdapterResult[SolidWorksModel]:
|
|
588
|
+
"""Create drawing using pool.
|
|
589
|
+
|
|
590
|
+
Args:
|
|
591
|
+
name (str | None): The name value. Defaults to None.
|
|
592
|
+
template (str | None): Template file path. Defaults to None.
|
|
593
|
+
|
|
594
|
+
Returns:
|
|
595
|
+
AdapterResult[SolidWorksModel]: The result produced by the operation.
|
|
596
|
+
"""
|
|
597
|
+
return await self._execute_with_pool(
|
|
598
|
+
"create_drawing", lambda adapter: adapter.create_drawing(name, template)
|
|
599
|
+
)
|
|
600
|
+
|
|
601
|
+
# Feature operations
|
|
602
|
+
|
|
603
|
+
async def create_extrusion(
|
|
604
|
+
self, params: ExtrusionParameters
|
|
605
|
+
) -> AdapterResult[SolidWorksFeature]:
|
|
606
|
+
"""Create extrusion using pool.
|
|
607
|
+
|
|
608
|
+
Args:
|
|
609
|
+
params (ExtrusionParameters): The params value.
|
|
610
|
+
|
|
611
|
+
Returns:
|
|
612
|
+
AdapterResult[SolidWorksFeature]: The result produced by the operation.
|
|
613
|
+
"""
|
|
614
|
+
return await self._execute_with_pool(
|
|
615
|
+
"create_extrusion", lambda adapter: adapter.create_extrusion(params)
|
|
616
|
+
)
|
|
617
|
+
|
|
618
|
+
async def create_cut_extrude(
|
|
619
|
+
self, params: ExtrusionParameters
|
|
620
|
+
) -> AdapterResult[SolidWorksFeature]:
|
|
621
|
+
"""Create cut-extrude using pool."""
|
|
622
|
+
return await self._execute_with_pool(
|
|
623
|
+
"create_cut_extrude", lambda adapter: adapter.create_cut_extrude(params)
|
|
624
|
+
)
|
|
625
|
+
|
|
626
|
+
async def add_fillet(
|
|
627
|
+
self, radius: float, edge_names: list[str]
|
|
628
|
+
) -> AdapterResult[SolidWorksFeature]:
|
|
629
|
+
"""Add fillet using pool."""
|
|
630
|
+
return await self._execute_with_pool(
|
|
631
|
+
"add_fillet", lambda adapter: adapter.add_fillet(radius, edge_names)
|
|
632
|
+
)
|
|
633
|
+
|
|
634
|
+
async def add_chamfer(
|
|
635
|
+
self, distance: float, edge_names: list[str]
|
|
636
|
+
) -> AdapterResult[SolidWorksFeature]:
|
|
637
|
+
"""Add chamfer using pool."""
|
|
638
|
+
return await self._execute_with_pool(
|
|
639
|
+
"add_chamfer", lambda adapter: adapter.add_chamfer(distance, edge_names)
|
|
640
|
+
)
|
|
641
|
+
|
|
642
|
+
async def get_selected_entities(self) -> AdapterResult[list[dict[str, Any]]]:
|
|
643
|
+
"""Report the current UI selection using pool."""
|
|
644
|
+
return await self._execute_with_pool(
|
|
645
|
+
"get_selected_entities", lambda adapter: adapter.get_selected_entities()
|
|
646
|
+
)
|
|
647
|
+
|
|
648
|
+
async def select_feature(
|
|
649
|
+
self, feature_name: str, append: bool = False
|
|
650
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
651
|
+
"""Select a named feature using pool."""
|
|
652
|
+
return await self._execute_with_pool(
|
|
653
|
+
"select_feature",
|
|
654
|
+
lambda adapter: adapter.select_feature(feature_name, append),
|
|
655
|
+
)
|
|
656
|
+
|
|
657
|
+
async def select_face_edges(
|
|
658
|
+
self,
|
|
659
|
+
point: list[float] | None = None,
|
|
660
|
+
side: str | None = None,
|
|
661
|
+
plane: str | None = None,
|
|
662
|
+
edge_type: str = "all",
|
|
663
|
+
append: bool = False,
|
|
664
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
665
|
+
"""Multi-select a face's edges using pool."""
|
|
666
|
+
return await self._execute_with_pool(
|
|
667
|
+
"select_face_edges",
|
|
668
|
+
lambda adapter: adapter.select_face_edges(
|
|
669
|
+
point, side, plane, edge_type, append
|
|
670
|
+
),
|
|
671
|
+
)
|
|
672
|
+
|
|
673
|
+
async def rebuild_model(
|
|
674
|
+
self, top_level_only: bool = False
|
|
675
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
676
|
+
"""Force a rebuild using pool."""
|
|
677
|
+
return await self._execute_with_pool(
|
|
678
|
+
"rebuild_model", lambda adapter: adapter.rebuild_model(top_level_only)
|
|
679
|
+
)
|
|
680
|
+
|
|
681
|
+
async def create_reference_plane(
|
|
682
|
+
self,
|
|
683
|
+
reference: str,
|
|
684
|
+
offset: float = 0.0,
|
|
685
|
+
angle: float = 0.0,
|
|
686
|
+
flip: bool = False,
|
|
687
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
688
|
+
"""Create reference plane using pool."""
|
|
689
|
+
return await self._execute_with_pool(
|
|
690
|
+
"create_reference_plane",
|
|
691
|
+
lambda adapter: adapter.create_reference_plane(
|
|
692
|
+
reference, offset, angle, flip
|
|
693
|
+
),
|
|
694
|
+
)
|
|
695
|
+
|
|
696
|
+
async def create_axis(self, reference: str) -> AdapterResult[dict[str, Any]]:
|
|
697
|
+
"""Create reference axis using pool."""
|
|
698
|
+
return await self._execute_with_pool(
|
|
699
|
+
"create_axis", lambda adapter: adapter.create_axis(reference)
|
|
700
|
+
)
|
|
701
|
+
|
|
702
|
+
async def create_reference_point(
|
|
703
|
+
self,
|
|
704
|
+
mode: str,
|
|
705
|
+
x: float,
|
|
706
|
+
y: float,
|
|
707
|
+
z: float,
|
|
708
|
+
distance: float | None = None,
|
|
709
|
+
percent: float | None = None,
|
|
710
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
711
|
+
"""Create a reference point using pool."""
|
|
712
|
+
return await self._execute_with_pool(
|
|
713
|
+
"create_reference_point",
|
|
714
|
+
lambda adapter: adapter.create_reference_point(
|
|
715
|
+
mode, x, y, z, distance, percent
|
|
716
|
+
),
|
|
717
|
+
)
|
|
718
|
+
|
|
719
|
+
async def mirror_feature(
|
|
720
|
+
self,
|
|
721
|
+
features: list[str],
|
|
722
|
+
mirror_plane: str,
|
|
723
|
+
merge: bool = True,
|
|
724
|
+
mirror_bodies: bool = True,
|
|
725
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
726
|
+
"""Mirror solid bodies or features using pool."""
|
|
727
|
+
return await self._execute_with_pool(
|
|
728
|
+
"mirror_feature",
|
|
729
|
+
lambda adapter: adapter.mirror_feature(
|
|
730
|
+
features, mirror_plane, merge, mirror_bodies
|
|
731
|
+
),
|
|
732
|
+
)
|
|
733
|
+
|
|
734
|
+
async def pattern_circular(
|
|
735
|
+
self,
|
|
736
|
+
features: list[str],
|
|
737
|
+
axis: str,
|
|
738
|
+
count: int,
|
|
739
|
+
angle: float = 360.0,
|
|
740
|
+
equal_spacing: bool = True,
|
|
741
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
742
|
+
"""Pattern features around an axis using pool."""
|
|
743
|
+
return await self._execute_with_pool(
|
|
744
|
+
"pattern_circular",
|
|
745
|
+
lambda adapter: adapter.pattern_circular(
|
|
746
|
+
features, axis, count, angle, equal_spacing
|
|
747
|
+
),
|
|
748
|
+
)
|
|
749
|
+
|
|
750
|
+
async def create_revolve(
|
|
751
|
+
self, params: RevolveParameters
|
|
752
|
+
) -> AdapterResult[SolidWorksFeature]:
|
|
753
|
+
"""Create revolve using pool.
|
|
754
|
+
|
|
755
|
+
Args:
|
|
756
|
+
params (RevolveParameters): The params value.
|
|
757
|
+
|
|
758
|
+
Returns:
|
|
759
|
+
AdapterResult[SolidWorksFeature]: The result produced by the operation.
|
|
760
|
+
"""
|
|
761
|
+
return await self._execute_with_pool(
|
|
762
|
+
"create_revolve", lambda adapter: adapter.create_revolve(params)
|
|
763
|
+
)
|
|
764
|
+
|
|
765
|
+
async def create_sweep(
|
|
766
|
+
self, params: SweepParameters
|
|
767
|
+
) -> AdapterResult[SolidWorksFeature]:
|
|
768
|
+
"""Create sweep using pool.
|
|
769
|
+
|
|
770
|
+
Args:
|
|
771
|
+
params (SweepParameters): The params value.
|
|
772
|
+
|
|
773
|
+
Returns:
|
|
774
|
+
AdapterResult[SolidWorksFeature]: The result produced by the operation.
|
|
775
|
+
"""
|
|
776
|
+
return await self._execute_with_pool(
|
|
777
|
+
"create_sweep", lambda adapter: adapter.create_sweep(params)
|
|
778
|
+
)
|
|
779
|
+
|
|
780
|
+
async def create_loft(
|
|
781
|
+
self, params: LoftParameters
|
|
782
|
+
) -> AdapterResult[SolidWorksFeature]:
|
|
783
|
+
"""Create loft using pool.
|
|
784
|
+
|
|
785
|
+
Args:
|
|
786
|
+
params (LoftParameters): The params value.
|
|
787
|
+
|
|
788
|
+
Returns:
|
|
789
|
+
AdapterResult[SolidWorksFeature]: The result produced by the operation.
|
|
790
|
+
"""
|
|
791
|
+
return await self._execute_with_pool(
|
|
792
|
+
"create_loft", lambda adapter: adapter.create_loft(params)
|
|
793
|
+
)
|
|
794
|
+
|
|
795
|
+
# Sketch operations
|
|
796
|
+
|
|
797
|
+
async def create_sketch(self, plane: str) -> AdapterResult[str]:
|
|
798
|
+
"""Create sketch using pool.
|
|
799
|
+
|
|
800
|
+
Args:
|
|
801
|
+
plane (str): The plane value.
|
|
802
|
+
|
|
803
|
+
Returns:
|
|
804
|
+
AdapterResult[str]: The result produced by the operation.
|
|
805
|
+
"""
|
|
806
|
+
return await self._execute_with_pool(
|
|
807
|
+
"create_sketch", lambda adapter: adapter.create_sketch(plane)
|
|
808
|
+
)
|
|
809
|
+
|
|
810
|
+
async def add_line(
|
|
811
|
+
self, x1: float, y1: float, x2: float, y2: float
|
|
812
|
+
) -> AdapterResult[str]:
|
|
813
|
+
"""Add line using pool.
|
|
814
|
+
|
|
815
|
+
Args:
|
|
816
|
+
x1 (float): The x1 value.
|
|
817
|
+
y1 (float): The y1 value.
|
|
818
|
+
x2 (float): The x2 value.
|
|
819
|
+
y2 (float): The y2 value.
|
|
820
|
+
|
|
821
|
+
Returns:
|
|
822
|
+
AdapterResult[str]: The result produced by the operation.
|
|
823
|
+
"""
|
|
824
|
+
return await self._execute_with_pool(
|
|
825
|
+
"add_line", lambda adapter: adapter.add_line(x1, y1, x2, y2)
|
|
826
|
+
)
|
|
827
|
+
|
|
828
|
+
async def add_centerline(
|
|
829
|
+
self, x1: float, y1: float, x2: float, y2: float
|
|
830
|
+
) -> AdapterResult[str]:
|
|
831
|
+
"""Add centerline using pool.
|
|
832
|
+
|
|
833
|
+
Args:
|
|
834
|
+
x1 (float): The x1 value.
|
|
835
|
+
y1 (float): The y1 value.
|
|
836
|
+
x2 (float): The x2 value.
|
|
837
|
+
y2 (float): The y2 value.
|
|
838
|
+
|
|
839
|
+
Returns:
|
|
840
|
+
AdapterResult[str]: The result produced by the operation.
|
|
841
|
+
"""
|
|
842
|
+
return await self._execute_with_pool(
|
|
843
|
+
"add_centerline",
|
|
844
|
+
lambda adapter: adapter.add_centerline(x1, y1, x2, y2),
|
|
845
|
+
)
|
|
846
|
+
|
|
847
|
+
async def add_circle(
|
|
848
|
+
self, center_x: float, center_y: float, radius: float
|
|
849
|
+
) -> AdapterResult[str]:
|
|
850
|
+
"""Add circle using pool.
|
|
851
|
+
|
|
852
|
+
Args:
|
|
853
|
+
center_x (float): The center x value.
|
|
854
|
+
center_y (float): The center y value.
|
|
855
|
+
radius (float): The radius value.
|
|
856
|
+
|
|
857
|
+
Returns:
|
|
858
|
+
AdapterResult[str]: The result produced by the operation.
|
|
859
|
+
"""
|
|
860
|
+
return await self._execute_with_pool(
|
|
861
|
+
"add_circle", lambda adapter: adapter.add_circle(center_x, center_y, radius)
|
|
862
|
+
)
|
|
863
|
+
|
|
864
|
+
async def add_rectangle(
|
|
865
|
+
self, x1: float, y1: float, x2: float, y2: float
|
|
866
|
+
) -> AdapterResult[str]:
|
|
867
|
+
"""Add rectangle using pool.
|
|
868
|
+
|
|
869
|
+
Args:
|
|
870
|
+
x1 (float): The x1 value.
|
|
871
|
+
y1 (float): The y1 value.
|
|
872
|
+
x2 (float): The x2 value.
|
|
873
|
+
y2 (float): The y2 value.
|
|
874
|
+
|
|
875
|
+
Returns:
|
|
876
|
+
AdapterResult[str]: The result produced by the operation.
|
|
877
|
+
"""
|
|
878
|
+
return await self._execute_with_pool(
|
|
879
|
+
"add_rectangle", lambda adapter: adapter.add_rectangle(x1, y1, x2, y2)
|
|
880
|
+
)
|
|
881
|
+
|
|
882
|
+
async def add_arc(
|
|
883
|
+
self,
|
|
884
|
+
center_x: float,
|
|
885
|
+
center_y: float,
|
|
886
|
+
start_x: float,
|
|
887
|
+
start_y: float,
|
|
888
|
+
end_x: float,
|
|
889
|
+
end_y: float,
|
|
890
|
+
) -> AdapterResult[str]:
|
|
891
|
+
"""Add arc using pool.
|
|
892
|
+
|
|
893
|
+
Args:
|
|
894
|
+
center_x (float): Arc center X coordinate.
|
|
895
|
+
center_y (float): Arc center Y coordinate.
|
|
896
|
+
start_x (float): Arc start X coordinate.
|
|
897
|
+
start_y (float): Arc start Y coordinate.
|
|
898
|
+
end_x (float): Arc end X coordinate.
|
|
899
|
+
end_y (float): Arc end Y coordinate.
|
|
900
|
+
|
|
901
|
+
Returns:
|
|
902
|
+
AdapterResult[str]: The result produced by the operation.
|
|
903
|
+
"""
|
|
904
|
+
return await self._execute_with_pool(
|
|
905
|
+
"add_arc",
|
|
906
|
+
lambda adapter: adapter.add_arc(
|
|
907
|
+
center_x,
|
|
908
|
+
center_y,
|
|
909
|
+
start_x,
|
|
910
|
+
start_y,
|
|
911
|
+
end_x,
|
|
912
|
+
end_y,
|
|
913
|
+
),
|
|
914
|
+
)
|
|
915
|
+
|
|
916
|
+
async def add_spline(self, points: list[dict[str, float]]) -> AdapterResult[str]:
|
|
917
|
+
"""Add spline using pool.
|
|
918
|
+
|
|
919
|
+
Args:
|
|
920
|
+
points (list[dict[str, float]]): The points value.
|
|
921
|
+
|
|
922
|
+
Returns:
|
|
923
|
+
AdapterResult[str]: The result produced by the operation.
|
|
924
|
+
"""
|
|
925
|
+
return await self._execute_with_pool(
|
|
926
|
+
"add_spline", lambda adapter: adapter.add_spline(points)
|
|
927
|
+
)
|
|
928
|
+
|
|
929
|
+
async def add_polygon(
|
|
930
|
+
self, center_x: float, center_y: float, radius: float, sides: int
|
|
931
|
+
) -> AdapterResult[str]:
|
|
932
|
+
"""Add polygon using pool.
|
|
933
|
+
|
|
934
|
+
Args:
|
|
935
|
+
center_x (float): The center x value.
|
|
936
|
+
center_y (float): The center y value.
|
|
937
|
+
radius (float): The radius value.
|
|
938
|
+
sides (int): The sides value.
|
|
939
|
+
|
|
940
|
+
Returns:
|
|
941
|
+
AdapterResult[str]: The result produced by the operation.
|
|
942
|
+
"""
|
|
943
|
+
return await self._execute_with_pool(
|
|
944
|
+
"add_polygon",
|
|
945
|
+
lambda adapter: adapter.add_polygon(center_x, center_y, radius, sides),
|
|
946
|
+
)
|
|
947
|
+
|
|
948
|
+
async def add_ellipse(
|
|
949
|
+
self,
|
|
950
|
+
center_x: float,
|
|
951
|
+
center_y: float,
|
|
952
|
+
major_axis: float,
|
|
953
|
+
minor_axis: float,
|
|
954
|
+
) -> AdapterResult[str]:
|
|
955
|
+
"""Add ellipse using pool.
|
|
956
|
+
|
|
957
|
+
Args:
|
|
958
|
+
center_x (float): The center x value.
|
|
959
|
+
center_y (float): The center y value.
|
|
960
|
+
major_axis (float): The major axis value.
|
|
961
|
+
minor_axis (float): The minor axis value.
|
|
962
|
+
|
|
963
|
+
Returns:
|
|
964
|
+
AdapterResult[str]: The result produced by the operation.
|
|
965
|
+
"""
|
|
966
|
+
return await self._execute_with_pool(
|
|
967
|
+
"add_ellipse",
|
|
968
|
+
lambda adapter: adapter.add_ellipse(
|
|
969
|
+
center_x, center_y, major_axis, minor_axis
|
|
970
|
+
),
|
|
971
|
+
)
|
|
972
|
+
|
|
973
|
+
async def sketch_linear_pattern(
|
|
974
|
+
self,
|
|
975
|
+
entities: list[str],
|
|
976
|
+
direction_x: float,
|
|
977
|
+
direction_y: float,
|
|
978
|
+
spacing: float,
|
|
979
|
+
count: int,
|
|
980
|
+
) -> AdapterResult[str]:
|
|
981
|
+
"""Sketch linear pattern using pool.
|
|
982
|
+
|
|
983
|
+
Args:
|
|
984
|
+
entities (list[str]): The entities value.
|
|
985
|
+
direction_x (float): The direction x value.
|
|
986
|
+
direction_y (float): The direction y value.
|
|
987
|
+
spacing (float): The spacing value.
|
|
988
|
+
count (int): The count value.
|
|
989
|
+
|
|
990
|
+
Returns:
|
|
991
|
+
AdapterResult[str]: The result produced by the operation.
|
|
992
|
+
"""
|
|
993
|
+
return await self._execute_with_pool(
|
|
994
|
+
"sketch_linear_pattern",
|
|
995
|
+
lambda adapter: adapter.sketch_linear_pattern(
|
|
996
|
+
entities, direction_x, direction_y, spacing, count
|
|
997
|
+
),
|
|
998
|
+
)
|
|
999
|
+
|
|
1000
|
+
async def sketch_circular_pattern(
|
|
1001
|
+
self,
|
|
1002
|
+
entities: list[str],
|
|
1003
|
+
angle: float,
|
|
1004
|
+
count: int,
|
|
1005
|
+
) -> AdapterResult[str]:
|
|
1006
|
+
"""Sketch circular pattern using pool.
|
|
1007
|
+
|
|
1008
|
+
Args:
|
|
1009
|
+
entities (list[str]): The entities value.
|
|
1010
|
+
angle (float): The angle value.
|
|
1011
|
+
count (int): The count value.
|
|
1012
|
+
|
|
1013
|
+
Returns:
|
|
1014
|
+
AdapterResult[str]: The result produced by the operation.
|
|
1015
|
+
"""
|
|
1016
|
+
return await self._execute_with_pool(
|
|
1017
|
+
"sketch_circular_pattern",
|
|
1018
|
+
lambda adapter: adapter.sketch_circular_pattern(entities, angle, count),
|
|
1019
|
+
)
|
|
1020
|
+
|
|
1021
|
+
async def sketch_mirror(
|
|
1022
|
+
self, entities: list[str], mirror_line: str
|
|
1023
|
+
) -> AdapterResult[str]:
|
|
1024
|
+
"""Sketch mirror using pool.
|
|
1025
|
+
|
|
1026
|
+
Args:
|
|
1027
|
+
entities (list[str]): The entities value.
|
|
1028
|
+
mirror_line (str): The mirror line value.
|
|
1029
|
+
|
|
1030
|
+
Returns:
|
|
1031
|
+
AdapterResult[str]: The result produced by the operation.
|
|
1032
|
+
"""
|
|
1033
|
+
return await self._execute_with_pool(
|
|
1034
|
+
"sketch_mirror",
|
|
1035
|
+
lambda adapter: adapter.sketch_mirror(entities, mirror_line),
|
|
1036
|
+
)
|
|
1037
|
+
|
|
1038
|
+
async def sketch_offset(
|
|
1039
|
+
self,
|
|
1040
|
+
entities: list[str],
|
|
1041
|
+
offset_distance: float,
|
|
1042
|
+
reverse_direction: bool,
|
|
1043
|
+
) -> AdapterResult[str]:
|
|
1044
|
+
"""Sketch offset using pool.
|
|
1045
|
+
|
|
1046
|
+
Args:
|
|
1047
|
+
entities (list[str]): The entities value.
|
|
1048
|
+
offset_distance (float): The offset distance value.
|
|
1049
|
+
reverse_direction (bool): The reverse direction value.
|
|
1050
|
+
|
|
1051
|
+
Returns:
|
|
1052
|
+
AdapterResult[str]: The result produced by the operation.
|
|
1053
|
+
"""
|
|
1054
|
+
return await self._execute_with_pool(
|
|
1055
|
+
"sketch_offset",
|
|
1056
|
+
lambda adapter: adapter.sketch_offset(
|
|
1057
|
+
entities, offset_distance, reverse_direction
|
|
1058
|
+
),
|
|
1059
|
+
)
|
|
1060
|
+
|
|
1061
|
+
async def add_sketch_constraint(
|
|
1062
|
+
self,
|
|
1063
|
+
entity1: str,
|
|
1064
|
+
entity2: str | None,
|
|
1065
|
+
relation_type: str,
|
|
1066
|
+
entity3: str | None = None,
|
|
1067
|
+
) -> AdapterResult[str]:
|
|
1068
|
+
"""Add sketch constraint using pool."""
|
|
1069
|
+
return await self._execute_with_pool(
|
|
1070
|
+
"add_sketch_constraint",
|
|
1071
|
+
lambda adapter: adapter.add_sketch_constraint(
|
|
1072
|
+
entity1,
|
|
1073
|
+
entity2,
|
|
1074
|
+
relation_type,
|
|
1075
|
+
entity3,
|
|
1076
|
+
),
|
|
1077
|
+
)
|
|
1078
|
+
|
|
1079
|
+
async def add_sketch_dimension(
|
|
1080
|
+
self,
|
|
1081
|
+
entity1: str,
|
|
1082
|
+
entity2: str | None,
|
|
1083
|
+
dimension_type: str,
|
|
1084
|
+
value: float,
|
|
1085
|
+
) -> AdapterResult[str]:
|
|
1086
|
+
"""Add sketch dimension using pool."""
|
|
1087
|
+
return await self._execute_with_pool(
|
|
1088
|
+
"add_sketch_dimension",
|
|
1089
|
+
lambda adapter: adapter.add_sketch_dimension(
|
|
1090
|
+
entity1,
|
|
1091
|
+
entity2,
|
|
1092
|
+
dimension_type,
|
|
1093
|
+
value,
|
|
1094
|
+
),
|
|
1095
|
+
)
|
|
1096
|
+
|
|
1097
|
+
async def check_sketch_fully_defined(
|
|
1098
|
+
self, sketch_name: str | None = None
|
|
1099
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
1100
|
+
"""Check sketch definition status using pool."""
|
|
1101
|
+
return await self._execute_with_pool(
|
|
1102
|
+
"check_sketch_fully_defined",
|
|
1103
|
+
lambda adapter: adapter.check_sketch_fully_defined(sketch_name),
|
|
1104
|
+
)
|
|
1105
|
+
|
|
1106
|
+
async def exit_sketch(self) -> AdapterResult[None]:
|
|
1107
|
+
"""Exit sketch using pool.
|
|
1108
|
+
|
|
1109
|
+
Returns:
|
|
1110
|
+
AdapterResult[None]: The result produced by the operation.
|
|
1111
|
+
"""
|
|
1112
|
+
return await self._execute_with_pool(
|
|
1113
|
+
"exit_sketch", lambda adapter: adapter.exit_sketch()
|
|
1114
|
+
)
|
|
1115
|
+
|
|
1116
|
+
# Analysis operations
|
|
1117
|
+
|
|
1118
|
+
async def get_mass_properties(self) -> AdapterResult[MassProperties]:
|
|
1119
|
+
"""Get mass properties using pool.
|
|
1120
|
+
|
|
1121
|
+
Returns:
|
|
1122
|
+
AdapterResult[MassProperties]: The result produced by the operation.
|
|
1123
|
+
"""
|
|
1124
|
+
return await self._execute_with_pool(
|
|
1125
|
+
"get_mass_properties", lambda adapter: adapter.get_mass_properties()
|
|
1126
|
+
)
|
|
1127
|
+
|
|
1128
|
+
async def get_model_info(self) -> AdapterResult[dict[str, object]]:
|
|
1129
|
+
"""Get active model metadata using pool.
|
|
1130
|
+
|
|
1131
|
+
Returns:
|
|
1132
|
+
AdapterResult[dict[str, object]]: The result produced by the operation.
|
|
1133
|
+
"""
|
|
1134
|
+
return await self._execute_with_pool(
|
|
1135
|
+
"get_model_info", lambda adapter: adapter.get_model_info()
|
|
1136
|
+
)
|
|
1137
|
+
|
|
1138
|
+
async def list_features(
|
|
1139
|
+
self, include_suppressed: bool = False, max_assembly_depth: int = 2
|
|
1140
|
+
) -> AdapterResult[list[dict[str, object]]]:
|
|
1141
|
+
"""List model features using pool.
|
|
1142
|
+
|
|
1143
|
+
Args:
|
|
1144
|
+
include_suppressed (bool): The include suppressed value. Defaults to False.
|
|
1145
|
+
max_assembly_depth (int): Sub-assembly recursion depth. Defaults to 2.
|
|
1146
|
+
|
|
1147
|
+
Returns:
|
|
1148
|
+
AdapterResult[list[dict[str, object]]]: The result produced by the operation.
|
|
1149
|
+
"""
|
|
1150
|
+
return await self._execute_with_pool(
|
|
1151
|
+
"list_features",
|
|
1152
|
+
lambda adapter: adapter.list_features(
|
|
1153
|
+
include_suppressed, max_assembly_depth
|
|
1154
|
+
),
|
|
1155
|
+
)
|
|
1156
|
+
|
|
1157
|
+
async def list_configurations(self) -> AdapterResult[list[str]]:
|
|
1158
|
+
"""List model configurations using pool.
|
|
1159
|
+
|
|
1160
|
+
Returns:
|
|
1161
|
+
AdapterResult[list[str]]: The result produced by the operation.
|
|
1162
|
+
"""
|
|
1163
|
+
return await self._execute_with_pool(
|
|
1164
|
+
"list_configurations", lambda adapter: adapter.list_configurations()
|
|
1165
|
+
)
|
|
1166
|
+
|
|
1167
|
+
async def execute_macro(
|
|
1168
|
+
self, params: dict[str, Any]
|
|
1169
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
1170
|
+
"""Provide execute macro support for the connection pool adapter.
|
|
1171
|
+
|
|
1172
|
+
Args:
|
|
1173
|
+
params (dict[str, Any]): The params value.
|
|
1174
|
+
|
|
1175
|
+
Returns:
|
|
1176
|
+
AdapterResult[dict[str, Any]]: The result produced by the operation.
|
|
1177
|
+
"""
|
|
1178
|
+
return await self._execute_with_pool(
|
|
1179
|
+
"execute_macro",
|
|
1180
|
+
lambda adapter: adapter.execute_macro(params), # type: ignore[attr-defined]
|
|
1181
|
+
)
|
|
1182
|
+
|
|
1183
|
+
# Export operations
|
|
1184
|
+
|
|
1185
|
+
async def export_image(self, payload: dict) -> AdapterResult[dict]:
|
|
1186
|
+
"""Export viewport image using pool.
|
|
1187
|
+
|
|
1188
|
+
Args:
|
|
1189
|
+
payload (dict): The payload value.
|
|
1190
|
+
|
|
1191
|
+
Returns:
|
|
1192
|
+
AdapterResult[dict]: The result produced by the operation.
|
|
1193
|
+
"""
|
|
1194
|
+
return await self._execute_with_pool(
|
|
1195
|
+
"export_image", lambda adapter: adapter.export_image(payload)
|
|
1196
|
+
)
|
|
1197
|
+
|
|
1198
|
+
async def export_file(
|
|
1199
|
+
self, file_path: str, format_type: str
|
|
1200
|
+
) -> AdapterResult[None]:
|
|
1201
|
+
"""Export file using pool.
|
|
1202
|
+
|
|
1203
|
+
Args:
|
|
1204
|
+
file_path (str): Path to the target file.
|
|
1205
|
+
format_type (str): The format type value.
|
|
1206
|
+
|
|
1207
|
+
Returns:
|
|
1208
|
+
AdapterResult[None]: The result produced by the operation.
|
|
1209
|
+
"""
|
|
1210
|
+
return await self._execute_with_pool(
|
|
1211
|
+
"export_file", lambda adapter: adapter.export_file(file_path, format_type)
|
|
1212
|
+
)
|
|
1213
|
+
|
|
1214
|
+
# Dimension operations
|
|
1215
|
+
|
|
1216
|
+
async def get_dimension(self, name: str) -> AdapterResult[float]:
|
|
1217
|
+
"""Get dimension using pool.
|
|
1218
|
+
|
|
1219
|
+
Args:
|
|
1220
|
+
name (str): The name value.
|
|
1221
|
+
|
|
1222
|
+
Returns:
|
|
1223
|
+
AdapterResult[float]: The result produced by the operation.
|
|
1224
|
+
"""
|
|
1225
|
+
return await self._execute_with_pool(
|
|
1226
|
+
"get_dimension", lambda adapter: adapter.get_dimension(name)
|
|
1227
|
+
)
|
|
1228
|
+
|
|
1229
|
+
async def set_dimension(self, name: str, value: float) -> AdapterResult[None]:
|
|
1230
|
+
"""Set dimension using pool.
|
|
1231
|
+
|
|
1232
|
+
Args:
|
|
1233
|
+
name (str): The name value.
|
|
1234
|
+
value (float): The value value.
|
|
1235
|
+
|
|
1236
|
+
Returns:
|
|
1237
|
+
AdapterResult[None]: The result produced by the operation.
|
|
1238
|
+
"""
|
|
1239
|
+
return await self._execute_with_pool(
|
|
1240
|
+
"set_dimension", lambda adapter: adapter.set_dimension(name, value)
|
|
1241
|
+
)
|
|
1242
|
+
|
|
1243
|
+
async def set_units(self, unit_system: str) -> AdapterResult[dict[str, Any]]:
|
|
1244
|
+
"""Set document units using pool.
|
|
1245
|
+
|
|
1246
|
+
Args:
|
|
1247
|
+
unit_system (str): One of ``mm``, ``cm``, ``m``, ``in``, ``ft``.
|
|
1248
|
+
|
|
1249
|
+
Returns:
|
|
1250
|
+
AdapterResult[dict[str, Any]]: The result produced by the operation.
|
|
1251
|
+
"""
|
|
1252
|
+
return await self._execute_with_pool(
|
|
1253
|
+
"set_units", lambda adapter: adapter.set_units(unit_system)
|
|
1254
|
+
)
|
|
1255
|
+
|
|
1256
|
+
async def list_open_documents(self) -> AdapterResult[list[dict[str, Any]]]:
|
|
1257
|
+
"""List open documents using pool.
|
|
1258
|
+
|
|
1259
|
+
Returns:
|
|
1260
|
+
AdapterResult[list[dict[str, Any]]]: The result produced by the
|
|
1261
|
+
operation.
|
|
1262
|
+
"""
|
|
1263
|
+
return await self._execute_with_pool(
|
|
1264
|
+
"list_open_documents", lambda adapter: adapter.list_open_documents()
|
|
1265
|
+
)
|
|
1266
|
+
|
|
1267
|
+
async def activate_document(
|
|
1268
|
+
self, title_or_path: str
|
|
1269
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
1270
|
+
"""Activate an open document using pool.
|
|
1271
|
+
|
|
1272
|
+
Args:
|
|
1273
|
+
title_or_path (str): Title, full path, or file name of an open
|
|
1274
|
+
document.
|
|
1275
|
+
|
|
1276
|
+
Returns:
|
|
1277
|
+
AdapterResult[dict[str, Any]]: The result produced by the operation.
|
|
1278
|
+
"""
|
|
1279
|
+
return await self._execute_with_pool(
|
|
1280
|
+
"activate_document",
|
|
1281
|
+
lambda adapter: adapter.activate_document(title_or_path),
|
|
1282
|
+
)
|
|
1283
|
+
|
|
1284
|
+
# Assembly operations
|
|
1285
|
+
|
|
1286
|
+
async def insert_component(
|
|
1287
|
+
self, file_path: str, x: float = 0.0, y: float = 0.0, z: float = 0.0
|
|
1288
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
1289
|
+
"""Insert component using pool.
|
|
1290
|
+
|
|
1291
|
+
Args:
|
|
1292
|
+
file_path (str): Path to the target file.
|
|
1293
|
+
x (float): X position in millimetres. Defaults to 0.0.
|
|
1294
|
+
y (float): Y position in millimetres. Defaults to 0.0.
|
|
1295
|
+
z (float): Z position in millimetres. Defaults to 0.0.
|
|
1296
|
+
|
|
1297
|
+
Returns:
|
|
1298
|
+
AdapterResult[dict[str, Any]]: The result produced by the operation.
|
|
1299
|
+
"""
|
|
1300
|
+
return await self._execute_with_pool(
|
|
1301
|
+
"insert_component",
|
|
1302
|
+
lambda adapter: adapter.insert_component(file_path, x, y, z),
|
|
1303
|
+
)
|
|
1304
|
+
|
|
1305
|
+
async def list_components(self) -> AdapterResult[list[str]]:
|
|
1306
|
+
"""List components using pool.
|
|
1307
|
+
|
|
1308
|
+
Returns:
|
|
1309
|
+
AdapterResult[list[str]]: The result produced by the operation.
|
|
1310
|
+
"""
|
|
1311
|
+
return await self._execute_with_pool(
|
|
1312
|
+
"list_components", lambda adapter: adapter.list_components()
|
|
1313
|
+
)
|
|
1314
|
+
|
|
1315
|
+
async def get_model_geometry_summary(self) -> AdapterResult[dict[str, Any]]:
|
|
1316
|
+
"""Summarise the active document using pool.
|
|
1317
|
+
|
|
1318
|
+
Returns:
|
|
1319
|
+
AdapterResult[dict[str, Any]]: The result produced by the operation.
|
|
1320
|
+
"""
|
|
1321
|
+
return await self._execute_with_pool(
|
|
1322
|
+
"get_model_geometry_summary",
|
|
1323
|
+
lambda adapter: adapter.get_model_geometry_summary(),
|
|
1324
|
+
)
|
|
1325
|
+
|
|
1326
|
+
async def create_drawing_view(
|
|
1327
|
+
self, payload: Any = None
|
|
1328
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
1329
|
+
"""Create a drawing view using pool.
|
|
1330
|
+
|
|
1331
|
+
Args:
|
|
1332
|
+
payload (Any): Tool payload for the drawing view.
|
|
1333
|
+
|
|
1334
|
+
Returns:
|
|
1335
|
+
AdapterResult[dict[str, Any]]: The result produced by the operation.
|
|
1336
|
+
"""
|
|
1337
|
+
return await self._execute_with_pool(
|
|
1338
|
+
"create_drawing_view", lambda adapter: adapter.create_drawing_view(payload)
|
|
1339
|
+
)
|
|
1340
|
+
|
|
1341
|
+
async def add_drawing_view(
|
|
1342
|
+
self, payload: Any = None
|
|
1343
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
1344
|
+
"""Add a drawing view using pool.
|
|
1345
|
+
|
|
1346
|
+
Args:
|
|
1347
|
+
payload (Any): Tool payload for the drawing view.
|
|
1348
|
+
|
|
1349
|
+
Returns:
|
|
1350
|
+
AdapterResult[dict[str, Any]]: The result produced by the operation.
|
|
1351
|
+
"""
|
|
1352
|
+
return await self._execute_with_pool(
|
|
1353
|
+
"add_drawing_view", lambda adapter: adapter.add_drawing_view(payload)
|
|
1354
|
+
)
|
|
1355
|
+
|
|
1356
|
+
async def create_technical_drawing(
|
|
1357
|
+
self, payload: Any = None
|
|
1358
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
1359
|
+
"""Create standard views using pool.
|
|
1360
|
+
|
|
1361
|
+
Args:
|
|
1362
|
+
payload (Any): Tool payload for the technical drawing.
|
|
1363
|
+
|
|
1364
|
+
Returns:
|
|
1365
|
+
AdapterResult[dict[str, Any]]: The result produced by the operation.
|
|
1366
|
+
"""
|
|
1367
|
+
return await self._execute_with_pool(
|
|
1368
|
+
"create_technical_drawing",
|
|
1369
|
+
lambda adapter: adapter.create_technical_drawing(payload),
|
|
1370
|
+
)
|
|
1371
|
+
|
|
1372
|
+
async def add_note(self, payload: Any = None) -> AdapterResult[dict[str, Any]]:
|
|
1373
|
+
"""Add a drawing note using pool.
|
|
1374
|
+
|
|
1375
|
+
Args:
|
|
1376
|
+
payload (Any): Tool payload for the note.
|
|
1377
|
+
|
|
1378
|
+
Returns:
|
|
1379
|
+
AdapterResult[dict[str, Any]]: The result produced by the operation.
|
|
1380
|
+
"""
|
|
1381
|
+
return await self._execute_with_pool(
|
|
1382
|
+
"add_note", lambda adapter: adapter.add_note(payload)
|
|
1383
|
+
)
|
|
1384
|
+
|
|
1385
|
+
async def list_drawing_views(self) -> AdapterResult[list[str]]:
|
|
1386
|
+
"""List drawing views using pool.
|
|
1387
|
+
|
|
1388
|
+
Returns:
|
|
1389
|
+
AdapterResult[list[str]]: The result produced by the operation.
|
|
1390
|
+
"""
|
|
1391
|
+
return await self._execute_with_pool(
|
|
1392
|
+
"list_drawing_views", lambda adapter: adapter.list_drawing_views()
|
|
1393
|
+
)
|
|
1394
|
+
|
|
1395
|
+
async def auto_center_marks(
|
|
1396
|
+
self,
|
|
1397
|
+
view_name: str,
|
|
1398
|
+
mark_holes: bool = True,
|
|
1399
|
+
mark_fillets: bool = False,
|
|
1400
|
+
mark_slots: bool = True,
|
|
1401
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
1402
|
+
"""Auto-insert drawing centre marks using pool."""
|
|
1403
|
+
return await self._execute_with_pool(
|
|
1404
|
+
"auto_center_marks",
|
|
1405
|
+
lambda adapter: adapter.auto_center_marks(
|
|
1406
|
+
view_name, mark_holes, mark_fillets, mark_slots
|
|
1407
|
+
),
|
|
1408
|
+
)
|
|
1409
|
+
|
|
1410
|
+
async def save_body_as_part(
|
|
1411
|
+
self, body_name: str, file_path: str
|
|
1412
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
1413
|
+
"""Save a body to a new part using pool."""
|
|
1414
|
+
return await self._execute_with_pool(
|
|
1415
|
+
"save_body_as_part",
|
|
1416
|
+
lambda adapter: adapter.save_body_as_part(body_name, file_path),
|
|
1417
|
+
)
|
|
1418
|
+
|
|
1419
|
+
async def check_interference(
|
|
1420
|
+
self, params: Any = None
|
|
1421
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
1422
|
+
"""Check interference using pool.
|
|
1423
|
+
|
|
1424
|
+
Args:
|
|
1425
|
+
params (Any): Optional interference-detection settings.
|
|
1426
|
+
|
|
1427
|
+
Returns:
|
|
1428
|
+
AdapterResult[dict[str, Any]]: The result produced by the operation.
|
|
1429
|
+
"""
|
|
1430
|
+
return await self._execute_with_pool(
|
|
1431
|
+
"check_interference", lambda adapter: adapter.check_interference(params)
|
|
1432
|
+
)
|
|
1433
|
+
|
|
1434
|
+
async def delete_feature(self, name: str) -> AdapterResult[dict[str, Any]]:
|
|
1435
|
+
"""Delete a feature using pool.
|
|
1436
|
+
|
|
1437
|
+
Args:
|
|
1438
|
+
name (str): Feature or sketch name.
|
|
1439
|
+
|
|
1440
|
+
Returns:
|
|
1441
|
+
AdapterResult[dict[str, Any]]: The result produced by the operation.
|
|
1442
|
+
"""
|
|
1443
|
+
return await self._execute_with_pool(
|
|
1444
|
+
"delete_feature", lambda adapter: adapter.delete_feature(name)
|
|
1445
|
+
)
|
|
1446
|
+
|
|
1447
|
+
async def suppress_feature(
|
|
1448
|
+
self, name: str, suppress: bool = True
|
|
1449
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
1450
|
+
"""Suppress or unsuppress a feature using pool.
|
|
1451
|
+
|
|
1452
|
+
Args:
|
|
1453
|
+
name (str): Feature name.
|
|
1454
|
+
suppress (bool): True to suppress, False to unsuppress.
|
|
1455
|
+
|
|
1456
|
+
Returns:
|
|
1457
|
+
AdapterResult[dict[str, Any]]: The result produced by the operation.
|
|
1458
|
+
"""
|
|
1459
|
+
return await self._execute_with_pool(
|
|
1460
|
+
"suppress_feature",
|
|
1461
|
+
lambda adapter: adapter.suppress_feature(name, suppress),
|
|
1462
|
+
)
|
|
1463
|
+
|
|
1464
|
+
async def rename_feature(
|
|
1465
|
+
self, old_name: str, new_name: str
|
|
1466
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
1467
|
+
"""Rename a feature using pool.
|
|
1468
|
+
|
|
1469
|
+
Args:
|
|
1470
|
+
old_name (str): Current feature name.
|
|
1471
|
+
new_name (str): New feature name.
|
|
1472
|
+
|
|
1473
|
+
Returns:
|
|
1474
|
+
AdapterResult[dict[str, Any]]: The result produced by the operation.
|
|
1475
|
+
"""
|
|
1476
|
+
return await self._execute_with_pool(
|
|
1477
|
+
"rename_feature",
|
|
1478
|
+
lambda adapter: adapter.rename_feature(old_name, new_name),
|
|
1479
|
+
)
|
|
1480
|
+
|
|
1481
|
+
async def undo(self, count: int = 1) -> AdapterResult[dict[str, Any]]:
|
|
1482
|
+
"""Undo using pool.
|
|
1483
|
+
|
|
1484
|
+
Args:
|
|
1485
|
+
count (int): Number of steps to undo.
|
|
1486
|
+
|
|
1487
|
+
Returns:
|
|
1488
|
+
AdapterResult[dict[str, Any]]: The result produced by the operation.
|
|
1489
|
+
"""
|
|
1490
|
+
return await self._execute_with_pool(
|
|
1491
|
+
"undo", lambda adapter: adapter.undo(count)
|
|
1492
|
+
)
|
|
1493
|
+
|
|
1494
|
+
async def add_mate(
|
|
1495
|
+
self,
|
|
1496
|
+
component_a: str,
|
|
1497
|
+
component_b: str,
|
|
1498
|
+
entity_a: str = "Front Plane",
|
|
1499
|
+
entity_b: str = "Front Plane",
|
|
1500
|
+
mate_type: str = "coincident",
|
|
1501
|
+
alignment: str = "aligned",
|
|
1502
|
+
distance: float = 0.0,
|
|
1503
|
+
angle: float = 0.0,
|
|
1504
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
1505
|
+
"""Add mate using pool.
|
|
1506
|
+
|
|
1507
|
+
Args:
|
|
1508
|
+
component_a (str): First component instance name.
|
|
1509
|
+
component_b (str): Second component instance name.
|
|
1510
|
+
entity_a (str): Named feature on the first component. Defaults to
|
|
1511
|
+
"Front Plane".
|
|
1512
|
+
entity_b (str): Named feature on the second component. Defaults to
|
|
1513
|
+
"Front Plane".
|
|
1514
|
+
mate_type (str): Mate type. Defaults to "coincident".
|
|
1515
|
+
alignment (str): Mate alignment. Defaults to "aligned".
|
|
1516
|
+
distance (float): Distance in millimetres. Defaults to 0.0.
|
|
1517
|
+
angle (float): Angle in degrees. Defaults to 0.0.
|
|
1518
|
+
|
|
1519
|
+
Returns:
|
|
1520
|
+
AdapterResult[dict[str, Any]]: The result produced by the operation.
|
|
1521
|
+
"""
|
|
1522
|
+
return await self._execute_with_pool(
|
|
1523
|
+
"add_mate",
|
|
1524
|
+
lambda adapter: adapter.add_mate(
|
|
1525
|
+
component_a,
|
|
1526
|
+
component_b,
|
|
1527
|
+
entity_a,
|
|
1528
|
+
entity_b,
|
|
1529
|
+
mate_type,
|
|
1530
|
+
alignment,
|
|
1531
|
+
distance,
|
|
1532
|
+
angle,
|
|
1533
|
+
),
|
|
1534
|
+
)
|
|
1535
|
+
|
|
1536
|
+
# --- Engineering-data and drawing-documentation methods ---
|
|
1537
|
+
|
|
1538
|
+
async def list_model_dimensions(
|
|
1539
|
+
self,
|
|
1540
|
+
feature_name: str | None = None,
|
|
1541
|
+
) -> AdapterResult[list[dict[str, Any]]]:
|
|
1542
|
+
"""List every dimension in the active part or assembly using pool."""
|
|
1543
|
+
return await self._execute_with_pool(
|
|
1544
|
+
"list_model_dimensions",
|
|
1545
|
+
lambda adapter: adapter.list_model_dimensions(feature_name),
|
|
1546
|
+
)
|
|
1547
|
+
|
|
1548
|
+
async def measure_entities(
|
|
1549
|
+
self,
|
|
1550
|
+
entities: list[str],
|
|
1551
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
1552
|
+
"""Measure one or two selected entities using pool."""
|
|
1553
|
+
return await self._execute_with_pool(
|
|
1554
|
+
"measure_entities",
|
|
1555
|
+
lambda adapter: adapter.measure_entities(entities),
|
|
1556
|
+
)
|
|
1557
|
+
|
|
1558
|
+
async def get_material(
|
|
1559
|
+
self,
|
|
1560
|
+
configuration: str | None = None,
|
|
1561
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
1562
|
+
"""Read the material assigned to the active part using pool."""
|
|
1563
|
+
return await self._execute_with_pool(
|
|
1564
|
+
"get_material",
|
|
1565
|
+
lambda adapter: adapter.get_material(configuration),
|
|
1566
|
+
)
|
|
1567
|
+
|
|
1568
|
+
async def set_material(
|
|
1569
|
+
self,
|
|
1570
|
+
material_name: str,
|
|
1571
|
+
database: str | None = None,
|
|
1572
|
+
configuration: str | None = None,
|
|
1573
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
1574
|
+
"""Assign a material to the active part using pool."""
|
|
1575
|
+
return await self._execute_with_pool(
|
|
1576
|
+
"set_material",
|
|
1577
|
+
lambda adapter: adapter.set_material(
|
|
1578
|
+
material_name, database, configuration
|
|
1579
|
+
),
|
|
1580
|
+
)
|
|
1581
|
+
|
|
1582
|
+
async def list_available_materials(
|
|
1583
|
+
self,
|
|
1584
|
+
search: str | None = None,
|
|
1585
|
+
) -> AdapterResult[list[dict[str, str]]]:
|
|
1586
|
+
"""List materials from the configured material libraries using pool."""
|
|
1587
|
+
return await self._execute_with_pool(
|
|
1588
|
+
"list_available_materials",
|
|
1589
|
+
lambda adapter: adapter.list_available_materials(search),
|
|
1590
|
+
)
|
|
1591
|
+
|
|
1592
|
+
async def get_custom_properties(
|
|
1593
|
+
self,
|
|
1594
|
+
configuration: str | None = None,
|
|
1595
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
1596
|
+
"""Read the custom properties of the active document using pool."""
|
|
1597
|
+
return await self._execute_with_pool(
|
|
1598
|
+
"get_custom_properties",
|
|
1599
|
+
lambda adapter: adapter.get_custom_properties(configuration),
|
|
1600
|
+
)
|
|
1601
|
+
|
|
1602
|
+
async def set_custom_property(
|
|
1603
|
+
self,
|
|
1604
|
+
name: str,
|
|
1605
|
+
value: str,
|
|
1606
|
+
configuration: str | None = None,
|
|
1607
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
1608
|
+
"""Create or overwrite one custom property using pool."""
|
|
1609
|
+
return await self._execute_with_pool(
|
|
1610
|
+
"set_custom_property",
|
|
1611
|
+
lambda adapter: adapter.set_custom_property(name, value, configuration),
|
|
1612
|
+
)
|
|
1613
|
+
|
|
1614
|
+
async def export_flat_pattern(
|
|
1615
|
+
self,
|
|
1616
|
+
file_path: str,
|
|
1617
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
1618
|
+
"""Export the active sheet-metal part's flat pattern using pool."""
|
|
1619
|
+
return await self._execute_with_pool(
|
|
1620
|
+
"export_flat_pattern",
|
|
1621
|
+
lambda adapter: adapter.export_flat_pattern(file_path),
|
|
1622
|
+
)
|
|
1623
|
+
|
|
1624
|
+
async def insert_model_dimensions(
|
|
1625
|
+
self,
|
|
1626
|
+
view_name: str | None = None,
|
|
1627
|
+
include_hole_wizard: bool = True,
|
|
1628
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
1629
|
+
"""Bring model dimensions into drawing views using pool."""
|
|
1630
|
+
return await self._execute_with_pool(
|
|
1631
|
+
"insert_model_dimensions",
|
|
1632
|
+
lambda adapter: adapter.insert_model_dimensions(
|
|
1633
|
+
view_name, include_hole_wizard
|
|
1634
|
+
),
|
|
1635
|
+
)
|
|
1636
|
+
|
|
1637
|
+
async def arrange_dimensions(
|
|
1638
|
+
self,
|
|
1639
|
+
view_name: str | None = None,
|
|
1640
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
1641
|
+
"""Move drawing dimensions so none overlaps, then verify using pool."""
|
|
1642
|
+
return await self._execute_with_pool(
|
|
1643
|
+
"arrange_dimensions",
|
|
1644
|
+
lambda adapter: adapter.arrange_dimensions(view_name),
|
|
1645
|
+
)
|
|
1646
|
+
|
|
1647
|
+
async def insert_bom_table(
|
|
1648
|
+
self,
|
|
1649
|
+
view_name: str,
|
|
1650
|
+
template_path: str | None = None,
|
|
1651
|
+
bom_type: str = "top_level_only",
|
|
1652
|
+
x_mm: float | None = None,
|
|
1653
|
+
y_mm: float | None = None,
|
|
1654
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
1655
|
+
"""Insert a BOM table anchored to an assembly drawing view using pool."""
|
|
1656
|
+
return await self._execute_with_pool(
|
|
1657
|
+
"insert_bom_table",
|
|
1658
|
+
lambda adapter: adapter.insert_bom_table(
|
|
1659
|
+
view_name, template_path, bom_type, x_mm, y_mm
|
|
1660
|
+
),
|
|
1661
|
+
)
|
|
1662
|
+
|
|
1663
|
+
async def set_sheet_scale(
|
|
1664
|
+
self,
|
|
1665
|
+
numerator: float,
|
|
1666
|
+
denominator: float,
|
|
1667
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
1668
|
+
"""Set the active drawing sheet's scale using pool."""
|
|
1669
|
+
return await self._execute_with_pool(
|
|
1670
|
+
"set_sheet_scale",
|
|
1671
|
+
lambda adapter: adapter.set_sheet_scale(numerator, denominator),
|
|
1672
|
+
)
|
|
1673
|
+
|
|
1674
|
+
async def add_gtol(
|
|
1675
|
+
self,
|
|
1676
|
+
characteristic: str,
|
|
1677
|
+
tolerance: float,
|
|
1678
|
+
x_mm: float,
|
|
1679
|
+
y_mm: float,
|
|
1680
|
+
diameter_zone: bool = False,
|
|
1681
|
+
material_condition: str = "none",
|
|
1682
|
+
datums: list[str] | None = None,
|
|
1683
|
+
attach_at_mm: tuple[float, float] | None = None,
|
|
1684
|
+
dimension: tuple[str, str] | None = None,
|
|
1685
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
1686
|
+
"""Add a GD&T feature control frame using pool."""
|
|
1687
|
+
return await self._execute_with_pool(
|
|
1688
|
+
"add_gtol",
|
|
1689
|
+
lambda adapter: adapter.add_gtol(
|
|
1690
|
+
characteristic,
|
|
1691
|
+
tolerance,
|
|
1692
|
+
x_mm,
|
|
1693
|
+
y_mm,
|
|
1694
|
+
diameter_zone,
|
|
1695
|
+
material_condition,
|
|
1696
|
+
datums,
|
|
1697
|
+
attach_at_mm,
|
|
1698
|
+
dimension,
|
|
1699
|
+
),
|
|
1700
|
+
)
|
|
1701
|
+
|
|
1702
|
+
async def add_datum_tag(
|
|
1703
|
+
self,
|
|
1704
|
+
label: str,
|
|
1705
|
+
attach_at_mm: tuple[float, float],
|
|
1706
|
+
x_mm: float,
|
|
1707
|
+
y_mm: float,
|
|
1708
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
1709
|
+
"""Add a datum feature symbol using pool."""
|
|
1710
|
+
return await self._execute_with_pool(
|
|
1711
|
+
"add_datum_tag",
|
|
1712
|
+
lambda adapter: adapter.add_datum_tag(label, attach_at_mm, x_mm, y_mm),
|
|
1713
|
+
)
|
|
1714
|
+
|
|
1715
|
+
async def create_standard_drawing(
|
|
1716
|
+
self,
|
|
1717
|
+
model_path: str,
|
|
1718
|
+
output_dir: str | None = None,
|
|
1719
|
+
title: str | None = None,
|
|
1720
|
+
subtitle: str | None = None,
|
|
1721
|
+
drawing_number: str | None = None,
|
|
1722
|
+
author: str = "",
|
|
1723
|
+
revision: str = "A",
|
|
1724
|
+
company: str = "",
|
|
1725
|
+
drawn_date: str | None = None,
|
|
1726
|
+
notes: list[str] | None = None,
|
|
1727
|
+
include_isometric: bool = True,
|
|
1728
|
+
write_model_properties: bool = True,
|
|
1729
|
+
title_block_text_height_mm: float | None = None,
|
|
1730
|
+
include_bom: bool = False,
|
|
1731
|
+
) -> AdapterResult[dict[str, Any]]:
|
|
1732
|
+
"""Create a complete standard A3 drawing using pool."""
|
|
1733
|
+
return await self._execute_with_pool(
|
|
1734
|
+
"create_standard_drawing",
|
|
1735
|
+
lambda adapter: adapter.create_standard_drawing(
|
|
1736
|
+
model_path,
|
|
1737
|
+
output_dir,
|
|
1738
|
+
title,
|
|
1739
|
+
subtitle,
|
|
1740
|
+
drawing_number,
|
|
1741
|
+
author,
|
|
1742
|
+
revision,
|
|
1743
|
+
company,
|
|
1744
|
+
drawn_date,
|
|
1745
|
+
notes,
|
|
1746
|
+
include_isometric,
|
|
1747
|
+
write_model_properties,
|
|
1748
|
+
title_block_text_height_mm,
|
|
1749
|
+
include_bom,
|
|
1750
|
+
),
|
|
1751
|
+
)
|
|
1752
|
+
|
|
1753
|
+
|
|
1754
|
+
class ConnectionPool:
|
|
1755
|
+
"""Legacy alias class expected by tests.
|
|
1756
|
+
|
|
1757
|
+
Args:
|
|
1758
|
+
create_connection (Callable[[], object | Awaitable[object]]): Factory callable used
|
|
1759
|
+
to create a
|
|
1760
|
+
connection.
|
|
1761
|
+
max_size (int): Maximum number of items allowed in the pool. Defaults to 3.
|
|
1762
|
+
timeout (float): Maximum time to wait in seconds. Defaults to 30.0.
|
|
1763
|
+
|
|
1764
|
+
Attributes:
|
|
1765
|
+
_create_connection (Any): The create connection value.
|
|
1766
|
+
_max_size (Any): The max size value.
|
|
1767
|
+
_timeout (Any): The timeout value.
|
|
1768
|
+
"""
|
|
1769
|
+
|
|
1770
|
+
def __init__(
|
|
1771
|
+
self,
|
|
1772
|
+
create_connection: Callable[[], object | Awaitable[object]],
|
|
1773
|
+
max_size: int = 3,
|
|
1774
|
+
timeout: float = 30.0,
|
|
1775
|
+
) -> None:
|
|
1776
|
+
"""Initialize the connection pool.
|
|
1777
|
+
|
|
1778
|
+
Args:
|
|
1779
|
+
create_connection (Callable[[], object | Awaitable[object]]): Factory callable used
|
|
1780
|
+
to create a
|
|
1781
|
+
connection.
|
|
1782
|
+
max_size (int): Maximum number of items allowed in the pool. Defaults to 3.
|
|
1783
|
+
timeout (float): Maximum time to wait in seconds. Defaults to 30.0.
|
|
1784
|
+
|
|
1785
|
+
Returns:
|
|
1786
|
+
None: None.
|
|
1787
|
+
"""
|
|
1788
|
+
self._create_connection = create_connection
|
|
1789
|
+
self._max_size = max_size
|
|
1790
|
+
self._timeout = timeout
|
|
1791
|
+
self._available: list[object] = []
|
|
1792
|
+
self._in_use: set[int] = set()
|
|
1793
|
+
self._all_connections: list[object] = []
|
|
1794
|
+
|
|
1795
|
+
@property
|
|
1796
|
+
def size(self) -> int:
|
|
1797
|
+
"""Provide size support for the connection pool.
|
|
1798
|
+
|
|
1799
|
+
Returns:
|
|
1800
|
+
int: The computed numeric result.
|
|
1801
|
+
"""
|
|
1802
|
+
return len(self._all_connections)
|
|
1803
|
+
|
|
1804
|
+
@property
|
|
1805
|
+
def active_connections(self) -> int:
|
|
1806
|
+
"""Provide active connections support for the connection pool.
|
|
1807
|
+
|
|
1808
|
+
Returns:
|
|
1809
|
+
int: The computed numeric result.
|
|
1810
|
+
"""
|
|
1811
|
+
return len(self._in_use)
|
|
1812
|
+
|
|
1813
|
+
async def _new_connection(self) -> object:
|
|
1814
|
+
"""Build internal new connection.
|
|
1815
|
+
|
|
1816
|
+
Returns:
|
|
1817
|
+
object: The result produced by the operation.
|
|
1818
|
+
"""
|
|
1819
|
+
conn = self._create_connection()
|
|
1820
|
+
if asyncio.iscoroutine(conn):
|
|
1821
|
+
conn = await conn
|
|
1822
|
+
self._all_connections.append(conn)
|
|
1823
|
+
return conn
|
|
1824
|
+
|
|
1825
|
+
async def acquire(self) -> object:
|
|
1826
|
+
"""Provide acquire support for the connection pool.
|
|
1827
|
+
|
|
1828
|
+
Returns:
|
|
1829
|
+
object: The result produced by the operation.
|
|
1830
|
+
|
|
1831
|
+
Raises:
|
|
1832
|
+
TimeoutError: No connection available within timeout.
|
|
1833
|
+
"""
|
|
1834
|
+
if self._available:
|
|
1835
|
+
conn = self._available.pop()
|
|
1836
|
+
self._in_use.add(id(conn))
|
|
1837
|
+
return conn
|
|
1838
|
+
|
|
1839
|
+
if len(self._all_connections) < self._max_size:
|
|
1840
|
+
conn = await self._new_connection()
|
|
1841
|
+
self._in_use.add(id(conn))
|
|
1842
|
+
return conn
|
|
1843
|
+
|
|
1844
|
+
end_time = time.time() + self._timeout
|
|
1845
|
+
while time.time() < end_time:
|
|
1846
|
+
if self._available:
|
|
1847
|
+
conn = self._available.pop()
|
|
1848
|
+
self._in_use.add(id(conn))
|
|
1849
|
+
return conn
|
|
1850
|
+
await asyncio.sleep(0.01)
|
|
1851
|
+
|
|
1852
|
+
raise TimeoutError("No connection available within timeout")
|
|
1853
|
+
|
|
1854
|
+
async def release(self, conn: object) -> None:
|
|
1855
|
+
"""Provide release support for the connection pool.
|
|
1856
|
+
|
|
1857
|
+
Args:
|
|
1858
|
+
conn (object): The conn value.
|
|
1859
|
+
|
|
1860
|
+
Returns:
|
|
1861
|
+
None: None.
|
|
1862
|
+
"""
|
|
1863
|
+
conn_id = id(conn)
|
|
1864
|
+
if conn_id in self._in_use:
|
|
1865
|
+
self._in_use.remove(conn_id)
|
|
1866
|
+
self._available.append(conn)
|
|
1867
|
+
|
|
1868
|
+
async def cleanup(self) -> None:
|
|
1869
|
+
"""Provide cleanup support for the connection pool.
|
|
1870
|
+
|
|
1871
|
+
Returns:
|
|
1872
|
+
None: None.
|
|
1873
|
+
"""
|
|
1874
|
+
for conn in self._all_connections:
|
|
1875
|
+
close = getattr(conn, "close", None)
|
|
1876
|
+
if close is None:
|
|
1877
|
+
continue
|
|
1878
|
+
result = close()
|
|
1879
|
+
if asyncio.iscoroutine(result):
|
|
1880
|
+
await result
|
|
1881
|
+
|
|
1882
|
+
self._available.clear()
|
|
1883
|
+
self._in_use.clear()
|
|
1884
|
+
self._all_connections.clear()
|