sapiopycommons 2025.8.20a713__tar.gz → 2025.9.8a728__tar.gz
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-2025.8.20a713 → sapiopycommons-2025.9.8a728}/PKG-INFO +1 -1
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/pyproject.toml +1 -1
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/converter_service_base.py +2 -1
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/protoapi/plan/item/item_container_pb2.py +4 -4
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/protoapi/plan/item/item_container_pb2.pyi +4 -2
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/server.py +6 -4
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/test_client.py +47 -30
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/tool_service_base.py +58 -19
- sapiopycommons-2025.9.8a728/src/sapiopycommons/files/temp_files.py +49 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/.gitignore +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/LICENSE +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/README.md +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/__init__.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/__init__.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/protoapi/fielddefinitions/fields_pb2.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/protoapi/fielddefinitions/fields_pb2.pyi +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/protoapi/fielddefinitions/fields_pb2_grpc.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/protoapi/fielddefinitions/velox_field_def_pb2.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/protoapi/fielddefinitions/velox_field_def_pb2.pyi +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/protoapi/fielddefinitions/velox_field_def_pb2_grpc.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/protoapi/plan/converter/converter_pb2.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/protoapi/plan/converter/converter_pb2.pyi +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/protoapi/plan/converter/converter_pb2_grpc.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/protoapi/plan/item/item_container_pb2_grpc.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/protoapi/plan/script/script_pb2.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/protoapi/plan/script/script_pb2.pyi +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/protoapi/plan/script/script_pb2_grpc.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/protoapi/plan/step_output_pb2.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/protoapi/plan/step_output_pb2.pyi +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/protoapi/plan/step_output_pb2_grpc.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/protoapi/plan/step_pb2.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/protoapi/plan/step_pb2.pyi +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/protoapi/plan/step_pb2_grpc.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/protoapi/plan/tool/entry_pb2.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/protoapi/plan/tool/entry_pb2.pyi +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/protoapi/plan/tool/entry_pb2_grpc.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/protoapi/plan/tool/tool_pb2.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/protoapi/plan/tool/tool_pb2.pyi +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/protoapi/plan/tool/tool_pb2_grpc.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/protoapi/session/sapio_conn_info_pb2.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/protoapi/session/sapio_conn_info_pb2.pyi +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/protoapi/session/sapio_conn_info_pb2_grpc.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/protobuf_utils.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/callbacks/__init__.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/callbacks/callback_util.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/callbacks/field_builder.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/chem/IndigoMolecules.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/chem/Molecules.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/chem/__init__.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/customreport/__init__.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/customreport/auto_pagers.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/customreport/column_builder.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/customreport/custom_report_builder.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/customreport/term_builder.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/datatype/__init__.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/datatype/attachment_util.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/datatype/data_fields.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/datatype/pseudo_data_types.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/eln/__init__.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/eln/experiment_cache.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/eln/experiment_handler.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/eln/experiment_report_util.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/eln/experiment_step_factory.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/eln/experiment_tags.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/eln/plate_designer.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/eln/step_creation.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/files/__init__.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/files/complex_data_loader.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/files/file_bridge.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/files/file_bridge_handler.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/files/file_data_handler.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/files/file_util.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/files/file_validator.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/files/file_writer.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/flowcyto/flow_cyto.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/flowcyto/flowcyto_data.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/general/__init__.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/general/accession_service.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/general/aliases.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/general/audit_log.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/general/custom_report_util.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/general/data_structure_util.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/general/directive_util.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/general/exceptions.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/general/html_formatter.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/general/popup_util.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/general/sapio_links.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/general/storage_util.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/general/time_util.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/multimodal/multimodal.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/multimodal/multimodal_data.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/processtracking/__init__.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/processtracking/custom_workflow_handler.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/processtracking/endpoints.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/recordmodel/__init__.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/recordmodel/record_handler.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/rules/__init__.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/rules/eln_rule_handler.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/rules/on_save_rule_handler.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/samples/aliquot.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/sftpconnect/__init__.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/sftpconnect/sftp_builder.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/webhook/__init__.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/webhook/webhook_context.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/webhook/webhook_handlers.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/webhook/webservice_handlers.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/tests/AF-A0A009IHW8-F1-model_v4.cif +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/tests/_do_not_add_init_py_here +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/tests/accession_test.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/tests/aliquot_test.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/tests/bio_reg_test.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/tests/chem_test.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/tests/chem_test_curation_queue.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/tests/curation_queue_test.sdf +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/tests/data_type_models.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/tests/flowcyto/101_DEN084Y5_15_E01_008_clean.fcs +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/tests/flowcyto/101_DEN084Y5_15_E03_009_clean.fcs +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/tests/flowcyto/101_DEN084Y5_15_E05_010_clean.fcs +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/tests/flowcyto/8_color_ICS.wsp +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/tests/flowcyto/COVID19_W_001_O.fcs +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/tests/flowcyto_test.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/tests/kappa.chains.fasta +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/tests/mafft_test.py +0 -0
- {sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/tests/test.gb +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: sapiopycommons
|
|
3
|
-
Version: 2025.
|
|
3
|
+
Version: 2025.9.8a728
|
|
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>
|
|
@@ -118,7 +118,8 @@ class ConverterBase(ABC):
|
|
|
118
118
|
:param target_type: The target content type.
|
|
119
119
|
:return: True if this converter can convert from the input type to the target type, False otherwise.
|
|
120
120
|
"""
|
|
121
|
-
return self.input_type() == input_type.name
|
|
121
|
+
return (self.input_type().lower() == input_type.name.lower()
|
|
122
|
+
and self.output_type().lower() == target_type.name.lower())
|
|
122
123
|
|
|
123
124
|
@abstractmethod
|
|
124
125
|
def convert(self, content: StepItemContainerPbo) -> StepItemContainerPbo:
|
|
@@ -24,7 +24,7 @@ _sym_db = _symbol_database.Default()
|
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n9sapiopycommons/ai/protoapi/plan/item/item_container.proto\"2\n\x0e\x43ontentTypePbo\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x12\n\nextensions\x18\x02 \x03(\t\"$\n\x13StepCsvHeaderRowPbo\x12\r\n\x05\x63\x65lls\x18\x01 \x03(\t\"\x1e\n\rStepCsvRowPbo\x12\r\n\x05\x63\x65lls\x18\x01 \x03(\t\"Z\n\x13StepCsvContainerPbo\x12$\n\x06header\x18\x0e \x01(\x0b\x32\x14.StepCsvHeaderRowPbo\x12\x1d\n\x05items\x18\x0f \x03(\x0b\x32\x0e.StepCsvRowPbo\"%\n\x14StepJsonContainerPbo\x12\r\n\x05items\x18\x0f \x03(\t\"%\n\x14StepTextContainerPbo\x12\r\n\x05items\x18\x0f \x03(\t\"\'\n\x16StepBinaryContainerPbo\x12\r\n\x05items\x18\x0f \x03(\x0c\"<\n\x15StepImageContainerPbo\x12\x14\n\x0cimage_format\x18\x01 \x01(\t\x12\r\n\x05items\x18\x0f \x03(\x0c\"\
|
|
27
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n9sapiopycommons/ai/protoapi/plan/item/item_container.proto\"2\n\x0e\x43ontentTypePbo\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x12\n\nextensions\x18\x02 \x03(\t\"$\n\x13StepCsvHeaderRowPbo\x12\r\n\x05\x63\x65lls\x18\x01 \x03(\t\"\x1e\n\rStepCsvRowPbo\x12\r\n\x05\x63\x65lls\x18\x01 \x03(\t\"Z\n\x13StepCsvContainerPbo\x12$\n\x06header\x18\x0e \x01(\x0b\x32\x14.StepCsvHeaderRowPbo\x12\x1d\n\x05items\x18\x0f \x03(\x0b\x32\x0e.StepCsvRowPbo\"%\n\x14StepJsonContainerPbo\x12\r\n\x05items\x18\x0f \x03(\t\"%\n\x14StepTextContainerPbo\x12\r\n\x05items\x18\x0f \x03(\t\"\'\n\x16StepBinaryContainerPbo\x12\r\n\x05items\x18\x0f \x03(\x0c\"<\n\x15StepImageContainerPbo\x12\x14\n\x0cimage_format\x18\x01 \x01(\t\x12\r\n\x05items\x18\x0f \x03(\x0c\"\xac\x02\n\x14StepItemContainerPbo\x12%\n\x0c\x63ontent_type\x18\x02 \x01(\x0b\x32\x0f.ContentTypePbo\x12\x16\n\x0e\x63ontainer_name\x18\x03 \x01(\t\x12\x34\n\x10\x62inary_container\x18\xff\x0f \x01(\x0b\x32\x17.StepBinaryContainerPboH\x00\x12.\n\rcsv_container\x18\xfe\x0f \x01(\x0b\x32\x14.StepCsvContainerPboH\x00\x12\x30\n\x0ejson_container\x18\xfd\x0f \x01(\x0b\x32\x15.StepJsonContainerPboH\x00\x12\x30\n\x0etext_container\x18\xfc\x0f \x01(\x0b\x32\x15.StepTextContainerPboH\x00\x42\x0b\n\tcontainer*A\n\x0b\x44\x61taTypePbo\x12\n\n\x06\x42INARY\x10\x00\x12\x08\n\x04JSON\x10\x01\x12\x07\n\x03\x43SV\x10\x02\x12\x08\n\x04TEXT\x10\x03\x12\t\n\x05IMAGE\x10\x04\x42 \n\x1c\x63om.velox.protoapi.plan.itemP\x01\x62\x06proto3')
|
|
28
28
|
|
|
29
29
|
_globals = globals()
|
|
30
30
|
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
@@ -32,8 +32,8 @@ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'sapiopycommons.ai.protoapi.
|
|
|
32
32
|
if not _descriptor._USE_C_DESCRIPTORS:
|
|
33
33
|
_globals['DESCRIPTOR']._loaded_options = None
|
|
34
34
|
_globals['DESCRIPTOR']._serialized_options = b'\n\034com.velox.protoapi.plan.itemP\001'
|
|
35
|
-
_globals['_DATATYPEPBO']._serialized_start=
|
|
36
|
-
_globals['_DATATYPEPBO']._serialized_end=
|
|
35
|
+
_globals['_DATATYPEPBO']._serialized_start=759
|
|
36
|
+
_globals['_DATATYPEPBO']._serialized_end=824
|
|
37
37
|
_globals['_CONTENTTYPEPBO']._serialized_start=61
|
|
38
38
|
_globals['_CONTENTTYPEPBO']._serialized_end=111
|
|
39
39
|
_globals['_STEPCSVHEADERROWPBO']._serialized_start=113
|
|
@@ -51,5 +51,5 @@ if not _descriptor._USE_C_DESCRIPTORS:
|
|
|
51
51
|
_globals['_STEPIMAGECONTAINERPBO']._serialized_start=394
|
|
52
52
|
_globals['_STEPIMAGECONTAINERPBO']._serialized_end=454
|
|
53
53
|
_globals['_STEPITEMCONTAINERPBO']._serialized_start=457
|
|
54
|
-
_globals['_STEPITEMCONTAINERPBO']._serialized_end=
|
|
54
|
+
_globals['_STEPITEMCONTAINERPBO']._serialized_end=757
|
|
55
55
|
# @@protoc_insertion_point(module_scope)
|
|
@@ -74,15 +74,17 @@ class StepImageContainerPbo(_message.Message):
|
|
|
74
74
|
def __init__(self, image_format: _Optional[str] = ..., items: _Optional[_Iterable[bytes]] = ...) -> None: ...
|
|
75
75
|
|
|
76
76
|
class StepItemContainerPbo(_message.Message):
|
|
77
|
-
__slots__ = ("content_type", "binary_container", "csv_container", "json_container", "text_container")
|
|
77
|
+
__slots__ = ("content_type", "container_name", "binary_container", "csv_container", "json_container", "text_container")
|
|
78
78
|
CONTENT_TYPE_FIELD_NUMBER: _ClassVar[int]
|
|
79
|
+
CONTAINER_NAME_FIELD_NUMBER: _ClassVar[int]
|
|
79
80
|
BINARY_CONTAINER_FIELD_NUMBER: _ClassVar[int]
|
|
80
81
|
CSV_CONTAINER_FIELD_NUMBER: _ClassVar[int]
|
|
81
82
|
JSON_CONTAINER_FIELD_NUMBER: _ClassVar[int]
|
|
82
83
|
TEXT_CONTAINER_FIELD_NUMBER: _ClassVar[int]
|
|
83
84
|
content_type: ContentTypePbo
|
|
85
|
+
container_name: str
|
|
84
86
|
binary_container: StepBinaryContainerPbo
|
|
85
87
|
csv_container: StepCsvContainerPbo
|
|
86
88
|
json_container: StepJsonContainerPbo
|
|
87
89
|
text_container: StepTextContainerPbo
|
|
88
|
-
def __init__(self, content_type: _Optional[_Union[ContentTypePbo, _Mapping]] = ..., binary_container: _Optional[_Union[StepBinaryContainerPbo, _Mapping]] = ..., csv_container: _Optional[_Union[StepCsvContainerPbo, _Mapping]] = ..., json_container: _Optional[_Union[StepJsonContainerPbo, _Mapping]] = ..., text_container: _Optional[_Union[StepTextContainerPbo, _Mapping]] = ...) -> None: ...
|
|
90
|
+
def __init__(self, content_type: _Optional[_Union[ContentTypePbo, _Mapping]] = ..., container_name: _Optional[str] = ..., binary_container: _Optional[_Union[StepBinaryContainerPbo, _Mapping]] = ..., csv_container: _Optional[_Union[StepCsvContainerPbo, _Mapping]] = ..., json_container: _Optional[_Union[StepJsonContainerPbo, _Mapping]] = ..., text_container: _Optional[_Union[StepTextContainerPbo, _Mapping]] = ...) -> None: ...
|
{sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/server.py
RENAMED
|
@@ -14,13 +14,13 @@ class SapioGrpcServer:
|
|
|
14
14
|
"""
|
|
15
15
|
A gRPC server for handling the various Sapio gRPC services.
|
|
16
16
|
"""
|
|
17
|
-
port:
|
|
17
|
+
port: int
|
|
18
18
|
options: list[tuple[str, Any]]
|
|
19
19
|
_converter_services: list[ConverterServiceServicer]
|
|
20
20
|
_script_services: list[ScriptServiceServicer]
|
|
21
21
|
_tool_services: list[ToolServiceServicer]
|
|
22
22
|
|
|
23
|
-
def __init__(self, port:
|
|
23
|
+
def __init__(self, port: int = 50051, message_mb_size: int = 1024, options: list[tuple[str, Any]] | None = None) \
|
|
24
24
|
-> None:
|
|
25
25
|
"""
|
|
26
26
|
Initialize the gRPC server with the specified port and message size.
|
|
@@ -30,6 +30,8 @@ class SapioGrpcServer:
|
|
|
30
30
|
:param options: Additional gRPC server options to set. This should be a list of tuples where the first item is
|
|
31
31
|
the option name and the second item is the option value.
|
|
32
32
|
"""
|
|
33
|
+
if isinstance(port, str):
|
|
34
|
+
port = int(port)
|
|
33
35
|
self.port = port
|
|
34
36
|
self.options = [
|
|
35
37
|
('grpc.max_send_message_length', message_mb_size * 1024 * 1024),
|
|
@@ -86,9 +88,9 @@ class SapioGrpcServer:
|
|
|
86
88
|
print(f"Registering Tool service: {service.__class__.__name__}")
|
|
87
89
|
add_ToolServiceServicer_to_server(service, server)
|
|
88
90
|
|
|
89
|
-
server.add_insecure_port("[::]:
|
|
91
|
+
server.add_insecure_port(f"[::]:{self.port}")
|
|
90
92
|
await server.start()
|
|
91
|
-
print("Server started, listening on
|
|
93
|
+
print(f"Server started, listening on {self.port}")
|
|
92
94
|
try:
|
|
93
95
|
await server.wait_for_termination()
|
|
94
96
|
finally:
|
{sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/test_client.py
RENAMED
|
@@ -43,10 +43,10 @@ class ToolOutput:
|
|
|
43
43
|
status: str
|
|
44
44
|
message: str
|
|
45
45
|
|
|
46
|
-
binary_output: list[bytes]
|
|
47
|
-
csv_output: list[dict[str, Any]]
|
|
48
|
-
json_output: list[Any]
|
|
49
|
-
text_output: list[str]
|
|
46
|
+
binary_output: list[list[bytes]]
|
|
47
|
+
csv_output: list[list[dict[str, Any]]]
|
|
48
|
+
json_output: list[list[Any]]
|
|
49
|
+
text_output: list[list[str]]
|
|
50
50
|
|
|
51
51
|
new_records: list[dict[str, FieldValue]]
|
|
52
52
|
|
|
@@ -67,24 +67,35 @@ class ToolOutput:
|
|
|
67
67
|
ret_val += f"\tMessage: {self.message}\n"
|
|
68
68
|
ret_val += "-" * 25 + "\n"
|
|
69
69
|
|
|
70
|
-
ret_val += f"Binary Output: {len(self.binary_output)} item(s)\n"
|
|
71
|
-
for
|
|
72
|
-
|
|
73
|
-
ret_val += f"\
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
ret_val += f"
|
|
86
|
-
for
|
|
87
|
-
|
|
70
|
+
ret_val += f"Binary Output: {sum(len(x) for x in self.binary_output)} item(s) across {len(self.binary_output)} outputs\n"
|
|
71
|
+
for i, output in enumerate(self.binary_output, start=1):
|
|
72
|
+
output: list[bytes]
|
|
73
|
+
ret_val += f"\tBinary Output {i}:\n"
|
|
74
|
+
for binary in output:
|
|
75
|
+
ret_val += f"\t\t{len(binary)} byte(s): {binary[:50]}...\n"
|
|
76
|
+
|
|
77
|
+
ret_val += f"CSV Output: {sum(len(x) for x in self.csv_output)} item(s) across {len(self.csv_output)} outputs\n"
|
|
78
|
+
for i, output in enumerate(self.csv_output, start=1):
|
|
79
|
+
output: list[dict[str, Any]]
|
|
80
|
+
ret_val += f"\tCSV Output {i}:\n"
|
|
81
|
+
ret_val += f"\t\tHeaders: {', '.join(output[0].keys())}\n"
|
|
82
|
+
for j, csv_row in enumerate(output):
|
|
83
|
+
ret_val += f"\t\t{j}: {', '.join(f'{v}' for k, v in csv_row.items())}\n"
|
|
84
|
+
|
|
85
|
+
ret_val += f"JSON Output: {sum(len(x) for x in self.json_output)} item(s) across {len(self.json_output)} outputs\n"
|
|
86
|
+
for i, output in enumerate(self.json_output, start=1):
|
|
87
|
+
output: list[Any]
|
|
88
|
+
ret_val += f"\tJSON Output {i}:\n"
|
|
89
|
+
for json_obj in output:
|
|
90
|
+
ret_val += f"\t\t"
|
|
91
|
+
ret_val += json.dumps(json_obj, indent=2).replace("\n", "\n\t\t") + "\n"
|
|
92
|
+
|
|
93
|
+
ret_val += f"Text Output: {sum(len(x) for x in self.text_output)} item(s) across {len(self.text_output)} outputs\n"
|
|
94
|
+
for i, output in enumerate(self.text_output, start=1):
|
|
95
|
+
output: list[str]
|
|
96
|
+
ret_val += f"\tText Output {i}:\n"
|
|
97
|
+
for text in output:
|
|
98
|
+
ret_val += f"\t\t{text}\n"
|
|
88
99
|
|
|
89
100
|
ret_val += f"New Records: {len(self.new_records)} item(s)\n"
|
|
90
101
|
for record in self.new_records:
|
|
@@ -277,14 +288,20 @@ class TestClient:
|
|
|
277
288
|
for item in response.output:
|
|
278
289
|
container = item.item_container
|
|
279
290
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
291
|
+
if container.HasField("binary_container"):
|
|
292
|
+
results.binary_output.append(list(container.binary_container.items))
|
|
293
|
+
elif container.HasField("csv_container"):
|
|
294
|
+
csv_output: list[dict[str, Any]] = []
|
|
295
|
+
for header in container.csv_container.header.cells:
|
|
296
|
+
output_row: dict[str, Any] = {}
|
|
297
|
+
for i, row in enumerate(container.csv_container.items):
|
|
298
|
+
output_row[header] = row.cells[i]
|
|
299
|
+
csv_output.append(output_row)
|
|
300
|
+
results.csv_output.append(csv_output)
|
|
301
|
+
elif container.HasField("json_container"):
|
|
302
|
+
results.json_output.append([json.loads(x) for x in container.json_container.items])
|
|
303
|
+
elif container.HasField("text_container"):
|
|
304
|
+
results.text_output.append(list(container.text_container.items))
|
|
288
305
|
|
|
289
306
|
for record in response.new_records:
|
|
290
307
|
field_map: dict[str, Any] = {x: ProtobufUtils.field_pbo_to_value(y) for x, y in record.fields.items()}
|
|
@@ -29,6 +29,7 @@ from sapiopycommons.ai.protoapi.session.sapio_conn_info_pb2 import SapioUserSecr
|
|
|
29
29
|
from sapiopycommons.ai.protobuf_utils import ProtobufUtils
|
|
30
30
|
from sapiopycommons.ai.test_client import ContainerType
|
|
31
31
|
from sapiopycommons.files.file_util import FileUtil
|
|
32
|
+
from sapiopycommons.files.temp_files import TempFileHandler
|
|
32
33
|
from sapiopycommons.general.aliases import FieldMap, FieldValue
|
|
33
34
|
|
|
34
35
|
|
|
@@ -53,21 +54,26 @@ class BinaryResult(SapioToolResult):
|
|
|
53
54
|
binary_data: list[bytes]
|
|
54
55
|
content_type: str
|
|
55
56
|
file_extensions: list[str]
|
|
57
|
+
name: str
|
|
56
58
|
|
|
57
|
-
def __init__(self, binary_data: list[bytes], content_type: str = "binary", file_extensions: list[str] = None
|
|
59
|
+
def __init__(self, binary_data: list[bytes], content_type: str = "binary", file_extensions: list[str] = None,
|
|
60
|
+
name: str | None = None):
|
|
58
61
|
"""
|
|
59
62
|
:param binary_data: The binary data as a list of bytes.
|
|
60
63
|
:param content_type: The content type of the data.
|
|
61
64
|
:param file_extensions: A list of file extensions that this binary data can be saved as.
|
|
65
|
+
:param name: An optional identifying name for this result that will be accessible to the next tool.
|
|
62
66
|
"""
|
|
63
67
|
self.binary_data = binary_data
|
|
64
68
|
self.content_type = content_type
|
|
65
69
|
self.file_extensions = file_extensions if file_extensions else []
|
|
70
|
+
self.name = name
|
|
66
71
|
|
|
67
72
|
def to_proto(self) -> StepOutputBatchPbo | list[FieldValueMapPbo]:
|
|
68
73
|
return StepOutputBatchPbo(
|
|
69
74
|
item_container=StepItemContainerPbo(
|
|
70
75
|
content_type=ContentTypePbo(name=self.content_type, extensions=self.file_extensions),
|
|
76
|
+
container_name=self.name,
|
|
71
77
|
binary_container=StepBinaryContainerPbo(items=self.binary_data)
|
|
72
78
|
)
|
|
73
79
|
)
|
|
@@ -80,21 +86,26 @@ class CsvResult(SapioToolResult):
|
|
|
80
86
|
csv_data: list[dict[str, Any]]
|
|
81
87
|
content_type: str
|
|
82
88
|
file_extensions: list[str]
|
|
89
|
+
name: str
|
|
83
90
|
|
|
84
|
-
def __init__(self, csv_data: list[dict[str, Any]], content_type: str = "csv", file_extensions: list[str] = None
|
|
91
|
+
def __init__(self, csv_data: list[dict[str, Any]], content_type: str = "csv", file_extensions: list[str] = None,
|
|
92
|
+
name: str | None = None):
|
|
85
93
|
"""
|
|
86
94
|
:param csv_data: The list of CSV data results, provided as a list of dictionaries of column name to value.
|
|
87
95
|
:param content_type: The content type of the data.
|
|
88
96
|
:param file_extensions: A list of file extensions that this binary data can be saved as.
|
|
97
|
+
:param name: An optional identifying name for this result that will be accessible to the next tool.
|
|
89
98
|
"""
|
|
90
99
|
self.csv_data = csv_data
|
|
91
100
|
self.content_type = content_type
|
|
92
101
|
self.file_extensions = file_extensions if file_extensions else ["csv"]
|
|
102
|
+
self.name = name
|
|
93
103
|
|
|
94
104
|
def to_proto(self) -> StepOutputBatchPbo | list[FieldValueMapPbo]:
|
|
95
105
|
return StepOutputBatchPbo(
|
|
96
106
|
item_container=StepItemContainerPbo(
|
|
97
107
|
content_type=ContentTypePbo(name=self.content_type, extensions=self.file_extensions),
|
|
108
|
+
container_name=self.name,
|
|
98
109
|
csv_container=StepCsvContainerPbo(
|
|
99
110
|
header=StepCsvHeaderRowPbo(cells=self.csv_data[0].keys()),
|
|
100
111
|
items=[StepCsvRowPbo(cells=[str(x) for x in row.values()]) for row in self.csv_data]
|
|
@@ -143,22 +154,27 @@ class JsonResult(SapioToolResult):
|
|
|
143
154
|
json_data: list[Any]
|
|
144
155
|
content_type: str
|
|
145
156
|
file_extensions: list[str]
|
|
157
|
+
name: str
|
|
146
158
|
|
|
147
|
-
def __init__(self, json_data: list[Any], content_type: str = "json", file_extensions: list[str] = None
|
|
159
|
+
def __init__(self, json_data: list[Any], content_type: str = "json", file_extensions: list[str] = None,
|
|
160
|
+
name: str | None = None):
|
|
148
161
|
"""
|
|
149
162
|
:param json_data: The list of JSON data results. Each entry in the list represents a separate JSON object.
|
|
150
163
|
These entries must be able to be serialized to JSON using json.dumps().
|
|
151
164
|
:param content_type: The content type of the data.
|
|
152
165
|
:param file_extensions: A list of file extensions that this binary data can be saved as.
|
|
166
|
+
:param name: An optional identifying name for this result that will be accessible to the next tool.
|
|
153
167
|
"""
|
|
154
168
|
self.json_data = json_data
|
|
155
169
|
self.content_type = content_type
|
|
156
170
|
self.file_extensions = file_extensions if file_extensions else ["json"]
|
|
171
|
+
self.name = name
|
|
157
172
|
|
|
158
173
|
def to_proto(self) -> StepOutputBatchPbo | list[FieldValueMapPbo]:
|
|
159
174
|
return StepOutputBatchPbo(
|
|
160
175
|
item_container=StepItemContainerPbo(
|
|
161
176
|
content_type=ContentTypePbo(name=self.content_type, extensions=self.file_extensions),
|
|
177
|
+
container_name=self.name,
|
|
162
178
|
json_container=StepJsonContainerPbo(items=[json.dumps(x) for x in self.json_data])
|
|
163
179
|
)
|
|
164
180
|
)
|
|
@@ -171,21 +187,26 @@ class TextResult(SapioToolResult):
|
|
|
171
187
|
text_data: list[str]
|
|
172
188
|
content_type: str
|
|
173
189
|
file_extensions: list[str]
|
|
190
|
+
name: str
|
|
174
191
|
|
|
175
|
-
def __init__(self, text_data: list[str], content_type: str = "text", file_extensions: list[str] = None
|
|
192
|
+
def __init__(self, text_data: list[str], content_type: str = "text", file_extensions: list[str] = None,
|
|
193
|
+
name: str | None = None):
|
|
176
194
|
"""
|
|
177
195
|
:param text_data: The text data as a list of strings.
|
|
178
196
|
:param content_type: The content type of the data.
|
|
179
197
|
:param file_extensions: A list of file extensions that this binary data can be saved as.
|
|
198
|
+
:param name: An optional identifying name for this result that will be accessible to the next tool.
|
|
180
199
|
"""
|
|
181
200
|
self.text_data = text_data
|
|
182
201
|
self.content_type = content_type
|
|
183
202
|
self.file_extensions = file_extensions if file_extensions else ["txt"]
|
|
203
|
+
self.name = name
|
|
184
204
|
|
|
185
205
|
def to_proto(self) -> StepOutputBatchPbo | list[FieldValueMapPbo]:
|
|
186
206
|
return StepOutputBatchPbo(
|
|
187
207
|
item_container=StepItemContainerPbo(
|
|
188
208
|
content_type=ContentTypePbo(name=self.content_type, extensions=self.file_extensions),
|
|
209
|
+
container_name=self.name,
|
|
189
210
|
text_container=StepTextContainerPbo(items=self.text_data)
|
|
190
211
|
)
|
|
191
212
|
)
|
|
@@ -298,8 +319,8 @@ class ToolServiceBase(ToolServiceServicer, ABC):
|
|
|
298
319
|
# If the tool is not found, list all of the registered tools for this service so that the LLM can correct
|
|
299
320
|
# the tool it is requesting.
|
|
300
321
|
all_tool_names: str = "\n".join(registered_tools.keys())
|
|
301
|
-
msg: str = (f"Tool \"{find_tool}\" not found in the registered tools for this service. The registered
|
|
302
|
-
f"for this service are: \n{all_tool_names}")
|
|
322
|
+
msg: str = (f"Tool \"{find_tool}\" not found in the registered tools for this service. The registered "
|
|
323
|
+
f"tools for this service are: \n{all_tool_names}")
|
|
303
324
|
return False, msg, [], []
|
|
304
325
|
|
|
305
326
|
# Instantiate the tool class.
|
|
@@ -309,7 +330,8 @@ class ToolServiceBase(ToolServiceServicer, ABC):
|
|
|
309
330
|
tool.setup(user, request, context)
|
|
310
331
|
# Validate that the provided inputs match the tool's expected inputs.
|
|
311
332
|
if len(request.input) != len(tool.input_configs):
|
|
312
|
-
msg: str = f"Expected {len(tool.input_configs)} inputs for this tool, but got {len(request.input)}
|
|
333
|
+
msg: str = (f"Expected {len(tool.input_configs)} inputs for this tool, but got {len(request.input)} "
|
|
334
|
+
f"instead.")
|
|
313
335
|
else:
|
|
314
336
|
msg: str = tool.validate_input()
|
|
315
337
|
# If there is no error message, then the inputs are valid.
|
|
@@ -327,6 +349,9 @@ class ToolServiceBase(ToolServiceServicer, ABC):
|
|
|
327
349
|
except Exception as e:
|
|
328
350
|
tool.log_exception("Exception occurred during tool execution.", e)
|
|
329
351
|
return False, str(e), [], tool.logs
|
|
352
|
+
finally:
|
|
353
|
+
# Clean up any temporary files created by the tool.
|
|
354
|
+
tool.temp_data.cleanup()
|
|
330
355
|
|
|
331
356
|
|
|
332
357
|
class ToolBase(ABC):
|
|
@@ -346,6 +371,8 @@ class ToolBase(ABC):
|
|
|
346
371
|
logger: Logger
|
|
347
372
|
verbose_logging: bool
|
|
348
373
|
|
|
374
|
+
temp_data: TempFileHandler
|
|
375
|
+
|
|
349
376
|
user: SapioUser
|
|
350
377
|
request: ProcessStepRequestPbo
|
|
351
378
|
context: ServicerContext
|
|
@@ -383,6 +410,7 @@ class ToolBase(ABC):
|
|
|
383
410
|
self.output_configs = []
|
|
384
411
|
self._output_container_types = []
|
|
385
412
|
self.config_fields = []
|
|
413
|
+
self.temp_data = TempFileHandler()
|
|
386
414
|
self.logs = []
|
|
387
415
|
self.logger = logging.getLogger(f"ToolBase.{self._name}")
|
|
388
416
|
ensure_logger_initialized(self.logger)
|
|
@@ -508,8 +536,8 @@ class ToolBase(ABC):
|
|
|
508
536
|
"""
|
|
509
537
|
self.config_fields.append(ProtobufUtils.field_def_to_pbo(field))
|
|
510
538
|
|
|
511
|
-
def add_boolean_config_field(self, field_name: str, display_name: str, description: str,
|
|
512
|
-
optional: bool = False) -> None:
|
|
539
|
+
def add_boolean_config_field(self, field_name: str, display_name: str, description: str,
|
|
540
|
+
default_value: bool | None = None, optional: bool = False) -> None:
|
|
513
541
|
"""
|
|
514
542
|
Add a boolean configuration field to the tool. This field will be used to configure the tool in the plan
|
|
515
543
|
manager.
|
|
@@ -532,9 +560,9 @@ class ToolBase(ABC):
|
|
|
532
560
|
)
|
|
533
561
|
))
|
|
534
562
|
|
|
535
|
-
def add_double_config_field(self, field_name: str, display_name: str, description: str,
|
|
536
|
-
|
|
537
|
-
optional: bool = False) -> None:
|
|
563
|
+
def add_double_config_field(self, field_name: str, display_name: str, description: str,
|
|
564
|
+
default_value: float | None = None, min_value: float = -10.**120,
|
|
565
|
+
max_value: float = 10.**120, precision: int = 2, optional: bool = False) -> None:
|
|
538
566
|
"""
|
|
539
567
|
Add a double configuration field to the tool. This field will be used to configure the tool in the plan
|
|
540
568
|
manager.
|
|
@@ -564,7 +592,7 @@ class ToolBase(ABC):
|
|
|
564
592
|
))
|
|
565
593
|
|
|
566
594
|
def add_integer_config_field(self, field_name: str, display_name: str, description: str,
|
|
567
|
-
default_value: int, min_value: int = -2**31, max_value: int = 2**31-1,
|
|
595
|
+
default_value: int | None = None, min_value: int = -2**31, max_value: int = 2**31-1,
|
|
568
596
|
optional: bool = False) -> None:
|
|
569
597
|
"""
|
|
570
598
|
Add an integer configuration field to the tool. This field will be used to configure the tool in the plan
|
|
@@ -593,7 +621,8 @@ class ToolBase(ABC):
|
|
|
593
621
|
))
|
|
594
622
|
|
|
595
623
|
def add_string_config_field(self, field_name: str, display_name: str, description: str,
|
|
596
|
-
default_value: str, max_length: int = 1000, optional: bool = False)
|
|
624
|
+
default_value: str | None = None, max_length: int = 1000, optional: bool = False) \
|
|
625
|
+
-> None:
|
|
597
626
|
"""
|
|
598
627
|
Add a string configuration field to the tool. This field will be used to configure the tool in the plan
|
|
599
628
|
manager.
|
|
@@ -618,8 +647,9 @@ class ToolBase(ABC):
|
|
|
618
647
|
)
|
|
619
648
|
))
|
|
620
649
|
|
|
621
|
-
def add_list_config_field(self, field_name: str, display_name: str, description: str,
|
|
622
|
-
|
|
650
|
+
def add_list_config_field(self, field_name: str, display_name: str, description: str,
|
|
651
|
+
default_value: str | None = None, allowed_values: list[str] | None = None,
|
|
652
|
+
direct_edit: bool = False, optional: bool = False) -> None:
|
|
623
653
|
"""
|
|
624
654
|
Add a list configuration field to the tool. This field will be used to configure the tool in the plan
|
|
625
655
|
manager.
|
|
@@ -648,8 +678,8 @@ class ToolBase(ABC):
|
|
|
648
678
|
))
|
|
649
679
|
|
|
650
680
|
def add_multi_list_config_field(self, field_name: str, display_name: str, description: str,
|
|
651
|
-
default_value: list[str], allowed_values: list[str]
|
|
652
|
-
optional: bool = False) -> None:
|
|
681
|
+
default_value: list[str] | None = None, allowed_values: list[str] | None = None,
|
|
682
|
+
direct_edit: bool = False, optional: bool = False) -> None:
|
|
653
683
|
"""
|
|
654
684
|
Add a multi-select list configuration field to the tool. This field will be used to configure the tool in the
|
|
655
685
|
plan manager.
|
|
@@ -671,7 +701,7 @@ class ToolBase(ABC):
|
|
|
671
701
|
required=not optional,
|
|
672
702
|
editable=True,
|
|
673
703
|
selection_properties=SelectionPropertiesPbo(
|
|
674
|
-
default_value=",".join(default_value),
|
|
704
|
+
default_value=",".join(default_value) if default_value else None,
|
|
675
705
|
static_list_values=allowed_values,
|
|
676
706
|
multi_select=True,
|
|
677
707
|
direct_edit=direct_edit,
|
|
@@ -817,6 +847,15 @@ class ToolBase(ABC):
|
|
|
817
847
|
self.logs.append(f"EXCEPTION: {self._name}: {message} - {e}")
|
|
818
848
|
self.logger.error(f"{message}\n{traceback.format_exc()}")
|
|
819
849
|
|
|
850
|
+
def get_input_name(self, index: int = 0) -> str | None:
|
|
851
|
+
"""
|
|
852
|
+
Get the name of the input from the request object.
|
|
853
|
+
|
|
854
|
+
:param index: The index of the input to parse. Defaults to 0. Used for tools that accept multiple inputs.
|
|
855
|
+
:return: The name of the input from the request object, or None if no name is set.
|
|
856
|
+
"""
|
|
857
|
+
return self.request.input[index].item_container.container_name
|
|
858
|
+
|
|
820
859
|
def get_input_binary(self, index: int = 0) -> list[bytes]:
|
|
821
860
|
"""
|
|
822
861
|
Get the binary data from the request object.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import shutil
|
|
3
|
+
import tempfile
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
# FR-47422: Created class.
|
|
7
|
+
class TempFileHandler:
|
|
8
|
+
"""
|
|
9
|
+
A utility class to manage temporary files and directories.
|
|
10
|
+
"""
|
|
11
|
+
directories: list[str]
|
|
12
|
+
files: list[str]
|
|
13
|
+
|
|
14
|
+
def __init__(self) -> None:
|
|
15
|
+
self.directories = []
|
|
16
|
+
self.files = []
|
|
17
|
+
|
|
18
|
+
def create_temp_directory(self) -> str:
|
|
19
|
+
"""
|
|
20
|
+
:return: The path to a newly created temporary directory.
|
|
21
|
+
"""
|
|
22
|
+
directory: str = tempfile.mkdtemp()
|
|
23
|
+
self.directories.append(directory)
|
|
24
|
+
return directory
|
|
25
|
+
|
|
26
|
+
def create_temp_file(self, data: str | bytes, suffix: str = "") -> str:
|
|
27
|
+
"""
|
|
28
|
+
:param data: The data to write to the temporary file.
|
|
29
|
+
:param suffix: An optional suffix for the temporary file.
|
|
30
|
+
:return: The path to a newly created temporary file containing the provided data.
|
|
31
|
+
"""
|
|
32
|
+
mode: str = 'w' if isinstance(data, str) else 'wb'
|
|
33
|
+
with tempfile.NamedTemporaryFile(mode=mode, suffix=suffix, delete=False) as tmp_file:
|
|
34
|
+
tmp_file.write(data)
|
|
35
|
+
file_path: str = tmp_file.name
|
|
36
|
+
self.files.append(file_path)
|
|
37
|
+
return file_path
|
|
38
|
+
|
|
39
|
+
def cleanup(self) -> None:
|
|
40
|
+
"""
|
|
41
|
+
Delete all temporary files and directories created by this handler.
|
|
42
|
+
"""
|
|
43
|
+
for directory in self.directories:
|
|
44
|
+
if os.path.exists(directory):
|
|
45
|
+
shutil.rmtree(directory)
|
|
46
|
+
|
|
47
|
+
for file_path in self.files:
|
|
48
|
+
if os.path.exists(file_path):
|
|
49
|
+
os.remove(file_path)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/ai/protobuf_utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/chem/Molecules.py
RENAMED
|
File without changes
|
{sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/chem/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/datatype/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/eln/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/eln/step_creation.py
RENAMED
|
File without changes
|
{sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/files/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/files/file_bridge.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/files/file_util.py
RENAMED
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/files/file_writer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/general/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/general/aliases.py
RENAMED
|
File without changes
|
{sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/general/audit_log.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/general/time_util.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/rules/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/samples/aliquot.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/src/sapiopycommons/webhook/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/tests/AF-A0A009IHW8-F1-model_v4.cif
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/tests/chem_test_curation_queue.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.8.20a713 → sapiopycommons-2025.9.8a728}/tests/flowcyto/COVID19_W_001_O.fcs
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|