sapiopycommons 2025.2.6a417__py3-none-any.whl → 2025.2.6a418__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/elain/tool_of_tools.py +87 -3
- {sapiopycommons-2025.2.6a417.dist-info → sapiopycommons-2025.2.6a418.dist-info}/METADATA +1 -1
- {sapiopycommons-2025.2.6a417.dist-info → sapiopycommons-2025.2.6a418.dist-info}/RECORD +5 -5
- {sapiopycommons-2025.2.6a417.dist-info → sapiopycommons-2025.2.6a418.dist-info}/WHEEL +0 -0
- {sapiopycommons-2025.2.6a417.dist-info → sapiopycommons-2025.2.6a418.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import base64
|
|
2
2
|
from typing import Final, Mapping, Any
|
|
3
3
|
|
|
4
|
+
from pandas import DataFrame
|
|
4
5
|
from sapiopylib.rest.DataRecordManagerService import DataRecordManager
|
|
5
6
|
from sapiopylib.rest.ELNService import ElnManager
|
|
6
7
|
from sapiopylib.rest.User import SapioUser
|
|
@@ -8,6 +9,7 @@ from sapiopylib.rest.pojo.DataRecord import DataRecord
|
|
|
8
9
|
from sapiopylib.rest.pojo.chartdata.DashboardDefinition import GaugeChartDefinition
|
|
9
10
|
from sapiopylib.rest.pojo.chartdata.DashboardEnums import ChartGroupingType, ChartOperationType, ChartType
|
|
10
11
|
from sapiopylib.rest.pojo.chartdata.DashboardSeries import GaugeChartSeries
|
|
12
|
+
from sapiopylib.rest.pojo.datatype.FieldDefinition import AbstractVeloxFieldDefinition
|
|
11
13
|
from sapiopylib.rest.pojo.eln.ElnExperiment import ElnExperiment
|
|
12
14
|
from sapiopylib.rest.pojo.eln.ExperimentEntry import ExperimentEntry
|
|
13
15
|
from sapiopylib.rest.pojo.eln.ExperimentEntryCriteria import ElnEntryCriteria, ElnFormEntryUpdateCriteria, \
|
|
@@ -18,6 +20,7 @@ from sapiopylib.rest.pojo.eln.field_set import ElnFieldSetInfo
|
|
|
18
20
|
from sapiopylib.rest.utils.ProtocolUtils import ELNStepFactory
|
|
19
21
|
from sapiopylib.rest.utils.Protocols import ElnEntryStep, ElnExperimentProtocol
|
|
20
22
|
|
|
23
|
+
from sapiopycommons.callbacks.field_builder import FieldBuilder
|
|
21
24
|
from sapiopycommons.general.exceptions import SapioException
|
|
22
25
|
from sapiopycommons.general.time_util import TimeUtil
|
|
23
26
|
|
|
@@ -78,6 +81,86 @@ def format_tot_headers(headers: Mapping[str, str]) -> dict[str, str]:
|
|
|
78
81
|
return {k.lower(): v for k, v in headers.items()}
|
|
79
82
|
|
|
80
83
|
|
|
84
|
+
def create_experiment_details_from_data_frame(user: SapioUser,
|
|
85
|
+
exp_id: int,
|
|
86
|
+
entry_name: str,
|
|
87
|
+
tab: ElnExperimentTab,
|
|
88
|
+
df: DataFrame) -> ExperimentEntry | None:
|
|
89
|
+
"""
|
|
90
|
+
Create an experiment detail entry from a DataFrame.
|
|
91
|
+
|
|
92
|
+
:param user: The user to send the request from.
|
|
93
|
+
:param exp_id: The ID of the experiment to create the entry in.
|
|
94
|
+
:param entry_name: The name of the entry.
|
|
95
|
+
:param tab: The tab that the entry should be added to.
|
|
96
|
+
:param df: The DataFrame to create the entry from.
|
|
97
|
+
:return: The created entry object.
|
|
98
|
+
"""
|
|
99
|
+
json_list: list[dict[str, Any]] = []
|
|
100
|
+
for _, row in df.iterrows():
|
|
101
|
+
json_list.append(row.to_dict())
|
|
102
|
+
return create_experiment_details_from_json(user, exp_id, entry_name, tab, json_list)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def create_experiment_details_from_json(user: SapioUser,
|
|
106
|
+
exp_id: int,
|
|
107
|
+
entry_name: str,
|
|
108
|
+
tab: ElnExperimentTab,
|
|
109
|
+
json_list: list[dict[str, Any]]) -> ExperimentEntry | None:
|
|
110
|
+
"""
|
|
111
|
+
Create an experiment detail entry from a list of JSON dictionaries.
|
|
112
|
+
|
|
113
|
+
:param user: The user to send the request from.
|
|
114
|
+
:param exp_id: The ID of the experiment to create the entry in.
|
|
115
|
+
:param entry_name: The name of the entry.
|
|
116
|
+
:param tab: The tab that the entry should be added to.
|
|
117
|
+
:param json_list: The list of JSON dictionaries to create the entry from. Each dictionary is expected to have the
|
|
118
|
+
same keys.
|
|
119
|
+
:return: The created entry object.
|
|
120
|
+
"""
|
|
121
|
+
if not json_list:
|
|
122
|
+
return None
|
|
123
|
+
|
|
124
|
+
# Determine which fields in the JSON can be used to create field definitions.
|
|
125
|
+
fb = FieldBuilder()
|
|
126
|
+
fields: list[AbstractVeloxFieldDefinition] = []
|
|
127
|
+
valid_keys: list[str] = []
|
|
128
|
+
display_to_field_name: dict[str, str] = {}
|
|
129
|
+
for key, value in json_list[0].items():
|
|
130
|
+
field_name: str = key.replace(" ", "_")
|
|
131
|
+
display_to_field_name[key] = field_name
|
|
132
|
+
if isinstance(value, str):
|
|
133
|
+
fields.append(fb.string_field(field_name, display_name=key))
|
|
134
|
+
valid_keys.append(key)
|
|
135
|
+
elif isinstance(value, (int, float)):
|
|
136
|
+
fields.append(fb.double_field(field_name, display_name=key))
|
|
137
|
+
valid_keys.append(key)
|
|
138
|
+
|
|
139
|
+
# Extract the valid field values from the JSON.
|
|
140
|
+
field_maps: list[dict[str, Any]] = []
|
|
141
|
+
for json_dict in json_list:
|
|
142
|
+
field_map: dict[str, Any] = {}
|
|
143
|
+
for key in valid_keys:
|
|
144
|
+
field_map[display_to_field_name[key]] = json_dict.get(key)
|
|
145
|
+
field_maps.append(field_map)
|
|
146
|
+
|
|
147
|
+
detail_entry = ElnEntryCriteria(ElnEntryType.Table, entry_name,
|
|
148
|
+
ElnBaseDataType.EXPERIMENT_DETAIL.data_type_name,
|
|
149
|
+
tab_next_entry_order(user, exp_id, tab),
|
|
150
|
+
notebook_experiment_tab_id=tab.tab_id,
|
|
151
|
+
field_definition_list=fields)
|
|
152
|
+
entry = ElnManager(user).add_experiment_entry(exp_id, detail_entry)
|
|
153
|
+
DataRecordManager(user).add_data_records_with_data(entry.data_type_name, field_maps)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def tab_next_entry_order(user: SapioUser, exp_id: int, tab: ElnExperimentTab) -> int:
|
|
157
|
+
max_order: int = 0
|
|
158
|
+
for step in ElnExperimentProtocol(ElnExperiment(exp_id, "", 0), user).get_sorted_step_list():
|
|
159
|
+
if step.eln_entry.notebook_experiment_tab_id == tab.tab_id and step.eln_entry.order > max_order:
|
|
160
|
+
max_order = step.eln_entry.order
|
|
161
|
+
return max_order + 1
|
|
162
|
+
|
|
163
|
+
|
|
81
164
|
class ToolOfToolsHelper:
|
|
82
165
|
"""
|
|
83
166
|
A class with helper methods utilized by the Tool of Tools for the creation and updating of experiment tabs that
|
|
@@ -213,6 +296,7 @@ class ToolOfToolsHelper:
|
|
|
213
296
|
# Hide the progress entry.
|
|
214
297
|
form_update_crit = ElnFormEntryUpdateCriteria()
|
|
215
298
|
form_update_crit.is_hidden = True
|
|
299
|
+
self.eln_man.update_experiment_entry(self.exp_id, self.progress_entry.get_id(), form_update_crit)
|
|
216
300
|
|
|
217
301
|
# Create the text entry that displays the description of the tool. Include the timestamp of when the
|
|
218
302
|
# tool started and format the description so that the text isn't too small to read.
|
|
@@ -227,6 +311,7 @@ class ToolOfToolsHelper:
|
|
|
227
311
|
# Shrink the text entry by one column.
|
|
228
312
|
text_update_crit = _ElnTextEntryUpdateCriteria()
|
|
229
313
|
text_update_crit.column_span = 2
|
|
314
|
+
self.eln_man.update_experiment_entry(self.exp_id, self.description_entry.get_id(), text_update_crit)
|
|
230
315
|
|
|
231
316
|
# Create a gauge entry to display the progress.
|
|
232
317
|
gauge_entry: ElnEntryStep = self._create_gauge_chart(self._protocol, progress_entry,
|
|
@@ -238,15 +323,14 @@ class ToolOfToolsHelper:
|
|
|
238
323
|
dash_update_crit.entry_height = 250
|
|
239
324
|
dash_update_crit.column_span = 2
|
|
240
325
|
dash_update_crit.column_order = 2
|
|
326
|
+
self.eln_man.update_experiment_entry(self.exp_id, self.progress_gauge_entry.get_id(), dash_update_crit)
|
|
241
327
|
|
|
328
|
+
# TODO: Bulk updates aren't working?
|
|
242
329
|
# self.eln_man.update_experiment_entries(self.exp_id, {
|
|
243
330
|
# self.progress_entry.get_id(): form_update_crit,
|
|
244
331
|
# self.progress_gauge_entry.get_id(): dash_update_crit,
|
|
245
332
|
# self.description_entry.get_id(): text_update_crit
|
|
246
333
|
# })
|
|
247
|
-
self.eln_man.update_experiment_entry(self.exp_id, self.progress_entry.get_id(), form_update_crit)
|
|
248
|
-
self.eln_man.update_experiment_entry(self.exp_id, self.description_entry.get_id(), text_update_crit)
|
|
249
|
-
self.eln_man.update_experiment_entry(self.exp_id, self.progress_gauge_entry.get_id(), dash_update_crit)
|
|
250
334
|
|
|
251
335
|
# Create a results entry if this tool produces result records.
|
|
252
336
|
if self.results_data_type:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: sapiopycommons
|
|
3
|
-
Version: 2025.2.
|
|
3
|
+
Version: 2025.2.6a418
|
|
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>
|
|
@@ -15,7 +15,7 @@ sapiopycommons/datatype/attachment_util.py,sha256=_l2swuP8noIGAl4bwzBUEhr6YlN_OV
|
|
|
15
15
|
sapiopycommons/datatype/data_fields.py,sha256=C6HpqtEuF0KsxhlBUprfyv1XguaXql3EYWVbh8y-IFU,4064
|
|
16
16
|
sapiopycommons/datatype/pseudo_data_types.py,sha256=6TG7aJxgmUZ8FQkWBcgmbK5oy7AFFNtKOPpi1w1OOYA,27657
|
|
17
17
|
sapiopycommons/elain/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
-
sapiopycommons/elain/tool_of_tools.py,sha256=
|
|
18
|
+
sapiopycommons/elain/tool_of_tools.py,sha256=zYcvsTqLgVP91vf16FMVIJcQ7Wa58nUDMSfS1B9W47Y,24690
|
|
19
19
|
sapiopycommons/eln/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
20
|
sapiopycommons/eln/experiment_handler.py,sha256=8hmR7sawDo9K6iBwB44QSoxlH1M91inor7dfuXQ4LKs,69323
|
|
21
21
|
sapiopycommons/eln/experiment_report_util.py,sha256=EA2Iq8gW17bSEI6lPoHYQQ-fDvG4O28RWOoTPXpOlUw,36640
|
|
@@ -57,7 +57,7 @@ sapiopycommons/webhook/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
|
|
|
57
57
|
sapiopycommons/webhook/webhook_context.py,sha256=D793uLsb1691SalaPnBUk3rOSxn_hYLhdvkaIxjNXss,1909
|
|
58
58
|
sapiopycommons/webhook/webhook_handlers.py,sha256=M5PMt-j7PpnzUQMUQDTvqwJUyJNxuFtC9wdnk5VRNpI,39703
|
|
59
59
|
sapiopycommons/webhook/webservice_handlers.py,sha256=Y5dHx_UFWFuSqaoPL6Re-fsKYRuxvCWZ8bj6KSZ3jfM,14285
|
|
60
|
-
sapiopycommons-2025.2.
|
|
61
|
-
sapiopycommons-2025.2.
|
|
62
|
-
sapiopycommons-2025.2.
|
|
63
|
-
sapiopycommons-2025.2.
|
|
60
|
+
sapiopycommons-2025.2.6a418.dist-info/METADATA,sha256=ybJdIh2Y18kYi7HOgROF0yXvJGIX9wSweV5ICol4BWg,3142
|
|
61
|
+
sapiopycommons-2025.2.6a418.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
|
|
62
|
+
sapiopycommons-2025.2.6a418.dist-info/licenses/LICENSE,sha256=HyVuytGSiAUQ6ErWBHTqt1iSGHhLmlC8fO7jTCuR8dU,16725
|
|
63
|
+
sapiopycommons-2025.2.6a418.dist-info/RECORD,,
|
|
File without changes
|
{sapiopycommons-2025.2.6a417.dist-info → sapiopycommons-2025.2.6a418.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|