sapiopycommons 2024.8.28a315__py3-none-any.whl → 2024.8.29a317__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.
- sapiopycommons/callbacks/callback_util.py +37 -133
- sapiopycommons/datatype/attachment_util.py +10 -11
- sapiopycommons/eln/experiment_handler.py +48 -209
- sapiopycommons/eln/experiment_report_util.py +129 -33
- sapiopycommons/files/complex_data_loader.py +4 -5
- sapiopycommons/files/file_bridge.py +14 -15
- sapiopycommons/files/file_bridge_handler.py +5 -27
- sapiopycommons/files/file_data_handler.py +5 -2
- sapiopycommons/files/file_util.py +5 -38
- sapiopycommons/files/file_validator.py +11 -26
- sapiopycommons/files/file_writer.py +15 -44
- sapiopycommons/general/aliases.py +3 -147
- sapiopycommons/general/custom_report_util.py +32 -34
- sapiopycommons/general/popup_util.py +0 -17
- sapiopycommons/general/time_util.py +0 -40
- sapiopycommons/multimodal/multimodal_data.py +1 -0
- sapiopycommons/processtracking/endpoints.py +22 -22
- sapiopycommons/recordmodel/record_handler.py +77 -228
- sapiopycommons/rules/eln_rule_handler.py +25 -34
- sapiopycommons/rules/on_save_rule_handler.py +31 -34
- sapiopycommons/webhook/webhook_handlers.py +26 -90
- {sapiopycommons-2024.8.28a315.dist-info → sapiopycommons-2024.8.29a317.dist-info}/METADATA +1 -1
- sapiopycommons-2024.8.29a317.dist-info/RECORD +43 -0
- sapiopycommons/customreport/__init__.py +0 -0
- sapiopycommons/customreport/column_builder.py +0 -60
- sapiopycommons/customreport/custom_report_builder.py +0 -125
- sapiopycommons/customreport/term_builder.py +0 -299
- sapiopycommons/general/audit_log.py +0 -196
- sapiopycommons/general/sapio_links.py +0 -50
- sapiopycommons/webhook/webservice_handlers.py +0 -67
- sapiopycommons-2024.8.28a315.dist-info/RECORD +0 -50
- {sapiopycommons-2024.8.28a315.dist-info → sapiopycommons-2024.8.29a317.dist-info}/WHEEL +0 -0
- {sapiopycommons-2024.8.28a315.dist-info → sapiopycommons-2024.8.29a317.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,47 +1,24 @@
|
|
|
1
1
|
from collections.abc import Iterable
|
|
2
2
|
from typing import Any
|
|
3
3
|
|
|
4
|
-
from sapiopylib.rest.User import SapioUser
|
|
5
4
|
from sapiopylib.rest.pojo.DataRecord import DataRecord
|
|
6
|
-
from sapiopylib.rest.pojo.datatype.FieldDefinition import FieldType
|
|
7
5
|
from sapiopylib.rest.pojo.eln.ElnExperiment import ElnExperiment
|
|
8
|
-
from sapiopylib.rest.pojo.webhook.WebhookContext import SapioWebhookContext
|
|
9
6
|
from sapiopylib.rest.utils.Protocols import ElnExperimentProtocol
|
|
10
7
|
from sapiopylib.rest.utils.recordmodel.PyRecordModel import PyRecordModel
|
|
11
|
-
from sapiopylib.rest.utils.recordmodel.RecordModelWrapper import WrappedRecordModel, WrappedType
|
|
8
|
+
from sapiopylib.rest.utils.recordmodel.RecordModelWrapper import WrappedRecordModel, WrappedType
|
|
12
9
|
|
|
13
|
-
from sapiopycommons.general.exceptions import SapioException
|
|
14
|
-
|
|
15
|
-
FieldValue = int | float | str | bool | None
|
|
16
|
-
"""Allowable values for fields in the system."""
|
|
17
10
|
RecordModel = PyRecordModel | WrappedRecordModel | WrappedType
|
|
18
11
|
"""Different forms that a record model could take."""
|
|
19
12
|
SapioRecord = DataRecord | RecordModel
|
|
20
13
|
"""A record could be provided as either a DataRecord, PyRecordModel, or WrappedRecordModel (WrappedType)."""
|
|
21
14
|
RecordIdentifier = SapioRecord | int
|
|
22
15
|
"""A RecordIdentifier is either a record type or an integer for the record's record ID."""
|
|
23
|
-
DataTypeIdentifier = SapioRecord | type[WrappedType] | str
|
|
24
|
-
"""A DataTypeIdentifier is either a SapioRecord, a record model wrapper type, or a string."""
|
|
25
|
-
FieldIdentifier = WrapperField | str | tuple[str, FieldType]
|
|
26
|
-
"""A FieldIdentifier is either wrapper field from a record model wrapper, a string, or a tuple of string
|
|
27
|
-
and field type."""
|
|
28
|
-
FieldIdentifierKey = WrapperField | str
|
|
29
|
-
"""A FieldIdentifierKey is a FieldIdentifier, except it can't be a tuple, s tuples can't be used as keys in
|
|
30
|
-
dictionaries.."""
|
|
31
|
-
HasFieldWrappers = type[WrappedType] | WrappedRecordModel
|
|
32
|
-
"""An identifier for classes that have wrapper fields."""
|
|
33
16
|
ExperimentIdentifier = ElnExperimentProtocol | ElnExperiment | int
|
|
34
17
|
"""An ExperimentIdentifier is either an experiment protocol, experiment, or an integer for te experiment's notebook
|
|
35
18
|
ID."""
|
|
36
|
-
FieldMap = dict[str,
|
|
19
|
+
FieldMap = dict[str, Any]
|
|
37
20
|
"""A field map is simply a dict of data field names to values. The purpose of aliasing this is to help distinguish
|
|
38
21
|
any random dict in a webhook from one which is explicitly used for record fields."""
|
|
39
|
-
FieldIdentifierMap = dict[FieldIdentifierKey, FieldValue]
|
|
40
|
-
"""A field identifier map is the same thing as a field map, except the keys can be field identifiers instead
|
|
41
|
-
of just strings. Note that although one of the allowed field identifiers is a tuple, you can't use tuples as
|
|
42
|
-
keys in a dictionary."""
|
|
43
|
-
UserIdentifier = SapioWebhookContext | SapioUser
|
|
44
|
-
"""An identifier for classes from which a user object can be used for sending requests."""
|
|
45
22
|
|
|
46
23
|
|
|
47
24
|
# FR-46064 - Initial port of PyWebhookUtils to sapiopycommons.
|
|
@@ -73,123 +50,7 @@ class AliasUtil:
|
|
|
73
50
|
|
|
74
51
|
:return: A list of record IDs for the input records.
|
|
75
52
|
"""
|
|
76
|
-
return [(
|
|
77
|
-
|
|
78
|
-
@staticmethod
|
|
79
|
-
def to_record_id(record: RecordIdentifier):
|
|
80
|
-
"""
|
|
81
|
-
Convert a single variable that could be either an integer, DataRecord, PyRecordModel,
|
|
82
|
-
or WrappedRecordModel to just an integer (taking the record ID from the record).
|
|
83
|
-
|
|
84
|
-
:return: A record ID for the input record.
|
|
85
|
-
"""
|
|
86
|
-
return record if isinstance(record, int) else record.record_id
|
|
87
|
-
|
|
88
|
-
@staticmethod
|
|
89
|
-
def to_data_type_name(value: DataTypeIdentifier) -> str:
|
|
90
|
-
"""
|
|
91
|
-
Convert a given value to a data type name.
|
|
92
|
-
|
|
93
|
-
:param value: A value which is a string, record, or record model type.
|
|
94
|
-
:return: A string of the data type name of the input value.
|
|
95
|
-
"""
|
|
96
|
-
if isinstance(value, str):
|
|
97
|
-
return value
|
|
98
|
-
if isinstance(value, SapioRecord):
|
|
99
|
-
return value.data_type_name
|
|
100
|
-
return value.get_wrapper_data_type_name()
|
|
101
|
-
|
|
102
|
-
@staticmethod
|
|
103
|
-
def to_data_type_names(values: Iterable[DataTypeIdentifier], return_set: bool = False) -> list[str] | set[str]:
|
|
104
|
-
"""
|
|
105
|
-
Convert a given iterable of values to a list or set of data type names.
|
|
106
|
-
|
|
107
|
-
:param values: An iterable of values which are strings, records, or record model types.
|
|
108
|
-
:param return_set: If true, return a set instead of a list.
|
|
109
|
-
:return: A list or set of strings of the data type name of the input value.
|
|
110
|
-
"""
|
|
111
|
-
values = [AliasUtil.to_data_type_name(x) for x in values]
|
|
112
|
-
return set(values) if return_set else values
|
|
113
|
-
|
|
114
|
-
@staticmethod
|
|
115
|
-
def to_singular_data_type_name(values: Iterable[DataTypeIdentifier]) -> str:
|
|
116
|
-
"""
|
|
117
|
-
Convert a given iterable of values to a singular data type name that they share. Throws an exception if more
|
|
118
|
-
than one data type name exists in the provided list of identifiers.
|
|
119
|
-
|
|
120
|
-
:param values: An iterable of values which are strings, records, or record model types.
|
|
121
|
-
:return: The single data type name that the input vales share.
|
|
122
|
-
"""
|
|
123
|
-
data_types: set[str] = AliasUtil.to_data_type_names(values, True)
|
|
124
|
-
if len(data_types) > 1:
|
|
125
|
-
raise SapioException(f"Provided values contain multiple data types: {data_types}. "
|
|
126
|
-
f"Only expecting a single data type.")
|
|
127
|
-
return data_types.pop()
|
|
128
|
-
|
|
129
|
-
@staticmethod
|
|
130
|
-
def to_data_field_name(value: FieldIdentifier) -> str:
|
|
131
|
-
"""
|
|
132
|
-
Convert a string or WrapperField to a data field name string.
|
|
133
|
-
|
|
134
|
-
:param value: A string or WrapperField.
|
|
135
|
-
:return: A string of the data field name of the input value.
|
|
136
|
-
"""
|
|
137
|
-
if isinstance(value, tuple):
|
|
138
|
-
return value[0]
|
|
139
|
-
if isinstance(value, WrapperField):
|
|
140
|
-
return value.field_name
|
|
141
|
-
return value
|
|
142
|
-
|
|
143
|
-
@staticmethod
|
|
144
|
-
def to_data_field_names(values: Iterable[FieldIdentifier]) -> list[str]:
|
|
145
|
-
"""
|
|
146
|
-
Convert an iterable of strings or WrapperFields to a list of data field name strings.
|
|
147
|
-
|
|
148
|
-
:param values: An iterable of strings or WrapperFields.
|
|
149
|
-
:return: A list of strings of the data field names of the input values.
|
|
150
|
-
"""
|
|
151
|
-
return [AliasUtil.to_data_field_name(x) for x in values]
|
|
152
|
-
|
|
153
|
-
@staticmethod
|
|
154
|
-
def to_data_field_names_dict(values: dict[FieldIdentifierKey, Any]) -> dict[str, Any]:
|
|
155
|
-
"""
|
|
156
|
-
Take a dictionary whose keys are field identifiers and convert them all to strings for the data field name.
|
|
157
|
-
|
|
158
|
-
:param values: A dictionary of field identifiers to field values.
|
|
159
|
-
:return: A dictionary of strings of the data field names to field values for the input values.
|
|
160
|
-
"""
|
|
161
|
-
ret_dict: dict[str, FieldValue] = {}
|
|
162
|
-
for field, value in values.items():
|
|
163
|
-
ret_dict[AliasUtil.to_data_field_name(field)] = value
|
|
164
|
-
return ret_dict
|
|
165
|
-
|
|
166
|
-
@staticmethod
|
|
167
|
-
def to_data_field_names_list_dict(values: list[dict[FieldIdentifierKey, Any]]) -> list[dict[str, Any]]:
|
|
168
|
-
ret_list: list[dict[str, Any]] = []
|
|
169
|
-
for field_map in values:
|
|
170
|
-
ret_list.append(AliasUtil.to_data_field_names_dict(field_map))
|
|
171
|
-
return ret_list
|
|
172
|
-
|
|
173
|
-
@staticmethod
|
|
174
|
-
def to_field_type(field: FieldIdentifier, data_type: HasFieldWrappers | None = None) -> FieldType:
|
|
175
|
-
"""
|
|
176
|
-
Convert a given field identifier to the field type for that field.
|
|
177
|
-
|
|
178
|
-
:param field: A string or WrapperField.
|
|
179
|
-
:param data_type: If the field is provided as a string, then a record model wrapper or wrapped record model
|
|
180
|
-
must be provided to determine the field type.
|
|
181
|
-
:return: The field type of the given field.
|
|
182
|
-
"""
|
|
183
|
-
if isinstance(field, tuple):
|
|
184
|
-
return field[1]
|
|
185
|
-
if isinstance(field, WrapperField):
|
|
186
|
-
return field.field_type
|
|
187
|
-
for var in dir(data_type):
|
|
188
|
-
attr = getattr(data_type, var)
|
|
189
|
-
if isinstance(attr, WrapperField) and attr.field_name == field:
|
|
190
|
-
return attr.field_type
|
|
191
|
-
raise SapioException(f"The wrapper of data type \"{data_type.get_wrapper_data_type_name()}\" doesn't have a "
|
|
192
|
-
f"field with the name \"{field}\",")
|
|
53
|
+
return [(x if isinstance(x, int) else x.record_id) for x in records]
|
|
193
54
|
|
|
194
55
|
@staticmethod
|
|
195
56
|
def to_field_map_lists(records: Iterable[SapioRecord]) -> list[FieldMap]:
|
|
@@ -202,7 +63,6 @@ class AliasUtil:
|
|
|
202
63
|
field_map_list: list[FieldMap] = []
|
|
203
64
|
for record in records:
|
|
204
65
|
if isinstance(record, DataRecord):
|
|
205
|
-
# noinspection PyTypeChecker
|
|
206
66
|
field_map_list.append(record.get_fields())
|
|
207
67
|
else:
|
|
208
68
|
field_map_list.append(record.fields.copy_to_dict())
|
|
@@ -220,7 +80,3 @@ class AliasUtil:
|
|
|
220
80
|
if isinstance(experiment, ElnExperiment):
|
|
221
81
|
return experiment.notebook_experiment_id
|
|
222
82
|
return experiment.get_id()
|
|
223
|
-
|
|
224
|
-
@staticmethod
|
|
225
|
-
def to_sapio_user(context: UserIdentifier) -> SapioUser:
|
|
226
|
-
return context if isinstance(context, SapioUser) else context.user
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
from collections.abc import Iterable
|
|
2
|
+
from typing import Any
|
|
2
3
|
|
|
3
4
|
from sapiopylib.rest.DataMgmtService import DataMgmtServer
|
|
4
5
|
from sapiopylib.rest.User import SapioUser
|
|
5
6
|
from sapiopylib.rest.pojo.CustomReport import ReportColumn, CustomReport, CustomReportCriteria, RawReportTerm
|
|
6
|
-
|
|
7
|
-
from sapiopycommons.general.aliases import UserIdentifier, FieldValue, AliasUtil, FieldIdentifierKey
|
|
7
|
+
from sapiopylib.rest.pojo.webhook.WebhookContext import SapioWebhookContext
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
# FR-46064 - Initial port of PyWebhookUtils to sapiopycommons.
|
|
11
11
|
class CustomReportUtil:
|
|
12
12
|
@staticmethod
|
|
13
|
-
def run_system_report(context:
|
|
13
|
+
def run_system_report(context: SapioWebhookContext | SapioUser,
|
|
14
14
|
report_name: str,
|
|
15
|
-
filters: dict[
|
|
15
|
+
filters: dict[str, Iterable[Any]] | None = None,
|
|
16
16
|
page_limit: int | None = None,
|
|
17
17
|
page_size: int | None = None,
|
|
18
|
-
page_number: int | None = None) -> list[dict[str,
|
|
18
|
+
page_number: int | None = None) -> list[dict[str, Any]]:
|
|
19
19
|
"""
|
|
20
20
|
Run a system report and return the results of that report as a list of dictionaries for the values of each
|
|
21
21
|
column in each row.
|
|
@@ -41,16 +41,16 @@ class CustomReportUtil:
|
|
|
41
41
|
results: tuple = CustomReportUtil.__exhaust_system_report(context, report_name, page_limit,
|
|
42
42
|
page_size, page_number)
|
|
43
43
|
columns: list[ReportColumn] = results[0]
|
|
44
|
-
rows: list[list[
|
|
44
|
+
rows: list[list[Any]] = results[1]
|
|
45
45
|
return CustomReportUtil.__process_results(rows, columns, filters)
|
|
46
46
|
|
|
47
47
|
@staticmethod
|
|
48
|
-
def run_custom_report(context:
|
|
48
|
+
def run_custom_report(context: SapioWebhookContext | SapioUser,
|
|
49
49
|
report_criteria: CustomReportCriteria,
|
|
50
|
-
filters: dict[
|
|
50
|
+
filters: dict[str, Iterable[Any]] | None = None,
|
|
51
51
|
page_limit: int | None = None,
|
|
52
52
|
page_size: int | None = None,
|
|
53
|
-
page_number: int | None = None) -> list[dict[str,
|
|
53
|
+
page_number: int | None = None) -> list[dict[str, Any]]:
|
|
54
54
|
"""
|
|
55
55
|
Run a custom report and return the results of that report as a list of dictionaries for the values of each
|
|
56
56
|
column in each row.
|
|
@@ -82,16 +82,16 @@ class CustomReportUtil:
|
|
|
82
82
|
results: tuple = CustomReportUtil.__exhaust_custom_report(context, report_criteria, page_limit,
|
|
83
83
|
page_size, page_number)
|
|
84
84
|
columns: list[ReportColumn] = results[0]
|
|
85
|
-
rows: list[list[
|
|
85
|
+
rows: list[list[Any]] = results[1]
|
|
86
86
|
return CustomReportUtil.__process_results(rows, columns, filters)
|
|
87
87
|
|
|
88
88
|
@staticmethod
|
|
89
|
-
def run_quick_report(context:
|
|
89
|
+
def run_quick_report(context: SapioWebhookContext | SapioUser,
|
|
90
90
|
report_term: RawReportTerm,
|
|
91
|
-
filters: dict[
|
|
91
|
+
filters: dict[str, Iterable[Any]] | None = None,
|
|
92
92
|
page_limit: int | None = None,
|
|
93
93
|
page_size: int | None = None,
|
|
94
|
-
page_number: int | None = None) -> list[dict[str,
|
|
94
|
+
page_number: int | None = None) -> list[dict[str, Any]]:
|
|
95
95
|
"""
|
|
96
96
|
Run a quick report and return the results of that report as a list of dictionaries for the values of each
|
|
97
97
|
column in each row.
|
|
@@ -115,11 +115,11 @@ class CustomReportUtil:
|
|
|
115
115
|
results: tuple = CustomReportUtil.__exhaust_quick_report(context, report_term, page_limit,
|
|
116
116
|
page_size, page_number)
|
|
117
117
|
columns: list[ReportColumn] = results[0]
|
|
118
|
-
rows: list[list[
|
|
118
|
+
rows: list[list[Any]] = results[1]
|
|
119
119
|
return CustomReportUtil.__process_results(rows, columns, filters)
|
|
120
120
|
|
|
121
121
|
@staticmethod
|
|
122
|
-
def get_system_report_criteria(context:
|
|
122
|
+
def get_system_report_criteria(context: SapioWebhookContext | SapioUser, report_name: str) -> CustomReport:
|
|
123
123
|
"""
|
|
124
124
|
Retrieve a custom report from the system given the name of the report. This works by querying the system report
|
|
125
125
|
with a page number and size of 1 to minimize the amount of data transfer needed to retrieve the report's config.
|
|
@@ -134,27 +134,27 @@ class CustomReportUtil:
|
|
|
134
134
|
:param report_name: The name of the system report to run.
|
|
135
135
|
:return: The CustomReport object for the given system report name.
|
|
136
136
|
"""
|
|
137
|
-
user: SapioUser =
|
|
137
|
+
user: SapioUser = context if isinstance(context, SapioUser) else context.user
|
|
138
138
|
report_man = DataMgmtServer.get_custom_report_manager(user)
|
|
139
139
|
return report_man.run_system_report_by_name(report_name, 1, 1)
|
|
140
140
|
|
|
141
141
|
@staticmethod
|
|
142
|
-
def __exhaust_system_report(context:
|
|
142
|
+
def __exhaust_system_report(context: SapioWebhookContext | SapioUser,
|
|
143
143
|
report_name: str,
|
|
144
144
|
page_limit: int | None,
|
|
145
145
|
page_size: int | None,
|
|
146
146
|
page_number: int | None) \
|
|
147
|
-
-> tuple[list[ReportColumn], list[list[
|
|
147
|
+
-> tuple[list[ReportColumn], list[list[Any]]]:
|
|
148
148
|
"""
|
|
149
149
|
Given a system report, iterate over every page of the report and collect the results
|
|
150
150
|
until there are no remaining pages.
|
|
151
151
|
"""
|
|
152
|
-
user: SapioUser =
|
|
152
|
+
user: SapioUser = context if isinstance(context, SapioUser) else context.user
|
|
153
153
|
report_man = DataMgmtServer.get_custom_report_manager(user)
|
|
154
154
|
|
|
155
155
|
result = None
|
|
156
156
|
has_next_page: bool = True
|
|
157
|
-
rows: list[list[
|
|
157
|
+
rows: list[list[Any]] = []
|
|
158
158
|
cur_page: int = 1
|
|
159
159
|
while has_next_page and (not page_limit or cur_page <= page_limit):
|
|
160
160
|
result = report_man.run_system_report_by_name(report_name, page_size, page_number)
|
|
@@ -166,17 +166,17 @@ class CustomReportUtil:
|
|
|
166
166
|
return result.column_list, rows
|
|
167
167
|
|
|
168
168
|
@staticmethod
|
|
169
|
-
def __exhaust_custom_report(context:
|
|
169
|
+
def __exhaust_custom_report(context: SapioWebhookContext | SapioUser,
|
|
170
170
|
report: CustomReportCriteria,
|
|
171
171
|
page_limit: int | None,
|
|
172
172
|
page_size: int | None,
|
|
173
173
|
page_number: int | None) \
|
|
174
|
-
-> tuple[list[ReportColumn], list[list[
|
|
174
|
+
-> tuple[list[ReportColumn], list[list[Any]]]:
|
|
175
175
|
"""
|
|
176
176
|
Given a custom report, iterate over every page of the report and collect the results
|
|
177
177
|
until there are no remaining pages.
|
|
178
178
|
"""
|
|
179
|
-
user: SapioUser =
|
|
179
|
+
user: SapioUser = context if isinstance(context, SapioUser) else context.user
|
|
180
180
|
report_man = DataMgmtServer.get_custom_report_manager(user)
|
|
181
181
|
|
|
182
182
|
result = None
|
|
@@ -185,7 +185,7 @@ class CustomReportUtil:
|
|
|
185
185
|
if page_number is not None:
|
|
186
186
|
report.page_number = page_number
|
|
187
187
|
has_next_page: bool = True
|
|
188
|
-
rows: list[list[
|
|
188
|
+
rows: list[list[Any]] = []
|
|
189
189
|
cur_page: int = 1
|
|
190
190
|
while has_next_page and (not page_limit or cur_page <= page_limit):
|
|
191
191
|
result = report_man.run_custom_report(report)
|
|
@@ -197,22 +197,22 @@ class CustomReportUtil:
|
|
|
197
197
|
return result.column_list, rows
|
|
198
198
|
|
|
199
199
|
@staticmethod
|
|
200
|
-
def __exhaust_quick_report(context:
|
|
200
|
+
def __exhaust_quick_report(context: SapioWebhookContext | SapioUser,
|
|
201
201
|
report_term: RawReportTerm,
|
|
202
202
|
page_limit: int | None,
|
|
203
203
|
page_size: int | None,
|
|
204
204
|
page_number: int | None) \
|
|
205
|
-
-> tuple[list[ReportColumn], list[list[
|
|
205
|
+
-> tuple[list[ReportColumn], list[list[Any]]]:
|
|
206
206
|
"""
|
|
207
207
|
Given a quick report, iterate over every page of the report and collect the results
|
|
208
208
|
until there are no remaining pages.
|
|
209
209
|
"""
|
|
210
|
-
user: SapioUser =
|
|
210
|
+
user: SapioUser = context if isinstance(context, SapioUser) else context.user
|
|
211
211
|
report_man = DataMgmtServer.get_custom_report_manager(user)
|
|
212
212
|
|
|
213
213
|
result = None
|
|
214
214
|
has_next_page: bool = True
|
|
215
|
-
rows: list[list[
|
|
215
|
+
rows: list[list[Any]] = []
|
|
216
216
|
cur_page: int = 1
|
|
217
217
|
while has_next_page and (not page_limit or cur_page <= page_limit):
|
|
218
218
|
result = report_man.run_quick_report(report_term, page_size, page_number)
|
|
@@ -224,8 +224,8 @@ class CustomReportUtil:
|
|
|
224
224
|
return result.column_list, rows
|
|
225
225
|
|
|
226
226
|
@staticmethod
|
|
227
|
-
def __process_results(rows: list[list[
|
|
228
|
-
filters: dict[
|
|
227
|
+
def __process_results(rows: list[list[Any]], columns: list[ReportColumn],
|
|
228
|
+
filters: dict[str, Iterable[Any]] | None) -> list[dict[str, Any]]:
|
|
229
229
|
"""
|
|
230
230
|
Given the results of a report as a list of row values and the report's columns, combine these lists to
|
|
231
231
|
result in a singular list of dictionaries for each row in the results.
|
|
@@ -243,11 +243,9 @@ class CustomReportUtil:
|
|
|
243
243
|
else:
|
|
244
244
|
encountered_names.append(field_name)
|
|
245
245
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
ret: list[dict[str, FieldValue]] = []
|
|
246
|
+
ret: list[dict[str, Any]] = []
|
|
249
247
|
for row in rows:
|
|
250
|
-
row_data: dict[str,
|
|
248
|
+
row_data: dict[str, Any] = {}
|
|
251
249
|
filter_row: bool = False
|
|
252
250
|
for value, column in zip(row, columns):
|
|
253
251
|
header: str = column.data_field_name
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import warnings
|
|
2
|
-
|
|
3
1
|
from sapiopylib.rest.DataMgmtService import DataMgmtServer
|
|
4
2
|
from sapiopylib.rest.pojo.datatype.DataType import DataTypeDefinition
|
|
5
3
|
from sapiopylib.rest.pojo.datatype.FieldDefinition import VeloxStringFieldDefinition, AbstractVeloxFieldDefinition, \
|
|
@@ -53,7 +51,6 @@ class PopupUtil:
|
|
|
53
51
|
:param request_context: Context that will be returned to the webhook server in the client callback result.
|
|
54
52
|
:return: A SapioWebhookResult with the popup as its client callback request.
|
|
55
53
|
"""
|
|
56
|
-
warnings.warn("PopupUtil is deprecated as of 24.5+. Use CallbackUtil instead.", DeprecationWarning)
|
|
57
54
|
if display_name is None:
|
|
58
55
|
display_name = data_type
|
|
59
56
|
if plural_display_name is None:
|
|
@@ -100,7 +97,6 @@ class PopupUtil:
|
|
|
100
97
|
:param request_context: Context that will be returned to the webhook server in the client callback result.
|
|
101
98
|
:return: A SapioWebhookResult with the popup as its client callback request.
|
|
102
99
|
"""
|
|
103
|
-
warnings.warn("PopupUtil is deprecated as of 24.5+. Use CallbackUtil instead.", DeprecationWarning)
|
|
104
100
|
# Get the field definitions of the data type.
|
|
105
101
|
data_type: str = record.data_type_name
|
|
106
102
|
type_man = DataMgmtServer.get_data_type_manager(context.user)
|
|
@@ -159,7 +155,6 @@ class PopupUtil:
|
|
|
159
155
|
:param request_context: Context that will be returned to the webhook server in the client callback result.
|
|
160
156
|
:return: A SapioWebhookResult with the popup as its client callback request.
|
|
161
157
|
"""
|
|
162
|
-
warnings.warn("PopupUtil is deprecated as of 24.5+. Use CallbackUtil instead.", DeprecationWarning)
|
|
163
158
|
if max_length is None:
|
|
164
159
|
max_length = len(default_value) if default_value else 100
|
|
165
160
|
string_field = VeloxStringFieldDefinition(data_type, field_name, field_name, default_value=default_value,
|
|
@@ -196,7 +191,6 @@ class PopupUtil:
|
|
|
196
191
|
:param request_context: Context that will be returned to the webhook server in the client callback result.
|
|
197
192
|
:return: A SapioWebhookResult with the popup as its client callback request.
|
|
198
193
|
"""
|
|
199
|
-
warnings.warn("PopupUtil is deprecated as of 24.5+. Use CallbackUtil instead.", DeprecationWarning)
|
|
200
194
|
if default_value is None:
|
|
201
195
|
default_value = max(0, min_value)
|
|
202
196
|
integer_field = VeloxIntegerFieldDefinition(data_type, field_name, field_name, default_value=default_value,
|
|
@@ -235,7 +229,6 @@ class PopupUtil:
|
|
|
235
229
|
:param request_context: Context that will be returned to the webhook server in the client callback result.
|
|
236
230
|
:return: A SapioWebhookResult with the popup as its client callback request.
|
|
237
231
|
"""
|
|
238
|
-
warnings.warn("PopupUtil is deprecated as of 24.5+. Use CallbackUtil instead.", DeprecationWarning)
|
|
239
232
|
if default_value is None:
|
|
240
233
|
default_value = min_value
|
|
241
234
|
double_field = VeloxDoubleFieldDefinition(data_type, field_name, field_name, default_value=default_value,
|
|
@@ -267,7 +260,6 @@ class PopupUtil:
|
|
|
267
260
|
:param request_context: Context that will be returned to the webhook server in the client callback result.
|
|
268
261
|
:return: A SapioWebhookResult with the popup as its client callback request.
|
|
269
262
|
"""
|
|
270
|
-
warnings.warn("PopupUtil is deprecated as of 24.5+. Use CallbackUtil instead.", DeprecationWarning)
|
|
271
263
|
if display_name is None:
|
|
272
264
|
display_name = data_type
|
|
273
265
|
if plural_display_name is None:
|
|
@@ -303,7 +295,6 @@ class PopupUtil:
|
|
|
303
295
|
:param request_context: Context that will be returned to the webhook server in the client callback result.
|
|
304
296
|
:return: A SapioWebhookResult with the popup as its client callback request.
|
|
305
297
|
"""
|
|
306
|
-
warnings.warn("PopupUtil is deprecated as of 24.5+. Use CallbackUtil instead.", DeprecationWarning)
|
|
307
298
|
data_types: set[str] = {x.data_type_name for x in records}
|
|
308
299
|
if len(data_types) > 1:
|
|
309
300
|
raise SapioException("Multiple data type names encountered in records list for record table popup.")
|
|
@@ -356,7 +347,6 @@ class PopupUtil:
|
|
|
356
347
|
:param request_context: Context that will be returned to the webhook server in the client callback result.
|
|
357
348
|
:return: A SapioWebhookResult with the popup as its client callback request.
|
|
358
349
|
"""
|
|
359
|
-
warnings.warn("PopupUtil is deprecated as of 24.5+. Use CallbackUtil instead.", DeprecationWarning)
|
|
360
350
|
data_types: set[str] = {x.data_type_name for x in records}
|
|
361
351
|
if len(data_types) > 1:
|
|
362
352
|
raise SapioException("Multiple data type names encountered in records list for record table popup.")
|
|
@@ -401,7 +391,6 @@ class PopupUtil:
|
|
|
401
391
|
:param request_context: Context that will be returned to the webhook server in the client callback result.
|
|
402
392
|
:return: A SapioWebhookResult with the popup as its client callback request.
|
|
403
393
|
"""
|
|
404
|
-
warnings.warn("PopupUtil is deprecated as of 24.5+. Use CallbackUtil instead.", DeprecationWarning)
|
|
405
394
|
callback = ListDialogRequest(title, multi_select, options,
|
|
406
395
|
callback_context_data=request_context)
|
|
407
396
|
return SapioWebhookResult(True, client_callback_request=callback)
|
|
@@ -426,7 +415,6 @@ class PopupUtil:
|
|
|
426
415
|
:param request_context: Context that will be returned to the webhook server in the client callback result.
|
|
427
416
|
:return: A SapioWebhookResult with the popup as its client callback request.
|
|
428
417
|
"""
|
|
429
|
-
warnings.warn("PopupUtil is deprecated as of 24.5+. Use CallbackUtil instead.", DeprecationWarning)
|
|
430
418
|
callback = OptionDialogRequest(title, msg, options, default_option, user_can_cancel,
|
|
431
419
|
callback_context_data=request_context)
|
|
432
420
|
return SapioWebhookResult(True, client_callback_request=callback)
|
|
@@ -449,7 +437,6 @@ class PopupUtil:
|
|
|
449
437
|
:param request_context: Context that will be returned to the webhook server in the client callback result.
|
|
450
438
|
:return: A SapioWebhookResult with the popup as its client callback request.
|
|
451
439
|
"""
|
|
452
|
-
warnings.warn("PopupUtil is deprecated as of 24.5+. Use CallbackUtil instead.", DeprecationWarning)
|
|
453
440
|
return PopupUtil.option_popup(title, msg, ["OK"], 0, user_can_cancel, request_context=request_context)
|
|
454
441
|
|
|
455
442
|
@staticmethod
|
|
@@ -471,7 +458,6 @@ class PopupUtil:
|
|
|
471
458
|
:param request_context: Context that will be returned to the webhook server in the client callback result.
|
|
472
459
|
:return: A SapioWebhookResult with the popup as its client callback request.
|
|
473
460
|
"""
|
|
474
|
-
warnings.warn("PopupUtil is deprecated as of 24.5+. Use CallbackUtil instead.", DeprecationWarning)
|
|
475
461
|
return PopupUtil.option_popup(title, msg, ["Yes", "No"], 0 if default_yes else 1, user_can_cancel,
|
|
476
462
|
request_context=request_context)
|
|
477
463
|
|
|
@@ -484,7 +470,6 @@ class PopupUtil:
|
|
|
484
470
|
|
|
485
471
|
Deprecated for PopupUtil.text_field_popup.
|
|
486
472
|
"""
|
|
487
|
-
warnings.warn("PopupUtil is deprecated as of 24.5+. Use CallbackUtil instead.", DeprecationWarning)
|
|
488
473
|
return PopupUtil.string_field_popup(title, "", field_name, msg, len(msg), False, data_type,
|
|
489
474
|
request_context=request_context, auto_size=True)
|
|
490
475
|
|
|
@@ -496,7 +481,6 @@ class PopupUtil:
|
|
|
496
481
|
|
|
497
482
|
Deprecated for PopupUtil.option_popup.
|
|
498
483
|
"""
|
|
499
|
-
warnings.warn("PopupUtil is deprecated as of 24.5+. Use CallbackUtil instead.", DeprecationWarning)
|
|
500
484
|
return PopupUtil.option_popup(title, msg, options, 0, user_can_cancel, request_context=request_context)
|
|
501
485
|
|
|
502
486
|
@staticmethod
|
|
@@ -506,5 +490,4 @@ class PopupUtil:
|
|
|
506
490
|
|
|
507
491
|
Deprecated for PopupUtil.ok_popup.
|
|
508
492
|
"""
|
|
509
|
-
warnings.warn("PopupUtil is deprecated as of 24.5+. Use CallbackUtil instead.", DeprecationWarning)
|
|
510
493
|
return PopupUtil.ok_popup(title, msg, False, request_context=request_context)
|
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
1
|
import time
|
|
4
2
|
from datetime import datetime
|
|
5
3
|
|
|
6
4
|
import pytz
|
|
7
5
|
|
|
8
|
-
from sapiopycommons.general.exceptions import SapioException
|
|
9
|
-
|
|
10
6
|
__timezone = None
|
|
11
7
|
"""The default timezone. Use TimeUtil.set_default_timezone in a global context before making use of TimeUtil."""
|
|
12
8
|
|
|
@@ -141,39 +137,3 @@ class TimeUtil:
|
|
|
141
137
|
return True
|
|
142
138
|
except Exception:
|
|
143
139
|
return False
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
class DateRange:
|
|
147
|
-
start: int | None
|
|
148
|
-
end: int | None
|
|
149
|
-
|
|
150
|
-
@staticmethod
|
|
151
|
-
def from_string(value: str | None) -> DateRange:
|
|
152
|
-
"""
|
|
153
|
-
Construct a DateRange object from a string. The field value of date range fields is a string of the form
|
|
154
|
-
<start timestamp>/<end timestamp>.
|
|
155
|
-
|
|
156
|
-
:param value: A date range field value.
|
|
157
|
-
:return: A DateRange object matching the input field value.
|
|
158
|
-
"""
|
|
159
|
-
if not value:
|
|
160
|
-
return DateRange(None, None)
|
|
161
|
-
values: list[str] = value.split("/")
|
|
162
|
-
return DateRange(int(values[0]), int(values[1]))
|
|
163
|
-
|
|
164
|
-
def __init__(self, start: int | None, end: int | None):
|
|
165
|
-
"""
|
|
166
|
-
:param start: The timestamp for the start of the date range.
|
|
167
|
-
:param end: The timestamp for the end of the date rate.
|
|
168
|
-
"""
|
|
169
|
-
if (start and end is None) or (end and start is None):
|
|
170
|
-
raise SapioException("Both start and end values must be present in a date range.")
|
|
171
|
-
if start and end and end < start:
|
|
172
|
-
raise SapioException(f"End timestamp {end} is earlier than the start timestamp {start}.")
|
|
173
|
-
self.start = start
|
|
174
|
-
self.end = end
|
|
175
|
-
|
|
176
|
-
def __str__(self) -> str | None:
|
|
177
|
-
if not self.start and not self.end:
|
|
178
|
-
return None
|
|
179
|
-
return f"{self.start}/{self.end}"
|