sapiopycommons 2025.4.17a486__tar.gz → 2025.4.17a488__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.4.17a486 → sapiopycommons-2025.4.17a488}/PKG-INFO +1 -1
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/pyproject.toml +1 -1
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/eln/experiment_handler.py +100 -208
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/general/aliases.py +0 -2
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/.gitignore +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/LICENSE +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/README.md +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/__init__.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/callbacks/__init__.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/callbacks/callback_util.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/callbacks/field_builder.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/chem/IndigoMolecules.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/chem/Molecules.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/chem/__init__.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/customreport/__init__.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/customreport/auto_pagers.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/customreport/column_builder.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/customreport/custom_report_builder.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/customreport/term_builder.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/datatype/__init__.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/datatype/attachment_util.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/datatype/data_fields.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/datatype/pseudo_data_types.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/eln/__init__.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/eln/experiment_cache.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/eln/experiment_report_util.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/eln/experiment_step_factory.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/eln/experiment_tags.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/eln/plate_designer.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/eln/step_creation.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/files/__init__.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/files/complex_data_loader.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/files/file_bridge.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/files/file_bridge_handler.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/files/file_data_handler.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/files/file_util.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/files/file_validator.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/files/file_writer.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/flowcyto/flow_cyto.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/flowcyto/flowcyto_data.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/general/__init__.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/general/accession_service.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/general/audit_log.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/general/custom_report_util.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/general/data_structure_util.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/general/directive_util.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/general/exceptions.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/general/popup_util.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/general/sapio_links.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/general/storage_util.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/general/time_util.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/multimodal/multimodal.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/multimodal/multimodal_data.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/processtracking/__init__.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/processtracking/custom_workflow_handler.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/processtracking/endpoints.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/recordmodel/__init__.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/recordmodel/record_handler.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/rules/__init__.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/rules/eln_rule_handler.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/rules/on_save_rule_handler.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/samples/aliquot.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/sftpconnect/__init__.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/sftpconnect/sftp_builder.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/webhook/__init__.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/webhook/webhook_context.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/webhook/webhook_handlers.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/webhook/webservice_handlers.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/tests/AF-A0A009IHW8-F1-model_v4.cif +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/tests/_do_not_add_init_py_here +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/tests/accession_test.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/tests/aliquot_test.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/tests/bio_reg_test.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/tests/chem_test.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/tests/chem_test_curation_queue.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/tests/curation_queue_test.sdf +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/tests/data_type_models.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/tests/flowcyto/101_DEN084Y5_15_E01_008_clean.fcs +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/tests/flowcyto/101_DEN084Y5_15_E03_009_clean.fcs +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/tests/flowcyto/101_DEN084Y5_15_E05_010_clean.fcs +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/tests/flowcyto/8_color_ICS.wsp +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/tests/flowcyto/COVID19_W_001_O.fcs +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/tests/flowcyto_test.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/tests/kappa.chains.fasta +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/tests/mafft_test.py +0 -0
- {sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/tests/test.gb +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: sapiopycommons
|
|
3
|
-
Version: 2025.4.
|
|
3
|
+
Version: 2025.4.17a488
|
|
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>
|
|
@@ -8,7 +8,7 @@ from weakref import WeakValueDictionary
|
|
|
8
8
|
from sapiopycommons.eln.experiment_cache import ExperimentCacheManager
|
|
9
9
|
from sapiopycommons.eln.experiment_report_util import ExperimentReportUtil
|
|
10
10
|
from sapiopycommons.general.aliases import AliasUtil, SapioRecord, ExperimentIdentifier, UserIdentifier, \
|
|
11
|
-
DataTypeIdentifier, RecordModel, ExperimentEntryIdentifier
|
|
11
|
+
DataTypeIdentifier, RecordModel, ExperimentEntryIdentifier
|
|
12
12
|
from sapiopycommons.general.exceptions import SapioException
|
|
13
13
|
from sapiopycommons.general.time_util import TimeUtil
|
|
14
14
|
from sapiopycommons.recordmodel.record_handler import RecordHandler
|
|
@@ -40,8 +40,11 @@ from sapiopylib.rest.utils.recordmodel.RecordModelWrapper import WrappedType
|
|
|
40
40
|
from sapiopylib.rest.utils.recordmodel.properties import Child
|
|
41
41
|
|
|
42
42
|
Step: TypeAlias = str | ExperimentEntryIdentifier
|
|
43
|
-
"""An object representing an identifier to an
|
|
44
|
-
|
|
43
|
+
"""An object representing an identifier to an entry in a particular experiment. This may be the name of the experiment,
|
|
44
|
+
or a typical experiment entry identifier."""
|
|
45
|
+
Tab: TypeAlias = int | str | ElnExperimentTab
|
|
46
|
+
"""An object representing an identifier to a tab in a particular experiment. This may be the tab's order, its name,
|
|
47
|
+
or the tab object itself."""
|
|
45
48
|
|
|
46
49
|
|
|
47
50
|
# FR-46064 - Initial port of PyWebhookUtils to sapiopycommons.
|
|
@@ -686,7 +689,7 @@ class ExperimentHandler:
|
|
|
686
689
|
# Re-sort the steps in case any new steps were added before the last time that this was called.
|
|
687
690
|
def sort_steps(step: ElnEntryStep) -> tuple:
|
|
688
691
|
entry = step.eln_entry
|
|
689
|
-
tab_order: int = self.
|
|
692
|
+
tab_order: int = self.get_tab_for_step(step).tab_order
|
|
690
693
|
entry_order: int = entry.order
|
|
691
694
|
column_order: int = entry.column_order
|
|
692
695
|
return tab_order, entry_order, column_order
|
|
@@ -1114,128 +1117,45 @@ class ExperimentHandler:
|
|
|
1114
1117
|
If you wish to add options to the existing map of options that an entry has, use the
|
|
1115
1118
|
add_step_options method.
|
|
1116
1119
|
"""
|
|
1117
|
-
# FR-47468: Deprecating this since the
|
|
1118
|
-
|
|
1119
|
-
warnings.warn("Update step is deprecated. Use force_entry_update_params instead.",
|
|
1120
|
+
# FR-47468: Deprecating this since the entry-specific update criteria should be used instead.
|
|
1121
|
+
warnings.warn("Update step is deprecated. Use force_entry_update instead.",
|
|
1120
1122
|
DeprecationWarning)
|
|
1121
|
-
self.
|
|
1122
|
-
|
|
1123
|
-
related_entry_set=related_entry_set,
|
|
1124
|
-
dependency_set=dependency_set,
|
|
1125
|
-
entry_status=entry_status,
|
|
1126
|
-
order=order,
|
|
1127
|
-
description=description,
|
|
1128
|
-
requires_grabber_plugin=requires_grabber_plugin,
|
|
1129
|
-
is_initialization_required=is_initialization_required,
|
|
1130
|
-
notebook_experiment_tab_id=notebook_experiment_tab_id,
|
|
1131
|
-
entry_height=entry_height,
|
|
1132
|
-
column_order=column_order,
|
|
1133
|
-
column_span=column_span,
|
|
1134
|
-
is_removable=is_removable,
|
|
1135
|
-
is_renamable=is_renamable,
|
|
1136
|
-
source_entry_id=source_entry_id,
|
|
1137
|
-
clear_source_entry_id=clear_source_entry_id,
|
|
1138
|
-
is_hidden=is_hidden,
|
|
1139
|
-
is_static_view=is_static_View,
|
|
1140
|
-
is_shown_in_template=is_shown_in_template,
|
|
1141
|
-
template_item_fulfilled_timestamp=template_item_fulfilled_timestamp,
|
|
1142
|
-
clear_template_item_fulfilled_timestamp=clear_template_item_fulfilled_timestamp,
|
|
1143
|
-
entry_options_map=entry_options_map)
|
|
1144
|
-
|
|
1145
|
-
# FR-47468: Some functions that can help with entry updates.
|
|
1146
|
-
def force_step_update_params(self, step: Step, *,
|
|
1147
|
-
entry_name: str | None = None,
|
|
1148
|
-
related_entry_set: Iterable[int] | None = None,
|
|
1149
|
-
dependency_set: Iterable[int] | None = None,
|
|
1150
|
-
entry_status: ExperimentEntryStatus | None = None,
|
|
1151
|
-
order: int | None = None,
|
|
1152
|
-
description: str | None = None,
|
|
1153
|
-
requires_grabber_plugin: bool | None = None,
|
|
1154
|
-
is_initialization_required: bool | None = None,
|
|
1155
|
-
notebook_experiment_tab_id: int | None = None,
|
|
1156
|
-
entry_height: int | None = None,
|
|
1157
|
-
column_order: int | None = None,
|
|
1158
|
-
column_span: int | None = None,
|
|
1159
|
-
is_removable: bool | None = None,
|
|
1160
|
-
is_renamable: bool | None = None,
|
|
1161
|
-
source_entry_id: int | None = None,
|
|
1162
|
-
clear_source_entry_id: bool | None = None,
|
|
1163
|
-
is_hidden: bool | None = None,
|
|
1164
|
-
is_static_view: bool | None = None,
|
|
1165
|
-
is_shown_in_template: bool | None = None,
|
|
1166
|
-
template_item_fulfilled_timestamp: int | None = None,
|
|
1167
|
-
clear_template_item_fulfilled_timestamp: bool | None = None,
|
|
1168
|
-
entry_options_map: dict[str, str] | None = None) -> None:
|
|
1169
|
-
"""
|
|
1170
|
-
Immediately sent an update to an entry in this experiment. All changes will be reflected by the ExperimentEntry
|
|
1171
|
-
of the Step that is being updated.
|
|
1123
|
+
step: ElnEntryStep = self.__to_eln_step(step)
|
|
1124
|
+
update = AbstractElnEntryUpdateCriteria(step.eln_entry.entry_type)
|
|
1172
1125
|
|
|
1173
|
-
|
|
1126
|
+
# These two variables could be iterables that aren't lists. Convert them to plain
|
|
1127
|
+
# lists, since that's what the update criteria is expecting.
|
|
1128
|
+
if related_entry_set is not None:
|
|
1129
|
+
related_entry_set = list(related_entry_set)
|
|
1130
|
+
if dependency_set is not None:
|
|
1131
|
+
dependency_set = list(dependency_set)
|
|
1174
1132
|
|
|
1175
|
-
|
|
1176
|
-
|
|
1133
|
+
update.entry_name = entry_name
|
|
1134
|
+
update.related_entry_set = related_entry_set
|
|
1135
|
+
update.dependency_set = dependency_set
|
|
1136
|
+
update.entry_status = entry_status
|
|
1137
|
+
update.order = order
|
|
1138
|
+
update.description = description
|
|
1139
|
+
update.requires_grabber_plugin = requires_grabber_plugin
|
|
1140
|
+
update.is_initialization_required = is_initialization_required
|
|
1141
|
+
update.notebook_experiment_tab_id = notebook_experiment_tab_id
|
|
1142
|
+
update.entry_height = entry_height
|
|
1143
|
+
update.column_order = column_order
|
|
1144
|
+
update.column_span = column_span
|
|
1145
|
+
update.is_removable = is_removable
|
|
1146
|
+
update.is_renamable = is_renamable
|
|
1147
|
+
update.source_entry_id = source_entry_id
|
|
1148
|
+
update.clear_source_entry_id = clear_source_entry_id
|
|
1149
|
+
update.is_hidden = is_hidden
|
|
1150
|
+
update.is_static_View = is_static_View
|
|
1151
|
+
update.is_shown_in_template = is_shown_in_template
|
|
1152
|
+
update.template_item_fulfilled_timestamp = template_item_fulfilled_timestamp
|
|
1153
|
+
update.clear_template_item_fulfilled_timestamp = clear_template_item_fulfilled_timestamp
|
|
1154
|
+
update.entry_options_map = entry_options_map
|
|
1177
1155
|
|
|
1178
|
-
:param step:
|
|
1179
|
-
The entry step to update.
|
|
1180
|
-
The step may be provided as either a string for the name of the step or an ElnEntryStep.
|
|
1181
|
-
If given a name, throws an exception if no step of the given name exists in the experiment.
|
|
1182
|
-
:param entry_name: The new name of this entry.
|
|
1183
|
-
:param related_entry_set: The new set of entry IDs for the entries that are related (implicitly dependent) to
|
|
1184
|
-
this entry. Completely overwrites the existing related entries.
|
|
1185
|
-
:param dependency_set: The new set of entry IDs for the entries that are dependent (explicitly dependent) on
|
|
1186
|
-
this entry. Completely overwrites the existing dependent entries.
|
|
1187
|
-
:param entry_status: The new status of this entry.
|
|
1188
|
-
:param order: The row order of this entry in its tab.
|
|
1189
|
-
:param description: The new description of this entry.
|
|
1190
|
-
:param requires_grabber_plugin: Whether this entry's initialization is handled by a grabber plugin. If true,
|
|
1191
|
-
then is_initialization_required is forced to true by the server.
|
|
1192
|
-
:param is_initialization_required: Whether the user is required to manually initialize this entry.
|
|
1193
|
-
:param notebook_experiment_tab_id: The ID of the tab that this entry should appear on.
|
|
1194
|
-
:param entry_height: The height of this entry.
|
|
1195
|
-
:param column_order: The column order of this entry.
|
|
1196
|
-
:param column_span: How many columns this entry spans.
|
|
1197
|
-
:param is_removable: Whether this entry can be removed by the user.
|
|
1198
|
-
:param is_renamable: Whether this entry can be renamed by the user.
|
|
1199
|
-
:param source_entry_id: The ID of this entry from its template.
|
|
1200
|
-
:param clear_source_entry_id: True if the source entry ID should be cleared.
|
|
1201
|
-
:param is_hidden: Whether this entry is hidden from the user.
|
|
1202
|
-
:param is_static_view: Whether this entry is static. Static entries are uneditable and shared across all
|
|
1203
|
-
experiments of the same template.
|
|
1204
|
-
:param is_shown_in_template: Whether this entry is saved to and shown in the experiment's template.
|
|
1205
|
-
:param template_item_fulfilled_timestamp: A timestamp in milliseconds for when this entry was initialized.
|
|
1206
|
-
:param clear_template_item_fulfilled_timestamp: True if the template item fulfilled timestamp should be cleared,
|
|
1207
|
-
uninitializing the entry.
|
|
1208
|
-
:param entry_options_map:
|
|
1209
|
-
The new map of options for this entry. Completely overwrites the existing options map.
|
|
1210
|
-
Any changes to the entry options will update this ExperimentHandler's cache of entry options.
|
|
1211
|
-
If you wish to add options to the existing map of options that an entry has, use the
|
|
1212
|
-
add_step_options method.
|
|
1213
|
-
"""
|
|
1214
|
-
update = self._criteria_from_params(step,
|
|
1215
|
-
entry_name=entry_name,
|
|
1216
|
-
related_entry_set=related_entry_set,
|
|
1217
|
-
dependency_set=dependency_set,
|
|
1218
|
-
entry_status=entry_status,
|
|
1219
|
-
order=order,
|
|
1220
|
-
description=description,
|
|
1221
|
-
requires_grabber_plugin=requires_grabber_plugin,
|
|
1222
|
-
is_initialization_required=is_initialization_required,
|
|
1223
|
-
notebook_experiment_tab_id=notebook_experiment_tab_id,
|
|
1224
|
-
entry_height=entry_height,
|
|
1225
|
-
column_order=column_order,
|
|
1226
|
-
column_span=column_span,
|
|
1227
|
-
is_removable=is_removable,
|
|
1228
|
-
is_renamable=is_renamable,
|
|
1229
|
-
source_entry_id=source_entry_id,
|
|
1230
|
-
clear_source_entry_id=clear_source_entry_id,
|
|
1231
|
-
is_hidden=is_hidden,
|
|
1232
|
-
is_static_view=is_static_view,
|
|
1233
|
-
is_shown_in_template=is_shown_in_template,
|
|
1234
|
-
template_item_fulfilled_timestamp=template_item_fulfilled_timestamp,
|
|
1235
|
-
clear_template_item_fulfilled_timestamp=clear_template_item_fulfilled_timestamp,
|
|
1236
|
-
entry_options_map=entry_options_map)
|
|
1237
1156
|
self.force_step_update(step, update)
|
|
1238
1157
|
|
|
1158
|
+
# FR-47468: Some functions that can help with entry updates.
|
|
1239
1159
|
def force_step_update(self, step: Step, update: AbstractElnEntryUpdateCriteria) -> None:
|
|
1240
1160
|
"""
|
|
1241
1161
|
Immediately sent an update to an entry in this experiment. All changes will be reflected by the ExperimentEntry
|
|
@@ -1307,67 +1227,6 @@ class ExperimentHandler:
|
|
|
1307
1227
|
self._update_entry_details(self._steps_by_id[step_id], criteria)
|
|
1308
1228
|
self._step_updates.clear()
|
|
1309
1229
|
|
|
1310
|
-
def _criteria_from_params(self, step: Step, *,
|
|
1311
|
-
entry_name: str | None = None,
|
|
1312
|
-
related_entry_set: Iterable[int] | None = None,
|
|
1313
|
-
dependency_set: Iterable[int] | None = None,
|
|
1314
|
-
entry_status: ExperimentEntryStatus | None = None,
|
|
1315
|
-
order: int | None = None,
|
|
1316
|
-
description: str | None = None,
|
|
1317
|
-
requires_grabber_plugin: bool | None = None,
|
|
1318
|
-
is_initialization_required: bool | None = None,
|
|
1319
|
-
notebook_experiment_tab_id: int | None = None,
|
|
1320
|
-
entry_height: int | None = None,
|
|
1321
|
-
column_order: int | None = None,
|
|
1322
|
-
column_span: int | None = None,
|
|
1323
|
-
is_removable: bool | None = None,
|
|
1324
|
-
is_renamable: bool | None = None,
|
|
1325
|
-
source_entry_id: int | None = None,
|
|
1326
|
-
clear_source_entry_id: bool | None = None,
|
|
1327
|
-
is_hidden: bool | None = None,
|
|
1328
|
-
is_static_view: bool | None = None,
|
|
1329
|
-
is_shown_in_template: bool | None = None,
|
|
1330
|
-
template_item_fulfilled_timestamp: int | None = None,
|
|
1331
|
-
clear_template_item_fulfilled_timestamp: bool | None = None,
|
|
1332
|
-
entry_options_map: dict[str, str] | None = None) -> AbstractElnEntryUpdateCriteria:
|
|
1333
|
-
"""
|
|
1334
|
-
Create an abstract update criteria object from the provided parameters for the given step.
|
|
1335
|
-
"""
|
|
1336
|
-
step: ElnEntryStep = self.__to_eln_step(step)
|
|
1337
|
-
update = AbstractElnEntryUpdateCriteria(step.eln_entry.entry_type)
|
|
1338
|
-
|
|
1339
|
-
# These two variables could be iterables that aren't lists. Convert them to plain
|
|
1340
|
-
# lists, since that's what the update criteria is expecting.
|
|
1341
|
-
if related_entry_set is not None:
|
|
1342
|
-
related_entry_set = list(related_entry_set)
|
|
1343
|
-
if dependency_set is not None:
|
|
1344
|
-
dependency_set = list(dependency_set)
|
|
1345
|
-
|
|
1346
|
-
update.entry_name = entry_name
|
|
1347
|
-
update.related_entry_set = related_entry_set
|
|
1348
|
-
update.dependency_set = dependency_set
|
|
1349
|
-
update.entry_status = entry_status
|
|
1350
|
-
update.order = order
|
|
1351
|
-
update.description = description
|
|
1352
|
-
update.requires_grabber_plugin = requires_grabber_plugin
|
|
1353
|
-
update.is_initialization_required = is_initialization_required
|
|
1354
|
-
update.notebook_experiment_tab_id = notebook_experiment_tab_id
|
|
1355
|
-
update.entry_height = entry_height
|
|
1356
|
-
update.column_order = column_order
|
|
1357
|
-
update.column_span = column_span
|
|
1358
|
-
update.is_removable = is_removable
|
|
1359
|
-
update.is_renamable = is_renamable
|
|
1360
|
-
update.source_entry_id = source_entry_id
|
|
1361
|
-
update.clear_source_entry_id = clear_source_entry_id
|
|
1362
|
-
update.is_hidden = is_hidden
|
|
1363
|
-
update.is_static_View = is_static_view
|
|
1364
|
-
update.is_shown_in_template = is_shown_in_template
|
|
1365
|
-
update.template_item_fulfilled_timestamp = template_item_fulfilled_timestamp
|
|
1366
|
-
update.clear_template_item_fulfilled_timestamp = clear_template_item_fulfilled_timestamp
|
|
1367
|
-
update.entry_options_map = entry_options_map
|
|
1368
|
-
|
|
1369
|
-
return update
|
|
1370
|
-
|
|
1371
1230
|
@staticmethod
|
|
1372
1231
|
def _merge_updates(new_update: AbstractElnEntryUpdateCriteria, old_update: AbstractElnEntryUpdateCriteria) -> None:
|
|
1373
1232
|
"""
|
|
@@ -1552,12 +1411,14 @@ class ExperimentHandler:
|
|
|
1552
1411
|
The step may be provided as either a string for the name of the step or an ElnEntryStep.
|
|
1553
1412
|
If given a name, throws an exception if no step of the given name exists in the experiment.
|
|
1554
1413
|
:param mapping: The new options and values to add to the existing step options, provided as some Mapping
|
|
1555
|
-
(e.g. a
|
|
1556
|
-
for that key.
|
|
1414
|
+
(e.g. a dictionary). If an option key already exists and is provided in the mapping, overwrites the existing
|
|
1415
|
+
value for that key.
|
|
1557
1416
|
"""
|
|
1558
1417
|
options: dict[str, str] = self.get_step_options(step)
|
|
1559
1418
|
options.update(mapping)
|
|
1560
|
-
|
|
1419
|
+
update = AbstractElnEntryUpdateCriteria(step.eln_entry.entry_type)
|
|
1420
|
+
update.entry_options_map = options
|
|
1421
|
+
self.force_step_update(step, update)
|
|
1561
1422
|
|
|
1562
1423
|
def initialize_step(self, step: Step) -> None:
|
|
1563
1424
|
"""
|
|
@@ -1575,7 +1436,9 @@ class ExperimentHandler:
|
|
|
1575
1436
|
# Avoid unnecessary calls if the step is already initialized.
|
|
1576
1437
|
step: ElnEntryStep = self.__to_eln_step(step)
|
|
1577
1438
|
if step.eln_entry.template_item_fulfilled_timestamp is None:
|
|
1578
|
-
|
|
1439
|
+
update = AbstractElnEntryUpdateCriteria(step.eln_entry.entry_type)
|
|
1440
|
+
update.template_item_fulfilled_timestamp = TimeUtil.now_in_millis()
|
|
1441
|
+
self.force_step_update(step, update)
|
|
1579
1442
|
|
|
1580
1443
|
def uninitialize_step(self, step: Step) -> None:
|
|
1581
1444
|
"""
|
|
@@ -1593,7 +1456,9 @@ class ExperimentHandler:
|
|
|
1593
1456
|
# Avoid unnecessary calls if the step is already uninitialized.
|
|
1594
1457
|
step: ElnEntryStep = self.__to_eln_step(step)
|
|
1595
1458
|
if step.eln_entry.template_item_fulfilled_timestamp is not None:
|
|
1596
|
-
|
|
1459
|
+
update = AbstractElnEntryUpdateCriteria(step.eln_entry.entry_type)
|
|
1460
|
+
update.clear_template_item_fulfilled_timestamp = True
|
|
1461
|
+
self.force_step_update(step, update)
|
|
1597
1462
|
|
|
1598
1463
|
def complete_step(self, step: Step) -> None:
|
|
1599
1464
|
"""
|
|
@@ -1650,7 +1515,9 @@ class ExperimentHandler:
|
|
|
1650
1515
|
"""
|
|
1651
1516
|
step = self.__to_eln_step(step)
|
|
1652
1517
|
if step.eln_entry.entry_status in self._ENTRY_LOCKED_STATUSES:
|
|
1653
|
-
|
|
1518
|
+
update = AbstractElnEntryUpdateCriteria(step.eln_entry.entry_type)
|
|
1519
|
+
update.entry_status = ExperimentEntryStatus.Disabled
|
|
1520
|
+
self.force_step_update(step, update)
|
|
1654
1521
|
|
|
1655
1522
|
def step_is_submitted(self, step: Step) -> bool:
|
|
1656
1523
|
"""
|
|
@@ -1728,28 +1595,33 @@ class ExperimentHandler:
|
|
|
1728
1595
|
self.add_tab_to_cache(tab)
|
|
1729
1596
|
return tab
|
|
1730
1597
|
|
|
1731
|
-
def get_tab(self,
|
|
1598
|
+
def get_tab(self, tab: str | int, exception_on_none: bool = True) -> ElnExperimentTab:
|
|
1732
1599
|
"""
|
|
1733
1600
|
Return the tab with the input name.
|
|
1734
1601
|
|
|
1735
1602
|
If no tab functions have been called before and a tab is being searched for by name, queries for the
|
|
1736
1603
|
list of tabs in the experiment and caches them.
|
|
1737
1604
|
|
|
1738
|
-
:param
|
|
1605
|
+
:param tab: The name or order of the tab to get. The order is 1-indexed.
|
|
1739
1606
|
:param exception_on_none: If True, raises an exception if no tab with the given name exists.
|
|
1740
1607
|
:return: The tab with the input name, or None if no such tab exists.
|
|
1741
1608
|
"""
|
|
1742
|
-
if
|
|
1743
|
-
self.
|
|
1744
|
-
|
|
1745
|
-
|
|
1609
|
+
if isinstance(tab, str):
|
|
1610
|
+
if tab not in self._tabs_by_name:
|
|
1611
|
+
self.get_all_tabs()
|
|
1612
|
+
eln_tab = self._tabs_by_name.get(tab)
|
|
1613
|
+
elif isinstance(tab, int):
|
|
1614
|
+
# The given integer is expected to be 1-indexed, but we read from the list with a 0-index.
|
|
1615
|
+
tab -= 1
|
|
1616
|
+
tabs = self.get_all_tabs()
|
|
1617
|
+
eln_tab = tabs[tab] if len(tabs) > tab else None
|
|
1746
1618
|
else:
|
|
1747
|
-
|
|
1748
|
-
if
|
|
1749
|
-
raise SapioException(f"No tab with the name\\
|
|
1750
|
-
return
|
|
1619
|
+
raise SapioException(f"Tab must be a string or an integer, not {type(tab)}.")
|
|
1620
|
+
if eln_tab is None and exception_on_none:
|
|
1621
|
+
raise SapioException(f"No tab with the name\\order \"{tab}\" exists in this experiment.")
|
|
1622
|
+
return eln_tab
|
|
1751
1623
|
|
|
1752
|
-
def get_steps_in_tab(self, tab:
|
|
1624
|
+
def get_steps_in_tab(self, tab: Tab, data_type: DataTypeIdentifier | None = None) \
|
|
1753
1625
|
-> list[ElnEntryStep]:
|
|
1754
1626
|
"""
|
|
1755
1627
|
Get all the steps in the input tab sorted in order of appearance.
|
|
@@ -1760,8 +1632,8 @@ class ExperimentHandler:
|
|
|
1760
1632
|
If the steps in the experiment have not been queried before, queries for the list of steps in the experiment
|
|
1761
1633
|
and caches them.
|
|
1762
1634
|
|
|
1763
|
-
:param tab: The tab to get the steps of. This can be
|
|
1764
|
-
|
|
1635
|
+
:param tab: The tab to get the steps of. This can be the tab's order, name, or the tab object itself.
|
|
1636
|
+
The order is 1-indexed.
|
|
1765
1637
|
:param data_type: The data type to filter the steps by. If None, all steps are returned.
|
|
1766
1638
|
:return: A list of all the steps in the input tab sorted in order of appearance.
|
|
1767
1639
|
"""
|
|
@@ -1772,7 +1644,29 @@ class ExperimentHandler:
|
|
|
1772
1644
|
steps.append(step)
|
|
1773
1645
|
return steps
|
|
1774
1646
|
|
|
1775
|
-
def
|
|
1647
|
+
def get_tab_for_step(self, step: Step) -> ElnExperimentTab:
|
|
1648
|
+
"""
|
|
1649
|
+
Get the tab that a particular step is located in.
|
|
1650
|
+
|
|
1651
|
+
If no tab functions have been called before and a tab is being searched for by name, queries for the
|
|
1652
|
+
list of tabs in the experiment and caches them.
|
|
1653
|
+
|
|
1654
|
+
If the steps in the experiment have not been queried before, queries for the list of steps in the experiment
|
|
1655
|
+
and caches them.
|
|
1656
|
+
|
|
1657
|
+
:param step:
|
|
1658
|
+
The step to get the position of.
|
|
1659
|
+
The step may be provided as either a string for the name of the step or an ElnEntryStep.
|
|
1660
|
+
If given a name, throws an exception if no step of the given name exists in the experiment.
|
|
1661
|
+
:return: The tab that the input step is located in.
|
|
1662
|
+
"""
|
|
1663
|
+
step = self.__to_eln_step(step)
|
|
1664
|
+
tab_id = step.eln_entry.notebook_experiment_tab_id
|
|
1665
|
+
if tab_id not in self._tabs_by_id:
|
|
1666
|
+
self.get_all_tabs()
|
|
1667
|
+
return self._tabs_by_id.get(tab_id)
|
|
1668
|
+
|
|
1669
|
+
def get_next_entry_order_in_tab(self, tab: Tab) -> int:
|
|
1776
1670
|
"""
|
|
1777
1671
|
Get the next available order for a new entry in the input tab.
|
|
1778
1672
|
|
|
@@ -1782,8 +1676,8 @@ class ExperimentHandler:
|
|
|
1782
1676
|
If the steps in the experiment have not been queried before, queries for the list of steps in the experiment
|
|
1783
1677
|
and caches them.
|
|
1784
1678
|
|
|
1785
|
-
:param tab: The tab to get the
|
|
1786
|
-
|
|
1679
|
+
:param tab: The tab to get the steps of. This can be the tab's order, name, or the tab object itself.
|
|
1680
|
+
The order is 1-indexed.
|
|
1787
1681
|
:return: The next available order for a new entry in the input tab.
|
|
1788
1682
|
"""
|
|
1789
1683
|
steps = self.get_steps_in_tab(tab)
|
|
@@ -1863,16 +1757,14 @@ class ExperimentHandler:
|
|
|
1863
1757
|
return self.add_entry_to_caches(step)
|
|
1864
1758
|
return step
|
|
1865
1759
|
|
|
1866
|
-
def __to_eln_tab(self, tab:
|
|
1760
|
+
def __to_eln_tab(self, tab: Tab) -> ElnExperimentTab:
|
|
1867
1761
|
"""
|
|
1868
|
-
Convert a variable that could be either a
|
|
1762
|
+
Convert a variable that could be either a tab name, tab order, or ElnExperimentTab to just a tab object.
|
|
1869
1763
|
This will query and cache the tabs for the experiment if the input tab is a name and the tabs have not been
|
|
1870
1764
|
cached before.
|
|
1871
1765
|
|
|
1872
1766
|
:return: The input tab as an ElnExperimentTab.
|
|
1873
1767
|
"""
|
|
1874
|
-
if isinstance(tab,
|
|
1768
|
+
if not isinstance(tab, ElnExperimentTab):
|
|
1875
1769
|
return self.get_tab(tab)
|
|
1876
|
-
if isinstance(tab, int):
|
|
1877
|
-
return [x for x in self._tabs if x.tab_id == tab][0]
|
|
1878
1770
|
return tab
|
{sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/general/aliases.py
RENAMED
|
@@ -38,8 +38,6 @@ ExperimentIdentifier: TypeAlias = ElnExperimentProtocol | ElnExperiment | int
|
|
|
38
38
|
ID."""
|
|
39
39
|
ExperimentEntryIdentifier: TypeAlias = ElnEntryStep | ExperimentEntry | int
|
|
40
40
|
"""An ExperimentEntryIdentifier is either an ELN entry step, experiment entry, or an integer for the entry's ID."""
|
|
41
|
-
TabIdentifier: TypeAlias = int | ElnExperimentTab
|
|
42
|
-
"""A TabIdentifier is either an integer for the tab's ID or an ElnExperimentTab object."""
|
|
43
41
|
FieldMap: TypeAlias = dict[str, FieldValue]
|
|
44
42
|
"""A field map is simply a dict of data field names to values. The purpose of aliasing this is to help distinguish
|
|
45
43
|
any random dict in a webhook from one which is explicitly used for record fields."""
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/chem/Molecules.py
RENAMED
|
File without changes
|
{sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/chem/__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
|
{sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/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.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/files/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/files/file_util.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/general/__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
|
{sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/rules/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/samples/aliquot.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/src/sapiopycommons/webhook/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/tests/AF-A0A009IHW8-F1-model_v4.cif
RENAMED
|
File without changes
|
{sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/tests/_do_not_add_init_py_here
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/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
|
{sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/tests/flowcyto/8_color_ICS.wsp
RENAMED
|
File without changes
|
{sapiopycommons-2025.4.17a486 → sapiopycommons-2025.4.17a488}/tests/flowcyto/COVID19_W_001_O.fcs
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|