sapiopycommons 2025.7.7a580__py3-none-any.whl → 2025.7.9a582__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.
- sapiopycommons/ai/__init__.py +0 -0
- sapiopycommons/ai/api/fielddefinitions/proto/fields_pb2.py +43 -0
- sapiopycommons/ai/api/fielddefinitions/proto/fields_pb2.pyi +31 -0
- sapiopycommons/ai/api/fielddefinitions/proto/fields_pb2_grpc.py +24 -0
- sapiopycommons/ai/api/fielddefinitions/proto/velox_field_def_pb2.py +123 -0
- sapiopycommons/ai/api/fielddefinitions/proto/velox_field_def_pb2.pyi +598 -0
- sapiopycommons/ai/api/fielddefinitions/proto/velox_field_def_pb2_grpc.py +24 -0
- sapiopycommons/ai/api/plan/proto/step_output_pb2.py +45 -0
- sapiopycommons/ai/api/plan/proto/step_output_pb2.pyi +42 -0
- sapiopycommons/ai/api/plan/proto/step_output_pb2_grpc.py +24 -0
- sapiopycommons/ai/api/plan/proto/step_pb2.py +43 -0
- sapiopycommons/ai/api/plan/proto/step_pb2.pyi +43 -0
- sapiopycommons/ai/api/plan/proto/step_pb2_grpc.py +24 -0
- sapiopycommons/ai/api/plan/script/proto/script_pb2.py +55 -0
- sapiopycommons/ai/api/plan/script/proto/script_pb2.pyi +115 -0
- sapiopycommons/ai/api/plan/script/proto/script_pb2_grpc.py +153 -0
- sapiopycommons/ai/api/plan/tool/proto/entry_pb2.py +57 -0
- sapiopycommons/ai/api/plan/tool/proto/entry_pb2.pyi +96 -0
- sapiopycommons/ai/api/plan/tool/proto/entry_pb2_grpc.py +24 -0
- sapiopycommons/ai/api/plan/tool/proto/tool_pb2.py +67 -0
- sapiopycommons/ai/api/plan/tool/proto/tool_pb2.pyi +220 -0
- sapiopycommons/ai/api/plan/tool/proto/tool_pb2_grpc.py +154 -0
- sapiopycommons/ai/api/session/proto/sapio_conn_info_pb2.py +39 -0
- sapiopycommons/ai/api/session/proto/sapio_conn_info_pb2.pyi +32 -0
- sapiopycommons/ai/api/session/proto/sapio_conn_info_pb2_grpc.py +24 -0
- sapiopycommons/ai/protobuf_utils.py +508 -0
- sapiopycommons/ai/test_client.py +251 -0
- sapiopycommons/ai/tool_service_base.py +798 -0
- sapiopycommons/callbacks/callback_util.py +332 -665
- sapiopycommons/callbacks/field_builder.py +0 -2
- sapiopycommons/chem/IndigoMolecules.py +1 -31
- sapiopycommons/chem/Molecules.py +3 -3
- sapiopycommons/customreport/auto_pagers.py +1 -26
- sapiopycommons/customreport/term_builder.py +1 -1
- sapiopycommons/datatype/pseudo_data_types.py +326 -349
- sapiopycommons/eln/experiment_handler.py +767 -408
- sapiopycommons/eln/experiment_report_util.py +6 -11
- sapiopycommons/eln/plate_designer.py +2 -7
- sapiopycommons/files/file_util.py +5 -7
- sapiopycommons/general/accession_service.py +2 -2
- sapiopycommons/general/aliases.py +1 -3
- sapiopycommons/general/audit_log.py +0 -7
- sapiopycommons/general/custom_report_util.py +0 -12
- sapiopycommons/processtracking/custom_workflow_handler.py +1 -11
- sapiopycommons/processtracking/endpoints.py +0 -27
- sapiopycommons/recordmodel/record_handler.py +317 -657
- sapiopycommons/rules/eln_rule_handler.py +1 -8
- sapiopycommons/rules/on_save_rule_handler.py +1 -8
- sapiopycommons/webhook/webhook_handlers.py +0 -3
- sapiopycommons/webhook/webservice_handlers.py +2 -2
- {sapiopycommons-2025.7.7a580.dist-info → sapiopycommons-2025.7.9a582.dist-info}/METADATA +2 -2
- sapiopycommons-2025.7.9a582.dist-info/RECORD +92 -0
- sapiopycommons/chem/ps_commons.py +0 -455
- sapiopycommons/eln/experiment_cache.py +0 -188
- sapiopycommons/eln/experiment_step_factory.py +0 -476
- sapiopycommons/eln/step_creation.py +0 -236
- sapiopycommons/general/data_structure_util.py +0 -115
- sapiopycommons-2025.7.7a580.dist-info/RECORD +0 -69
- {sapiopycommons-2025.7.7a580.dist-info → sapiopycommons-2025.7.9a582.dist-info}/WHEEL +0 -0
- {sapiopycommons-2025.7.7a580.dist-info → sapiopycommons-2025.7.9a582.dist-info}/licenses/LICENSE +0 -0
|
@@ -443,8 +443,6 @@ class FieldBuilder:
|
|
|
443
443
|
raise SapioException("Unable to set multiple list modes at once for a selection list.")
|
|
444
444
|
# Static values don't have a list mode. Evaluate this last so that the multiple list modes check doesn't
|
|
445
445
|
# need to be more complex.
|
|
446
|
-
# PR-47531: Even though static values don't use an existing list mode, a list mode must still be set.
|
|
447
|
-
list_mode = ListMode.USER
|
|
448
446
|
|
|
449
447
|
if not list_mode and static_values is None:
|
|
450
448
|
raise SapioException("A list mode must be chosen for selection list fields.")
|
|
@@ -6,42 +6,13 @@ indigo = Indigo()
|
|
|
6
6
|
renderer = IndigoRenderer(indigo)
|
|
7
7
|
indigo.setOption("render-output-format", "svg")
|
|
8
8
|
indigo.setOption("ignore-stereochemistry-errors", True)
|
|
9
|
-
# Ignore only if loading as non-query object. That is the meaning of this flag. Does nothing if it's query molecule.
|
|
10
|
-
indigo.setOption("ignore-noncritical-query-features", True)
|
|
11
9
|
indigo.setOption("render-stereo-style", "ext")
|
|
12
10
|
indigo.setOption("aromaticity-model", "generic")
|
|
13
11
|
indigo.setOption("render-coloring", True)
|
|
14
12
|
indigo.setOption("molfile-saving-mode", "3000")
|
|
15
|
-
indigo.setOption("dearomatize-verification", False)
|
|
16
13
|
indigo_inchi = IndigoInchi(indigo)
|
|
17
14
|
|
|
18
15
|
|
|
19
|
-
def get_aromatic_dearomatic_forms(m: IndigoObject):
|
|
20
|
-
"""
|
|
21
|
-
Get the aromatic and dearomatic forms of the molecule. Retain the original form if it's not inversible.
|
|
22
|
-
Inversible: after aromatic-dearomatic-aromatic transformation, the molecule is the same as the first aromatic transformation.
|
|
23
|
-
:param m: molecule from indigo.
|
|
24
|
-
:return: pair of indigo objects, first is aromatic, second is dearomatic.
|
|
25
|
-
"""
|
|
26
|
-
try:
|
|
27
|
-
aromatic_reaction = m.clone()
|
|
28
|
-
aromatic_reaction.aromatize()
|
|
29
|
-
dearomatic_reaction = aromatic_reaction.clone()
|
|
30
|
-
dearomatic_reaction.dearomatize()
|
|
31
|
-
second_aromatic_reaction = dearomatic_reaction.clone()
|
|
32
|
-
second_aromatic_reaction.aromatize()
|
|
33
|
-
match = indigo.exactMatch(aromatic_reaction, second_aromatic_reaction)
|
|
34
|
-
if match:
|
|
35
|
-
return aromatic_reaction, dearomatic_reaction
|
|
36
|
-
else:
|
|
37
|
-
return m, dearomatic_reaction
|
|
38
|
-
except (Exception):
|
|
39
|
-
# If aromatization then following deromatization fails, we just skip it.
|
|
40
|
-
dearomatic_reaction = m.clone()
|
|
41
|
-
dearomatic_reaction.dearomatize()
|
|
42
|
-
return m, dearomatic_reaction
|
|
43
|
-
|
|
44
|
-
|
|
45
16
|
# Function to process dative bonds in a molecule
|
|
46
17
|
# Returns True if at least one dative bond (_BOND_COORDINATION) was removed
|
|
47
18
|
def remove_dative_bonds_in_mol(molecule: IndigoObject) -> bool:
|
|
@@ -80,8 +51,7 @@ def remove_dative_in_reaction(reaction: IndigoObject) -> bool:
|
|
|
80
51
|
:param reaction: The reaction to remove dative bonds.
|
|
81
52
|
:return: Whether there are any dative bonds in the reaction that were removed.
|
|
82
53
|
"""
|
|
83
|
-
reactant_dative_removed: bool = any(
|
|
84
|
-
remove_dative_bonds_in_mol(reactant) for reactant in reaction.iterateReactants())
|
|
54
|
+
reactant_dative_removed: bool = any(remove_dative_bonds_in_mol(reactant) for reactant in reaction.iterateReactants())
|
|
85
55
|
product_dative_removed: bool = any(remove_dative_bonds_in_mol(product) for product in reaction.iterateProducts())
|
|
86
56
|
return reactant_dative_removed or product_dative_removed
|
|
87
57
|
|
sapiopycommons/chem/Molecules.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Author Yechen Qiao
|
|
2
2
|
# Common Molecule Utilities for Molecule Transfers with Sapio
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
from rdkit import Chem
|
|
5
5
|
from rdkit.Chem import Crippen, MolToInchi
|
|
6
6
|
from rdkit.Chem import Descriptors
|
|
@@ -10,7 +10,7 @@ from rdkit.Chem.MolStandardize import rdMolStandardize
|
|
|
10
10
|
from rdkit.Chem.SaltRemover import SaltRemover
|
|
11
11
|
from rdkit.Chem.rdchem import Mol, RWMol, Bond
|
|
12
12
|
|
|
13
|
-
from sapiopycommons.chem.IndigoMolecules import indigo, renderer, indigo_inchi
|
|
13
|
+
from sapiopycommons.chem.IndigoMolecules import indigo, renderer, indigo_inchi
|
|
14
14
|
|
|
15
15
|
metal_disconnector = rdMolStandardize.MetalDisconnector()
|
|
16
16
|
tautomer_params = Chem.MolStandardize.rdMolStandardize.CleanupParameters()
|
|
@@ -247,7 +247,7 @@ def mol_to_sapio_substance(mol: Mol, include_stereoisomers=False,
|
|
|
247
247
|
molecule["image"] = None
|
|
248
248
|
# We need to test the INCHI can be loaded back to indigo.
|
|
249
249
|
indigo_mol = indigo.loadMolecule(molBlock)
|
|
250
|
-
indigo_mol
|
|
250
|
+
indigo_mol.aromatize()
|
|
251
251
|
if enhanced_stereo:
|
|
252
252
|
# Remove enhanced stereo layer when generating InChI as the stereo hash is generated separately for reg.
|
|
253
253
|
Chem.CanonicalizeEnhancedStereo(inchi_mol)
|
|
@@ -6,7 +6,6 @@ from sapiopylib.rest.CustomReportService import CustomReportManager
|
|
|
6
6
|
from sapiopylib.rest.DataMgmtService import DataMgmtServer
|
|
7
7
|
from sapiopylib.rest.pojo.CustomReport import CustomReportCriteria, CustomReport, RawReportTerm, ReportColumn
|
|
8
8
|
from sapiopylib.rest.pojo.datatype.FieldDefinition import FieldType
|
|
9
|
-
# noinspection PyProtectedMember
|
|
10
9
|
from sapiopylib.rest.utils.autopaging import SapioPyAutoPager, PagerResultCriteriaType, _default_report_page_size, \
|
|
11
10
|
_default_record_page_size
|
|
12
11
|
from sapiopylib.rest.utils.recordmodel.PyRecordModel import PyRecordModel
|
|
@@ -62,12 +61,6 @@ class CustomReportDictAutoPager(_DictReportPagerBase):
|
|
|
62
61
|
def __init__(self, user: UserIdentifier, report_criteria: CustomReportCriteria,
|
|
63
62
|
page_number: int = 0, page_size: int = _default_report_page_size):
|
|
64
63
|
"""
|
|
65
|
-
IMPORTANT NOTICE: Custom reports that are not single data type (i.e. they have terms or columns from multiple
|
|
66
|
-
data types) may not be 100% time accurate. Such reports use the system's ancestor table to retrieve the
|
|
67
|
-
relationships, and this table takes some time to update after relationships are updated, especially for more
|
|
68
|
-
populous data types. If you need 100% time accurate results to the current state of the records and
|
|
69
|
-
relationships in the database, you should query for the records directly instead of using a custom report.
|
|
70
|
-
|
|
71
64
|
:param user: The current webhook context or a user object to send requests from.
|
|
72
65
|
:param report_criteria: The custom report criteria to run.
|
|
73
66
|
:param page_number: The page number to start on. The first page is page 0.
|
|
@@ -89,12 +82,6 @@ class SystemReportDictAutoPager(_DictReportPagerBase):
|
|
|
89
82
|
def __init__(self, user: UserIdentifier, report_name: str,
|
|
90
83
|
page_number: int = 0, page_size: int = _default_report_page_size):
|
|
91
84
|
"""
|
|
92
|
-
IMPORTANT NOTICE: Custom reports that are not single data type (i.e. they have terms or columns from multiple
|
|
93
|
-
data types) may not be 100% time accurate. Such reports use the system's ancestor table to retrieve the
|
|
94
|
-
relationships, and this table takes some time to update after relationships are updated, especially for more
|
|
95
|
-
populous data types. If you need 100% time accurate results to the current state of the records and
|
|
96
|
-
relationships in the database, you should query for the records directly instead of using a custom report.
|
|
97
|
-
|
|
98
85
|
:param user: The current webhook context or a user object to send requests from.
|
|
99
86
|
:param report_name: The name of the system report to run.
|
|
100
87
|
:param page_number: The page number to start on. The first page is page 0.
|
|
@@ -166,7 +153,7 @@ class _RecordReportPagerBase(SapioPyAutoPager[CustomReportCriteria, WrappedType
|
|
|
166
153
|
if id_index == -1:
|
|
167
154
|
raise SapioException(f"This report does not contain a Record ID column for the given record model type "
|
|
168
155
|
f"{self._data_type}.")
|
|
169
|
-
ids:
|
|
156
|
+
ids: list[int] = [row[id_index] for row in report.result_table]
|
|
170
157
|
for row in self._rec_handler.query_models_by_id(self._query_type, ids, page_size=report.page_size):
|
|
171
158
|
queue.put(row)
|
|
172
159
|
if report.has_next_page:
|
|
@@ -185,12 +172,6 @@ class CustomReportRecordAutoPager(_RecordReportPagerBase):
|
|
|
185
172
|
wrapper_type: type[WrappedType] | str, page_number: int = 0,
|
|
186
173
|
page_size: int = _default_record_page_size):
|
|
187
174
|
"""
|
|
188
|
-
IMPORTANT NOTICE: Custom reports that are not single data type (i.e. they have terms or columns from multiple
|
|
189
|
-
data types) may not be 100% time accurate. Such reports use the system's ancestor table to retrieve the
|
|
190
|
-
relationships, and this table takes some time to update after relationships are updated, especially for more
|
|
191
|
-
populous data types. If you need 100% time accurate results to the current state of the records and
|
|
192
|
-
relationships in the database, you should query for the records directly instead of using a custom report.
|
|
193
|
-
|
|
194
175
|
:param user: The current webhook context or a user object to send requests from.
|
|
195
176
|
:param report_criteria: The custom report criteria to run.
|
|
196
177
|
:param wrapper_type: The record model wrapper type or data type name of the records being searched for.
|
|
@@ -216,12 +197,6 @@ class SystemReportRecordAutoPager(_RecordReportPagerBase):
|
|
|
216
197
|
def __init__(self, user: UserIdentifier, report_name: str, wrapper_type: type[WrappedType] | str,
|
|
217
198
|
page_number: int = 0, page_size: int = _default_record_page_size):
|
|
218
199
|
"""
|
|
219
|
-
IMPORTANT NOTICE: Custom reports that are not single data type (i.e. they have terms or columns from multiple
|
|
220
|
-
data types) may not be 100% time accurate. Such reports use the system's ancestor table to retrieve the
|
|
221
|
-
relationships, and this table takes some time to update after relationships are updated, especially for more
|
|
222
|
-
populous data types. If you need 100% time accurate results to the current state of the records and
|
|
223
|
-
relationships in the database, you should query for the records directly instead of using a custom report.
|
|
224
|
-
|
|
225
200
|
:param user: The current webhook context or a user object to send requests from.
|
|
226
201
|
:param report_name: The name of the system report to run.
|
|
227
202
|
:param wrapper_type: The record model wrapper type or data type name of the records being searched for.
|
|
@@ -279,7 +279,7 @@ class TermBuilder:
|
|
|
279
279
|
|
|
280
280
|
:param a: The first term in the operation.
|
|
281
281
|
:param b: The second term in the operation.
|
|
282
|
-
:param is_negated: Whether the returned term should be negated (i.e. turn this into an
|
|
282
|
+
:param is_negated: Whether the returned term should be negated (i.e. turn this into an xnor operation).
|
|
283
283
|
:return: A composite report term for "A xor B".
|
|
284
284
|
"""
|
|
285
285
|
return TermBuilder.and_terms(TermBuilder.or_terms(a, b),
|