sapiopycommons 2025.10.10a778__py3-none-any.whl → 2025.10.13a781__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/test_client.py +52 -0
- {sapiopycommons-2025.10.10a778.dist-info → sapiopycommons-2025.10.13a781.dist-info}/METADATA +1 -1
- {sapiopycommons-2025.10.10a778.dist-info → sapiopycommons-2025.10.13a781.dist-info}/RECORD +5 -5
- {sapiopycommons-2025.10.10a778.dist-info → sapiopycommons-2025.10.13a781.dist-info}/WHEEL +0 -0
- {sapiopycommons-2025.10.10a778.dist-info → sapiopycommons-2025.10.13a781.dist-info}/licenses/LICENSE +0 -0
sapiopycommons/ai/test_client.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import base64
|
|
2
2
|
import json
|
|
3
|
+
import os
|
|
3
4
|
from enum import Enum
|
|
4
5
|
from typing import Any
|
|
5
6
|
|
|
@@ -20,6 +21,7 @@ from sapiopycommons.ai.protoapi.plan.tool.tool_pb2_grpc import ToolServiceStub
|
|
|
20
21
|
from sapiopycommons.ai.protoapi.session.sapio_conn_info_pb2 import SapioConnectionInfoPbo, SapioUserSecretTypePbo
|
|
21
22
|
from sapiopycommons.ai.protobuf_utils import ProtobufUtils
|
|
22
23
|
from sapiopycommons.general.aliases import FieldValue
|
|
24
|
+
from sapiopycommons.general.time_util import TimeUtil
|
|
23
25
|
|
|
24
26
|
|
|
25
27
|
class ContainerType(Enum):
|
|
@@ -43,6 +45,8 @@ class AgentOutput:
|
|
|
43
45
|
status: str
|
|
44
46
|
message: str
|
|
45
47
|
|
|
48
|
+
# Outputs are lists of lists, where the outer lists are the different outputs of the tool, and the inner lists
|
|
49
|
+
# are the entries for that output.
|
|
46
50
|
binary_output: list[list[bytes]]
|
|
47
51
|
csv_output: list[list[dict[str, Any]]]
|
|
48
52
|
json_output: list[list[dict[str, Any]]]
|
|
@@ -61,10 +65,54 @@ class AgentOutput:
|
|
|
61
65
|
self.new_records = []
|
|
62
66
|
self.logs = []
|
|
63
67
|
|
|
68
|
+
def save_outputs(self, path: str = "test_outputs", subfolder: str | None = None, file_extensions: list[str] | None = None) -> None:
|
|
69
|
+
"""
|
|
70
|
+
Save all outputs to files in the specified output directory.
|
|
71
|
+
|
|
72
|
+
:param path: The directory to save the output files to.
|
|
73
|
+
:param subfolder: An optional subfolder within the path to save the output files to. Useful for when you are
|
|
74
|
+
calling the same agent multiple times for separate test cases.
|
|
75
|
+
:param file_extensions: A list of file extensions to use for binary output files. The length of this list
|
|
76
|
+
should match the number of binary outputs.
|
|
77
|
+
"""
|
|
78
|
+
if not self:
|
|
79
|
+
return
|
|
80
|
+
output_path: str = os.path.join(path, self.agent_name)
|
|
81
|
+
if subfolder:
|
|
82
|
+
output_path = os.path.join(output_path, subfolder)
|
|
83
|
+
os.makedirs(output_path, exist_ok=True)
|
|
84
|
+
if self.binary_output and (file_extensions is None or len(file_extensions) != len(self.binary_output)):
|
|
85
|
+
raise ValueError("File extensions must be provided for each binary output.")
|
|
86
|
+
for i, output in enumerate(self.binary_output):
|
|
87
|
+
ext: str = "." + file_extensions[i].lstrip(".")
|
|
88
|
+
for j, entry in enumerate(output):
|
|
89
|
+
with open(os.path.join(output_path, f"binary_output_{i}_{j}{ext}"), "wb") as f:
|
|
90
|
+
f.write(entry)
|
|
91
|
+
for i, output in enumerate(self.csv_output):
|
|
92
|
+
with open(os.path.join(output_path, f"csv_output_{i}.csv"), "w", encoding="utf-8") as f:
|
|
93
|
+
headers = output[0].keys()
|
|
94
|
+
f.write(",".join(headers) + "\n")
|
|
95
|
+
for row in output:
|
|
96
|
+
f.write(",".join(f'"{str(row[h])}"' for h in headers) + "\n")
|
|
97
|
+
for i, output in enumerate(self.json_output):
|
|
98
|
+
for j, entry in enumerate(output):
|
|
99
|
+
with open(os.path.join(output_path, f"json_output_{i}_{j}.json"), "w", encoding="utf-8") as f:
|
|
100
|
+
json.dump(entry, f, indent=2)
|
|
101
|
+
for i, output in enumerate(self.text_output):
|
|
102
|
+
for j, entry in enumerate(output):
|
|
103
|
+
with open(os.path.join(output_path, f"text_output_{i}_{j}.txt"), "w", encoding="utf-8") as f:
|
|
104
|
+
f.write(entry)
|
|
105
|
+
|
|
64
106
|
def __bool__(self):
|
|
107
|
+
"""
|
|
108
|
+
Return True if the agent call was successful, False otherwise.
|
|
109
|
+
"""
|
|
65
110
|
return self.status == "Success"
|
|
66
111
|
|
|
67
112
|
def __str__(self):
|
|
113
|
+
"""
|
|
114
|
+
Return a string representing a summary of the agent output.
|
|
115
|
+
"""
|
|
68
116
|
ret_val: str = f"{self.agent_name} Output:\n"
|
|
69
117
|
ret_val += f"\tStatus: {self.status}\n"
|
|
70
118
|
ret_val += f"\tMessage: {self.message}\n"
|
|
@@ -271,9 +319,11 @@ class TestClient:
|
|
|
271
319
|
:param is_dry_run: If True, the agent will not be executed, but the request will be validated.
|
|
272
320
|
:return: An AgentOutput object containing the results of the agent service call.
|
|
273
321
|
"""
|
|
322
|
+
print(f"Calling agent \"{agent_name}\"...")
|
|
274
323
|
with grpc.insecure_channel(self.grpc_server_url, options=self.options) as channel:
|
|
275
324
|
stub = ToolServiceStub(channel)
|
|
276
325
|
|
|
326
|
+
start = TimeUtil.now_in_millis()
|
|
277
327
|
response: ProcessStepResponsePbo = stub.ProcessData(
|
|
278
328
|
ProcessStepRequestPbo(
|
|
279
329
|
sapio_user=self.connection,
|
|
@@ -287,6 +337,8 @@ class TestClient:
|
|
|
287
337
|
]
|
|
288
338
|
)
|
|
289
339
|
)
|
|
340
|
+
end = TimeUtil.now_in_millis()
|
|
341
|
+
print(f"Agent call completed in {(end - start) / 1000.:.3f} seconds")
|
|
290
342
|
|
|
291
343
|
results = AgentOutput(agent_name)
|
|
292
344
|
|
{sapiopycommons-2025.10.10a778.dist-info → sapiopycommons-2025.10.13a781.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: sapiopycommons
|
|
3
|
-
Version: 2025.10.
|
|
3
|
+
Version: 2025.10.13a781
|
|
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>
|
|
@@ -6,7 +6,7 @@ sapiopycommons/ai/external_credentials.py,sha256=40AI7VtHf6PzvwJLR_mZemUCrfAUvC-
|
|
|
6
6
|
sapiopycommons/ai/protobuf_utils.py,sha256=cBjbxoFAwU02kNUxEce95WnMU2CMuDD-qFaeWgvQJMQ,24599
|
|
7
7
|
sapiopycommons/ai/request_validation.py,sha256=TD2EUi_G5cy1OOVK1AmY2SQc3PEoAKGWs2pT8Qnp2Oo,25092
|
|
8
8
|
sapiopycommons/ai/server.py,sha256=gutSskn_Fenq1uz0DDMvjx4QVFiKt2WVEP3-01a69eU,6384
|
|
9
|
-
sapiopycommons/ai/test_client.py,sha256=
|
|
9
|
+
sapiopycommons/ai/test_client.py,sha256=aiS58O_A3KSgRCzDT61iKyVXy9F4UY7xUyGQu5E7bTw,19432
|
|
10
10
|
sapiopycommons/ai/protoapi/externalcredentials/external_credentials_pb2.py,sha256=mEonoj6Iq-AyvO4m3YsPYu85aZfD1E0a0cL8B9yPfEo,2481
|
|
11
11
|
sapiopycommons/ai/protoapi/externalcredentials/external_credentials_pb2.pyi,sha256=sfExq8fFwIwFxCpV50ytdxW5ePNBjJBr_80_trq_JQw,1658
|
|
12
12
|
sapiopycommons/ai/protoapi/externalcredentials/external_credentials_pb2_grpc.py,sha256=TNS1CB_QGBSa1YU9sYR_hF-pmBwv2GpxjaNQoM_r9iU,948
|
|
@@ -106,7 +106,7 @@ sapiopycommons/webhook/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
|
|
|
106
106
|
sapiopycommons/webhook/webhook_context.py,sha256=D793uLsb1691SalaPnBUk3rOSxn_hYLhdvkaIxjNXss,1909
|
|
107
107
|
sapiopycommons/webhook/webhook_handlers.py,sha256=7o_wXOruhT9auNh8OfhJAh4WhhiPKij67FMBSpGPICc,39939
|
|
108
108
|
sapiopycommons/webhook/webservice_handlers.py,sha256=cvW6Mk_110BzYqkbk63Kg7jWrltBCDALOlkJRu8h4VQ,14300
|
|
109
|
-
sapiopycommons-2025.10.
|
|
110
|
-
sapiopycommons-2025.10.
|
|
111
|
-
sapiopycommons-2025.10.
|
|
112
|
-
sapiopycommons-2025.10.
|
|
109
|
+
sapiopycommons-2025.10.13a781.dist-info/METADATA,sha256=Ex7Fc6UXveEGSs8qgYNAUSzjwKhsBOZU3jyOzIWKlyY,3143
|
|
110
|
+
sapiopycommons-2025.10.13a781.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
|
|
111
|
+
sapiopycommons-2025.10.13a781.dist-info/licenses/LICENSE,sha256=HyVuytGSiAUQ6ErWBHTqt1iSGHhLmlC8fO7jTCuR8dU,16725
|
|
112
|
+
sapiopycommons-2025.10.13a781.dist-info/RECORD,,
|
|
File without changes
|
{sapiopycommons-2025.10.10a778.dist-info → sapiopycommons-2025.10.13a781.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|