sapiopycommons 2024.8.2a301__py3-none-any.whl → 2024.8.15a304__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.

@@ -1,200 +0,0 @@
1
- from enum import Enum
2
- from typing import Any
3
-
4
- from sapiopylib.rest.DataRecordManagerService import DataRecordManager
5
- from sapiopylib.rest.User import SapioUser
6
- from sapiopylib.rest.pojo.CustomReport import ReportColumn, RawReportTerm, CustomReportCriteria, RawTermOperation, \
7
- CompositeReportTerm, CompositeTermOperation
8
- from sapiopylib.rest.pojo.datatype.FieldDefinition import FieldType
9
- from sapiopylib.rest.pojo.webhook.WebhookContext import SapioWebhookContext
10
-
11
- from sapiopycommons.src.sapiopycommons.general.aliases import RecordIdentifier, AliasUtil
12
- from sapiopycommons.src.sapiopycommons.general.custom_report_util import CustomReportUtil
13
-
14
- EVENTTYPE_COLUMN = "EVENTTYPE"
15
- TIMESTAMP_COLUMN = "TIMESTAMP"
16
- DATATYPENAME_COLUMN = "DATATYPENAME"
17
- RECORDID_COLUMN = "RECORDID"
18
- DESCRIPTION_COLUMN = "DESCRIPTION"
19
- USERNAME_COLUMN = "USERNAME"
20
- USERCOMMENT_COLUMN = "USERCOMMENT"
21
- RECORDNAME_COLUMN = "RECORDNAME"
22
- DATAFIELDNAME_COLUMN = "DATAFIELDNAME"
23
- ORIGINALVALUE_COLUMN = "ORIGINALVALUE"
24
- NEWVALUE_COLUMN = "NEWVALUE"
25
-
26
-
27
- class EventType(Enum):
28
- """An enum to represent the possible event type values with the event type column in the audit log table."""
29
- ADD = 0
30
- DELETE = 1
31
- MODIFY = 2
32
- INFO = 3
33
- ERROR = 4
34
- WARNING = 5
35
- IMPORT = 6
36
- GENERATE = 7
37
- EXPORT = 8
38
- ADDREF = 9
39
- REMOVEREF = 10
40
- ESIGNATURE = 11
41
- ROLEASSIGNMENT = 12
42
-
43
-
44
- class AuditLogEntry:
45
-
46
- __event_type: EventType
47
- __date: int
48
- __data_type_name: str
49
- __record_id: int
50
- __description: str
51
- __users_login_name: str
52
- __comment: str
53
- __data_record_name: str
54
- __data_field_name: str
55
- __original_value: str
56
- __new_value: str
57
-
58
- @property
59
- def event_type(self) -> EventType:
60
- return self.__event_type
61
-
62
- @property
63
- def date(self) -> int:
64
- return self.__date
65
-
66
- @property
67
- def data_type_name(self) -> str:
68
- return self.__data_type_name
69
-
70
- @property
71
- def record_id(self) -> int:
72
- return self.__record_id
73
-
74
- @property
75
- def description(self) -> str:
76
- return self.__description
77
-
78
- @property
79
- def users_login_name(self) -> str:
80
- return self.__users_login_name
81
-
82
- @property
83
- def comment(self) -> str:
84
- return self.__comment
85
-
86
- @property
87
- def data_record_name(self) -> str:
88
- return self.__data_record_name
89
-
90
- @property
91
- def data_field_name(self) -> str:
92
- return self.__data_field_name
93
-
94
- @property
95
- def original_value(self) -> str:
96
- return self.__original_value
97
-
98
- @property
99
- def new_value(self) -> str:
100
- return self.__new_value
101
-
102
- def __init__(self, report_row: dict[str, Any]):
103
- self.__event_type = EventType((report_row[EVENTTYPE_COLUMN]))
104
- self.__date = report_row[TIMESTAMP_COLUMN]
105
- self.__data_type_name = report_row[DATATYPENAME_COLUMN]
106
- self.__record_id = report_row[RECORDID_COLUMN]
107
- self.__description = report_row[DESCRIPTION_COLUMN]
108
- self.__users_login_name = report_row[USERNAME_COLUMN]
109
- self.__comment = report_row[USERCOMMENT_COLUMN]
110
- self.__data_record_name = report_row[RECORDNAME_COLUMN]
111
- self.__data_field_name = report_row[DATAFIELDNAME_COLUMN]
112
- self.__original_value = report_row[ORIGINALVALUE_COLUMN]
113
- self.__new_value = report_row[NEWVALUE_COLUMN]
114
-
115
-
116
- class AuditLog:
117
- AUDIT_LOG_PSEUDO_DATATYPE: str = "AUDITLOG"
118
- EVENT_TYPE: ReportColumn = ReportColumn(AUDIT_LOG_PSEUDO_DATATYPE, EVENTTYPE_COLUMN, FieldType.ENUM)
119
- DATE: ReportColumn = ReportColumn(AUDIT_LOG_PSEUDO_DATATYPE, TIMESTAMP_COLUMN, FieldType.DATE)
120
- DATA_TYPE_NAME: ReportColumn = ReportColumn(AUDIT_LOG_PSEUDO_DATATYPE, DATATYPENAME_COLUMN, FieldType.STRING)
121
- RECORD_ID: ReportColumn = ReportColumn(AUDIT_LOG_PSEUDO_DATATYPE, RECORDID_COLUMN, FieldType.LONG)
122
- DESCRIPTION: ReportColumn = ReportColumn(AUDIT_LOG_PSEUDO_DATATYPE, DESCRIPTION_COLUMN, FieldType.STRING)
123
- USERS_LOGIN_NAME: ReportColumn = ReportColumn(AUDIT_LOG_PSEUDO_DATATYPE, USERNAME_COLUMN, FieldType.STRING)
124
- COMMENT: ReportColumn = ReportColumn(AUDIT_LOG_PSEUDO_DATATYPE, USERCOMMENT_COLUMN, FieldType.STRING)
125
- DATA_RECORD_NAME: ReportColumn = ReportColumn(AUDIT_LOG_PSEUDO_DATATYPE, RECORDNAME_COLUMN, FieldType.STRING)
126
- DATA_FIELD_NAME: ReportColumn = ReportColumn(AUDIT_LOG_PSEUDO_DATATYPE, DATAFIELDNAME_COLUMN, FieldType.STRING)
127
- ORIGINAL_VALUE: ReportColumn = ReportColumn(AUDIT_LOG_PSEUDO_DATATYPE, ORIGINALVALUE_COLUMN, FieldType.STRING)
128
- NEW_VALUE: ReportColumn = ReportColumn(AUDIT_LOG_PSEUDO_DATATYPE, NEWVALUE_COLUMN, FieldType.STRING)
129
-
130
- AUDIT_LOG_COLUMNS = [EVENT_TYPE, DATE, DATA_TYPE_NAME, RECORD_ID, DESCRIPTION, USERS_LOGIN_NAME, COMMENT,
131
- DATA_RECORD_NAME, DATA_FIELD_NAME, ORIGINAL_VALUE, NEW_VALUE]
132
- user: SapioUser
133
-
134
- def __init__(self, context: SapioWebhookContext | SapioUser):
135
- self.user = context if isinstance(context, SapioUser) else context.user
136
-
137
- @staticmethod
138
- def create_data_record_audit_log_report(records: list[RecordIdentifier], fields: list[str] | None = None) -> CustomReportCriteria:
139
- """
140
- This method creates a CustomReportCriteria object for running an audit log query based on data records.
141
-
142
- Creates a CustomReportCriteria object with a query term based on the record ids/records passed into the method.
143
- Optionally, the fields parameter can be populated to limit the search to particular fields. If the fields
144
- parameter is not populated, the search will include results for all field changes.
145
-
146
- :param records: The DataRecords, RecordModels, or record ids to base the search on.
147
- :param fields: The data field names to include changes for.
148
- :return: The constructed CustomReportCriteria object, which can be used to run a report on the audit log.
149
- """
150
- # We need to compile the record ids from these record identifiers as "str" variables, so they can be
151
- # concatenated.
152
- record_ids = AliasUtil.to_record_ids(records)
153
- id_strs = [str(id_int) for id_int in record_ids]
154
-
155
- # Next we'll build the raw report term querying for any entry with a matching record id value to the record ID's
156
- # passed in
157
- root_term = RawReportTerm(AuditLog.AUDIT_LOG_PSEUDO_DATATYPE, RECORDID_COLUMN,
158
- RawTermOperation.EQUAL_TO_OPERATOR, "{" + ",".join(id_strs) + "}")
159
-
160
- # If the user passed in any specific fields, then we should limit the query to those fields.
161
- if fields:
162
- field_term = RawReportTerm(AuditLog.AUDIT_LOG_PSEUDO_DATATYPE, DATAFIELDNAME_COLUMN,
163
- RawTermOperation.EQUAL_TO_OPERATOR, "{" + ",".join(fields) + "}")
164
- root_term = CompositeReportTerm(root_term, CompositeTermOperation.AND_OPERATOR, field_term)
165
-
166
- return CustomReportCriteria(AuditLog.AUDIT_LOG_COLUMNS, root_term)
167
-
168
- def run_data_record_audit_log_report(self, records: list[RecordIdentifier], fields: list[str] | None = None) -> dict[RecordIdentifier, list[AuditLogEntry]]:
169
- """
170
- This method runs a custom report for changes made to the given data records using the audit log.
171
- See "create_data_record_audit_log_report" for more details about the data record audit log report.
172
-
173
- :param records: The DataRecords, RecordModels, or record ids to base the search on.
174
- :param fields: The data field names to include changes for.
175
- :return: A dictionary where the keys are the record identifiers passed in, and the values are a list of
176
- AuditLogEntry objects which match the record id value of those records.
177
- """
178
- # First, we must build our report criteria for running the Custom Report.
179
- criteria = AuditLog.create_data_record_audit_log_report(records, fields)
180
-
181
- # Then we must run the custom report using that criteria.
182
- raw_report_data: list[dict[str, Any]] = CustomReportUtil.run_custom_report(self.user, criteria)
183
-
184
- # This section will prepare a map matching the original RecordIdentifier by record id.
185
- # This is because the audit log entries will have record ids, but we want the keys in our result map
186
- # to match the record identifiers that the user passed in, for convenience.
187
- record_identifier_mapping: dict[int, RecordIdentifier] = dict()
188
- for record in records:
189
- record_id = AliasUtil.to_record_id(record)
190
- record_identifier_mapping[record_id] = record
191
-
192
- # Finally, we compile our audit data into a map where the keys are the record identifiers passed in,
193
- # and the value is a list of applicable audit log entries.
194
- final_audit_data: dict[RecordIdentifier, list[AuditLogEntry]] = dict()
195
- for audit_entry_data in raw_report_data:
196
- audit_entry: AuditLogEntry = AuditLogEntry(audit_entry_data)
197
- identifier: RecordIdentifier = record_identifier_mapping.get(audit_entry.record_id)
198
- final_audit_data.setdefault(identifier, []).append(audit_entry)
199
-
200
- return final_audit_data
@@ -1,48 +0,0 @@
1
- from sapiopylib.rest.User import SapioUser
2
- from sapiopylib.rest.pojo.webhook.WebhookContext import SapioWebhookContext
3
-
4
- from sapiopycommons.general.aliases import RecordIdentifier, ExperimentIdentifier, AliasUtil
5
- from sapiopycommons.general.exceptions import SapioException
6
-
7
-
8
- class SapioNavigationLinker:
9
- """
10
- Given a URL to a system's webservice API (example: https://company.exemplareln.com/webservice/api), construct
11
- URLs for navigation links to various locations in the system.
12
- """
13
- base_url: str
14
-
15
- def __init__(self, url: str | SapioUser | SapioWebhookContext):
16
- """
17
- :param url: A user or context object that is being used to send requests to a Sapio system, or a URL to a
18
- system's webservice API.
19
- """
20
- if isinstance(url, SapioWebhookContext):
21
- url = url.user.url
22
- elif isinstance(url, SapioUser):
23
- url = url.url
24
- self.base_url = url.rstrip("/").replace('webservice/api', 'veloxClient')
25
-
26
- def data_record(self, record_identifier: RecordIdentifier, data_type_name: str | None = None) -> str:
27
- """
28
- :param record_identifier: An object that can be used to identify a record in the system, be that a record ID,
29
- a data record, or a record model.
30
- :param data_type_name: If the provided record identifier is a record ID, then the data type name of the record
31
- must be provided in this parameter. Otherwise, this parameter is ignored.
32
- :return: A URL for navigating to the input record.
33
- """
34
- record_id: int = AliasUtil.to_record_id(record_identifier)
35
- if not isinstance(record_identifier, int):
36
- data_type_name = AliasUtil.to_data_type_name(record_identifier)
37
- if not data_type_name:
38
- raise SapioException("Unable to create a data record link without a data type name. "
39
- "Only a record ID was provided.")
40
- return self.base_url + f"/#dataType={data_type_name};recordId={record_id};view=dataRecord"
41
-
42
- def experiment(self, experiment: ExperimentIdentifier) -> str:
43
- """
44
- :param experiment: An object that can be used to identify an experiment in the system, be that an experiment
45
- object, experiment protocol, or a notebook ID.
46
- :return: A URL for navigating to the input experiment.
47
- """
48
- return self.base_url + f"/#notebookExperimentId={AliasUtil.to_notebook_id(experiment)};view=eln"