sapiopycommons 2025.10.15a782__py3-none-any.whl → 2025.10.17a787__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of sapiopycommons might be problematic. Click here for more details.

Files changed (50) hide show
  1. sapiopycommons/ai/tool_of_tools.py +917 -0
  2. sapiopycommons/callbacks/callback_util.py +18 -4
  3. sapiopycommons/files/file_util.py +1 -128
  4. sapiopycommons/general/aliases.py +3 -0
  5. sapiopycommons/webhook/webservice_handlers.py +1 -1
  6. {sapiopycommons-2025.10.15a782.dist-info → sapiopycommons-2025.10.17a787.dist-info}/METADATA +1 -1
  7. {sapiopycommons-2025.10.15a782.dist-info → sapiopycommons-2025.10.17a787.dist-info}/RECORD +9 -49
  8. sapiopycommons/ai/agent_service_base.py +0 -1148
  9. sapiopycommons/ai/converter_service_base.py +0 -163
  10. sapiopycommons/ai/external_credentials.py +0 -128
  11. sapiopycommons/ai/protoapi/externalcredentials/external_credentials_pb2.py +0 -41
  12. sapiopycommons/ai/protoapi/externalcredentials/external_credentials_pb2.pyi +0 -35
  13. sapiopycommons/ai/protoapi/externalcredentials/external_credentials_pb2_grpc.py +0 -24
  14. sapiopycommons/ai/protoapi/fielddefinitions/fields_pb2.py +0 -43
  15. sapiopycommons/ai/protoapi/fielddefinitions/fields_pb2.pyi +0 -31
  16. sapiopycommons/ai/protoapi/fielddefinitions/fields_pb2_grpc.py +0 -24
  17. sapiopycommons/ai/protoapi/fielddefinitions/velox_field_def_pb2.py +0 -123
  18. sapiopycommons/ai/protoapi/fielddefinitions/velox_field_def_pb2.pyi +0 -598
  19. sapiopycommons/ai/protoapi/fielddefinitions/velox_field_def_pb2_grpc.py +0 -24
  20. sapiopycommons/ai/protoapi/plan/converter/converter_pb2.py +0 -51
  21. sapiopycommons/ai/protoapi/plan/converter/converter_pb2.pyi +0 -63
  22. sapiopycommons/ai/protoapi/plan/converter/converter_pb2_grpc.py +0 -149
  23. sapiopycommons/ai/protoapi/plan/item/item_container_pb2.py +0 -55
  24. sapiopycommons/ai/protoapi/plan/item/item_container_pb2.pyi +0 -90
  25. sapiopycommons/ai/protoapi/plan/item/item_container_pb2_grpc.py +0 -24
  26. sapiopycommons/ai/protoapi/plan/script/script_pb2.py +0 -61
  27. sapiopycommons/ai/protoapi/plan/script/script_pb2.pyi +0 -108
  28. sapiopycommons/ai/protoapi/plan/script/script_pb2_grpc.py +0 -153
  29. sapiopycommons/ai/protoapi/plan/step_output_pb2.py +0 -45
  30. sapiopycommons/ai/protoapi/plan/step_output_pb2.pyi +0 -42
  31. sapiopycommons/ai/protoapi/plan/step_output_pb2_grpc.py +0 -24
  32. sapiopycommons/ai/protoapi/plan/step_pb2.py +0 -43
  33. sapiopycommons/ai/protoapi/plan/step_pb2.pyi +0 -43
  34. sapiopycommons/ai/protoapi/plan/step_pb2_grpc.py +0 -24
  35. sapiopycommons/ai/protoapi/plan/tool/entry_pb2.py +0 -41
  36. sapiopycommons/ai/protoapi/plan/tool/entry_pb2.pyi +0 -35
  37. sapiopycommons/ai/protoapi/plan/tool/entry_pb2_grpc.py +0 -24
  38. sapiopycommons/ai/protoapi/plan/tool/tool_pb2.py +0 -79
  39. sapiopycommons/ai/protoapi/plan/tool/tool_pb2.pyi +0 -261
  40. sapiopycommons/ai/protoapi/plan/tool/tool_pb2_grpc.py +0 -154
  41. sapiopycommons/ai/protoapi/session/sapio_conn_info_pb2.py +0 -39
  42. sapiopycommons/ai/protoapi/session/sapio_conn_info_pb2.pyi +0 -32
  43. sapiopycommons/ai/protoapi/session/sapio_conn_info_pb2_grpc.py +0 -24
  44. sapiopycommons/ai/protobuf_utils.py +0 -504
  45. sapiopycommons/ai/request_validation.py +0 -470
  46. sapiopycommons/ai/server.py +0 -152
  47. sapiopycommons/ai/test_client.py +0 -446
  48. sapiopycommons/files/temp_files.py +0 -82
  49. {sapiopycommons-2025.10.15a782.dist-info → sapiopycommons-2025.10.17a787.dist-info}/WHEEL +0 -0
  50. {sapiopycommons-2025.10.15a782.dist-info → sapiopycommons-2025.10.17a787.dist-info}/licenses/LICENSE +0 -0
@@ -858,9 +858,9 @@ class CallbackUtil:
858
858
  raise SapioException("No records provided.")
859
859
  data_type: str = AliasUtil.to_singular_data_type_name(records)
860
860
  if index_field is not None:
861
- field_map_list: list[FieldMap] = self.__get_indexed_field_maps(records, index_field)
861
+ field_map_list: list[FieldMap] = self.__get_indexed_field_maps(records, index_field, True)
862
862
  else:
863
- field_map_list: list[FieldMap] = AliasUtil.to_field_map_list(records)
863
+ field_map_list: list[FieldMap] = AliasUtil.to_field_map_list(records, True)
864
864
 
865
865
  # Convert the group_by parameter to a field name.
866
866
  if group_by is not None:
@@ -882,6 +882,18 @@ class CallbackUtil:
882
882
  temp_dt = self.__temp_dt_from_field_names(data_type, fields, None, default_modifier, field_modifiers)
883
883
  temp_dt.record_image_assignable = bool(image_data)
884
884
 
885
+ # PR-47894: If the RecordId field is not present in the layout, then it should not be included in the field
886
+ # maps, as otherwise selection list fields can break.
887
+ remove_record_id: bool = True
888
+ for field_def in temp_dt.get_field_def_list():
889
+ if field_def.data_field_name == "RecordId":
890
+ remove_record_id = False
891
+ break
892
+ if remove_record_id:
893
+ for field_map in field_map_list:
894
+ if "RecordId" in field_map:
895
+ del field_map["RecordId"]
896
+
885
897
  # Send the request to the user.
886
898
  request = TableEntryDialogRequest(title, msg, temp_dt, field_map_list,
887
899
  record_image_data_list=image_data, group_by_field=group_by,
@@ -1928,7 +1940,8 @@ class CallbackUtil:
1928
1940
  self.write_file(zip_name, FileUtil.zip_files(files))
1929
1941
 
1930
1942
  @staticmethod
1931
- def __get_indexed_field_maps(records: Iterable[SapioRecord], index_field: str) -> list[FieldMap]:
1943
+ def __get_indexed_field_maps(records: Iterable[SapioRecord], index_field: str, include_record_id: bool = False) \
1944
+ -> list[FieldMap]:
1932
1945
  """
1933
1946
  For dialogs that accept multiple records, we may want to be able to match the returned results back to the
1934
1947
  records that they're for. In this case, we need to add an index to each record so that we can match them back
@@ -1938,12 +1951,13 @@ class CallbackUtil:
1938
1951
  :param records: The records to return indexed field maps of.
1939
1952
  :param index_field: The name of the field to use as the index. Make sure that this field doesn't exist on the
1940
1953
  records, as then it will overwrite the existing value.
1954
+ :param include_record_id: Whether to include the RecordId field in the field maps.
1941
1955
  :return: A list of field maps for the records, with an index field added to each. The value of the index on
1942
1956
  each field map is the record's record ID (even if it's a record model with a negative ID).
1943
1957
  """
1944
1958
  ret_val: list[FieldMap] = []
1945
1959
  for record in records:
1946
- field_map: FieldMap = AliasUtil.to_field_map(record)
1960
+ field_map: FieldMap = AliasUtil.to_field_map(record, include_record_id)
1947
1961
  field_map[index_field] = AliasUtil.to_record_id(record)
1948
1962
  ret_val.append(field_map)
1949
1963
  return ret_val
@@ -1,7 +1,4 @@
1
- import gzip
2
1
  import io
3
- import tarfile
4
- import time
5
2
  import warnings
6
3
  import zipfile
7
4
 
@@ -325,7 +322,7 @@ class FileUtil:
325
322
  @staticmethod
326
323
  def zip_files(files: dict[str, str | bytes]) -> bytes:
327
324
  """
328
- Create a .zip file for a collection of files.
325
+ Create a zip file for a collection of files.
329
326
 
330
327
  :param files: A dictionary of file name to file data as a string or bytes.
331
328
  :return: The bytes for a zip file containing the input files.
@@ -338,130 +335,6 @@ class FileUtil:
338
335
  # throws an I/O exception.
339
336
  return zip_buffer.getvalue()
340
337
 
341
- # FR-47422: Add a function for unzipping files that may have been zipped by the above function.
342
- @staticmethod
343
- def unzip_files(zip_file: bytes) -> dict[str, bytes]:
344
- """
345
- Decompress a .zip file from an in-memory bytes object and extracts all files into a dictionary.
346
-
347
- :param zip_file: The bytes of the zip file to be decompressed.
348
- :return: A dictionary of file name to file bytes for each file in the zip.
349
- """
350
- extracted_files: dict[str, bytes] = {}
351
- with io.BytesIO(zip_file) as zip_buffer:
352
- with zipfile.ZipFile(zip_buffer, "r") as zip_file:
353
- for file_name in zip_file.namelist():
354
- with zip_file.open(file_name) as file:
355
- extracted_files[file_name] = file.read()
356
- return extracted_files
357
-
358
- # FR-47422: Add functions for compressing and decompressing .gz, .tar, and .tar.gz files.
359
- @staticmethod
360
- def gzip_file(file_data: bytes | str) -> bytes:
361
- """
362
- Create a .gz file for a single file.
363
-
364
- :param file_data: The file data to be compressed as bytes or a string.
365
- :return: The bytes of the gzip-compressed file.
366
- """
367
- return gzip.compress(file_data.encode() if isinstance(file_data, str) else file_data)
368
-
369
- @staticmethod
370
- def ungzip_file(gzip_file: bytes) -> bytes:
371
- """
372
- Decompress a .gz file.
373
-
374
- :param gzip_file: The bytes of the gzip-compressed file.
375
- :return: The decompressed file data as bytes.
376
- """
377
- return gzip.decompress(gzip_file)
378
-
379
- @staticmethod
380
- def tar_files(files: dict[str, str | bytes]) -> bytes:
381
- """
382
- Create a .tar file for a collection of files.
383
-
384
- :param files: A dictionary of file name to file data as a string or bytes.
385
- :return: The bytes for a tar file containing the input files.
386
- """
387
- with io.BytesIO() as tar_buffer:
388
- with tarfile.open(fileobj=tar_buffer, mode="w") as tar:
389
- for name, data in files.items():
390
- if isinstance(data, str):
391
- data: bytes = data.encode('utf-8')
392
-
393
- tarinfo = tarfile.TarInfo(name=name)
394
- tarinfo.size = len(data)
395
- tarinfo.mtime = int(time.time())
396
-
397
- with io.BytesIO(data) as file:
398
- tar.addfile(tarinfo=tarinfo, fileobj=file)
399
-
400
- tar_buffer.seek(0)
401
- return tar_buffer.getvalue()
402
-
403
- @staticmethod
404
- def untar_files(tar_file: bytes) -> dict[str, bytes]:
405
- """
406
- Decompress a .tar file from an in-memory bytes object and extracts all files into a dictionary.
407
-
408
- :param tar_file: The bytes of the tar file to be decompressed.
409
- :return: A dictionary of file name to file bytes for each file in the tar.
410
- """
411
- extracted_files: dict[str, bytes] = {}
412
- with io.BytesIO(tar_file) as tar_buffer:
413
- with tarfile.open(fileobj=tar_buffer, mode="r") as tar:
414
- for member in tar.getmembers():
415
- if member.isfile():
416
- file_obj = tar.extractfile(member)
417
- if file_obj:
418
- with file_obj:
419
- extracted_files[member.name] = file_obj.read()
420
- return extracted_files
421
-
422
- @staticmethod
423
- def tar_gzip_files(files: dict[str, str | bytes]) -> bytes:
424
- """
425
- Create a .tar.gz file for a collection of files.
426
-
427
- :param files: A dictionary of file name to file data as a string or bytes.
428
- :return: The bytes for a tar.gz file containing the input files.
429
- """
430
- with io.BytesIO() as tar_buffer:
431
- with tarfile.open(fileobj=tar_buffer, mode="w:gz") as tar:
432
- for name, data in files.items():
433
- if isinstance(data, str):
434
- data: bytes = data.encode('utf-8')
435
-
436
- tarinfo = tarfile.TarInfo(name=name)
437
- tarinfo.size = len(data)
438
- tarinfo.mtime = int(time.time())
439
-
440
- with io.BytesIO(data) as file:
441
- tar.addfile(tarinfo=tarinfo, fileobj=file)
442
-
443
- tar_buffer.seek(0)
444
- return tar_buffer.getvalue()
445
-
446
- @staticmethod
447
- def untar_gzip_files(tar_gzip_file: bytes) -> dict[str, bytes]:
448
- """
449
- Decompress a .tar.gz file from an in-memory bytes object and extracts all files into a dictionary.
450
-
451
- :param tar_gzip_file: The bytes of the tar.gz file to be decompressed.
452
- :return: A dictionary of file name to file bytes for each file in the tar.gz
453
- """
454
- extracted_files: dict[str, bytes] = {}
455
- with io.BytesIO(tar_gzip_file) as tar_buffer:
456
- with tarfile.open(fileobj=tar_buffer, mode="r:gz") as tar:
457
- for member in tar.getmembers():
458
- if member.isfile():
459
- file_obj = tar.extractfile(member)
460
- if file_obj:
461
- with file_obj:
462
- extracted_files[member.name] = file_obj.read()
463
- return extracted_files
464
-
465
338
  # Deprecated functions:
466
339
 
467
340
  # FR-46097 - Add write file request shorthand functions to FileUtil.
@@ -224,8 +224,11 @@ class AliasUtil:
224
224
  fields: FieldMap = {f: record.fields.get(f) for f in record.fields}
225
225
  # PR-47457: Only include the record ID if the caller requests it, since including the record ID can break
226
226
  # callbacks in certain circumstances if the record ID is negative.
227
+ # PR-47894: Also remove the RecordId key if it exists and the caller doesn't want it included.
227
228
  if include_record_id:
228
229
  fields["RecordId"] = AliasUtil.to_record_id(record)
230
+ elif "RecordId" in fields:
231
+ del fields["RecordId"]
229
232
  return fields
230
233
 
231
234
  @staticmethod
@@ -140,7 +140,7 @@ class AbstractWebserviceHandler(AbstractWebhookHandler):
140
140
  # Get the login credentials from the headers.
141
141
  auth: str = headers.get("Authorization")
142
142
  if auth and auth.startswith("Basic "):
143
- credentials: list[str] = b64decode(auth.split("Basic ")[1]).decode().split(":", 1)
143
+ credentials: list[str] = b64decode(auth.split("Basic ")[1]).decode().split(":")
144
144
  user = self.basic_auth(url, credentials[0], credentials[1])
145
145
  elif auth and auth.startswith("Bearer "):
146
146
  user = self.bearer_token_auth(url, auth.split("Bearer ")[1])
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: sapiopycommons
3
- Version: 2025.10.15a782
3
+ Version: 2025.10.17a787
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,47 +1,8 @@
1
1
  sapiopycommons/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  sapiopycommons/ai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- sapiopycommons/ai/agent_service_base.py,sha256=LVZg_4Kw5WTcIB7ru5hEqJoMWQr2eTDYjMrX8pzpn9I,56301
4
- sapiopycommons/ai/converter_service_base.py,sha256=HiUXmwqv1STgyQeF9_eTFXzjIFXp5-NJ7sEhMpV3aAU,6351
5
- sapiopycommons/ai/external_credentials.py,sha256=ki_xIH4J843b_sSwEa8YHr8vW9erVv-jowZJXSgPQs8,4347
6
- sapiopycommons/ai/protobuf_utils.py,sha256=cBjbxoFAwU02kNUxEce95WnMU2CMuDD-qFaeWgvQJMQ,24599
7
- sapiopycommons/ai/request_validation.py,sha256=TD2EUi_G5cy1OOVK1AmY2SQc3PEoAKGWs2pT8Qnp2Oo,25092
8
- sapiopycommons/ai/server.py,sha256=gutSskn_Fenq1uz0DDMvjx4QVFiKt2WVEP3-01a69eU,6384
9
- sapiopycommons/ai/test_client.py,sha256=IRZ-8prhg7XMDmN9aC1MQr5mSkMgfT37aLsOy-VB-MU,20495
10
- sapiopycommons/ai/protoapi/externalcredentials/external_credentials_pb2.py,sha256=mEonoj6Iq-AyvO4m3YsPYu85aZfD1E0a0cL8B9yPfEo,2481
11
- sapiopycommons/ai/protoapi/externalcredentials/external_credentials_pb2.pyi,sha256=sfExq8fFwIwFxCpV50ytdxW5ePNBjJBr_80_trq_JQw,1658
12
- sapiopycommons/ai/protoapi/externalcredentials/external_credentials_pb2_grpc.py,sha256=TNS1CB_QGBSa1YU9sYR_hF-pmBwv2GpxjaNQoM_r9iU,948
13
- sapiopycommons/ai/protoapi/fielddefinitions/fields_pb2.py,sha256=8tKXwLXcqFGdQHHSEBSi6Fd7dcaCFoOqmhjzqhenb_M,2372
14
- sapiopycommons/ai/protoapi/fielddefinitions/fields_pb2.pyi,sha256=FwtXmNAf7iYGEFm4kbqb04v77jNHbZg18ZmEDhle_bU,1444
15
- sapiopycommons/ai/protoapi/fielddefinitions/fields_pb2_grpc.py,sha256=uO25bcnfGqXpP4ggUur54Nr73Wj-DGWftExzLNcxdHI,931
16
- sapiopycommons/ai/protoapi/fielddefinitions/velox_field_def_pb2.py,sha256=in9iHiLPYcnLWoLeqy4nWSI0jZGHD_bMhEFRIRtJPuo,20864
17
- sapiopycommons/ai/protoapi/fielddefinitions/velox_field_def_pb2.pyi,sha256=U5zXrbBxsWilLTsRWJd1TqjdjLKFsr3enF9OJ8GfyWw,34028
18
- sapiopycommons/ai/protoapi/fielddefinitions/velox_field_def_pb2_grpc.py,sha256=Vj6qDKvsHgl25iBi3UjtTuGxihekgqCuufExvnJKzQI,940
19
- sapiopycommons/ai/protoapi/plan/step_output_pb2.py,sha256=EBNCzLUDwwCqDCh35zSfFdfq0RP8WrmTMXEzEPu_1_E,2655
20
- sapiopycommons/ai/protoapi/plan/step_output_pb2.pyi,sha256=yuxOYnDZ9DRuu-TLzaKOW_B4LUiYxTrNc2AbssXg4kE,2022
21
- sapiopycommons/ai/protoapi/plan/step_output_pb2_grpc.py,sha256=ebWLIfOFeVE2WuUIThMBerVweH-1phviGX195UTwYyg,924
22
- sapiopycommons/ai/protoapi/plan/step_pb2.py,sha256=mKTm_syaX99GzhWtGIPkxMTsfcsvW0QbRqjv06eHSM0,2433
23
- sapiopycommons/ai/protoapi/plan/step_pb2.pyi,sha256=QPIcsjcUvEGQkdZMUMiVzFFNDl8yOUe_qJtf5XEp5Ck,2062
24
- sapiopycommons/ai/protoapi/plan/step_pb2_grpc.py,sha256=1CBna5NBBxPwQhrkN8-Fim_j3FGmOfDo5C4c8sIBV8Q,917
25
- sapiopycommons/ai/protoapi/plan/converter/converter_pb2.py,sha256=rZYBRfR0umwDYvBdYnzxR1VZSutRqunhd3QsdtQXiCM,3593
26
- sapiopycommons/ai/protoapi/plan/converter/converter_pb2.pyi,sha256=_35yHfKTJH3SMdA5_c6qF6OZG6UwFWXpNh6dwRFDKkk,4250
27
- sapiopycommons/ai/protoapi/plan/converter/converter_pb2_grpc.py,sha256=6T5FCmT_vEFSywUVlAlWWfBDPaILb0Dq8yCGuO_Q-BU,6448
28
- sapiopycommons/ai/protoapi/plan/item/item_container_pb2.py,sha256=VIXmIw8-9jtH7peJZ16BEmGDfaVjjxTKhmlfcHWT82M,3863
29
- sapiopycommons/ai/protoapi/plan/item/item_container_pb2.pyi,sha256=bbPNQDwfFDd7_S7yU99Co1O7sRhxjle-RM0_nK8jgjc,4246
30
- sapiopycommons/ai/protoapi/plan/item/item_container_pb2_grpc.py,sha256=1NzBWBUINC0Rk-NGYZ-97BVKvVUxcn_I44IjQO2h-nQ,932
31
- sapiopycommons/ai/protoapi/plan/script/script_pb2.py,sha256=4TN7NlJEENAVqwfymoEDj5hhHYxHLdrHdpRUVgzVG8A,5621
32
- sapiopycommons/ai/protoapi/plan/script/script_pb2.pyi,sha256=l250ak1sOfm7Ue-PyBQC-7j7-p4DeBxltnOzwDsQIYc,6870
33
- sapiopycommons/ai/protoapi/plan/script/script_pb2_grpc.py,sha256=ginPYpsiI6U6dB6gfWHJM8LWjSHUgcqz_gR7Dmdsyck,6864
34
- sapiopycommons/ai/protoapi/plan/tool/entry_pb2.py,sha256=yNyyyVvz94ewjGaHw3t0pUP-KH7ACg5hLC0QzrsFPis,2130
35
- sapiopycommons/ai/protoapi/plan/tool/entry_pb2.pyi,sha256=2vI0WSy0KGFHDewMSRyX5rUkmmmSaMBLvFO7txqA6Ug,2354
36
- sapiopycommons/ai/protoapi/plan/tool/entry_pb2_grpc.py,sha256=i24BfJEt7LtyROxHVEyS9RLYqLZKPvyJMKRFZj6NUTg,923
37
- sapiopycommons/ai/protoapi/plan/tool/tool_pb2.py,sha256=aLD5j60lWUxhHW8b1AoUOClLOjFPjEMmM1KrY337-gI,9095
38
- sapiopycommons/ai/protoapi/plan/tool/tool_pb2.pyi,sha256=HGNou2THKPk8o9G_ZPvbGXDb6cBnv8L1R_l10i9ceHI,18441
39
- sapiopycommons/ai/protoapi/plan/tool/tool_pb2_grpc.py,sha256=CLSGEgSpN4D6wcE-P_5lzb2Nttjr4XjumxGUrZQSip0,6915
40
- sapiopycommons/ai/protoapi/session/sapio_conn_info_pb2.py,sha256=MhWzTyJz3xZgpdW8_LCVKuzKXT0cv6iHMRB-UNCUNzM,2094
41
- sapiopycommons/ai/protoapi/session/sapio_conn_info_pb2.pyi,sha256=vLYA8Tkzq2AwgVadoUp5vAg4HgGlgga0kzeS3e_XkCQ,1621
42
- sapiopycommons/ai/protoapi/session/sapio_conn_info_pb2_grpc.py,sha256=imcciy_kbmm7OV_W3jYZ53R6GQ6Yh-eUcVW0A9GkWdg,931
3
+ sapiopycommons/ai/tool_of_tools.py,sha256=zYmQ4rNX-qYQnc-vNDnYZjtv9JgmQAmVVuHfVOdBF3w,46984
43
4
  sapiopycommons/callbacks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
44
- sapiopycommons/callbacks/callback_util.py,sha256=Z1LcXnRRjXyhmcSDUwh4NzcA6ICtcbFUMKcvAqQcS8E,153811
5
+ sapiopycommons/callbacks/callback_util.py,sha256=aLkH5p5PMI74MN7tdrJ3Xy6LDDggHpCf4Lhr9XuOreA,154535
45
6
  sapiopycommons/callbacks/field_builder.py,sha256=rnIP-RJafk3mZlAx1eJ8a0eSW9Ps_L6_WadCmusnENw,38772
46
7
  sapiopycommons/chem/IndigoMolecules.py,sha256=7ucCaRMLu1zfH2uPIvXwRTSdpNcS03O1P9p_O-5B4xQ,5110
47
8
  sapiopycommons/chem/Molecules.py,sha256=mVqPn32MPMjF0iZas-5MFkS-upIdoW5OB72KKZmJRJA,12523
@@ -70,15 +31,14 @@ sapiopycommons/files/file_bridge.py,sha256=vKbqxPexi15epr_-_qLrEfYoxNxB031mXN92i
70
31
  sapiopycommons/files/file_bridge_handler.py,sha256=SEYDIQhSCmjI6qyLdDJE8JVKSd0WYvF7JvAq_Ahp9Do,25503
71
32
  sapiopycommons/files/file_data_handler.py,sha256=f96MlkMuQhUCi4oLnzJK5AiuElCp5jLI8_sJkZVwpws,36779
72
33
  sapiopycommons/files/file_text_converter.py,sha256=Gaj_divTiKXWd6flDOgrxNXpcn9fDWqxX6LUG0joePk,7516
73
- sapiopycommons/files/file_util.py,sha256=WBA3FYG8R2HtfxjWSzQhZKW6_1s6JSxTo9lk3SeNDu8,37140
34
+ sapiopycommons/files/file_util.py,sha256=djouyGjsYgWzjz2OBRnSeMDgj6NrsJUm1a2J93J8Wco,31915
74
35
  sapiopycommons/files/file_validator.py,sha256=ryg22-93csmRO_Pv0ZpWphNkB74xWZnHyJ23K56qLj0,28761
75
36
  sapiopycommons/files/file_writer.py,sha256=hACVl0duCjP28gJ1NPljkjagNCLod0ygUlPbvUmRDNM,17605
76
- sapiopycommons/files/temp_files.py,sha256=s2sGvn9uh2dTI8AVAQJWOf6RAZ0xZs7DSccCi4AGmlw,3175
77
37
  sapiopycommons/flowcyto/flow_cyto.py,sha256=B6DFquLi-gcWfJWyP4vYfwTXXJKl6O9W5-k8FzkM0Oo,2610
78
38
  sapiopycommons/flowcyto/flowcyto_data.py,sha256=mYKFuLbtpJ-EsQxLGtu4tNHVlygTxKixgJxJqD68F58,2596
79
39
  sapiopycommons/general/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
80
40
  sapiopycommons/general/accession_service.py,sha256=ZvtvZg7d_siMJUedjrF14mcqo5ZqVA5IJxDa5enlB-8,12792
81
- sapiopycommons/general/aliases.py,sha256=VwnWf_P803pcteoAIs0DkLScVChCS5XNgryTp8FzaNc,14696
41
+ sapiopycommons/general/aliases.py,sha256=pHfpH5veukVdjlR62_INCy2ItZG1omQv4dCoo8NeGlM,14869
82
42
  sapiopycommons/general/audit_log.py,sha256=sQAMcJx0cNkgZm7nTZSaGPxWvHG0_x6dBtU0jESavb4,9131
83
43
  sapiopycommons/general/custom_report_util.py,sha256=9elLEUSgfM0gli8nRPz1uYkhaXN4Vnx3piSiNHv5IBs,19156
84
44
  sapiopycommons/general/data_structure_util.py,sha256=fbQR_Fh4Scg67IpFPbQW9wVLw1oxlYxqp4LjBRTpjgU,4702
@@ -105,8 +65,8 @@ sapiopycommons/sftpconnect/sftp_builder.py,sha256=lFK3FeXk-sFLefW0hqY8WGUQDeYiGa
105
65
  sapiopycommons/webhook/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
106
66
  sapiopycommons/webhook/webhook_context.py,sha256=D793uLsb1691SalaPnBUk3rOSxn_hYLhdvkaIxjNXss,1909
107
67
  sapiopycommons/webhook/webhook_handlers.py,sha256=7o_wXOruhT9auNh8OfhJAh4WhhiPKij67FMBSpGPICc,39939
108
- sapiopycommons/webhook/webservice_handlers.py,sha256=cvW6Mk_110BzYqkbk63Kg7jWrltBCDALOlkJRu8h4VQ,14300
109
- sapiopycommons-2025.10.15a782.dist-info/METADATA,sha256=DIeUTx52EZpA1ZIecBFRA4_LsTMKBwOZLzB6i2iBgxs,3143
110
- sapiopycommons-2025.10.15a782.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
111
- sapiopycommons-2025.10.15a782.dist-info/licenses/LICENSE,sha256=HyVuytGSiAUQ6ErWBHTqt1iSGHhLmlC8fO7jTCuR8dU,16725
112
- sapiopycommons-2025.10.15a782.dist-info/RECORD,,
68
+ sapiopycommons/webhook/webservice_handlers.py,sha256=tyaYGG1-v_JJrJHZ6cy5mGCxX9z1foLw7pM4MDJlFxs,14297
69
+ sapiopycommons-2025.10.17a787.dist-info/METADATA,sha256=3mZft6DRxhP-QWhIDnysHuAHlxoYaghDr4kWHRpUG9g,3143
70
+ sapiopycommons-2025.10.17a787.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
71
+ sapiopycommons-2025.10.17a787.dist-info/licenses/LICENSE,sha256=HyVuytGSiAUQ6ErWBHTqt1iSGHhLmlC8fO7jTCuR8dU,16725
72
+ sapiopycommons-2025.10.17a787.dist-info/RECORD,,