sapiopycommons 2025.2.3a410__tar.gz → 2025.2.3a411__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.2.3a410 → sapiopycommons-2025.2.3a411}/PKG-INFO +1 -1
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/pyproject.toml +1 -1
- sapiopycommons-2025.2.3a411/src/sapiopycommons/elain/tool_of_tools.py +264 -0
- sapiopycommons-2025.2.3a411/tests/_do_not_add_init_py_here +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/.gitignore +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/LICENSE +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/README.md +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/__init__.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/callbacks/__init__.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/callbacks/callback_util.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/callbacks/field_builder.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/chem/IndigoMolecules.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/chem/Molecules.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/chem/__init__.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/customreport/__init__.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/customreport/auto_pagers.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/customreport/column_builder.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/customreport/custom_report_builder.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/customreport/term_builder.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/datatype/__init__.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/datatype/attachment_util.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/datatype/data_fields.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/datatype/pseudo_data_types.py +0 -0
- {sapiopycommons-2025.2.3a410/src/sapiopycommons/eln → sapiopycommons-2025.2.3a411/src/sapiopycommons/elain}/__init__.py +0 -0
- {sapiopycommons-2025.2.3a410/src/sapiopycommons/files → sapiopycommons-2025.2.3a411/src/sapiopycommons/eln}/__init__.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/eln/experiment_handler.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/eln/experiment_report_util.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/eln/plate_designer.py +0 -0
- {sapiopycommons-2025.2.3a410/src/sapiopycommons/general → sapiopycommons-2025.2.3a411/src/sapiopycommons/files}/__init__.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/files/complex_data_loader.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/files/file_bridge.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/files/file_bridge_handler.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/files/file_data_handler.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/files/file_util.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/files/file_validator.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/files/file_writer.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/flowcyto/flow_cyto.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/flowcyto/flowcyto_data.py +0 -0
- {sapiopycommons-2025.2.3a410/src/sapiopycommons/processtracking → sapiopycommons-2025.2.3a411/src/sapiopycommons/general}/__init__.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/general/accession_service.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/general/aliases.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/general/audit_log.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/general/custom_report_util.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/general/directive_util.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/general/exceptions.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/general/popup_util.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/general/sapio_links.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/general/storage_util.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/general/time_util.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/multimodal/multimodal.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/multimodal/multimodal_data.py +0 -0
- {sapiopycommons-2025.2.3a410/src/sapiopycommons/recordmodel → sapiopycommons-2025.2.3a411/src/sapiopycommons/processtracking}/__init__.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/processtracking/custom_workflow_handler.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/processtracking/endpoints.py +0 -0
- {sapiopycommons-2025.2.3a410/src/sapiopycommons/rules → sapiopycommons-2025.2.3a411/src/sapiopycommons/recordmodel}/__init__.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/recordmodel/record_handler.py +0 -0
- {sapiopycommons-2025.2.3a410/src/sapiopycommons/sftpconnect → sapiopycommons-2025.2.3a411/src/sapiopycommons/rules}/__init__.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/rules/eln_rule_handler.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/rules/on_save_rule_handler.py +0 -0
- {sapiopycommons-2025.2.3a410/src/sapiopycommons/webhook → sapiopycommons-2025.2.3a411/src/sapiopycommons/sftpconnect}/__init__.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/sftpconnect/sftp_builder.py +0 -0
- /sapiopycommons-2025.2.3a410/tests/_do_not_add_init_py_here → /sapiopycommons-2025.2.3a411/src/sapiopycommons/webhook/__init__.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/webhook/webhook_context.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/webhook/webhook_handlers.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/webhook/webservice_handlers.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/tests/AF-A0A009IHW8-F1-model_v4.cif +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/tests/accession_test.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/tests/bio_reg_test.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/tests/chem_test.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/tests/chem_test_curation_queue.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/tests/curation_queue_test.sdf +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/tests/data_type_models.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/tests/flowcyto/101_DEN084Y5_15_E01_008_clean.fcs +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/tests/flowcyto/101_DEN084Y5_15_E03_009_clean.fcs +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/tests/flowcyto/101_DEN084Y5_15_E05_010_clean.fcs +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/tests/flowcyto/8_color_ICS.wsp +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/tests/flowcyto/COVID19_W_001_O.fcs +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/tests/flowcyto_test.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/tests/kappa.chains.fasta +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/tests/mafft_test.py +0 -0
- {sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/tests/test.gb +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: sapiopycommons
|
|
3
|
-
Version: 2025.2.
|
|
3
|
+
Version: 2025.2.3a411
|
|
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>
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
|
|
3
|
+
from sapiopylib.rest.DataRecordManagerService import DataRecordManager
|
|
4
|
+
from sapiopylib.rest.ELNService import ElnManager
|
|
5
|
+
from sapiopylib.rest.User import SapioUser
|
|
6
|
+
from sapiopylib.rest.pojo.DataRecord import DataRecord
|
|
7
|
+
from sapiopylib.rest.pojo.chartdata.DashboardDefinition import GaugeChartDefinition
|
|
8
|
+
from sapiopylib.rest.pojo.chartdata.DashboardEnums import ChartGroupingType, ChartOperationType, ChartType
|
|
9
|
+
from sapiopylib.rest.pojo.chartdata.DashboardSeries import GaugeChartSeries
|
|
10
|
+
from sapiopylib.rest.pojo.eln.ElnExperiment import ElnExperiment
|
|
11
|
+
from sapiopylib.rest.pojo.eln.ExperimentEntry import ExperimentEntry
|
|
12
|
+
from sapiopylib.rest.pojo.eln.ExperimentEntryCriteria import ElnEntryCriteria, ElnFormEntryUpdateCriteria
|
|
13
|
+
from sapiopylib.rest.pojo.eln.SapioELNEnums import ElnEntryType, ElnBaseDataType
|
|
14
|
+
from sapiopylib.rest.pojo.eln.eln_headings import ElnExperimentTabAddCriteria, ElnExperimentTab
|
|
15
|
+
from sapiopylib.rest.pojo.eln.field_set import ElnFieldSetInfo
|
|
16
|
+
from sapiopylib.rest.utils.ProtocolUtils import ELNStepFactory
|
|
17
|
+
from sapiopylib.rest.utils.Protocols import ElnEntryStep, ElnExperimentProtocol
|
|
18
|
+
|
|
19
|
+
from sapiopycommons.general.exceptions import SapioException
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# FR-47422: Create utility methods to assist the tool of tools.
|
|
23
|
+
def create_tot_headers(url: str, username: str, password: str, experiment_id: int, tab_prefix: str) \
|
|
24
|
+
-> tuple[str, dict[str, str]]:
|
|
25
|
+
"""
|
|
26
|
+
Create the headers to be passed to a tool of tools endpoint.
|
|
27
|
+
|
|
28
|
+
:param url: The webservice URL of the system to make the changes in.
|
|
29
|
+
:param username: The username of the user making the changes.
|
|
30
|
+
:param password: The password of the user making the changes.
|
|
31
|
+
:param experiment_id: The ID of the experiment to make the changes in.
|
|
32
|
+
:param tab_prefix: The prefix to use for the tab name that will be created by the tool.
|
|
33
|
+
:return: The encoded credentials and the headers to be passed to the endpoint.
|
|
34
|
+
"""
|
|
35
|
+
# Combine the credentials into the format "username:password"
|
|
36
|
+
credentials: str = f"{username}:{password}"
|
|
37
|
+
# Encode the credentials to bytes, then encode them using base64,
|
|
38
|
+
# and finally convert the result back into a string.
|
|
39
|
+
encoded_credentials: str = base64.b64encode(credentials.encode('utf-8')).decode('utf-8')
|
|
40
|
+
headers: dict[str, str] = {
|
|
41
|
+
"SAPIO_APP_API_KEY": f"Basic {encoded_credentials}",
|
|
42
|
+
"SAPIO_APP_API_URL": url,
|
|
43
|
+
"EXPERIMENT_ID": str(experiment_id),
|
|
44
|
+
"TAB_PREFIX": tab_prefix
|
|
45
|
+
}
|
|
46
|
+
return encoded_credentials, headers
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def create_user_from_tot_headers(headers: dict[str, str]) -> SapioUser:
|
|
50
|
+
"""
|
|
51
|
+
Create a SapioUser object from the headers passed to a tool of tools endpoint.
|
|
52
|
+
|
|
53
|
+
:param headers: The headers that were passed to the endpoint.
|
|
54
|
+
:return: A SapioUser object created from the headers that can be used to communicate with the Sapio server.
|
|
55
|
+
"""
|
|
56
|
+
credentials = base64.b64decode(headers["SAPIO_APP_API_KEY"].removeprefix("Basic ")).decode("utf-8").split(":", 1)
|
|
57
|
+
return SapioUser(headers["SAPIO_APP_API_URL"], username=credentials[0], password=credentials[1])
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class ToolOfToolsHelper:
|
|
61
|
+
"""
|
|
62
|
+
A class with helper methods utilized by the Tool of Tools for the creation and updating of experiment tabs that
|
|
63
|
+
track a tool's progress and results.
|
|
64
|
+
"""
|
|
65
|
+
# Contextual info.
|
|
66
|
+
user: SapioUser
|
|
67
|
+
tab_prefix: str
|
|
68
|
+
exp_id: int
|
|
69
|
+
_protocol: ElnExperimentProtocol
|
|
70
|
+
|
|
71
|
+
# Tool info.
|
|
72
|
+
name: str
|
|
73
|
+
description: str
|
|
74
|
+
results_data_type: str | None
|
|
75
|
+
|
|
76
|
+
# Managers.
|
|
77
|
+
eln_man: ElnManager
|
|
78
|
+
dr_man: DataRecordManager
|
|
79
|
+
|
|
80
|
+
# Stuff created by this helper.
|
|
81
|
+
_initialized: bool
|
|
82
|
+
"""Whether a tab for this tool has been initialized."""
|
|
83
|
+
tab: ElnExperimentTab
|
|
84
|
+
"""The tab that contains the tool's entries."""
|
|
85
|
+
description_entry: ElnEntryStep
|
|
86
|
+
"""The text entry that displays the description of the tool."""
|
|
87
|
+
progress_entry: ElnEntryStep
|
|
88
|
+
"""A hidden entry for tracking the progress of the tool."""
|
|
89
|
+
progress_record: DataRecord
|
|
90
|
+
"""The record that stores the progress of the tool."""
|
|
91
|
+
progress_gauge_entry: ElnEntryStep
|
|
92
|
+
"""A chart entry that displays the progress of the tool using the hidden progress entry."""
|
|
93
|
+
results_entry: ElnEntryStep | None
|
|
94
|
+
"""An entry for displaying the results of the tool. If None, the tool does not produce result records."""
|
|
95
|
+
|
|
96
|
+
def __init__(self, headers: dict[str, str], name: str, description: str, results_data_type: str | None = None):
|
|
97
|
+
"""
|
|
98
|
+
:param headers: The headers that were passed to the endpoint.
|
|
99
|
+
:param name: The name of the tool.
|
|
100
|
+
:param description: A description of the tool.
|
|
101
|
+
:param results_data_type: The data type name for the results of the tool. If None, the tool does not produce
|
|
102
|
+
result records.
|
|
103
|
+
"""
|
|
104
|
+
self.user = create_user_from_tot_headers(headers)
|
|
105
|
+
self.exp_id = int(headers["EXPERIMENT_ID"])
|
|
106
|
+
self.tab_prefix = headers["TAB_PREFIX"]
|
|
107
|
+
# The experiment name and record ID aren't necessary to know.
|
|
108
|
+
self._protocol = ElnExperimentProtocol(ElnExperiment(self.exp_id, "", 0), self.user)
|
|
109
|
+
|
|
110
|
+
self.name = name
|
|
111
|
+
self.description = description
|
|
112
|
+
self.results_data_type = results_data_type
|
|
113
|
+
|
|
114
|
+
self.eln_man = ElnManager(self.user)
|
|
115
|
+
self.dr_man = DataRecordManager(self.user)
|
|
116
|
+
|
|
117
|
+
self._initialized = False
|
|
118
|
+
|
|
119
|
+
def initialize_tab(self) -> ElnExperimentTab:
|
|
120
|
+
if self._initialized:
|
|
121
|
+
return self.tab
|
|
122
|
+
self._initialized = True
|
|
123
|
+
|
|
124
|
+
# Create the tab for the tool progress and results.
|
|
125
|
+
# The entry IDs list can't be empty, so we need to create a dummy entry just to get the tab created.
|
|
126
|
+
tab_crit = ElnExperimentTabAddCriteria(f"{self.tab_prefix} {self.name}", [])
|
|
127
|
+
tab: ElnExperimentTab = self.eln_man.add_tab_for_experiment(self.exp_id, tab_crit)
|
|
128
|
+
self.tab = tab
|
|
129
|
+
|
|
130
|
+
# Create a hidden entry for tracking the progress of the tool.
|
|
131
|
+
field_sets: list[ElnFieldSetInfo] = self.eln_man.get_field_set_info_list()
|
|
132
|
+
progress_field_set: list[ElnFieldSetInfo] = [x for x in field_sets if
|
|
133
|
+
x.field_set_name == "Tool of Tools Progress"]
|
|
134
|
+
if not progress_field_set:
|
|
135
|
+
raise SapioException("Unable to locate the field set for the Tool of Tools progress.")
|
|
136
|
+
progress_entry_crit = ElnEntryCriteria(ElnEntryType.Form, f"ELaiN: {self.name} Progress",
|
|
137
|
+
ElnBaseDataType.EXPERIMENT_DETAIL.data_type_name, 1,
|
|
138
|
+
notebook_experiment_tab_id=tab.tab_id,
|
|
139
|
+
enb_field_set_id=progress_field_set[0].field_set_id)
|
|
140
|
+
progress_entry = ElnEntryStep(self._protocol,
|
|
141
|
+
self.eln_man.add_experiment_entry(self.exp_id, progress_entry_crit))
|
|
142
|
+
self.progress_entry = progress_entry
|
|
143
|
+
self.progress_record = progress_entry.get_records()[0]
|
|
144
|
+
|
|
145
|
+
# Hide the progress entry.
|
|
146
|
+
update_crit = ElnFormEntryUpdateCriteria()
|
|
147
|
+
update_crit.is_hidden = True
|
|
148
|
+
self.eln_man.update_experiment_entry(self.exp_id, progress_entry.get_id(), update_crit)
|
|
149
|
+
|
|
150
|
+
# Create a gauge entry to display the progress.
|
|
151
|
+
gauge_entry: ElnEntryStep = self._create_gauge_chart(self._protocol, progress_entry,
|
|
152
|
+
f"{self.name} Progress", "Progress")
|
|
153
|
+
self.progress_gauge_entry = gauge_entry
|
|
154
|
+
|
|
155
|
+
# Create the text entry that displays the description of the tool.
|
|
156
|
+
text_entry: ElnEntryStep = ELNStepFactory.create_text_entry(self._protocol, self.description)
|
|
157
|
+
self.description_entry = text_entry
|
|
158
|
+
|
|
159
|
+
# Create a results entry if this tool produces result records.
|
|
160
|
+
if self.results_data_type:
|
|
161
|
+
results_entry = ELNStepFactory.create_table_step(self._protocol, f"{self.name} Results", self.results_data_type)
|
|
162
|
+
self.results_entry = results_entry
|
|
163
|
+
else:
|
|
164
|
+
self.results_entry = None
|
|
165
|
+
|
|
166
|
+
return tab
|
|
167
|
+
|
|
168
|
+
def update_progress(self, progress: float, status_msg: str | None = None) -> None:
|
|
169
|
+
"""
|
|
170
|
+
Updates the progress of the tool.
|
|
171
|
+
|
|
172
|
+
:param progress: A value between 0 and 100 representing the progress of the tool.
|
|
173
|
+
:param status_msg: A status message to display to the user alongside the progress gauge.
|
|
174
|
+
"""
|
|
175
|
+
if not self._initialized:
|
|
176
|
+
raise SapioException("The tab for this tool has not been initialized.")
|
|
177
|
+
self.progress_record.set_field_value("Progress", progress)
|
|
178
|
+
self.progress_record.set_field_value("StatusMsg", status_msg)
|
|
179
|
+
self.dr_man.commit_data_records([self.progress_record])
|
|
180
|
+
|
|
181
|
+
def add_attachment_entry(self, file_name: str, file_data: str | bytes, entry_name: str,
|
|
182
|
+
tab: ElnExperimentTab | None = None) -> ExperimentEntry:
|
|
183
|
+
"""
|
|
184
|
+
Add a new attachment entry to the experiment with the provided attachment data.
|
|
185
|
+
|
|
186
|
+
:param file_name: The name of the attachment.
|
|
187
|
+
:param file_data: The data of the attachment. This can be a string or bytes.
|
|
188
|
+
:param entry_name: Name of the attachment entry to create in the experiment.
|
|
189
|
+
:param tab: The tab where the attachment will be added. If not provided, the tab initialized by this helper
|
|
190
|
+
will be used.
|
|
191
|
+
:return: The created entry object.
|
|
192
|
+
"""
|
|
193
|
+
# Check if the tab has been initialized or a tab has been provided.
|
|
194
|
+
if not self._initialized and tab is None:
|
|
195
|
+
raise SapioException("The tab for this tool has not been initialized. Either initialize a tab for this "
|
|
196
|
+
"tool or provide the tab to this function to add the attachment entry to.")
|
|
197
|
+
tab_id: int = self.tab.tab_id if tab is None else tab.tab_id
|
|
198
|
+
|
|
199
|
+
# Encode the file contents in base64.
|
|
200
|
+
if isinstance(file_data, str):
|
|
201
|
+
file_data: bytes = file_data.encode("utf-8")
|
|
202
|
+
base64_encoded: str = base64.b64encode(file_data).decode("utf-8")
|
|
203
|
+
|
|
204
|
+
# Crete an attachment entry with the provided data.
|
|
205
|
+
attachment_entry = self.eln_man.add_experiment_entry(
|
|
206
|
+
self.exp_id,
|
|
207
|
+
ElnEntryCriteria(ElnEntryType.Attachment, entry_name, "Attachment", order=2,
|
|
208
|
+
notebook_experiment_tab_id=tab_id, attachment_file_name=file_name,
|
|
209
|
+
attachment_data_base64=base64_encoded)
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
# Return the entry object for further use.
|
|
213
|
+
return attachment_entry
|
|
214
|
+
|
|
215
|
+
def add_attachment_entry_from_file_system(self, file_path: str, entry_name: str,
|
|
216
|
+
tab: ElnExperimentTab | None = None) -> ExperimentEntry:
|
|
217
|
+
"""
|
|
218
|
+
Add a new attachment entry to the experiment with the provided file path to a file in the file system.
|
|
219
|
+
|
|
220
|
+
:param file_path: The path to a file in the system to attach to the experiment.
|
|
221
|
+
:param entry_name: Name of the attachment entry to create in the experiment.
|
|
222
|
+
:param tab: The tab where the attachment will be added. If not provided, the tab initialized by this helper
|
|
223
|
+
will be used.
|
|
224
|
+
:return: The created entry object.
|
|
225
|
+
"""
|
|
226
|
+
# Check if the tab has been initialized or a tab has been provided.
|
|
227
|
+
# This is redundant with the same check in the add_attachment_entry function, but it's duplicated here as to
|
|
228
|
+
# not read the provided file and then find out we can't do anything with it anyway.
|
|
229
|
+
if not self._initialized and tab is None:
|
|
230
|
+
raise SapioException("The tab for this tool has not been initialized. Either initialize a tab for this "
|
|
231
|
+
"tool or provide the tab to this function to add the attachment entry to.")
|
|
232
|
+
|
|
233
|
+
with open(file_path, 'rb') as f:
|
|
234
|
+
file_contents: bytes = f.read()
|
|
235
|
+
return self.add_attachment_entry(file_path, file_contents, entry_name, tab)
|
|
236
|
+
|
|
237
|
+
# TODO: Remove this once pylib has a gauge chart function in ElnStepFactory.
|
|
238
|
+
@staticmethod
|
|
239
|
+
def _create_gauge_chart(protocol: ElnExperimentProtocol, data_source_step: ElnEntryStep, step_name: str,
|
|
240
|
+
field_name: str, group_by_field_name: str = "DataRecordName") -> ElnEntryStep:
|
|
241
|
+
"""
|
|
242
|
+
Create a gauge chart step in the experiment protocol.
|
|
243
|
+
"""
|
|
244
|
+
if not data_source_step.get_data_type_names():
|
|
245
|
+
raise ValueError("The data source step did not declare a data type name.")
|
|
246
|
+
data_type_name: str = data_source_step.get_data_type_names()[0]
|
|
247
|
+
series = GaugeChartSeries(data_type_name, field_name)
|
|
248
|
+
series.operation_type = ChartOperationType.VALUE
|
|
249
|
+
chart = _FixedGaugeChartDefinition()
|
|
250
|
+
chart.minimum_value = 0.
|
|
251
|
+
chart.maximum_value = 100.
|
|
252
|
+
chart.series_list = [series]
|
|
253
|
+
chart.grouping_type = ChartGroupingType.GROUP_BY_FIELD
|
|
254
|
+
chart.grouping_type_data_type_name = data_type_name
|
|
255
|
+
chart.grouping_type_data_field_name = group_by_field_name
|
|
256
|
+
dashboard, step = ELNStepFactory._create_dashboard_step_from_chart(chart, data_source_step, protocol, step_name)
|
|
257
|
+
protocol.invalidate()
|
|
258
|
+
return step
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
# TODO: This is only here because the get_chart_type function in pylib is wrong. Remove this once pylib is fixed.
|
|
262
|
+
class _FixedGaugeChartDefinition(GaugeChartDefinition):
|
|
263
|
+
def get_chart_type(self) -> ChartType:
|
|
264
|
+
return ChartType.GAUGE_CHART
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/callbacks/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/chem/Molecules.py
RENAMED
|
File without changes
|
{sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/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.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/datatype/__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
|
{sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/eln/plate_designer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/files/file_bridge.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/files/file_util.py
RENAMED
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/files/file_writer.py
RENAMED
|
File without changes
|
{sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/flowcyto/flow_cyto.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/general/aliases.py
RENAMED
|
File without changes
|
{sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/general/audit_log.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/general/exceptions.py
RENAMED
|
File without changes
|
{sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/src/sapiopycommons/general/popup_util.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/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
|
|
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.2.3a410 → sapiopycommons-2025.2.3a411}/tests/AF-A0A009IHW8-F1-model_v4.cif
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.2.3a410 → sapiopycommons-2025.2.3a411}/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.2.3a410 → sapiopycommons-2025.2.3a411}/tests/flowcyto/COVID19_W_001_O.fcs
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|