sapiopycommons 2025.8.12a697__py3-none-any.whl → 2025.8.12a699__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 sapiopycommons might be problematic. Click here for more details.
- sapiopycommons/ai/converter_service_base.py +11 -21
- sapiopycommons/ai/test_client.py +13 -6
- sapiopycommons/ai/tool_service_base.py +5 -1
- {sapiopycommons-2025.8.12a697.dist-info → sapiopycommons-2025.8.12a699.dist-info}/METADATA +1 -1
- {sapiopycommons-2025.8.12a697.dist-info → sapiopycommons-2025.8.12a699.dist-info}/RECORD +7 -7
- {sapiopycommons-2025.8.12a697.dist-info → sapiopycommons-2025.8.12a699.dist-info}/WHEEL +0 -0
- {sapiopycommons-2025.8.12a697.dist-info → sapiopycommons-2025.8.12a699.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import traceback
|
|
3
4
|
from abc import ABC, abstractmethod
|
|
4
5
|
|
|
5
6
|
from grpc import ServicerContext
|
|
@@ -22,7 +23,9 @@ class ConverterServiceBase(ConverterServiceServicer, ABC):
|
|
|
22
23
|
output_content_type=converter.output_type_pbo()
|
|
23
24
|
))
|
|
24
25
|
return ConverterDetailsResponsePbo(supported_types=supported_types)
|
|
25
|
-
except Exception:
|
|
26
|
+
except Exception as e:
|
|
27
|
+
print(f"CRITICAL ERROR: {e}")
|
|
28
|
+
print(traceback.format_exc())
|
|
26
29
|
return ConverterDetailsResponsePbo()
|
|
27
30
|
|
|
28
31
|
def ConvertContent(self, request: ConvertRequestPbo, context: ServicerContext) -> ConvertResponsePbo:
|
|
@@ -33,9 +36,12 @@ class ConverterServiceBase(ConverterServiceServicer, ABC):
|
|
|
33
36
|
for c in self.register_converters():
|
|
34
37
|
converter = c()
|
|
35
38
|
if converter.can_convert(input_type, target_type):
|
|
36
|
-
return ConvertResponsePbo(converter.convert(input_container))
|
|
37
|
-
raise ValueError(f"No converter found for converting {input_type}
|
|
38
|
-
|
|
39
|
+
return ConvertResponsePbo(item_container=converter.convert(input_container))
|
|
40
|
+
raise ValueError(f"No converter found for converting {input_type.name} ({', '.join(input_type.extensions)}) "
|
|
41
|
+
f"to {target_type.name} ({', '.join(target_type.extensions)}).")
|
|
42
|
+
except Exception as e:
|
|
43
|
+
print(f"CRITICAL ERROR: {e}")
|
|
44
|
+
print(traceback.format_exc())
|
|
39
45
|
return ConvertResponsePbo()
|
|
40
46
|
|
|
41
47
|
@abstractmethod
|
|
@@ -97,8 +103,7 @@ class ConverterBase(ABC):
|
|
|
97
103
|
:param target_type: The target content type.
|
|
98
104
|
:return: True if this converter can convert from the input type to the target type, False otherwise.
|
|
99
105
|
"""
|
|
100
|
-
return
|
|
101
|
-
content_types_match(self.output_type_pbo(), target_type))
|
|
106
|
+
return self.input_type() == input_type.name and self.output_type() == target_type.name
|
|
102
107
|
|
|
103
108
|
@abstractmethod
|
|
104
109
|
def convert(self, content: StepItemContainerPbo) -> StepItemContainerPbo:
|
|
@@ -109,18 +114,3 @@ class ConverterBase(ABC):
|
|
|
109
114
|
:return: The converted content.
|
|
110
115
|
"""
|
|
111
116
|
pass
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
def content_types_match(a: ContentTypePbo, b: ContentTypePbo) -> bool:
|
|
115
|
-
"""
|
|
116
|
-
Check if two ContentTypePbo objects match by comparing their names and file extensions.
|
|
117
|
-
|
|
118
|
-
:param a: The first ContentTypePbo to compare.
|
|
119
|
-
:param b: The second ContentTypePbo to compare.
|
|
120
|
-
:return: True if the content types match, False otherwise.
|
|
121
|
-
"""
|
|
122
|
-
if a.name != b.name:
|
|
123
|
-
return False
|
|
124
|
-
if set(a.extensions) != set(b.extensions):
|
|
125
|
-
return False
|
|
126
|
-
return True
|
sapiopycommons/ai/test_client.py
CHANGED
|
@@ -100,17 +100,21 @@ class TestClient:
|
|
|
100
100
|
A client for testing a ToolService.
|
|
101
101
|
"""
|
|
102
102
|
grpc_server_url: str
|
|
103
|
+
options: list[tuple[str, Any]] | None
|
|
103
104
|
connection: SapioConnectionInfoPbo
|
|
104
105
|
_request_inputs: list[StepItemContainerPbo]
|
|
105
106
|
_config_fields: dict[str, Any]
|
|
106
107
|
|
|
107
|
-
def __init__(self, grpc_server_url: str, user: SapioUser | None = None
|
|
108
|
+
def __init__(self, grpc_server_url: str, user: SapioUser | None = None,
|
|
109
|
+
options: list[tuple[str, Any]] | None = None):
|
|
108
110
|
"""
|
|
109
111
|
:param grpc_server_url: The URL of the gRPC server to connect to.
|
|
110
112
|
:param user: Optional SapioUser object to use for the connection. If not provided, a default connection
|
|
111
113
|
will be created with test credentials.
|
|
114
|
+
:param options: Optional list of gRPC channel options.
|
|
112
115
|
"""
|
|
113
116
|
self.grpc_server_url = grpc_server_url
|
|
117
|
+
self.options = options
|
|
114
118
|
self._create_connection(user)
|
|
115
119
|
self._request_inputs = []
|
|
116
120
|
self._config_fields = {}
|
|
@@ -224,7 +228,7 @@ class TestClient:
|
|
|
224
228
|
|
|
225
229
|
:return: A ToolDetailsResponsePbo object containing the details of the tool service.
|
|
226
230
|
"""
|
|
227
|
-
with grpc.insecure_channel(self.grpc_server_url) as channel:
|
|
231
|
+
with grpc.insecure_channel(self.grpc_server_url, options=self.options) as channel:
|
|
228
232
|
stub = ToolServiceStub(channel)
|
|
229
233
|
return stub.GetToolDetails(ToolDetailsRequestPbo(sapio_conn_info=self.connection))
|
|
230
234
|
|
|
@@ -237,7 +241,7 @@ class TestClient:
|
|
|
237
241
|
:param is_dry_run: If True, the tool will not be executed, but the request will be validated.
|
|
238
242
|
:return: A ToolOutput object containing the results of the tool service call.
|
|
239
243
|
"""
|
|
240
|
-
with grpc.insecure_channel(self.grpc_server_url) as channel:
|
|
244
|
+
with grpc.insecure_channel(self.grpc_server_url, options=self.options) as channel:
|
|
241
245
|
stub = ToolServiceStub(channel)
|
|
242
246
|
|
|
243
247
|
response: ProcessStepResponsePbo = stub.ProcessData(
|
|
@@ -291,12 +295,15 @@ class TestConverterClient:
|
|
|
291
295
|
A client for testing a ConverterService.
|
|
292
296
|
"""
|
|
293
297
|
grpc_server_url: str
|
|
298
|
+
options: list[tuple[str, Any]] | None
|
|
294
299
|
|
|
295
|
-
def __init__(self, grpc_server_url: str):
|
|
300
|
+
def __init__(self, grpc_server_url: str, options: list[tuple[str, Any]] | None = None):
|
|
296
301
|
"""
|
|
297
302
|
:param grpc_server_url: The URL of the gRPC server to connect to.
|
|
303
|
+
:param options: Optional list of gRPC channel options.
|
|
298
304
|
"""
|
|
299
305
|
self.grpc_server_url = grpc_server_url
|
|
306
|
+
self.options = options
|
|
300
307
|
|
|
301
308
|
def get_converter_details(self) -> ConverterDetailsResponsePbo:
|
|
302
309
|
"""
|
|
@@ -304,7 +311,7 @@ class TestConverterClient:
|
|
|
304
311
|
|
|
305
312
|
:return: A ToolDetailsResponsePbo object containing the details of the converter service.
|
|
306
313
|
"""
|
|
307
|
-
with grpc.insecure_channel(self.grpc_server_url) as channel:
|
|
314
|
+
with grpc.insecure_channel(self.grpc_server_url, options=self.options) as channel:
|
|
308
315
|
stub = ConverterServiceStub(channel)
|
|
309
316
|
return stub.GetConverterDetails(ConverterDetailsRequestPbo())
|
|
310
317
|
|
|
@@ -319,7 +326,7 @@ class TestConverterClient:
|
|
|
319
326
|
converter service supports.
|
|
320
327
|
:return: A StepItemContainerPbo object containing the converted content.
|
|
321
328
|
"""
|
|
322
|
-
with grpc.insecure_channel(self.grpc_server_url) as channel:
|
|
329
|
+
with grpc.insecure_channel(self.grpc_server_url, options=self.options) as channel:
|
|
323
330
|
stub = ConverterServiceStub(channel)
|
|
324
331
|
response: ConvertResponsePbo = stub.ConvertContent(
|
|
325
332
|
ConvertRequestPbo(item_container=input_container, target_content_type=target_type)
|
|
@@ -205,9 +205,11 @@ class ToolServiceBase(ToolServiceServicer, ABC):
|
|
|
205
205
|
if not details:
|
|
206
206
|
raise Exception("No tools registered with this service.")
|
|
207
207
|
return ToolDetailsResponsePbo(tool_framework_version=self.tool_version(), tool_details=details)
|
|
208
|
-
except Exception:
|
|
208
|
+
except Exception as e:
|
|
209
209
|
# Woe to you if you somehow cause an exception to be raised when just initializing your tools.
|
|
210
210
|
# There's no way to log this.
|
|
211
|
+
print(f"CRITICAL ERROR: {e}")
|
|
212
|
+
print(traceback.format_exc())
|
|
211
213
|
return ToolDetailsResponsePbo()
|
|
212
214
|
|
|
213
215
|
def ProcessData(self, request: ProcessStepRequestPbo, context: ServicerContext) -> ProcessStepResponsePbo:
|
|
@@ -232,6 +234,8 @@ class ToolServiceBase(ToolServiceServicer, ABC):
|
|
|
232
234
|
except Exception as e:
|
|
233
235
|
# This try/except should never be needed, as the tool should handle its own exceptions, but better safe
|
|
234
236
|
# than sorry.
|
|
237
|
+
print(f"CRITICAL ERROR: {e}")
|
|
238
|
+
print(traceback.format_exc())
|
|
235
239
|
return ProcessStepResponsePbo(status=ProcessStepResponseStatusPbo.FAILURE,
|
|
236
240
|
status_message=f"CRITICAL ERROR: {e}",
|
|
237
241
|
log=[traceback.format_exc()])
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: sapiopycommons
|
|
3
|
-
Version: 2025.8.
|
|
3
|
+
Version: 2025.8.12a699
|
|
4
4
|
Summary: Official Sapio Python API Utilities Package
|
|
5
5
|
Project-URL: Homepage, https://github.com/sapiosciences
|
|
6
6
|
Author-email: Jonathan Steck <jsteck@sapiosciences.com>, Yechen Qiao <yqiao@sapiosciences.com>
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
sapiopycommons/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
2
|
sapiopycommons/ai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
-
sapiopycommons/ai/converter_service_base.py,sha256=
|
|
3
|
+
sapiopycommons/ai/converter_service_base.py,sha256=w4_PXjlk7_F5AUMlPUhKJ9gZlxY9RNG6yH9cDDFROuo,4620
|
|
4
4
|
sapiopycommons/ai/protobuf_utils.py,sha256=AZnZDshismfAzdSewqG0lwvSoEM2tjXBmJkVq22075Q,23831
|
|
5
|
-
sapiopycommons/ai/test_client.py,sha256=
|
|
6
|
-
sapiopycommons/ai/tool_service_base.py,sha256=
|
|
5
|
+
sapiopycommons/ai/test_client.py,sha256=ALV_od1ej7tmgKFbFNsFaCrb6ssSZ2kB33JDfLhVchU,14149
|
|
6
|
+
sapiopycommons/ai/tool_service_base.py,sha256=LkmX_kQyHAQtR02S8x6hKc0DnR7mmNNcykBrn87sVVw,43473
|
|
7
7
|
sapiopycommons/ai/api/fielddefinitions/proto/fields_pb2.py,sha256=YcZjb_YM-XeLErM8hEC_S7vGMVGvcXAMGs2b-u5zvOE,2377
|
|
8
8
|
sapiopycommons/ai/api/fielddefinitions/proto/fields_pb2.pyi,sha256=FwtXmNAf7iYGEFm4kbqb04v77jNHbZg18ZmEDhle_bU,1444
|
|
9
9
|
sapiopycommons/ai/api/fielddefinitions/proto/fields_pb2_grpc.py,sha256=wPImJPdCUZNVEVoUWzsba9kGIXjEKPdUkawP5SnVyiU,932
|
|
@@ -97,7 +97,7 @@ sapiopycommons/webhook/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
|
|
|
97
97
|
sapiopycommons/webhook/webhook_context.py,sha256=D793uLsb1691SalaPnBUk3rOSxn_hYLhdvkaIxjNXss,1909
|
|
98
98
|
sapiopycommons/webhook/webhook_handlers.py,sha256=7o_wXOruhT9auNh8OfhJAh4WhhiPKij67FMBSpGPICc,39939
|
|
99
99
|
sapiopycommons/webhook/webservice_handlers.py,sha256=cvW6Mk_110BzYqkbk63Kg7jWrltBCDALOlkJRu8h4VQ,14300
|
|
100
|
-
sapiopycommons-2025.8.
|
|
101
|
-
sapiopycommons-2025.8.
|
|
102
|
-
sapiopycommons-2025.8.
|
|
103
|
-
sapiopycommons-2025.8.
|
|
100
|
+
sapiopycommons-2025.8.12a699.dist-info/METADATA,sha256=NfsKnuKXPbnwtm2tE9QP4aYEQJ-RHDL75VHZsimjTV8,3143
|
|
101
|
+
sapiopycommons-2025.8.12a699.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
|
|
102
|
+
sapiopycommons-2025.8.12a699.dist-info/licenses/LICENSE,sha256=HyVuytGSiAUQ6ErWBHTqt1iSGHhLmlC8fO7jTCuR8dU,16725
|
|
103
|
+
sapiopycommons-2025.8.12a699.dist-info/RECORD,,
|
|
File without changes
|
{sapiopycommons-2025.8.12a697.dist-info → sapiopycommons-2025.8.12a699.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|