sapiopycommons 2025.1.21a408__tar.gz → 2025.2.3a410__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.1.21a408 → sapiopycommons-2025.2.3a410}/PKG-INFO +1 -1
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/pyproject.toml +1 -1
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/chem/Molecules.py +0 -2
- sapiopycommons-2025.2.3a410/src/sapiopycommons/customreport/auto_pagers.py +270 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/datatype/data_fields.py +1 -1
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/eln/experiment_report_util.py +7 -7
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/files/file_validator.py +3 -3
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/general/accession_service.py +1 -1
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/general/audit_log.py +2 -2
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/general/custom_report_util.py +24 -1
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/multimodal/multimodal.py +1 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/processtracking/custom_workflow_handler.py +3 -3
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/recordmodel/record_handler.py +5 -3
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/.gitignore +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/LICENSE +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/README.md +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/__init__.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/callbacks/__init__.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/callbacks/callback_util.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/callbacks/field_builder.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/chem/IndigoMolecules.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/chem/__init__.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/customreport/__init__.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/customreport/column_builder.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/customreport/custom_report_builder.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/customreport/term_builder.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/datatype/__init__.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/datatype/attachment_util.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/datatype/pseudo_data_types.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/eln/__init__.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/eln/experiment_handler.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/eln/plate_designer.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/files/__init__.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/files/complex_data_loader.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/files/file_bridge.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/files/file_bridge_handler.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/files/file_data_handler.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/files/file_util.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/files/file_writer.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/flowcyto/flow_cyto.py +1 -1
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/flowcyto/flowcyto_data.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/general/__init__.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/general/aliases.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/general/directive_util.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/general/exceptions.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/general/popup_util.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/general/sapio_links.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/general/storage_util.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/general/time_util.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/multimodal/multimodal_data.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/processtracking/__init__.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/processtracking/endpoints.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/recordmodel/__init__.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/rules/__init__.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/rules/eln_rule_handler.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/rules/on_save_rule_handler.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/sftpconnect/__init__.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/sftpconnect/sftp_builder.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/webhook/__init__.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/webhook/webhook_context.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/webhook/webhook_handlers.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/webhook/webservice_handlers.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/tests/AF-A0A009IHW8-F1-model_v4.cif +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/tests/_do_not_add_init_py_here +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/tests/accession_test.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/tests/bio_reg_test.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/tests/chem_test.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/tests/chem_test_curation_queue.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/tests/curation_queue_test.sdf +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/tests/data_type_models.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/tests/flowcyto/101_DEN084Y5_15_E01_008_clean.fcs +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/tests/flowcyto/101_DEN084Y5_15_E03_009_clean.fcs +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/tests/flowcyto/101_DEN084Y5_15_E05_010_clean.fcs +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/tests/flowcyto/8_color_ICS.wsp +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/tests/flowcyto/COVID19_W_001_O.fcs +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/tests/flowcyto_test.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/tests/kappa.chains.fasta +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/tests/mafft_test.py +0 -0
- {sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/tests/test.gb +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: sapiopycommons
|
|
3
|
-
Version: 2025.
|
|
3
|
+
Version: 2025.2.3a410
|
|
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>
|
{sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/chem/Molecules.py
RENAMED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
# Author Yechen Qiao
|
|
2
2
|
# Common Molecule Utilities for Molecule Transfers with Sapio
|
|
3
|
-
from typing import cast
|
|
4
3
|
|
|
5
4
|
from rdkit import Chem
|
|
6
5
|
from rdkit.Chem import Crippen, MolToInchi
|
|
@@ -9,7 +8,6 @@ from rdkit.Chem import rdMolDescriptors
|
|
|
9
8
|
from rdkit.Chem.EnumerateStereoisomers import StereoEnumerationOptions, EnumerateStereoisomers
|
|
10
9
|
from rdkit.Chem.MolStandardize import rdMolStandardize
|
|
11
10
|
from rdkit.Chem.SaltRemover import SaltRemover
|
|
12
|
-
from rdkit.Chem.rdChemReactions import ChemicalReaction
|
|
13
11
|
from rdkit.Chem.rdchem import Mol, RWMol, Bond
|
|
14
12
|
|
|
15
13
|
from sapiopycommons.chem.IndigoMolecules import indigo, renderer, indigo_inchi
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
from abc import ABC
|
|
2
|
+
from copy import copy
|
|
3
|
+
from queue import Queue
|
|
4
|
+
|
|
5
|
+
from sapiopylib.rest.CustomReportService import CustomReportManager
|
|
6
|
+
from sapiopylib.rest.DataMgmtService import DataMgmtServer
|
|
7
|
+
from sapiopylib.rest.pojo.CustomReport import CustomReportCriteria, CustomReport, RawReportTerm, ReportColumn
|
|
8
|
+
from sapiopylib.rest.pojo.datatype.FieldDefinition import FieldType
|
|
9
|
+
from sapiopylib.rest.utils.autopaging import SapioPyAutoPager, PagerResultCriteriaType, _default_report_page_size, \
|
|
10
|
+
_default_record_page_size
|
|
11
|
+
from sapiopylib.rest.utils.recordmodel.RecordModelWrapper import WrappedType
|
|
12
|
+
|
|
13
|
+
from sapiopycommons.general.aliases import FieldValue, UserIdentifier, AliasUtil, RecordModel
|
|
14
|
+
from sapiopycommons.general.custom_report_util import CustomReportUtil
|
|
15
|
+
from sapiopycommons.general.exceptions import SapioException
|
|
16
|
+
from sapiopycommons.recordmodel.record_handler import RecordHandler
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# FR-47389: Create auto pagers for running custom/system/quick reports that return dictionaries or records for each row.
|
|
20
|
+
class _DictReportPagerBase(SapioPyAutoPager[CustomReportCriteria, dict[str, FieldValue]], ABC):
|
|
21
|
+
"""
|
|
22
|
+
A base class for automatically paging through a report and returning the results as a list of dictionaries.
|
|
23
|
+
"""
|
|
24
|
+
_columns: list[ReportColumn]
|
|
25
|
+
_report_man: CustomReportManager
|
|
26
|
+
|
|
27
|
+
def __init__(self, user: UserIdentifier, first_page_criteria: CustomReportCriteria):
|
|
28
|
+
self._columns = first_page_criteria.column_list
|
|
29
|
+
super().__init__(AliasUtil.to_sapio_user(user), first_page_criteria)
|
|
30
|
+
self._report_man = DataMgmtServer.get_custom_report_manager(self.user)
|
|
31
|
+
|
|
32
|
+
def get_all_at_once(self) -> list[dict[str, FieldValue]]:
|
|
33
|
+
"""
|
|
34
|
+
Get the results of all pages. Be cautious of client memory usage.
|
|
35
|
+
"""
|
|
36
|
+
if self.has_iterated:
|
|
37
|
+
raise BrokenPipeError("Cannot use this method if the iterator has already been used.")
|
|
38
|
+
return [x for x in self]
|
|
39
|
+
|
|
40
|
+
def default_first_page_criteria(self) -> PagerResultCriteriaType:
|
|
41
|
+
raise ValueError("Cannot generate a default first page criteria for custom reports.")
|
|
42
|
+
|
|
43
|
+
def get_next_page_result(self) -> tuple[CustomReportCriteria | None, Queue[dict[str, FieldValue]]]:
|
|
44
|
+
report: CustomReport = self._report_man.run_custom_report(self.next_page_criteria)
|
|
45
|
+
queue: Queue[dict[str, FieldValue]] = Queue()
|
|
46
|
+
for row in _process_results(report.result_table, self._columns):
|
|
47
|
+
queue.put(row)
|
|
48
|
+
if report.has_next_page:
|
|
49
|
+
next_page_criteria = copy(self.next_page_criteria)
|
|
50
|
+
next_page_criteria.page_number += 1
|
|
51
|
+
return next_page_criteria, queue
|
|
52
|
+
else:
|
|
53
|
+
return None, queue
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class CustomReportDictAutoPager(_DictReportPagerBase):
|
|
57
|
+
"""
|
|
58
|
+
A class that automatically pages through a custom report and returns the results as a list of dictionaries.
|
|
59
|
+
"""
|
|
60
|
+
def __init__(self, user: UserIdentifier, report_criteria: CustomReportCriteria,
|
|
61
|
+
page_number: int = 0, page_size: int = _default_report_page_size):
|
|
62
|
+
"""
|
|
63
|
+
:param user: The current webhook context or a user object to send requests from.
|
|
64
|
+
:param report_criteria: The custom report criteria to run.
|
|
65
|
+
:param page_number: The page number to start on. The first page is page 0.
|
|
66
|
+
:param page_size: The number of results to return per page.
|
|
67
|
+
"""
|
|
68
|
+
first_page_criteria: CustomReportCriteria = copy(report_criteria)
|
|
69
|
+
first_page_criteria.page_number = page_number
|
|
70
|
+
first_page_criteria.page_size = page_size
|
|
71
|
+
super().__init__(user, first_page_criteria)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class SystemReportDictAutoPager(_DictReportPagerBase):
|
|
75
|
+
"""
|
|
76
|
+
A class that automatically pages through a system report and returns the results as a list of dictionaries.
|
|
77
|
+
|
|
78
|
+
System reports are also known as predefined searches in the system and must be defined in the data designer for
|
|
79
|
+
a specific data type. That is, saved searches created by users cannot be run using this function.
|
|
80
|
+
"""
|
|
81
|
+
def __init__(self, user: UserIdentifier, report_name: str,
|
|
82
|
+
page_number: int = 0, page_size: int = _default_report_page_size):
|
|
83
|
+
"""
|
|
84
|
+
:param user: The current webhook context or a user object to send requests from.
|
|
85
|
+
:param report_name: The name of the system report to run.
|
|
86
|
+
:param page_number: The page number to start on. The first page is page 0.
|
|
87
|
+
:param page_size: The number of results to return per page.
|
|
88
|
+
"""
|
|
89
|
+
first_page_criteria: CustomReportCriteria = CustomReportUtil.get_system_report_criteria(user, report_name)
|
|
90
|
+
first_page_criteria.page_number = page_number
|
|
91
|
+
first_page_criteria.page_size = page_size
|
|
92
|
+
super().__init__(user, first_page_criteria)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class QuickReportDictAutoPager(_DictReportPagerBase):
|
|
96
|
+
"""
|
|
97
|
+
A class that automatically pages through a quick report and returns the results as a list of dictionaries.
|
|
98
|
+
"""
|
|
99
|
+
def __init__(self, user: UserIdentifier, report_term: RawReportTerm,
|
|
100
|
+
page_number: int = 0, page_size: int = _default_report_page_size):
|
|
101
|
+
"""
|
|
102
|
+
:param user: The current webhook context or a user object to send requests from.
|
|
103
|
+
:param report_term: The raw report term to use for the quick report.
|
|
104
|
+
:param page_number: The page number to start on. The first page is page 0.
|
|
105
|
+
:param page_size: The number of results to return per page.
|
|
106
|
+
"""
|
|
107
|
+
first_page_criteria: CustomReportCriteria = CustomReportUtil.get_quick_report_criteria(user, report_term)
|
|
108
|
+
first_page_criteria.page_number = page_number
|
|
109
|
+
first_page_criteria.page_size = page_size
|
|
110
|
+
super().__init__(user, first_page_criteria)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
class _RecordReportPagerBase(SapioPyAutoPager[CustomReportCriteria, WrappedType], ABC):
|
|
114
|
+
"""
|
|
115
|
+
A base class for automatically paging through a report and returning the results as a list of records.
|
|
116
|
+
"""
|
|
117
|
+
_columns: list[ReportColumn]
|
|
118
|
+
_wrapper: type[WrappedType]
|
|
119
|
+
_data_type: str
|
|
120
|
+
_rec_handler: RecordHandler
|
|
121
|
+
_report_man: CustomReportManager
|
|
122
|
+
|
|
123
|
+
def __init__(self, user: UserIdentifier, first_page_criteria: CustomReportCriteria, wrapper_type: type[WrappedType]):
|
|
124
|
+
self._columns = first_page_criteria.column_list
|
|
125
|
+
self._wrapper = wrapper_type
|
|
126
|
+
self._data_type = wrapper_type.get_wrapper_data_type_name()
|
|
127
|
+
self._rec_handler = RecordHandler(user)
|
|
128
|
+
super().__init__(AliasUtil.to_sapio_user(user), first_page_criteria)
|
|
129
|
+
self._report_man = DataMgmtServer.get_custom_report_manager(self.user)
|
|
130
|
+
|
|
131
|
+
def get_all_at_once(self) -> list[RecordModel]:
|
|
132
|
+
"""
|
|
133
|
+
Get the results of all pages. Be cautious of client memory usage.
|
|
134
|
+
"""
|
|
135
|
+
if self.has_iterated:
|
|
136
|
+
raise BrokenPipeError("Cannot use this method if the iterator has already been used.")
|
|
137
|
+
return [x for x in self]
|
|
138
|
+
|
|
139
|
+
def default_first_page_criteria(self) -> PagerResultCriteriaType:
|
|
140
|
+
raise ValueError("Cannot generate a default first page criteria for custom reports.")
|
|
141
|
+
|
|
142
|
+
def get_next_page_result(self) -> tuple[CustomReportCriteria | None, Queue[WrappedType]]:
|
|
143
|
+
report: CustomReport = self._report_man.run_custom_report(self.next_page_criteria)
|
|
144
|
+
queue: Queue[WrappedType] = Queue()
|
|
145
|
+
id_index: int = -1
|
|
146
|
+
for i, column in enumerate(self._columns):
|
|
147
|
+
if column.data_type_name == self._data_type and column.data_field_name == "RecordId":
|
|
148
|
+
id_index = i
|
|
149
|
+
break
|
|
150
|
+
if id_index == -1:
|
|
151
|
+
raise SapioException(f"This report does not contain a Record ID column for the given record model type "
|
|
152
|
+
f"{self._data_type}.")
|
|
153
|
+
ids: list[int] = [row[id_index] for row in report.result_table]
|
|
154
|
+
for row in self._rec_handler.query_models_by_id(self._wrapper, ids, page_size=report.page_size):
|
|
155
|
+
queue.put(row)
|
|
156
|
+
if report.has_next_page:
|
|
157
|
+
next_page_criteria = copy(self.next_page_criteria)
|
|
158
|
+
next_page_criteria.page_number += 1
|
|
159
|
+
return next_page_criteria, queue
|
|
160
|
+
else:
|
|
161
|
+
return None, queue
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
class CustomReportRecordAutoPager(_RecordReportPagerBase):
|
|
165
|
+
"""
|
|
166
|
+
A class that automatically pages through a custom report and returns the results as a list of records.
|
|
167
|
+
"""
|
|
168
|
+
def __init__(self, user: UserIdentifier, report_criteria: CustomReportCriteria, wrapper_type: type[WrappedType],
|
|
169
|
+
page_number: int = 0, page_size: int = _default_record_page_size):
|
|
170
|
+
"""
|
|
171
|
+
:param user: The current webhook context or a user object to send requests from.
|
|
172
|
+
:param report_criteria: The custom report criteria to run.
|
|
173
|
+
:param wrapper_type: The record model wrapper type to use for the records.
|
|
174
|
+
:param page_number: The page number to start on. The first page is page 0.
|
|
175
|
+
:param page_size: The number of results to return per page.
|
|
176
|
+
"""
|
|
177
|
+
first_page_criteria: CustomReportCriteria = copy(report_criteria)
|
|
178
|
+
_add_record_id_column(first_page_criteria, wrapper_type)
|
|
179
|
+
first_page_criteria.page_number = page_number
|
|
180
|
+
first_page_criteria.page_size = page_size
|
|
181
|
+
super().__init__(user, first_page_criteria, wrapper_type)
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
class SystemReportRecordAutoPager(_RecordReportPagerBase):
|
|
185
|
+
"""
|
|
186
|
+
A class that automatically pages through a system report and returns the results as a list of records.
|
|
187
|
+
|
|
188
|
+
System reports are also known as predefined searches in the system and must be defined in the data designer for
|
|
189
|
+
a specific data type. That is, saved searches created by users cannot be run using this function.
|
|
190
|
+
"""
|
|
191
|
+
def __init__(self, user: UserIdentifier, report_name: str, wrapper_type: type[WrappedType],
|
|
192
|
+
page_number: int = 0, page_size: int = _default_record_page_size):
|
|
193
|
+
"""
|
|
194
|
+
:param user: The current webhook context or a user object to send requests from.
|
|
195
|
+
:param report_name: The name of the system report to run.
|
|
196
|
+
:param wrapper_type: The record model wrapper type to use for the records.
|
|
197
|
+
:param page_number: The page number to start on. The first page is page 0.
|
|
198
|
+
:param page_size: The number of results to return per page.
|
|
199
|
+
"""
|
|
200
|
+
first_page_criteria: CustomReportCriteria = CustomReportUtil.get_system_report_criteria(user, report_name)
|
|
201
|
+
_add_record_id_column(first_page_criteria, wrapper_type)
|
|
202
|
+
first_page_criteria.page_number = page_number
|
|
203
|
+
first_page_criteria.page_size = page_size
|
|
204
|
+
super().__init__(user, first_page_criteria, wrapper_type)
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
class QuickReportRecordAutoPager(_RecordReportPagerBase):
|
|
208
|
+
"""
|
|
209
|
+
A class that automatically pages through a quick report and returns the results as a list of records.
|
|
210
|
+
"""
|
|
211
|
+
def __init__(self, user: UserIdentifier, report_term: RawReportTerm, wrapper_type: type[WrappedType],
|
|
212
|
+
page_number: int = 0, page_size: int = _default_record_page_size):
|
|
213
|
+
"""
|
|
214
|
+
:param user: The current webhook context or a user object to send requests from.
|
|
215
|
+
:param report_term: The raw report term to use for the quick report.
|
|
216
|
+
:param wrapper_type: The record model wrapper type to use for the records.
|
|
217
|
+
:param page_number: The page number to start on. The first page is page 0.
|
|
218
|
+
:param page_size: The number of results to return per page.
|
|
219
|
+
"""
|
|
220
|
+
if report_term.data_type_name != wrapper_type.get_wrapper_data_type_name():
|
|
221
|
+
raise SapioException("The data type name of the report term must match the data type name of the wrapper type.")
|
|
222
|
+
first_page_criteria: CustomReportCriteria = CustomReportUtil.get_quick_report_criteria(user, report_term)
|
|
223
|
+
first_page_criteria.page_number = page_number
|
|
224
|
+
first_page_criteria.page_size = page_size
|
|
225
|
+
super().__init__(user, first_page_criteria, wrapper_type)
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def _add_record_id_column(report: CustomReportCriteria, wrapper_type: type[WrappedType]) -> None:
|
|
229
|
+
"""
|
|
230
|
+
Given a custom report criteria, ensure that the report contains a Record ID column for the given record model's
|
|
231
|
+
data type. Add one if it is missing.
|
|
232
|
+
"""
|
|
233
|
+
dt: str = wrapper_type.get_wrapper_data_type_name()
|
|
234
|
+
# Ensure that the root data type is the one we're looking for.
|
|
235
|
+
report.root_data_type = dt
|
|
236
|
+
# Enforce that the given custom report has a record ID column.
|
|
237
|
+
if not any([x.data_type_name == dt and x.data_field_name == "RecordId" for x in report.column_list]):
|
|
238
|
+
report.column_list.append(ReportColumn(dt, "RecordId", FieldType.LONG))
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def _process_results(rows: list[list[FieldValue]], columns: list[ReportColumn]) -> list[dict[str, FieldValue]]:
|
|
242
|
+
"""
|
|
243
|
+
Given the results of a report as a list of row values and the report's columns, combine these lists to
|
|
244
|
+
result in a singular list of dictionaries for each row in the results.
|
|
245
|
+
"""
|
|
246
|
+
# It may be the case that two columns have the same data field name but differing data type names.
|
|
247
|
+
# If this occurs, then we need to be able to differentiate these columns in the resulting dictionary.
|
|
248
|
+
prepend_dt: set[str] = set()
|
|
249
|
+
encountered_names: list[str] = []
|
|
250
|
+
for column in columns:
|
|
251
|
+
field_name: str = column.data_field_name
|
|
252
|
+
if field_name in encountered_names:
|
|
253
|
+
prepend_dt.add(field_name)
|
|
254
|
+
else:
|
|
255
|
+
encountered_names.append(field_name)
|
|
256
|
+
|
|
257
|
+
ret: list[dict[str, FieldValue]] = []
|
|
258
|
+
for row in rows:
|
|
259
|
+
row_data: dict[str, FieldValue] = {}
|
|
260
|
+
filter_row: bool = False
|
|
261
|
+
for value, column in zip(row, columns):
|
|
262
|
+
header: str = column.data_field_name
|
|
263
|
+
# If two columns share the same data field name, prepend the data type name of the column to the
|
|
264
|
+
# data field name.
|
|
265
|
+
if header in prepend_dt:
|
|
266
|
+
header = column.data_type_name + "." + header
|
|
267
|
+
row_data.update({header: value})
|
|
268
|
+
if filter_row is False:
|
|
269
|
+
ret.append(row_data)
|
|
270
|
+
return ret
|
|
@@ -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)
|
|
@@ -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
|
|
9
10
|
from sapiopycommons.customreport.custom_report_builder import CustomReportBuilder
|
|
10
11
|
from sapiopycommons.customreport.term_builder import TermBuilder
|
|
11
12
|
from sapiopycommons.datatype.pseudo_data_types import EnbEntryOptionsPseudoDef, NotebookExperimentOptionPseudoDef, \
|
|
12
13
|
NotebookExperimentPseudoDef, ExperimentEntryRecordPseudoDef, EnbEntryPseudoDef
|
|
13
14
|
from sapiopycommons.general.aliases import SapioRecord, UserIdentifier, AliasUtil, FieldValue, \
|
|
14
15
|
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]] =
|
|
204
|
+
rows: list[dict[str, FieldValue]] = CustomReportDictAutoPager(context, criteria).get_all_at_once()
|
|
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]] =
|
|
271
|
+
results: list[dict[str, FieldValue]] = CustomReportDictAutoPager(context, report).get_all_at_once()
|
|
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]] =
|
|
302
|
+
results: list[dict[str, FieldValue]] = CustomReportDictAutoPager(context, report).get_all_at_once()
|
|
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]] =
|
|
335
|
+
results: list[dict[str, FieldValue]] = CustomReportDictAutoPager(context, report).get_all_at_once()
|
|
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
|
|
584
|
+
for row in CustomReportDictAutoPager(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
|
|
649
|
+
return CustomReportDictAutoPager(user, report_builder.build_report_criteria()).get_all_at_once()
|
|
@@ -10,9 +10,9 @@ from sapiopylib.rest.pojo.datatype.FieldDefinition import VeloxIntegerFieldDefin
|
|
|
10
10
|
AbstractVeloxFieldDefinition
|
|
11
11
|
|
|
12
12
|
from sapiopycommons.callbacks.callback_util import CallbackUtil
|
|
13
|
+
from sapiopycommons.customreport.auto_pagers import QuickReportDictAutoPager
|
|
13
14
|
from sapiopycommons.files.file_data_handler import FileDataHandler, FilterList
|
|
14
15
|
from sapiopycommons.general.aliases import UserIdentifier, AliasUtil
|
|
15
|
-
from sapiopycommons.general.custom_report_util import CustomReportUtil
|
|
16
16
|
from sapiopycommons.general.exceptions import SapioUserCancelledException
|
|
17
17
|
from sapiopycommons.general.time_util import TimeUtil
|
|
18
18
|
|
|
@@ -530,7 +530,7 @@ class UniqueSystemValueRule(ColumnRule):
|
|
|
530
530
|
# Run a quick report for all records of this type that match these field values.
|
|
531
531
|
term = RawReportTerm(self.data_type_name, self.data_field_name, RawTermOperation.EQUAL_TO_OPERATOR,
|
|
532
532
|
"{" + ",".join(values) + "}")
|
|
533
|
-
results: list[dict[str, Any]] =
|
|
533
|
+
results: list[dict[str, Any]] = QuickReportDictAutoPager(self.user, term).get_all_at_once()
|
|
534
534
|
existing_values: list[Any] = [x.get(self.data_field_name) for x in results]
|
|
535
535
|
return file_handler.get_in_list(self.header, existing_values)
|
|
536
536
|
|
|
@@ -564,6 +564,6 @@ class ExistingSystemValueRule(ColumnRule):
|
|
|
564
564
|
# Run a quick report for all records of this type that match these field values.
|
|
565
565
|
term = RawReportTerm(self.data_type_name, self.data_field_name, RawTermOperation.EQUAL_TO_OPERATOR,
|
|
566
566
|
"{" + ",".join(values) + "}")
|
|
567
|
-
results: list[dict[str, Any]] =
|
|
567
|
+
results: list[dict[str, Any]] = QuickReportDictAutoPager(self.user, term).get_all_at_once()
|
|
568
568
|
existing_values: list[Any] = [x.get(self.data_field_name) for x in results]
|
|
569
569
|
return file_handler.get_not_in_list(self.header, existing_values)
|
|
@@ -95,7 +95,7 @@ class AccessionWithPrefixSuffix(AbstractAccessionServiceOperator):
|
|
|
95
95
|
|
|
96
96
|
@property
|
|
97
97
|
def default_accessor_name(self):
|
|
98
|
-
return "PREFIX_AND_SUFFIX" + "(" + self.prefix + "," + self.suffix + ")"
|
|
98
|
+
return "PREFIX_AND_SUFFIX" + "(" + self.prefix + "," + self.suffix + ")"
|
|
99
99
|
|
|
100
100
|
|
|
101
101
|
class AccessionGlobalPrefixSuffix(AbstractAccessionServiceOperator):
|
{sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/general/audit_log.py
RENAMED
|
@@ -3,11 +3,11 @@ from enum import Enum
|
|
|
3
3
|
from sapiopylib.rest.User import SapioUser
|
|
4
4
|
from sapiopylib.rest.pojo.CustomReport import ReportColumn, CustomReportCriteria
|
|
5
5
|
|
|
6
|
+
from sapiopycommons.customreport.auto_pagers import CustomReportDictAutoPager
|
|
6
7
|
from sapiopycommons.customreport.column_builder import ColumnBuilder
|
|
7
8
|
from sapiopycommons.customreport.term_builder import TermBuilder
|
|
8
9
|
from sapiopycommons.datatype.pseudo_data_types import AuditLogPseudoDef
|
|
9
10
|
from sapiopycommons.general.aliases import RecordIdentifier, AliasUtil, UserIdentifier, FieldIdentifier, FieldValue
|
|
10
|
-
from sapiopycommons.general.custom_report_util import CustomReportUtil
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class EventType(Enum):
|
|
@@ -164,7 +164,7 @@ class AuditLogUtil:
|
|
|
164
164
|
criteria = AuditLogUtil.create_data_record_audit_log_report(records, fields)
|
|
165
165
|
|
|
166
166
|
# Then we must run the custom report using that criteria.
|
|
167
|
-
raw_report_data: list[dict[str, FieldValue]] =
|
|
167
|
+
raw_report_data: list[dict[str, FieldValue]] = CustomReportDictAutoPager(self.user, criteria).get_all_at_once()
|
|
168
168
|
|
|
169
169
|
# This section will prepare a map matching the original RecordIdentifier by record id.
|
|
170
170
|
# This is because the audit log entries will have record ids, but we want the keys in our result map
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import warnings
|
|
1
2
|
from collections.abc import Iterable
|
|
2
3
|
|
|
3
4
|
from sapiopylib.rest.DataMgmtService import DataMgmtServer
|
|
@@ -40,6 +41,7 @@ class CustomReportUtil:
|
|
|
40
41
|
had a Sample column with a data field name of Identifier and a Request column with the same data field name,
|
|
41
42
|
then the dictionary keys for these columns would be Sample.Identifier and Request.Identifier respectively.
|
|
42
43
|
"""
|
|
44
|
+
warnings.warn("Deprecated in favor of the SystemReportDictAutoPager class.", DeprecationWarning)
|
|
43
45
|
results: tuple = CustomReportUtil._exhaust_system_report(context, report_name, page_limit,
|
|
44
46
|
page_size, page_number)
|
|
45
47
|
columns: list[ReportColumn] = results[0]
|
|
@@ -82,6 +84,7 @@ class CustomReportUtil:
|
|
|
82
84
|
had a Sample column with a data field name of Identifier and a Request column with the same data field name,
|
|
83
85
|
then the dictionary keys for these columns would be Sample.Identifier and Request.Identifier respectively.
|
|
84
86
|
"""
|
|
87
|
+
warnings.warn("Deprecated in favor of the CustomReportDictAutoPager class.", DeprecationWarning)
|
|
85
88
|
results: tuple = CustomReportUtil._exhaust_custom_report(context, report_criteria, page_limit,
|
|
86
89
|
page_size, page_number)
|
|
87
90
|
columns: list[ReportColumn] = results[0]
|
|
@@ -117,6 +120,7 @@ class CustomReportUtil:
|
|
|
117
120
|
:return: The results of the report listed row by row, mapping each cell to the header it is under. The header
|
|
118
121
|
values in the dicts are the data field names of the columns.
|
|
119
122
|
"""
|
|
123
|
+
warnings.warn("Deprecated in favor of the QuickReportDictAutoPager class.", DeprecationWarning)
|
|
120
124
|
results: tuple = CustomReportUtil._exhaust_quick_report(context, report_term, page_limit,
|
|
121
125
|
page_size, page_number)
|
|
122
126
|
columns: list[ReportColumn] = results[0]
|
|
@@ -127,7 +131,8 @@ class CustomReportUtil:
|
|
|
127
131
|
def get_system_report_criteria(context: UserIdentifier, report_name: str) -> CustomReport:
|
|
128
132
|
"""
|
|
129
133
|
Retrieve a custom report from the system given the name of the report. This works by querying the system report
|
|
130
|
-
with a page number and size of 1 to minimize the amount of data transfer needed to retrieve the
|
|
134
|
+
with a page number of 0 and page size of 1 to minimize the amount of data transfer needed to retrieve the
|
|
135
|
+
report's config.
|
|
131
136
|
|
|
132
137
|
System reports are also known as predefined searches in the system and must be defined in the data designer for
|
|
133
138
|
a specific data type. That is, saved searches created by users cannot be run using this function.
|
|
@@ -143,6 +148,24 @@ class CustomReportUtil:
|
|
|
143
148
|
report_man = DataMgmtServer.get_custom_report_manager(user)
|
|
144
149
|
return report_man.run_system_report_by_name(report_name, 1, 0)
|
|
145
150
|
|
|
151
|
+
@staticmethod
|
|
152
|
+
def get_quick_report_criteria(context: UserIdentifier, report_term: RawReportTerm) -> CustomReport:
|
|
153
|
+
"""
|
|
154
|
+
Retrieve a quick report from the system given a report term. This works by making a quick report query
|
|
155
|
+
with a page number of 0 and page size of 1 to minimize the amount of data transfer needed to retrieve the
|
|
156
|
+
report's config.
|
|
157
|
+
|
|
158
|
+
Using this, you can add to the root term of the search to then run a new search, or provide it to client
|
|
159
|
+
callbacks or directives that take CustomReports.
|
|
160
|
+
|
|
161
|
+
:param context: The current webhook context or a user object to send requests from.
|
|
162
|
+
:param report_term: The raw report term to use for the quick report.
|
|
163
|
+
:return: The CustomReport object for the given report term.
|
|
164
|
+
"""
|
|
165
|
+
user: SapioUser = AliasUtil.to_sapio_user(context)
|
|
166
|
+
report_man = DataMgmtServer.get_custom_report_manager(user)
|
|
167
|
+
return report_man.run_quick_report(report_term, 1, 0)
|
|
168
|
+
|
|
146
169
|
@staticmethod
|
|
147
170
|
def _exhaust_system_report(context: UserIdentifier,
|
|
148
171
|
report_name: str,
|
|
@@ -6,6 +6,7 @@ from weakref import WeakValueDictionary
|
|
|
6
6
|
|
|
7
7
|
from databind.json import dumps, loads
|
|
8
8
|
from sapiopylib.rest.User import SapioUser
|
|
9
|
+
from sapiopylib.rest.pojo.DataRecord import DataRecord
|
|
9
10
|
|
|
10
11
|
from sapiopycommons.general.exceptions import SapioException
|
|
11
12
|
from sapiopycommons.multimodal.multimodal_data import *
|
|
@@ -5,10 +5,10 @@ from sapiopylib.rest.pojo.CustomReport import CustomReportCriteria
|
|
|
5
5
|
from sapiopylib.rest.pojo.webhook.WebhookContext import SapioWebhookContext
|
|
6
6
|
from sapiopylib.rest.utils.recordmodel.RecordModelWrapper import WrappedType
|
|
7
7
|
|
|
8
|
+
from sapiopycommons.customreport.auto_pagers import CustomReportDictAutoPager, CustomReportRecordAutoPager
|
|
8
9
|
from sapiopycommons.customreport.custom_report_builder import CustomReportBuilder
|
|
9
10
|
from sapiopycommons.datatype.data_fields import ProcessQueueItemFields, SystemFields, ProcessWorkflowTrackingFields
|
|
10
11
|
from sapiopycommons.general.aliases import UserIdentifier, AliasUtil, SapioRecord
|
|
11
|
-
from sapiopycommons.general.custom_report_util import CustomReportUtil
|
|
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
|
|
@@ -185,7 +185,7 @@ class QueueItemHandler:
|
|
|
185
185
|
:return: A list of every queue item in the system that matches the search criteria.
|
|
186
186
|
"""
|
|
187
187
|
report = self.build_queue_item_report(criteria)
|
|
188
|
-
return self.
|
|
188
|
+
return CustomReportRecordAutoPager(self.user, report, wrapper).get_all_at_once()
|
|
189
189
|
|
|
190
190
|
def get_records_from_item_report(self, wrapper: type[WrappedType],
|
|
191
191
|
criteria: QueueItemReportCriteria = QueueItemReportCriteria()) -> list[WrappedType]:
|
|
@@ -203,7 +203,7 @@ class QueueItemHandler:
|
|
|
203
203
|
criteria.not_data_type_names = None
|
|
204
204
|
report = self.build_queue_item_report(criteria)
|
|
205
205
|
record_ids: list[int] = [x[ProcessQueueItemFields.DATA_RECORD_ID__FIELD.field_name]
|
|
206
|
-
for x in
|
|
206
|
+
for x in CustomReportDictAutoPager(self.user, report)]
|
|
207
207
|
return self.rec_handler.query_models_by_id(wrapper, record_ids)
|
|
208
208
|
|
|
209
209
|
def get_queue_items_for_records(self, records: Iterable[SapioRecord], wrapper: type[WrappedType],
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import warnings
|
|
3
4
|
from collections.abc import Iterable
|
|
4
5
|
from weakref import WeakValueDictionary
|
|
5
6
|
|
|
@@ -232,7 +233,7 @@ class RecordHandler:
|
|
|
232
233
|
:param page_size: The size of the pages to query. If None, the page size may be limited by the platform.
|
|
233
234
|
:return: The record models for the queried records mapped in a dictionary by their record ID.
|
|
234
235
|
"""
|
|
235
|
-
return {x
|
|
236
|
+
return {AliasUtil.to_record_id(x): x for x in self.query_models_by_id(wrapper_type, ids, page_limit, page_size)}
|
|
236
237
|
|
|
237
238
|
def query_all_models(self, wrapper_type: type[WrappedType], page_limit: int | None = None,
|
|
238
239
|
page_size: int | None = None) -> list[WrappedType]:
|
|
@@ -300,6 +301,7 @@ class RecordHandler:
|
|
|
300
301
|
not None, in which case it overwrites the given report's value. Note that the number of the first page is 0.
|
|
301
302
|
:return: The record models for the queried records that matched the given report.
|
|
302
303
|
"""
|
|
304
|
+
warnings.warn("Deprecated in favor of the [System/Custom/Quick]ReportRecordAutoPager classes.", DeprecationWarning)
|
|
303
305
|
if isinstance(report_name, str):
|
|
304
306
|
results: list[dict[str, FieldValue]] = CustomReportUtil.run_system_report(self.user, report_name, filters,
|
|
305
307
|
page_limit, page_size, page_number)
|
|
@@ -893,14 +895,14 @@ class RecordHandler:
|
|
|
893
895
|
|
|
894
896
|
@staticmethod
|
|
895
897
|
def values_to_field_maps(field_name: FieldIdentifier, values: Iterable[FieldValue],
|
|
896
|
-
existing_fields: list[
|
|
898
|
+
existing_fields: list[FieldMap] | None = None) -> list[FieldMap]:
|
|
897
899
|
"""
|
|
898
900
|
Add a list of values for a specific field to a list of dictionaries pairing each value to that field name.
|
|
899
901
|
|
|
900
902
|
:param field_name: The name of the field that the values are from.
|
|
901
903
|
:param values: A list of field values.
|
|
902
904
|
:param existing_fields: An optional existing fields map list to add the new values to. Values are added in the
|
|
903
|
-
|
|
905
|
+
list in the same order that they appear. If no existing fields are provided, returns a new fields map list.
|
|
904
906
|
:return: A fields map list that contains the given values mapped by the given field name.
|
|
905
907
|
"""
|
|
906
908
|
# Update the existing fields map list if one is given.
|
|
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.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/chem/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/datatype/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/eln/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/files/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/files/file_bridge.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/files/file_util.py
RENAMED
|
File without changes
|
{sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/files/file_writer.py
RENAMED
|
File without changes
|
|
@@ -2,8 +2,8 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from weakref import WeakValueDictionary
|
|
4
4
|
|
|
5
|
-
from sapiopylib.rest.User import SapioUser
|
|
6
5
|
from databind.json import dumps
|
|
6
|
+
from sapiopylib.rest.User import SapioUser
|
|
7
7
|
|
|
8
8
|
from sapiopycommons.flowcyto.flowcyto_data import FlowJoWorkspaceInputJson, UploadFCSInputJson, \
|
|
9
9
|
ComputeFlowStatisticsInputJson
|
|
File without changes
|
{sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/general/__init__.py
RENAMED
|
File without changes
|
{sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/general/aliases.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/general/time_util.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/rules/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/src/sapiopycommons/webhook/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/tests/AF-A0A009IHW8-F1-model_v4.cif
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2025.1.21a408 → sapiopycommons-2025.2.3a410}/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.1.21a408 → sapiopycommons-2025.2.3a410}/tests/flowcyto/COVID19_W_001_O.fcs
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|