sapiopycommons 2025.3.6a454__py3-none-any.whl → 2025.3.10a455__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.

Files changed (29) hide show
  1. sapiopycommons/callbacks/callback_util.py +366 -1220
  2. sapiopycommons/chem/Molecules.py +2 -0
  3. sapiopycommons/datatype/data_fields.py +1 -1
  4. sapiopycommons/eln/experiment_handler.py +1 -2
  5. sapiopycommons/eln/experiment_report_util.py +7 -7
  6. sapiopycommons/files/file_bridge.py +0 -76
  7. sapiopycommons/files/file_bridge_handler.py +110 -325
  8. sapiopycommons/files/file_data_handler.py +2 -2
  9. sapiopycommons/files/file_util.py +11 -36
  10. sapiopycommons/files/file_validator.py +5 -6
  11. sapiopycommons/files/file_writer.py +1 -1
  12. sapiopycommons/flowcyto/flow_cyto.py +1 -1
  13. sapiopycommons/general/accession_service.py +1 -1
  14. sapiopycommons/general/aliases.py +28 -48
  15. sapiopycommons/general/audit_log.py +2 -2
  16. sapiopycommons/general/custom_report_util.py +1 -24
  17. sapiopycommons/general/exceptions.py +2 -41
  18. sapiopycommons/general/popup_util.py +2 -2
  19. sapiopycommons/multimodal/multimodal.py +0 -1
  20. sapiopycommons/processtracking/custom_workflow_handler.py +3 -3
  21. sapiopycommons/recordmodel/record_handler.py +3 -5
  22. sapiopycommons/webhook/webhook_handlers.py +55 -445
  23. {sapiopycommons-2025.3.6a454.dist-info → sapiopycommons-2025.3.10a455.dist-info}/METADATA +1 -1
  24. {sapiopycommons-2025.3.6a454.dist-info → sapiopycommons-2025.3.10a455.dist-info}/RECORD +26 -29
  25. sapiopycommons/customreport/auto_pagers.py +0 -270
  26. sapiopycommons/general/directive_util.py +0 -86
  27. sapiopycommons/samples/aliquot.py +0 -48
  28. {sapiopycommons-2025.3.6a454.dist-info → sapiopycommons-2025.3.10a455.dist-info}/WHEEL +0 -0
  29. {sapiopycommons-2025.3.6a454.dist-info → sapiopycommons-2025.3.10a455.dist-info}/licenses/LICENSE +0 -0
@@ -1,5 +1,6 @@
1
1
  # Author Yechen Qiao
2
2
  # Common Molecule Utilities for Molecule Transfers with Sapio
3
+ from typing import cast
3
4
 
4
5
  from rdkit import Chem
5
6
  from rdkit.Chem import Crippen, MolToInchi
@@ -8,6 +9,7 @@ from rdkit.Chem import rdMolDescriptors
8
9
  from rdkit.Chem.EnumerateStereoisomers import StereoEnumerationOptions, EnumerateStereoisomers
9
10
  from rdkit.Chem.MolStandardize import rdMolStandardize
10
11
  from rdkit.Chem.SaltRemover import SaltRemover
12
+ from rdkit.Chem.rdChemReactions import ChemicalReaction
11
13
  from rdkit.Chem.rdchem import Mol, RWMol, Bond
12
14
 
13
15
  from sapiopycommons.chem.IndigoMolecules import indigo, renderer, indigo_inchi
@@ -58,4 +58,4 @@ class ProcessWorkflowTrackingFields:
58
58
  WORKFLOW_PROCESS_TAT__FIELD = WrapperField("WorkflowProcessTAT", FieldType.DOUBLE)
59
59
  WORKFLOW_START_USER_ID__FIELD = WrapperField("WorkflowStartUserId", FieldType.STRING)
60
60
  WORKFLOW_TAT__FIELD = WrapperField("WorkflowTAT", FieldType.DOUBLE)
61
- WORKFLOW_VERSION__FIELD = WrapperField("WorkflowVersion", FieldType.LONG)
61
+ WORKFLOW_VERSION__FIELD = WrapperField("WorkflowVersion", FieldType.LONG)
@@ -2,7 +2,6 @@ from __future__ import annotations
2
2
 
3
3
  import time
4
4
  from collections.abc import Mapping, Iterable
5
- from typing import TypeAlias
6
5
  from weakref import WeakValueDictionary
7
6
 
8
7
  from sapiopylib.rest.DataMgmtService import DataMgmtServer
@@ -29,7 +28,7 @@ from sapiopycommons.general.aliases import AliasUtil, SapioRecord, ExperimentIde
29
28
  DataTypeIdentifier, RecordModel
30
29
  from sapiopycommons.general.exceptions import SapioException
31
30
 
32
- Step: TypeAlias = str | ElnEntryStep
31
+ Step = str | ElnEntryStep
33
32
  """An object representing an identifier to an ElnEntryStep. May be either the name of the step or the ElnEntryStep
34
33
  itself."""
35
34
 
@@ -6,13 +6,13 @@ from sapiopylib.rest.pojo.eln.ElnExperiment import ElnExperiment, ElnExperimentQ
6
6
  from sapiopylib.rest.pojo.eln.SapioELNEnums import ElnExperimentStatus, ElnBaseDataType
7
7
  from sapiopylib.rest.utils.recordmodel.RecordModelWrapper import WrappedType
8
8
 
9
- from sapiopycommons.customreport.auto_pagers import CustomReportDictAutoPager
10
9
  from sapiopycommons.customreport.custom_report_builder import CustomReportBuilder
11
10
  from sapiopycommons.customreport.term_builder import TermBuilder
12
11
  from sapiopycommons.datatype.pseudo_data_types import EnbEntryOptionsPseudoDef, NotebookExperimentOptionPseudoDef, \
13
12
  NotebookExperimentPseudoDef, ExperimentEntryRecordPseudoDef, EnbEntryPseudoDef
14
13
  from sapiopycommons.general.aliases import SapioRecord, UserIdentifier, AliasUtil, FieldValue, \
15
14
  ExperimentEntryIdentifier, ExperimentIdentifier
15
+ from sapiopycommons.general.custom_report_util import CustomReportUtil
16
16
  from sapiopycommons.general.exceptions import SapioException
17
17
  from sapiopycommons.recordmodel.record_handler import RecordHandler
18
18
 
@@ -201,7 +201,7 @@ class ExperimentReportUtil:
201
201
  criteria = report_builder.build_report_criteria()
202
202
 
203
203
  ret_val: dict[SapioRecord, int] = {}
204
- rows: list[dict[str, FieldValue]] = CustomReportDictAutoPager(context, criteria).get_all_at_once()
204
+ rows: list[dict[str, FieldValue]] = CustomReportUtil.run_custom_report(context, criteria)
205
205
  for row in rows:
206
206
  dt: str = row[EnbEntryPseudoDef.DATA_TYPE_NAME__FIELD_NAME.field_name]
207
207
  exp_id: int = row[EnbEntryPseudoDef.EXPERIMENT_ID__FIELD_NAME.field_name]
@@ -268,7 +268,7 @@ class ExperimentReportUtil:
268
268
 
269
269
  # Ensure that each experiment appears in the dictionary, even if it has no experiment options.
270
270
  options: dict[int, dict[str, str]] = {x: {} for x in exp_ids}
271
- results: list[dict[str, FieldValue]] = CustomReportDictAutoPager(context, report).get_all_at_once()
271
+ results: list[dict[str, FieldValue]] = CustomReportUtil.run_custom_report(context, report)
272
272
  for row in results:
273
273
  exp_id: int = row[NotebookExperimentOptionPseudoDef.EXPERIMENT_ID__FIELD_NAME.field_name]
274
274
  key: str = row[NotebookExperimentOptionPseudoDef.OPTION_KEY__FIELD_NAME.field_name]
@@ -299,7 +299,7 @@ class ExperimentReportUtil:
299
299
 
300
300
  # Ensure that each entry appears in the dictionary, even if it has no entry options.
301
301
  options: dict[int, dict[str, str]] = {x: {} for x in entries}
302
- results: list[dict[str, FieldValue]] = CustomReportDictAutoPager(context, report).get_all_at_once()
302
+ results: list[dict[str, FieldValue]] = CustomReportUtil.run_custom_report(context, report)
303
303
  for row in results:
304
304
  entry_id: int = row[EnbEntryOptionsPseudoDef.ENTRY_ID__FIELD_NAME.field_name]
305
305
  key: str = row[EnbEntryOptionsPseudoDef.ENTRY_OPTION_KEY__FIELD_NAME.field_name]
@@ -332,7 +332,7 @@ class ExperimentReportUtil:
332
332
  report = report_builder.build_report_criteria()
333
333
 
334
334
  ret_val: dict[int, str] = {}
335
- results: list[dict[str, FieldValue]] = CustomReportDictAutoPager(context, report).get_all_at_once()
335
+ results: list[dict[str, FieldValue]] = CustomReportUtil.run_custom_report(context, report)
336
336
  for row in results:
337
337
  exp_id: int = row[NotebookExperimentPseudoDef.EXPERIMENT_ID__FIELD_NAME.field_name]
338
338
  name: str = row["TemplateExperimentName"]
@@ -581,7 +581,7 @@ class ExperimentReportUtil:
581
581
  """
582
582
  user = AliasUtil.to_sapio_user(context)
583
583
  exp_ids: list[int] = []
584
- for row in CustomReportDictAutoPager(user, report):
584
+ for row in CustomReportUtil.run_custom_report(user, report):
585
585
  exp_ids.append(row[NotebookExperimentPseudoDef.EXPERIMENT_ID__FIELD_NAME.field_name])
586
586
  if not exp_ids:
587
587
  return []
@@ -646,4 +646,4 @@ class ExperimentReportUtil:
646
646
  report_builder.add_join(records_entry_join, ExperimentEntryRecordPseudoDef.DATA_TYPE_NAME)
647
647
  report_builder.add_join(experiment_entry_enb_entry_join, EnbEntryPseudoDef.DATA_TYPE_NAME)
648
648
  report_builder.add_join(enb_entry_experiment_join, NotebookExperimentPseudoDef.DATA_TYPE_NAME)
649
- return CustomReportDictAutoPager(user, report_builder.build_report_criteria()).get_all_at_once()
649
+ return CustomReportUtil.run_custom_report(user, report_builder.build_report_criteria())
@@ -1,7 +1,6 @@
1
1
  import base64
2
2
  import io
3
3
  import urllib.parse
4
- from typing import Any
5
4
 
6
5
  from requests import Response
7
6
  from sapiopylib.rest.User import SapioUser
@@ -9,36 +8,6 @@ from sapiopylib.rest.User import SapioUser
9
8
  from sapiopycommons.general.aliases import UserIdentifier, AliasUtil
10
9
 
11
10
 
12
- # FR-47387: Add support for the metadata endpoints in FileBridge.
13
- class FileBridgeMetadata:
14
- """
15
- Metadata for a file or directory in FileBridge.
16
- """
17
- file_name: str
18
- """The name of the file or directory."""
19
- is_file: bool
20
- """True if the metadata is for a file, False if it is for a directory."""
21
- is_directory: bool
22
- """True if the metadata is for a directory, False if it is for a file."""
23
- size: int
24
- """The size of the file in bytes. For directories, this value will always be zero."""
25
- creation_time: int
26
- """The time the file or directory was created, in milliseconds since the epoch."""
27
- last_accessed_time: int
28
- """The time the file or directory was last accessed, in milliseconds since the epoch."""
29
- last_modified_time: int
30
- """The time the file or directory was last modified, in milliseconds since the epoch."""
31
-
32
- def __init__(self, json_dict: dict[str, Any]):
33
- self.file_name = json_dict['fileName']
34
- self.is_file = json_dict['isFile']
35
- self.is_directory = json_dict['isDirectory']
36
- self.size = json_dict['size']
37
- self.creation_time = json_dict['creationTime']
38
- self.last_accessed_time = json_dict['lastAccessTime']
39
- self.last_modified_time = json_dict['lastModifiedTime']
40
-
41
-
42
11
  # FR-46064 - Initial port of PyWebhookUtils to sapiopycommons.
43
12
  class FileBridge:
44
13
  @staticmethod
@@ -168,48 +137,3 @@ class FileBridge:
168
137
  user: SapioUser = AliasUtil.to_sapio_user(context)
169
138
  response = user.delete(sub_path, params=params)
170
139
  user.raise_for_status(response)
171
-
172
- @staticmethod
173
- def file_metadata(context: UserIdentifier, bridge_name: str, file_path: str) -> FileBridgeMetadata:
174
- """
175
- Get metadata for a file or directory in FileBridge.
176
-
177
- The file path may be to a directory, in which case only the metadata for that directory will be returned. If you
178
- want the metadata for the contents of a directory, then use the directory_metadata function.
179
-
180
- :param context: The current webhook context or a user object to send requests from.
181
- :param bridge_name: The name of the bridge to use. This is the "connection name" in the
182
- file bridge configurations.
183
- :param file_path: The path to the file to retrieve the metadata from.
184
- :return: The metadata for the file.
185
- """
186
- sub_path = '/ext/filebridge/file/metadata'
187
- params = {
188
- 'Filepath': f"bridge://{bridge_name}/{file_path}"
189
- }
190
- user: SapioUser = AliasUtil.to_sapio_user(context)
191
- response = user.get(sub_path, params=params)
192
- user.raise_for_status(response)
193
- response_body: dict[str, Any] = response.json()
194
- return FileBridgeMetadata(response_body)
195
-
196
- @staticmethod
197
- def directory_metadata(context: UserIdentifier, bridge_name: str, file_path: str) -> list[FileBridgeMetadata]:
198
- """
199
- Get metadata for every file or nested directory in a directory in FileBridge.
200
-
201
- :param context: The current webhook context or a user object to send requests from.
202
- :param bridge_name: The name of the bridge to use. This is the "connection name" in the
203
- file bridge configurations.
204
- :param file_path: The path to the directory to retrieve the metadata of the contents.
205
- :return: A list of the metadata for the contents of the directory.
206
- """
207
- sub_path = '/ext/filebridge/directory/metadata'
208
- params = {
209
- 'Filepath': f"bridge://{bridge_name}/{file_path}"
210
- }
211
- user: SapioUser = AliasUtil.to_sapio_user(context)
212
- response = user.get(sub_path, params=params)
213
- user.raise_for_status(response)
214
- response_body: list[dict[str, Any]] = response.json()
215
- return [FileBridgeMetadata(x) for x in response_body]