sapiopycommons 2025.4.5a470__py3-none-any.whl → 2025.4.8a473__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/eln/experiment_handler.py +90 -440
- sapiopycommons/eln/experiment_step_factory.py +474 -0
- sapiopycommons/eln/step_creation.py +235 -0
- sapiopycommons/general/aliases.py +3 -0
- {sapiopycommons-2025.4.5a470.dist-info → sapiopycommons-2025.4.8a473.dist-info}/METADATA +1 -1
- {sapiopycommons-2025.4.5a470.dist-info → sapiopycommons-2025.4.8a473.dist-info}/RECORD +9 -7
- /sapiopycommons/{datatype → eln}/experiment_cache.py +0 -0
- {sapiopycommons-2025.4.5a470.dist-info → sapiopycommons-2025.4.8a473.dist-info}/WHEEL +0 -0
- {sapiopycommons-2025.4.5a470.dist-info → sapiopycommons-2025.4.8a473.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
from typing import Iterable
|
|
2
|
+
|
|
3
|
+
from sapiopycommons.general.aliases import DataTypeIdentifier, FieldIdentifier, ExperimentEntryIdentifier
|
|
4
|
+
from sapiopylib.rest.pojo.TableColumn import TableColumn
|
|
5
|
+
from sapiopylib.rest.pojo.datatype.FieldDefinition import AbstractVeloxFieldDefinition
|
|
6
|
+
from sapiopylib.rest.pojo.eln.SapioELNEnums import ExperimentEntryStatus, ElnEntryType
|
|
7
|
+
from sapiopylib.rest.pojo.eln.field_set import ElnFieldSetInfo
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# CR-47564: Created these classes to streamline entry creation using the ExperimentEntryFactory.
|
|
11
|
+
class StepCreation:
|
|
12
|
+
"""
|
|
13
|
+
An object that contains the criteria for creating a new entry in the experiment.
|
|
14
|
+
"""
|
|
15
|
+
_entry_type: ElnEntryType
|
|
16
|
+
"""The type of the entry to be created."""
|
|
17
|
+
is_shown_in_template: bool | None
|
|
18
|
+
"""Whether the entry will appear in the template if the experiment this entry is in is saved to a new template."""
|
|
19
|
+
is_removable: bool | None
|
|
20
|
+
"""Whether the entry can be removed by users."""
|
|
21
|
+
is_renamable: bool | None
|
|
22
|
+
"""Whether the entry can be renamed by users."""
|
|
23
|
+
is_static_view: bool | None
|
|
24
|
+
"""Whether the entry's attachment is static. For attachment entries only. Static attachment entries will store
|
|
25
|
+
their attachment data in the template."""
|
|
26
|
+
related_entry_set: Iterable[ExperimentEntryIdentifier | str] | None
|
|
27
|
+
"""The IDs of the entries this entry is implicitly dependent on. If any of the entries are deleted then this entry
|
|
28
|
+
is also deleted."""
|
|
29
|
+
dependency_set: Iterable[ExperimentEntryIdentifier | str] | None
|
|
30
|
+
"""The IDs of the entries this entry is dependent on. Requires the entries to be completed before this entry will
|
|
31
|
+
be enabled."""
|
|
32
|
+
requires_grabber_plugin: bool
|
|
33
|
+
"""Whether to run a grabber plugin when this entry is initialized."""
|
|
34
|
+
entry_singleton_id: str | None
|
|
35
|
+
"""When this field is present (i.e. not null or blank) it will enforce that only one entry with this singleton
|
|
36
|
+
value is present in the experiment. If you attempt to create an entry with the singletonId of an entry already
|
|
37
|
+
present in the experiment it will return the existing entry instead of creating a new one. If an entry isn't
|
|
38
|
+
present in the Notebook Experiment with a matching singletonId it will create a new entry like normal."""
|
|
39
|
+
is_hidden: bool | None
|
|
40
|
+
"""Whether the user is able to visibly see this entry within the experiment."""
|
|
41
|
+
entry_height: int | None
|
|
42
|
+
"""The height of this entry in pixels. Setting the height to 0 will cause the entry to auto-size to its contents."""
|
|
43
|
+
description: str | None
|
|
44
|
+
"""The description of the entry."""
|
|
45
|
+
is_initialization_required: bool | None
|
|
46
|
+
"""Whether the user must manually initialize this entry by clicking on it."""
|
|
47
|
+
collapse_entry: bool | None
|
|
48
|
+
"""Whether the entry should be collapsed by default."""
|
|
49
|
+
entry_status: ExperimentEntryStatus | None
|
|
50
|
+
"""The current status of the entry."""
|
|
51
|
+
template_item_fulfilled_timestamp: int | None
|
|
52
|
+
"""The time in milliseconds since the epoch that this entry became initialized."""
|
|
53
|
+
entry_options: dict[str, str] | None
|
|
54
|
+
"""The entry options of the entry."""
|
|
55
|
+
|
|
56
|
+
def __init__(self, entry_type: ElnEntryType):
|
|
57
|
+
self._entry_type = entry_type
|
|
58
|
+
self.is_shown_in_template = None
|
|
59
|
+
self.is_removable = None
|
|
60
|
+
self.is_renamable = None
|
|
61
|
+
self.is_static_view = None
|
|
62
|
+
self._related_entry_set = None
|
|
63
|
+
self._dependency_set = None
|
|
64
|
+
self.requires_grabber_plugin = False
|
|
65
|
+
self.entry_singleton_id = None
|
|
66
|
+
self.is_hidden = None
|
|
67
|
+
self.entry_height = None
|
|
68
|
+
self.description = None
|
|
69
|
+
self.is_initialization_required = None
|
|
70
|
+
self.collapse_entry = None
|
|
71
|
+
self.entry_status = None
|
|
72
|
+
self.template_item_fulfilled_timestamp = None
|
|
73
|
+
self.entry_options = None
|
|
74
|
+
|
|
75
|
+
@property
|
|
76
|
+
def entry_type(self) -> ElnEntryType:
|
|
77
|
+
return self._entry_type
|
|
78
|
+
|
|
79
|
+
class AttachmentStepCreation(StepCreation):
|
|
80
|
+
"""
|
|
81
|
+
An object that contains criteria for creating a new attachment entry in an experiment.
|
|
82
|
+
"""
|
|
83
|
+
def __init__(self):
|
|
84
|
+
super().__init__(ElnEntryType.Attachment)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class DashboardStepCreation(StepCreation):
|
|
88
|
+
"""
|
|
89
|
+
An object that contains criteria for creating a new dashboard entry in an experiment.
|
|
90
|
+
"""
|
|
91
|
+
source_entry: ExperimentEntryIdentifier | str | None
|
|
92
|
+
"""The entry that contains the source data for this entry's dashboard(s)."""
|
|
93
|
+
dashboard_guids: Iterable[str] | None
|
|
94
|
+
"""The GUIDs of the dashboards to display in this entry."""
|
|
95
|
+
|
|
96
|
+
def __init__(self):
|
|
97
|
+
super().__init__(ElnEntryType.Dashboard)
|
|
98
|
+
self.source_entry = None
|
|
99
|
+
self.dashboard_guids = None
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class GlobalDtFormStepCreation(StepCreation):
|
|
103
|
+
"""
|
|
104
|
+
An object that contains criteria for creating a new global data type form entry in an experiment.
|
|
105
|
+
"""
|
|
106
|
+
layout_name: str | None
|
|
107
|
+
"""The name of the data type layout to be displayed in this form. The layout must be for the data type for this
|
|
108
|
+
entry."""
|
|
109
|
+
form_names: Iterable[str] | None
|
|
110
|
+
"""The names of the components in the chosen data type layout to display in this form."""
|
|
111
|
+
extension_types: Iterable[DataTypeIdentifier] | None
|
|
112
|
+
"""The names of the extension data types to display fields from within the form."""
|
|
113
|
+
field_names: Iterable[FieldIdentifier] | None
|
|
114
|
+
"""A list of data field names for the fields to be displayed in the form."""
|
|
115
|
+
|
|
116
|
+
def __init__(self):
|
|
117
|
+
super().__init__(ElnEntryType.Form)
|
|
118
|
+
self.form_names = None
|
|
119
|
+
self.layout_name = None
|
|
120
|
+
self.extension_types = None
|
|
121
|
+
self.field_names = None
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class ELnDtFormStepCreation(StepCreation):
|
|
125
|
+
"""
|
|
126
|
+
An object that contains criteria for creating a new ELN data type form entry in an experiment.
|
|
127
|
+
"""
|
|
128
|
+
is_field_addable: bool | None
|
|
129
|
+
"""Whether new fields can be added to the entry by users."""
|
|
130
|
+
is_existing_field_removable: bool | None
|
|
131
|
+
"""Whether existing fields on the entry can be removed by users."""
|
|
132
|
+
field_sets: Iterable[int | str | ElnFieldSetInfo] | None
|
|
133
|
+
"""The predefined field sets to display in this form."""
|
|
134
|
+
field_definitions: Iterable[AbstractVeloxFieldDefinition] | None
|
|
135
|
+
"""New field definitions to be created for this entry."""
|
|
136
|
+
predefined_field_names: Iterable[str] | None
|
|
137
|
+
"""The names of the predefined fields to display in this form."""
|
|
138
|
+
|
|
139
|
+
def __init__(self):
|
|
140
|
+
super().__init__(ElnEntryType.Form)
|
|
141
|
+
self.is_field_addable = None
|
|
142
|
+
self.is_existing_field_removable = None
|
|
143
|
+
self.field_sets = None
|
|
144
|
+
self.field_definitions = None
|
|
145
|
+
self.predefined_field_names = None
|
|
146
|
+
self.table_columns = None
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
class PluginStepCreation(StepCreation):
|
|
150
|
+
"""
|
|
151
|
+
An object that contains criteria for creating a new plugin entry in an experiment.
|
|
152
|
+
"""
|
|
153
|
+
plugin_name: str | None
|
|
154
|
+
"""The client side plugin name to render this entry with."""
|
|
155
|
+
using_template_data: bool | None
|
|
156
|
+
"""Whether this entry will use the data from the template."""
|
|
157
|
+
provides_template_data: bool | None
|
|
158
|
+
"""Whether this entry can provide data to copy into a new template."""
|
|
159
|
+
|
|
160
|
+
def __init__(self):
|
|
161
|
+
super().__init__(ElnEntryType.Plugin)
|
|
162
|
+
self.plugin_name = None
|
|
163
|
+
self.using_template_data = None
|
|
164
|
+
self.provides_template_data = None
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
class GlobalDtTableStepCreation(StepCreation):
|
|
168
|
+
"""
|
|
169
|
+
An object that contains criteria for creating a new global data type table entry in an experiment.
|
|
170
|
+
"""
|
|
171
|
+
layout_name: str | None
|
|
172
|
+
"""The name of the data type layout to display in this table."""
|
|
173
|
+
extension_types: Iterable[str] | None
|
|
174
|
+
"""The names of the extension data types to display fields from within the table."""
|
|
175
|
+
table_columns: Iterable[TableColumn] | None
|
|
176
|
+
"""The columns to display in the table. This can be used to change the sort order and direction of columns."""
|
|
177
|
+
field_names: Iterable[FieldIdentifier] | None
|
|
178
|
+
"""A list of data field names for the fields to be displayed in the table. These will be added as TableColumns and
|
|
179
|
+
placed after any of the existing columns specified in the table_columns parameter without any sorting."""
|
|
180
|
+
show_key_fields: bool | None
|
|
181
|
+
"""Whether the key fields of the data type should be shown in the entry."""
|
|
182
|
+
|
|
183
|
+
def __init__(self):
|
|
184
|
+
super().__init__(ElnEntryType.Table)
|
|
185
|
+
self.layout_name = None
|
|
186
|
+
self.extension_types = None
|
|
187
|
+
self.table_columns = None
|
|
188
|
+
self.show_key_fields = None
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
class ELnDtTableStepCreation(StepCreation):
|
|
192
|
+
"""
|
|
193
|
+
An object that contains criteria for creating a new ELN data type table entry in an experiment.
|
|
194
|
+
"""
|
|
195
|
+
is_field_addable: bool | None
|
|
196
|
+
"""Whether new fields can be added to the entry by users."""
|
|
197
|
+
is_existing_field_removable: bool | None
|
|
198
|
+
"""Whether existing fields on the entry can be removed by users."""
|
|
199
|
+
field_sets: Iterable[int | str | ElnFieldSetInfo] | None
|
|
200
|
+
"""The predefined field sets to display in this form."""
|
|
201
|
+
field_definitions: Iterable[AbstractVeloxFieldDefinition] | None
|
|
202
|
+
"""New field definitions to be created for this entry."""
|
|
203
|
+
predefined_field_names: Iterable[str] | None
|
|
204
|
+
"""The names of the predefined fields to display in this form."""
|
|
205
|
+
table_columns: Iterable[TableColumn] | None
|
|
206
|
+
"""The columns to display in the table."""
|
|
207
|
+
|
|
208
|
+
def __init__(self):
|
|
209
|
+
super().__init__(ElnEntryType.Table)
|
|
210
|
+
self.is_field_addable = None
|
|
211
|
+
self.is_existing_field_removable = None
|
|
212
|
+
self.field_sets = None
|
|
213
|
+
self.field_definitions = None
|
|
214
|
+
self.predefined_field_names = None
|
|
215
|
+
self.table_columns = None
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
class TempDataStepCreation(StepCreation):
|
|
219
|
+
"""
|
|
220
|
+
An object that contains criteria for creating a new temp data entry in an experiment.
|
|
221
|
+
"""
|
|
222
|
+
plugin_path: str | None
|
|
223
|
+
"""The temp data plugin path to run to populate the entry."""
|
|
224
|
+
|
|
225
|
+
def __init__(self):
|
|
226
|
+
super().__init__(ElnEntryType.TempData)
|
|
227
|
+
self.plugin_path = None
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
class TextStepCreation(StepCreation):
|
|
231
|
+
"""
|
|
232
|
+
An object that contains criteria for creating a new text entry in an experiment.
|
|
233
|
+
"""
|
|
234
|
+
def __init__(self):
|
|
235
|
+
super().__init__(ElnEntryType.Text)
|
|
@@ -7,6 +7,7 @@ from sapiopylib.rest.pojo.datatype.FieldDefinition import FieldType, AbstractVel
|
|
|
7
7
|
from sapiopylib.rest.pojo.eln.ElnExperiment import ElnExperiment
|
|
8
8
|
from sapiopylib.rest.pojo.eln.ExperimentEntry import ExperimentEntry
|
|
9
9
|
from sapiopylib.rest.pojo.eln.SapioELNEnums import ElnBaseDataType
|
|
10
|
+
from sapiopylib.rest.pojo.eln.eln_headings import ElnExperimentTab
|
|
10
11
|
from sapiopylib.rest.pojo.webhook.WebhookContext import SapioWebhookContext
|
|
11
12
|
from sapiopylib.rest.utils.Protocols import ElnExperimentProtocol, ElnEntryStep
|
|
12
13
|
from sapiopylib.rest.utils.recordmodel.PyRecordModel import PyRecordModel, AbstractRecordModel
|
|
@@ -37,6 +38,8 @@ ExperimentIdentifier: TypeAlias = ElnExperimentProtocol | ElnExperiment | int
|
|
|
37
38
|
ID."""
|
|
38
39
|
ExperimentEntryIdentifier: TypeAlias = ElnEntryStep | ExperimentEntry | int
|
|
39
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."""
|
|
40
43
|
FieldMap: TypeAlias = dict[str, FieldValue]
|
|
41
44
|
"""A field map is simply a dict of data field names to values. The purpose of aliasing this is to help distinguish
|
|
42
45
|
any random dict in a webhook from one which is explicitly used for record fields."""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: sapiopycommons
|
|
3
|
-
Version: 2025.4.
|
|
3
|
+
Version: 2025.4.8a473
|
|
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>
|
|
@@ -13,13 +13,15 @@ sapiopycommons/customreport/term_builder.py,sha256=1_PGjxNUy5YWim8WJ_HJfiTq6i0D3
|
|
|
13
13
|
sapiopycommons/datatype/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
14
|
sapiopycommons/datatype/attachment_util.py,sha256=N-nhsJ0oxa_Ft6Y6VWeNFYLzfuQqsjhHA6_-yIt2wVw,3596
|
|
15
15
|
sapiopycommons/datatype/data_fields.py,sha256=pczUlEcE0TeHEDU0Gkvu7voacSLPXCB7l9UbI1Tb6V0,5656
|
|
16
|
-
sapiopycommons/datatype/experiment_cache.py,sha256=kiYZBZEAuQpv-rFviv8_6g7uvXdzH9BMUEprvAHT0Ds,8181
|
|
17
16
|
sapiopycommons/datatype/pseudo_data_types.py,sha256=6TG7aJxgmUZ8FQkWBcgmbK5oy7AFFNtKOPpi1w1OOYA,27657
|
|
18
17
|
sapiopycommons/eln/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
|
-
sapiopycommons/eln/
|
|
18
|
+
sapiopycommons/eln/experiment_cache.py,sha256=kiYZBZEAuQpv-rFviv8_6g7uvXdzH9BMUEprvAHT0Ds,8181
|
|
19
|
+
sapiopycommons/eln/experiment_handler.py,sha256=7vYRlYAW_xT5LcZ5nLqL9dxEHGRAPEuUxX8d8TElWV8,105742
|
|
20
20
|
sapiopycommons/eln/experiment_report_util.py,sha256=NNNNPVD3_2ZAjoOqCMOnlnmPD0SCjDcgYi453ATSJBs,37027
|
|
21
|
+
sapiopycommons/eln/experiment_step_factory.py,sha256=6mUv2JXN5-MCM_aUblcv95v4NMTp9i1W42AqJ8sdUkM,26007
|
|
21
22
|
sapiopycommons/eln/experiment_tags.py,sha256=7-fpOiSqrjbXmWIJhEhaxMgLsVCPAtKqH8xRzpDVKoE,356
|
|
22
23
|
sapiopycommons/eln/plate_designer.py,sha256=ix2cflz13PAHyu4deS3d5Qd3kQXk0C7IQxBQ2Dm9fEM,13692
|
|
24
|
+
sapiopycommons/eln/step_creation.py,sha256=DiniCKef2Nkpa2QeDiRvh_Q_QBu6J7o7vNlU28TaYRI,10141
|
|
23
25
|
sapiopycommons/files/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
24
26
|
sapiopycommons/files/complex_data_loader.py,sha256=T39veNhvYl6j_uZjIIJ8Mk5Aa7otR5RB-g8XlAdkksA,1421
|
|
25
27
|
sapiopycommons/files/file_bridge.py,sha256=vKbqxPexi15epr_-_qLrEfYoxNxB031mXN92iVtOMqE,9511
|
|
@@ -32,7 +34,7 @@ sapiopycommons/flowcyto/flow_cyto.py,sha256=vs9WhXXKz3urpjL8QKSk56B-NSmQR3O3x_WF
|
|
|
32
34
|
sapiopycommons/flowcyto/flowcyto_data.py,sha256=mYKFuLbtpJ-EsQxLGtu4tNHVlygTxKixgJxJqD68F58,2596
|
|
33
35
|
sapiopycommons/general/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
34
36
|
sapiopycommons/general/accession_service.py,sha256=3e__bVs7CYZ1CduLlGA9plnK7nCtdy7GXjCrNObPFgo,13484
|
|
35
|
-
sapiopycommons/general/aliases.py,sha256=
|
|
37
|
+
sapiopycommons/general/aliases.py,sha256=wDNg0HSZm13O4lS8L8DT5mMBZ5GDwSbSHpDDwSFcZpc,14711
|
|
36
38
|
sapiopycommons/general/audit_log.py,sha256=KQq0PsvukUoE3l6TQb3-vpu5-MbSINpWlnQ9e7jojPg,8743
|
|
37
39
|
sapiopycommons/general/custom_report_util.py,sha256=NwwmejSQLwSbrndEk1gPyFNYk9GZoS7Wrp9ab9moFgw,18014
|
|
38
40
|
sapiopycommons/general/data_structure_util.py,sha256=fbQR_Fh4Scg67IpFPbQW9wVLw1oxlYxqp4LjBRTpjgU,4702
|
|
@@ -59,7 +61,7 @@ sapiopycommons/webhook/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
|
|
|
59
61
|
sapiopycommons/webhook/webhook_context.py,sha256=D793uLsb1691SalaPnBUk3rOSxn_hYLhdvkaIxjNXss,1909
|
|
60
62
|
sapiopycommons/webhook/webhook_handlers.py,sha256=tUVNCw05CDGu1gFDm2g558hX_O203WVm_n__ojjoRRM,39841
|
|
61
63
|
sapiopycommons/webhook/webservice_handlers.py,sha256=tyaYGG1-v_JJrJHZ6cy5mGCxX9z1foLw7pM4MDJlFxs,14297
|
|
62
|
-
sapiopycommons-2025.4.
|
|
63
|
-
sapiopycommons-2025.4.
|
|
64
|
-
sapiopycommons-2025.4.
|
|
65
|
-
sapiopycommons-2025.4.
|
|
64
|
+
sapiopycommons-2025.4.8a473.dist-info/METADATA,sha256=j7dB9Oy9qtcyLF6QYmAzL3yIQc5NYGaLRvgudYh0pxg,3142
|
|
65
|
+
sapiopycommons-2025.4.8a473.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
|
|
66
|
+
sapiopycommons-2025.4.8a473.dist-info/licenses/LICENSE,sha256=HyVuytGSiAUQ6ErWBHTqt1iSGHhLmlC8fO7jTCuR8dU,16725
|
|
67
|
+
sapiopycommons-2025.4.8a473.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.4.5a470.dist-info → sapiopycommons-2025.4.8a473.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|