sapiopycommons 2024.8.7a303__py3-none-any.whl → 2024.8.19a305__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,3 +1,5 @@
1
+ import warnings
2
+
1
3
  from sapiopylib.rest.DataMgmtService import DataMgmtServer
2
4
  from sapiopylib.rest.pojo.datatype.DataType import DataTypeDefinition
3
5
  from sapiopylib.rest.pojo.datatype.FieldDefinition import VeloxStringFieldDefinition, AbstractVeloxFieldDefinition, \
@@ -51,6 +53,7 @@ class PopupUtil:
51
53
  :param request_context: Context that will be returned to the webhook server in the client callback result.
52
54
  :return: A SapioWebhookResult with the popup as its client callback request.
53
55
  """
56
+ warnings.warn("PopupUtil is deprecated as of 24.5+. Use CallbackUtil instead.", DeprecationWarning)
54
57
  if display_name is None:
55
58
  display_name = data_type
56
59
  if plural_display_name is None:
@@ -97,6 +100,7 @@ class PopupUtil:
97
100
  :param request_context: Context that will be returned to the webhook server in the client callback result.
98
101
  :return: A SapioWebhookResult with the popup as its client callback request.
99
102
  """
103
+ warnings.warn("PopupUtil is deprecated as of 24.5+. Use CallbackUtil instead.", DeprecationWarning)
100
104
  # Get the field definitions of the data type.
101
105
  data_type: str = record.data_type_name
102
106
  type_man = DataMgmtServer.get_data_type_manager(context.user)
@@ -155,6 +159,7 @@ class PopupUtil:
155
159
  :param request_context: Context that will be returned to the webhook server in the client callback result.
156
160
  :return: A SapioWebhookResult with the popup as its client callback request.
157
161
  """
162
+ warnings.warn("PopupUtil is deprecated as of 24.5+. Use CallbackUtil instead.", DeprecationWarning)
158
163
  if max_length is None:
159
164
  max_length = len(default_value) if default_value else 100
160
165
  string_field = VeloxStringFieldDefinition(data_type, field_name, field_name, default_value=default_value,
@@ -191,6 +196,7 @@ class PopupUtil:
191
196
  :param request_context: Context that will be returned to the webhook server in the client callback result.
192
197
  :return: A SapioWebhookResult with the popup as its client callback request.
193
198
  """
199
+ warnings.warn("PopupUtil is deprecated as of 24.5+. Use CallbackUtil instead.", DeprecationWarning)
194
200
  if default_value is None:
195
201
  default_value = max(0, min_value)
196
202
  integer_field = VeloxIntegerFieldDefinition(data_type, field_name, field_name, default_value=default_value,
@@ -229,6 +235,7 @@ class PopupUtil:
229
235
  :param request_context: Context that will be returned to the webhook server in the client callback result.
230
236
  :return: A SapioWebhookResult with the popup as its client callback request.
231
237
  """
238
+ warnings.warn("PopupUtil is deprecated as of 24.5+. Use CallbackUtil instead.", DeprecationWarning)
232
239
  if default_value is None:
233
240
  default_value = min_value
234
241
  double_field = VeloxDoubleFieldDefinition(data_type, field_name, field_name, default_value=default_value,
@@ -260,6 +267,7 @@ class PopupUtil:
260
267
  :param request_context: Context that will be returned to the webhook server in the client callback result.
261
268
  :return: A SapioWebhookResult with the popup as its client callback request.
262
269
  """
270
+ warnings.warn("PopupUtil is deprecated as of 24.5+. Use CallbackUtil instead.", DeprecationWarning)
263
271
  if display_name is None:
264
272
  display_name = data_type
265
273
  if plural_display_name is None:
@@ -295,6 +303,7 @@ class PopupUtil:
295
303
  :param request_context: Context that will be returned to the webhook server in the client callback result.
296
304
  :return: A SapioWebhookResult with the popup as its client callback request.
297
305
  """
306
+ warnings.warn("PopupUtil is deprecated as of 24.5+. Use CallbackUtil instead.", DeprecationWarning)
298
307
  data_types: set[str] = {x.data_type_name for x in records}
299
308
  if len(data_types) > 1:
300
309
  raise SapioException("Multiple data type names encountered in records list for record table popup.")
@@ -347,6 +356,7 @@ class PopupUtil:
347
356
  :param request_context: Context that will be returned to the webhook server in the client callback result.
348
357
  :return: A SapioWebhookResult with the popup as its client callback request.
349
358
  """
359
+ warnings.warn("PopupUtil is deprecated as of 24.5+. Use CallbackUtil instead.", DeprecationWarning)
350
360
  data_types: set[str] = {x.data_type_name for x in records}
351
361
  if len(data_types) > 1:
352
362
  raise SapioException("Multiple data type names encountered in records list for record table popup.")
@@ -391,6 +401,7 @@ class PopupUtil:
391
401
  :param request_context: Context that will be returned to the webhook server in the client callback result.
392
402
  :return: A SapioWebhookResult with the popup as its client callback request.
393
403
  """
404
+ warnings.warn("PopupUtil is deprecated as of 24.5+. Use CallbackUtil instead.", DeprecationWarning)
394
405
  callback = ListDialogRequest(title, multi_select, options,
395
406
  callback_context_data=request_context)
396
407
  return SapioWebhookResult(True, client_callback_request=callback)
@@ -415,6 +426,7 @@ class PopupUtil:
415
426
  :param request_context: Context that will be returned to the webhook server in the client callback result.
416
427
  :return: A SapioWebhookResult with the popup as its client callback request.
417
428
  """
429
+ warnings.warn("PopupUtil is deprecated as of 24.5+. Use CallbackUtil instead.", DeprecationWarning)
418
430
  callback = OptionDialogRequest(title, msg, options, default_option, user_can_cancel,
419
431
  callback_context_data=request_context)
420
432
  return SapioWebhookResult(True, client_callback_request=callback)
@@ -437,6 +449,7 @@ class PopupUtil:
437
449
  :param request_context: Context that will be returned to the webhook server in the client callback result.
438
450
  :return: A SapioWebhookResult with the popup as its client callback request.
439
451
  """
452
+ warnings.warn("PopupUtil is deprecated as of 24.5+. Use CallbackUtil instead.", DeprecationWarning)
440
453
  return PopupUtil.option_popup(title, msg, ["OK"], 0, user_can_cancel, request_context=request_context)
441
454
 
442
455
  @staticmethod
@@ -458,6 +471,7 @@ class PopupUtil:
458
471
  :param request_context: Context that will be returned to the webhook server in the client callback result.
459
472
  :return: A SapioWebhookResult with the popup as its client callback request.
460
473
  """
474
+ warnings.warn("PopupUtil is deprecated as of 24.5+. Use CallbackUtil instead.", DeprecationWarning)
461
475
  return PopupUtil.option_popup(title, msg, ["Yes", "No"], 0 if default_yes else 1, user_can_cancel,
462
476
  request_context=request_context)
463
477
 
@@ -470,6 +484,7 @@ class PopupUtil:
470
484
 
471
485
  Deprecated for PopupUtil.text_field_popup.
472
486
  """
487
+ warnings.warn("PopupUtil is deprecated as of 24.5+. Use CallbackUtil instead.", DeprecationWarning)
473
488
  return PopupUtil.string_field_popup(title, "", field_name, msg, len(msg), False, data_type,
474
489
  request_context=request_context, auto_size=True)
475
490
 
@@ -481,6 +496,7 @@ class PopupUtil:
481
496
 
482
497
  Deprecated for PopupUtil.option_popup.
483
498
  """
499
+ warnings.warn("PopupUtil is deprecated as of 24.5+. Use CallbackUtil instead.", DeprecationWarning)
484
500
  return PopupUtil.option_popup(title, msg, options, 0, user_can_cancel, request_context=request_context)
485
501
 
486
502
  @staticmethod
@@ -490,4 +506,5 @@ class PopupUtil:
490
506
 
491
507
  Deprecated for PopupUtil.ok_popup.
492
508
  """
509
+ warnings.warn("PopupUtil is deprecated as of 24.5+. Use CallbackUtil instead.", DeprecationWarning)
493
510
  return PopupUtil.ok_popup(title, msg, False, request_context=request_context)
@@ -1,8 +1,12 @@
1
+ from __future__ import annotations
2
+
1
3
  import time
2
4
  from datetime import datetime
3
5
 
4
6
  import pytz
5
7
 
8
+ from sapiopycommons.general.exceptions import SapioException
9
+
6
10
  __timezone = None
7
11
  """The default timezone. Use TimeUtil.set_default_timezone in a global context before making use of TimeUtil."""
8
12
 
@@ -137,3 +141,39 @@ class TimeUtil:
137
141
  return True
138
142
  except Exception:
139
143
  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}"
@@ -1,5 +1,8 @@
1
+ from __future__ import annotations
2
+
1
3
  from collections.abc import Iterable
2
4
  from typing import Any
5
+ from weakref import WeakValueDictionary
3
6
 
4
7
  from sapiopylib.rest.DataRecordManagerService import DataRecordManager
5
8
  from sapiopylib.rest.User import SapioUser
@@ -36,10 +39,29 @@ class RecordHandler:
36
39
  rel_man: RecordModelRelationshipManager
37
40
  an_man: RecordModelAncestorManager
38
41
 
42
+ __instances: WeakValueDictionary[SapioUser, RecordHandler] = WeakValueDictionary()
43
+ __initialized: bool
44
+
45
+ def __new__(cls, context: SapioWebhookContext | SapioUser):
46
+ """
47
+ :param context: The current webhook context or a user object to send requests from.
48
+ """
49
+ user = context if isinstance(context, SapioUser) else context.user
50
+ obj = cls.__instances.get(user)
51
+ if not obj:
52
+ obj = object.__new__(cls)
53
+ obj.__initialized = False
54
+ cls.__instances[user] = obj
55
+ return obj
56
+
39
57
  def __init__(self, context: SapioWebhookContext | SapioUser):
40
58
  """
41
59
  :param context: The current webhook context or a user object to send requests from.
42
60
  """
61
+ if self.__initialized:
62
+ return
63
+ self.__initialized = True
64
+
43
65
  self.user = context if isinstance(context, SapioUser) else context.user
44
66
  self.dr_man = DataRecordManager(self.user)
45
67
  self.rec_man = RecordModelManager(self.user)
@@ -174,6 +196,19 @@ class RecordHandler:
174
196
  pager.max_page = page_limit
175
197
  return self.wrap_models(pager.get_all_at_once(), wrapper_type), pager.next_page_criteria
176
198
 
199
+ def query_models_by_id_and_map(self, wrapper_type: type[WrappedType], ids: Iterable[int],
200
+ page_limit: int | None = None) -> dict[int, WrappedType]:
201
+ """
202
+ Shorthand for using the data record manager to query for a list of data records by record ID
203
+ and then converting the results into a dictionary of record ID to the record model for that ID.
204
+
205
+ :param wrapper_type: The record model wrapper to use.
206
+ :param ids: The list of record IDs to query.
207
+ :param page_limit: The maximum number of pages to query. If None, exhausts all possible pages.
208
+ :return: The record models for the queried records mapped in a dictionary by their record ID.
209
+ """
210
+ return {x.record_id: x for x in self.query_models_by_id(wrapper_type, ids, page_limit)}
211
+
177
212
  def query_all_models(self, wrapper_type: type[WrappedType], page_limit: int | None = None) -> list[WrappedType]:
178
213
  """
179
214
  Shorthand for using the data record manager to query for all data records of a given type
@@ -503,7 +538,7 @@ class RecordHandler:
503
538
 
504
539
  @staticmethod
505
540
  def map_by_child(models: Iterable[RecordModel], child_type: type[WrappedType]) \
506
- -> dict[WrappedType, list[RecordModel]]:
541
+ -> dict[WrappedType, RecordModel]:
507
542
  """
508
543
  Take a list of record models and map them by their children. Essentially an inversion of map_to_child.
509
544
  If two records share the same child, an exception will be thrown. The children must already be loaded.
@@ -1,3 +1,8 @@
1
+ from __future__ import annotations
2
+
3
+ from weakref import WeakValueDictionary
4
+
5
+ from sapiopylib.rest.User import SapioUser
1
6
  from sapiopylib.rest.pojo.DataRecord import DataRecord
2
7
  from sapiopylib.rest.pojo.eln.SapioELNEnums import ElnBaseDataType
3
8
  from sapiopylib.rest.pojo.webhook.WebhookContext import SapioWebhookContext
@@ -33,7 +38,25 @@ class ElnRuleHandler:
33
38
  """A mapping of entry name to the lists of field maps for that entry, each grouping of field maps being mapped by
34
39
  its data type."""
35
40
 
41
+ __instances: WeakValueDictionary[SapioUser, ElnRuleHandler] = WeakValueDictionary()
42
+ __initialized: bool
43
+
44
+ def __new__(cls, context: SapioWebhookContext):
45
+ if context.velox_eln_rule_result_map is None:
46
+ raise SapioException("No Velox ELN rule result map in context for ElnRuleHandler to parse.")
47
+ user = context if isinstance(context, SapioUser) else context.user
48
+ obj = cls.__instances.get(user)
49
+ if not obj:
50
+ obj = object.__new__(cls)
51
+ obj.__initialized = False
52
+ cls.__instances[user] = obj
53
+ return obj
54
+
36
55
  def __init__(self, context: SapioWebhookContext):
56
+ if self.__initialized:
57
+ return
58
+ self.__initialized = True
59
+
37
60
  if context.velox_eln_rule_result_map is None:
38
61
  raise SapioException("No Velox ELN rule result map in context for ElnRuleHandler to parse.")
39
62
  self.__context = context
@@ -1,3 +1,8 @@
1
+ from __future__ import annotations
2
+
3
+ from weakref import WeakValueDictionary
4
+
5
+ from sapiopylib.rest.User import SapioUser
1
6
  from sapiopylib.rest.pojo.DataRecord import DataRecord
2
7
  from sapiopylib.rest.pojo.eln.SapioELNEnums import ElnBaseDataType
3
8
  from sapiopylib.rest.pojo.webhook.WebhookContext import SapioWebhookContext
@@ -33,7 +38,25 @@ class OnSaveRuleHandler:
33
38
  """A mapping of record IDs of records in the context.data_record_list to the field maps related to that
34
39
  record, each grouping of field maps being mapped by its data type."""
35
40
 
41
+ __instances: WeakValueDictionary[SapioUser, OnSaveRuleHandler] = WeakValueDictionary()
42
+ __initialized: bool
43
+
44
+ def __new__(cls, context: SapioWebhookContext):
45
+ if context.velox_on_save_result_map is None:
46
+ raise SapioException("No Velox on save rule result map in context for OnSaveRuleHandler to parse.")
47
+ user = context if isinstance(context, SapioUser) else context.user
48
+ obj = cls.__instances.get(user)
49
+ if not obj:
50
+ obj = object.__new__(cls)
51
+ obj.__initialized = False
52
+ cls.__instances[user] = obj
53
+ return obj
54
+
36
55
  def __init__(self, context: SapioWebhookContext):
56
+ if self.__initialized:
57
+ return
58
+ self.__initialized = True
59
+
37
60
  if context.velox_on_save_result_map is None:
38
61
  raise SapioException("No Velox on save rule result map in context for OnSaveRuleHandler to parse.")
39
62
  self.__context = context
@@ -10,13 +10,19 @@ from sapiopylib.rest.pojo.Message import VeloxLogMessage, VeloxLogLevel
10
10
  from sapiopylib.rest.pojo.webhook.WebhookContext import SapioWebhookContext
11
11
  from sapiopylib.rest.pojo.webhook.WebhookEnums import WebhookEndpointType
12
12
  from sapiopylib.rest.pojo.webhook.WebhookResult import SapioWebhookResult
13
+ from sapiopylib.rest.utils.DataTypeCacheManager import DataTypeCacheManager
13
14
  from sapiopylib.rest.utils.recordmodel.RecordModelManager import RecordModelManager, RecordModelInstanceManager, \
14
15
  RecordModelRelationshipManager
15
16
  from sapiopylib.rest.utils.recordmodel.ancestry import RecordModelAncestorManager
16
17
 
18
+ from sapiopycommons.callbacks.callback_util import CallbackUtil
19
+ from sapiopycommons.eln.experiment_handler import ExperimentHandler
17
20
  from sapiopycommons.general.exceptions import SapioUserErrorException, SapioCriticalErrorException, \
18
- SapioUserCancelledException
21
+ SapioUserCancelledException, SapioException
19
22
  from sapiopycommons.general.sapio_links import SapioNavigationLinker
23
+ from sapiopycommons.recordmodel.record_handler import RecordHandler
24
+ from sapiopycommons.rules.eln_rule_handler import ElnRuleHandler
25
+ from sapiopycommons.rules.on_save_rule_handler import OnSaveRuleHandler
20
26
 
21
27
 
22
28
  # FR-46064 - Initial port of PyWebhookUtils to sapiopycommons.
@@ -38,6 +44,12 @@ class CommonsWebhookHandler(AbstractWebhookHandler):
38
44
  # FR-46329: Add the ancestor manager to CommonsWebhookHandler.
39
45
  an_man: RecordModelAncestorManager
40
46
 
47
+ dt_cache: DataTypeCacheManager
48
+ rec_handler: RecordHandler
49
+ callback: CallbackUtil
50
+ exp_handler: ExperimentHandler | None
51
+ rule_handler: OnSaveRuleHandler | ElnRuleHandler | None
52
+
41
53
  def run(self, context: SapioWebhookContext) -> SapioWebhookResult:
42
54
  self.user = context.user
43
55
  self.context = context
@@ -50,11 +62,28 @@ class CommonsWebhookHandler(AbstractWebhookHandler):
50
62
  self.rel_man = self.rec_man.relationship_manager
51
63
  self.an_man = RecordModelAncestorManager(self.rec_man)
52
64
 
65
+ self.dt_cache = DataTypeCacheManager(self.user)
66
+ self.rec_handler = RecordHandler(context)
67
+ self.callback = CallbackUtil(context)
68
+ if context.eln_experiment is not None:
69
+ self.exp_handler = ExperimentHandler(context)
70
+ else:
71
+ self.exp_handler = None
72
+ if self.is_on_save_rule():
73
+ self.rule_handler = OnSaveRuleHandler(context)
74
+ elif self.is_eln_rule():
75
+ self.rule_handler = ElnRuleHandler(context)
76
+ else:
77
+ self.rule_handler = None
78
+
53
79
  # Wrap the execution of each webhook in a try/catch. If an exception occurs, handle any special sapiopycommons
54
80
  # exceptions. Otherwise, return a generic message stating that an error occurred.
55
81
  try:
56
82
  self.initialize(context)
57
- return self.execute(context)
83
+ result = self.execute(context)
84
+ if result is None:
85
+ raise SapioException("Your execute function returned a None result! Don't forget your return statement!")
86
+ return result
58
87
  except SapioUserErrorException as e:
59
88
  return self.handle_user_error_exception(e)
60
89
  except SapioCriticalErrorException as e:
@@ -138,7 +167,7 @@ class CommonsWebhookHandler(AbstractWebhookHandler):
138
167
  result: SapioWebhookResult | None = self.handle_any_exception(e)
139
168
  if result is not None:
140
169
  return result
141
- return SapioWebhookResult(False, display_text="User cancelled.")
170
+ return SapioWebhookResult(False)
142
171
 
143
172
  # noinspection PyMethodMayBeStatic,PyUnusedLocal
144
173
  def handle_any_exception(self, e: Exception) -> SapioWebhookResult | None:
@@ -0,0 +1,67 @@
1
+ import sys
2
+ import traceback
3
+ from abc import abstractmethod
4
+ from typing import Any
5
+
6
+ from flask import request
7
+ from sapiopylib.rest.User import SapioUser
8
+ from sapiopylib.rest.WebhookService import AbstractWebhookHandler
9
+ from sapiopylib.rest.pojo.webhook.WebhookResult import SapioWebhookResult
10
+
11
+
12
+ class AbstractWebserviceHandler(AbstractWebhookHandler):
13
+ """
14
+ A base class for constructing "webservice" endpoints on your webhook server. These are endpoints that can be
15
+ communicated with by external sources without needing to format the payload JSON in the webhook context format that
16
+ webhook handlers expect.
17
+
18
+ The entire payload JSON is sent to the run method of this class. It is up to the run method to determine how
19
+ this JSON should be parsed. In order to communicate with a Sapio system, a SapioUser object must be able to be
20
+ defined using the payload. Functions have been provided for constructing users with various authentication methods.
21
+
22
+ Since this extends AbstractWebhookHandler, you can still register endpoints from this class in the same way you
23
+ would normal webhook endpoints.
24
+ """
25
+ def post(self) -> dict[str, Any]:
26
+ """
27
+ Internal method to be executed to translate incoming requests.
28
+ """
29
+ # noinspection PyBroadException
30
+ try:
31
+ return self.run(request.json).to_json()
32
+ except Exception:
33
+ print('Error occurred while running webservice custom logic. See traceback.', file=sys.stderr)
34
+ traceback.print_exc()
35
+ return SapioWebhookResult(False, display_text="Error occurred during webservice execution.").to_json()
36
+
37
+ @abstractmethod
38
+ def run(self, payload: dict[str, Any]) -> SapioWebhookResult:
39
+ pass
40
+
41
+ def basic_auth(self, url: str, username: str, password: str) -> SapioUser:
42
+ """
43
+ :param url: The URL of the Sapio system that requests from this user will be sent to.
44
+ Must end in /webservice/api
45
+ :param username: The username to authenticate requests with.
46
+ :param password: The password to authenticate requests with.
47
+ :return: A SapioUser that will authenticate requests using basic auth.
48
+ """
49
+ return SapioUser(url, self.verify_sapio_cert, self.client_timeout_seconds, username=username, password=password)
50
+
51
+ def api_token_auth(self, url: str, api_token: str) -> SapioUser:
52
+ """
53
+ :param url: The URL of the Sapio system that requests from this user will be sent to.
54
+ Must end in /webservice/api
55
+ :param api_token: The API token to authenticate requests with.
56
+ :return: A SapioUser that will authenticate requests using an API token.
57
+ """
58
+ return SapioUser(url, self.verify_sapio_cert, self.client_timeout_seconds, api_token=api_token)
59
+
60
+ def bearer_token_auth(self, url: str, bearer_token: str) -> SapioUser:
61
+ """
62
+ :param url: The URL of the Sapio system that requests from this user will be sent to.
63
+ Must end in /webservice/api
64
+ :param bearer_token: The bearer token to authenticate requests with.
65
+ :return: A SapioUser that will authenticate requests using a bearer token.
66
+ """
67
+ return SapioUser(url, self.verify_sapio_cert, self.client_timeout_seconds, bearer_token=bearer_token)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: sapiopycommons
3
- Version: 2024.8.7a303
3
+ Version: 2024.8.19a305
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>
@@ -1,45 +1,50 @@
1
1
  sapiopycommons/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  sapiopycommons/callbacks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- sapiopycommons/callbacks/callback_util.py,sha256=YdaN1iNnJ51EauvKfEOAUwahu1dt_YVvr4Zia29g9qc,61123
3
+ sapiopycommons/callbacks/callback_util.py,sha256=E9-PIO8NO2BBltd6Dy4eaha9u39V636NjM7IXR0TP_Y,63539
4
4
  sapiopycommons/chem/IndigoMolecules.py,sha256=QqFDi9CKERj6sn_ZwVcS2xZq4imlkaTeCrpq1iNcEJA,1992
5
5
  sapiopycommons/chem/Molecules.py,sha256=t80IsQBPJ9mwE8ZxnWomAGrZDhdsOuPvLaTPb_N6jGU,8639
6
6
  sapiopycommons/chem/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ sapiopycommons/customreport/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ sapiopycommons/customreport/column_builder.py,sha256=sS_wZYOR72rs3syTNjwCVP4h8M8N0b0burkTxFQItVU,3019
9
+ sapiopycommons/customreport/custom_report_builder.py,sha256=o2O89OrWPm0OYS8Ux6EKZTg6hcUzfz3ZxAgnzJg1wEw,6601
10
+ sapiopycommons/customreport/term_builder.py,sha256=mOnm2c6EUOQVgoURmXHzqSGKuQjP2gswJmWecoeC4yw,16606
7
11
  sapiopycommons/datatype/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
12
  sapiopycommons/datatype/attachment_util.py,sha256=23JQ4avSmBBJdCv95LVj31x8rUCclzB_DYFBijH0NII,3708
9
13
  sapiopycommons/eln/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- sapiopycommons/eln/experiment_handler.py,sha256=RspUDmPmBQIG7l7q_luFP8yeRljdU3E64066NH5CtdI,59817
14
+ sapiopycommons/eln/experiment_handler.py,sha256=9wNRjwWHekKSAA_1io5WW1iDSezDXidWKAVn0bQZkbc,66161
11
15
  sapiopycommons/eln/experiment_report_util.py,sha256=FTLw-6SLAMeoWTOO-qhGROE9g54pZdyoQJIhiIzlwGw,7848
12
16
  sapiopycommons/eln/plate_designer.py,sha256=FYJfhhNq8hdfuXgDYOYHy6g0m2zNwQXZWF_MTPzElDg,7184
13
17
  sapiopycommons/files/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
18
  sapiopycommons/files/complex_data_loader.py,sha256=8jgYF5iGDD6Abw8JRWLYxUWVwj4s4pH5HylyxEGFZSU,1471
15
19
  sapiopycommons/files/file_bridge.py,sha256=njx_5Z3tvQUNW4mPazQerL8lopLAFStIByHWHJ7m5ug,6220
16
- sapiopycommons/files/file_bridge_handler.py,sha256=MU2wZR4VY606yx6Bnv8-LzG3mGCeuXeRBn914WNRFCo,13601
20
+ sapiopycommons/files/file_bridge_handler.py,sha256=KCk8JTojMeHWgARqVlhOBXf-OInGuc6NW2vXG5Xf-7w,14352
17
21
  sapiopycommons/files/file_data_handler.py,sha256=3-guAdhJdeJWAFq1a27ijspkO7uMMZ6CapMCD_6o4jA,36746
18
- sapiopycommons/files/file_util.py,sha256=ronTlJimQ6ttJN6Y9qfAzEWoeWnDoUbohkdObNK5mJQ,27042
19
- sapiopycommons/files/file_validator.py,sha256=EqPCXfVCiilgnOb2G-yZg8XWeDqYp9iVCg8AaWznvf4,28040
20
- sapiopycommons/files/file_writer.py,sha256=5u_iZXTQvuUU7ceHZr8Q001_tvgJhOqBwAnB_pxcAbQ,16027
22
+ sapiopycommons/files/file_util.py,sha256=ZrgoGwHHfPdL5KHkGwlrEHJqGpttmZzRkGQCXdLjra8,28284
23
+ sapiopycommons/files/file_validator.py,sha256=HaZF4rqGXspkkyLPol5KAWvV7djuodzrIxg2EnNYoLw,28858
24
+ sapiopycommons/files/file_writer.py,sha256=96Xl8TTT46Krxe_J8rmmlEMtel4nzZB961f5Yqtl1-I,17616
21
25
  sapiopycommons/general/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
26
  sapiopycommons/general/accession_service.py,sha256=HYgyOsH_UaoRnoury-c2yTW8SeG4OtjLemdpCzoV4R8,13484
23
- sapiopycommons/general/aliases.py,sha256=UddtYCGqM-wkLXT0LAUqMlFGHZSyOPjA6hzQHvjlDcQ,4324
27
+ sapiopycommons/general/aliases.py,sha256=bSj4-oU6UDY1Yvlhr19RWVlSJf9NhfZE42y-xzYC-lg,7575
24
28
  sapiopycommons/general/audit_log.py,sha256=YwBkm1kT6faXtipcUpoOtME3FZaUM46OtCE6KIzAROQ,9038
25
29
  sapiopycommons/general/custom_report_util.py,sha256=cLgIR5Fn3M9uyAtgfTYRv3JRk2SKNevnsb_R5zidSYs,15557
26
30
  sapiopycommons/general/exceptions.py,sha256=DOlLKnpCatxQF-lVCToa8ryJgusWLvip6N_1ALN00QE,1679
27
- sapiopycommons/general/popup_util.py,sha256=-mN5IgYPrLrOEHJ4CHPi2rec4_WAN6X0yMxHwD5h3Bs,30126
31
+ sapiopycommons/general/popup_util.py,sha256=vqLSiCry4YClSKIdnk56CIKioBOtawGVmPi2iS1LOIc,31763
28
32
  sapiopycommons/general/sapio_links.py,sha256=UlqB09wmgDgbQiB8d3mEj7rxW_GMIXz3j3RlvADNt_A,2475
29
33
  sapiopycommons/general/storage_util.py,sha256=ovmK_jN7v09BoX07XxwShpBUC5WYQOM7dbKV_VeLXJU,8892
30
- sapiopycommons/general/time_util.py,sha256=jiJUh7jc1ZRCOem880S3HaLPZ4RboBtSl4_U9sqAQuM,7290
34
+ sapiopycommons/general/time_util.py,sha256=sXThADCRAQDWYDD9C5CdhcKYIt3qOaVNyZfGBR7HW9A,8701
31
35
  sapiopycommons/multimodal/multimodal.py,sha256=A1QsC8QTPmgZyPr7KtMbPRedn2Ie4WIErodUvQ9otgU,6724
32
36
  sapiopycommons/multimodal/multimodal_data.py,sha256=zqgYHO-ULaPKV0POFWZVY9N-Sfm1RQWwdsfwFxe5DjI,15038
33
37
  sapiopycommons/processtracking/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
38
  sapiopycommons/processtracking/endpoints.py,sha256=g5h_uCVByqacYm9zWAz8TyAdRsGfaO2o0b5RSJdOaSA,10926
35
39
  sapiopycommons/recordmodel/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
- sapiopycommons/recordmodel/record_handler.py,sha256=qqsHeGNyqQeFKuZ4U2v2MD278AlH4n1HMvSTOY0hbyo,58636
40
+ sapiopycommons/recordmodel/record_handler.py,sha256=Xr0fRkUW5nAY4NVKwkQR81WF23POX_FtVp4pP7QMgZ0,60188
37
41
  sapiopycommons/rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
- sapiopycommons/rules/eln_rule_handler.py,sha256=rz9E1PQLShCZM09JafMl_ylUqBbMs-et0FsOG41tQL0,9480
39
- sapiopycommons/rules/on_save_rule_handler.py,sha256=I06HwsNvulyU0avSXOU0itBDAmiOxsyW8KGk_gH0FHc,9238
42
+ sapiopycommons/rules/eln_rule_handler.py,sha256=QkK3TD9fxdw0usWik0eIRlcIDHaN3LgfR8laOElCA8A,10280
43
+ sapiopycommons/rules/on_save_rule_handler.py,sha256=STJ8QFeZGk5yUCPgiJ_Q0Trpn6rfXTFum0s2ECLfxHU,10047
40
44
  sapiopycommons/webhook/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
- sapiopycommons/webhook/webhook_handlers.py,sha256=1uM_epEaEB8w14padEdASXqF3BNalNiShP51a_hU-Ac,15267
42
- sapiopycommons-2024.8.7a303.dist-info/METADATA,sha256=dsDPcs5Sh34VkDj4caA7jFUaTMci4EbEs-RD98esOos,3175
43
- sapiopycommons-2024.8.7a303.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
44
- sapiopycommons-2024.8.7a303.dist-info/licenses/LICENSE,sha256=HyVuytGSiAUQ6ErWBHTqt1iSGHhLmlC8fO7jTCuR8dU,16725
45
- sapiopycommons-2024.8.7a303.dist-info/RECORD,,
45
+ sapiopycommons/webhook/webhook_handlers.py,sha256=jwc4xu-wwl8haS5k1dENZ1UIYK9GQk74TAo3CGxMW9U,16583
46
+ sapiopycommons/webhook/webservice_handlers.py,sha256=1J56zFI0pWl5MHoNTznvcZumITXgAHJMluj8-2BqYEw,3315
47
+ sapiopycommons-2024.8.19a305.dist-info/METADATA,sha256=RW_yNejA3ktxl81ktZx88D5R4g3Iq50c2gy6Svd5YBQ,3176
48
+ sapiopycommons-2024.8.19a305.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
49
+ sapiopycommons-2024.8.19a305.dist-info/licenses/LICENSE,sha256=HyVuytGSiAUQ6ErWBHTqt1iSGHhLmlC8fO7jTCuR8dU,16725
50
+ sapiopycommons-2024.8.19a305.dist-info/RECORD,,