sapiopycommons 2024.11.25a373__tar.gz → 2024.12.5a376__tar.gz
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-2024.11.25a373 → sapiopycommons-2024.12.5a376}/PKG-INFO +1 -1
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/pyproject.toml +1 -1
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/chem/IndigoMolecules.py +44 -1
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/chem/Molecules.py +28 -8
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/eln/experiment_handler.py +1 -1
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/general/time_util.py +83 -5
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/.gitignore +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/LICENSE +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/README.md +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/__init__.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/callbacks/__init__.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/callbacks/callback_util.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/callbacks/field_builder.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/chem/__init__.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/customreport/__init__.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/customreport/column_builder.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/customreport/custom_report_builder.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/customreport/term_builder.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/datatype/__init__.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/datatype/attachment_util.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/datatype/data_fields.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/datatype/pseudo_data_types.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/eln/__init__.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/eln/experiment_report_util.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/eln/plate_designer.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/files/__init__.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/files/complex_data_loader.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/files/file_bridge.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/files/file_bridge_handler.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/files/file_data_handler.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/files/file_util.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/files/file_validator.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/files/file_writer.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/flowcyto/flow_cyto.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/flowcyto/flowcyto_data.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/general/__init__.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/general/accession_service.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/general/aliases.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/general/audit_log.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/general/custom_report_util.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/general/exceptions.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/general/popup_util.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/general/sapio_links.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/general/storage_util.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/multimodal/multimodal.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/multimodal/multimodal_data.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/processtracking/__init__.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/processtracking/custom_workflow_handler.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/processtracking/endpoints.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/recordmodel/__init__.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/recordmodel/record_handler.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/rules/__init__.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/rules/eln_rule_handler.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/rules/on_save_rule_handler.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/sftpconnect/__init__.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/sftpconnect/sftp_builder.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/webhook/__init__.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/webhook/webhook_context.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/webhook/webhook_handlers.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/webhook/webservice_handlers.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/tests/AF-A0A009IHW8-F1-model_v4.cif +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/tests/_do_not_add_init_py_here +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/tests/accession_test.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/tests/bio_reg_test.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/tests/chem_test.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/tests/chem_test_curation_queue.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/tests/curation_queue_test.sdf +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/tests/data_type_models.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/tests/flowcyto/101_DEN084Y5_15_E01_008_clean.fcs +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/tests/flowcyto/101_DEN084Y5_15_E03_009_clean.fcs +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/tests/flowcyto/101_DEN084Y5_15_E05_010_clean.fcs +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/tests/flowcyto/8_color_ICS.wsp +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/tests/flowcyto/COVID19_W_001_O.fcs +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/tests/flowcyto_test.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/tests/kappa.chains.fasta +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/tests/mafft_test.py +0 -0
- {sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/tests/test.gb +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: sapiopycommons
|
|
3
|
-
Version: 2024.
|
|
3
|
+
Version: 2024.12.5a376
|
|
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>
|
|
@@ -10,7 +10,50 @@ indigo.setOption("render-stereo-style", "ext")
|
|
|
10
10
|
indigo.setOption("aromaticity-model", "generic")
|
|
11
11
|
indigo.setOption("render-coloring", True)
|
|
12
12
|
indigo.setOption("molfile-saving-mode", "3000")
|
|
13
|
-
indigo_inchi = IndigoInchi(indigo)
|
|
13
|
+
indigo_inchi = IndigoInchi(indigo)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# Function to process dative bonds in a molecule
|
|
17
|
+
# Returns True if at least one dative bond (_BOND_COORDINATION) was removed
|
|
18
|
+
def remove_dative_bonds_in_mol(molecule: IndigoObject) -> bool:
|
|
19
|
+
"""
|
|
20
|
+
Remove all dative bonds in a molecule or a query molecule.
|
|
21
|
+
:param molecule: The molecule to remove.
|
|
22
|
+
:return: Whether there are any dative bonds in the molecule that were removed.
|
|
23
|
+
"""
|
|
24
|
+
dative_bond_removed = False # Flag to track if any dative bond was removed
|
|
25
|
+
|
|
26
|
+
bonds_idx_to_remove = []
|
|
27
|
+
for bond in molecule.iterateBonds():
|
|
28
|
+
# Check if the bond is of a dative type (_BOND_COORDINATION = 9)
|
|
29
|
+
if bond.bondOrder() == 9: # _BOND_COORDINATION
|
|
30
|
+
atom1 = bond.source()
|
|
31
|
+
atom2 = bond.destination()
|
|
32
|
+
|
|
33
|
+
# Print bond details for debugging
|
|
34
|
+
print(f"Processing dative bond between atoms {atom1.index()} and {atom2.index()}")
|
|
35
|
+
|
|
36
|
+
# Cache bond information
|
|
37
|
+
# bond.setBondOrder(1)
|
|
38
|
+
bonds_idx_to_remove.append(bond.index())
|
|
39
|
+
dative_bond_removed = True # Set flag to True
|
|
40
|
+
|
|
41
|
+
if not dative_bond_removed:
|
|
42
|
+
return False
|
|
43
|
+
|
|
44
|
+
molecule.removeBonds(bonds_idx_to_remove)
|
|
45
|
+
return True # Return whether any dative bond was removed
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def remove_dative_in_reaction(reaction: IndigoObject) -> bool:
|
|
49
|
+
"""
|
|
50
|
+
Remove all dative bonds in a reaction or a query reaction, from all reactants and products.
|
|
51
|
+
:param reaction: The reaction to remove dative bonds.
|
|
52
|
+
:return: Whether there are any dative bonds in the reaction that were removed.
|
|
53
|
+
"""
|
|
54
|
+
reactant_dative_removed: bool = any(remove_dative_bonds_in_mol(reactant) for reactant in reaction.iterateReactants())
|
|
55
|
+
product_dative_removed: bool = any(remove_dative_bonds_in_mol(product) for product in reaction.iterateProducts())
|
|
56
|
+
return reactant_dative_removed or product_dative_removed
|
|
14
57
|
|
|
15
58
|
|
|
16
59
|
def highlight_mol_substructure(query: IndigoObject, sub_match: IndigoObject):
|
{sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/chem/Molecules.py
RENAMED
|
@@ -9,7 +9,8 @@ from rdkit.Chem import rdMolDescriptors
|
|
|
9
9
|
from rdkit.Chem.EnumerateStereoisomers import StereoEnumerationOptions, EnumerateStereoisomers
|
|
10
10
|
from rdkit.Chem.MolStandardize import rdMolStandardize
|
|
11
11
|
from rdkit.Chem.SaltRemover import SaltRemover
|
|
12
|
-
from rdkit.Chem.
|
|
12
|
+
from rdkit.Chem.rdChemReactions import ChemicalReaction
|
|
13
|
+
from rdkit.Chem.rdchem import Mol, RWMol, Bond
|
|
13
14
|
|
|
14
15
|
from sapiopycommons.chem.IndigoMolecules import indigo, renderer, indigo_inchi
|
|
15
16
|
|
|
@@ -22,6 +23,24 @@ tautomer_params.tautomerRemoveIsotopicHs = True
|
|
|
22
23
|
enumerator = rdMolStandardize.TautomerEnumerator(tautomer_params)
|
|
23
24
|
|
|
24
25
|
|
|
26
|
+
def remove_dative_bonds_from_mol(mol: Mol) -> RWMol:
|
|
27
|
+
"""
|
|
28
|
+
Create a new copy of RWMol molecule and remove all dative bonds in the molecule.
|
|
29
|
+
:param mol: The original molecule
|
|
30
|
+
:return: The new molecule with dative bonds removed.
|
|
31
|
+
"""
|
|
32
|
+
ret: RWMol = Chem.RWMol(mol)
|
|
33
|
+
bonds_to_remove = []
|
|
34
|
+
bond: Bond
|
|
35
|
+
for bond in ret.GetBonds():
|
|
36
|
+
if bond.GetBondType() in [Chem.BondType.DATIVER, Chem.BondType.DATIVE, Chem.BondType.DATIVEL,
|
|
37
|
+
Chem.BondType.DATIVEONE]:
|
|
38
|
+
bonds_to_remove.append((bond.GetBeginAtomIdx(), bond.GetEndAtomIdx()))
|
|
39
|
+
for atom1_idx, atom2_idx in bonds_to_remove:
|
|
40
|
+
ret.RemoveBond(atom1_idx, atom2_idx)
|
|
41
|
+
return ret
|
|
42
|
+
|
|
43
|
+
|
|
25
44
|
def get_enhanced_stereo_reg_hash(mol: Mol, enhanced_stereo: bool) -> str:
|
|
26
45
|
"""
|
|
27
46
|
Get the Registration Hash for the molecule by the current registration configuration.
|
|
@@ -217,7 +236,9 @@ def mol_to_sapio_substance(mol: Mol, include_stereoisomers=False,
|
|
|
217
236
|
# This is number of H-Bond Donor
|
|
218
237
|
molecule["numHBonds"] = rdMolDescriptors.CalcNumHBD(mol)
|
|
219
238
|
molecule["molBlock"] = molBlock
|
|
220
|
-
|
|
239
|
+
# Create a copy of molecule before modifying it for InChI generation.
|
|
240
|
+
inchi_mol: Mol = remove_dative_bonds_from_mol(mol)
|
|
241
|
+
rdkit_inchi = MolToInchi(inchi_mol)
|
|
221
242
|
# If INCHI is completely invalid, we fail this molecule.
|
|
222
243
|
if not rdkit_inchi:
|
|
223
244
|
MolToInchi(mol, treatWarningAsError=True)
|
|
@@ -231,13 +252,13 @@ def mol_to_sapio_substance(mol: Mol, include_stereoisomers=False,
|
|
|
231
252
|
indigo_mol.aromatize()
|
|
232
253
|
if enhanced_stereo:
|
|
233
254
|
# Remove enhanced stereo layer when generating InChI as the stereo hash is generated separately for reg.
|
|
234
|
-
|
|
235
|
-
Chem.
|
|
236
|
-
molecule["
|
|
237
|
-
molecule["inchiKey"] = Chem.MolToInchiKey(mol_copy)
|
|
255
|
+
Chem.CanonicalizeEnhancedStereo(inchi_mol)
|
|
256
|
+
molecule["inchi"] = Chem.MolToInchi(inchi_mol)
|
|
257
|
+
molecule["inchiKey"] = Chem.MolToInchiKey(inchi_mol)
|
|
238
258
|
else:
|
|
239
259
|
indigo_inchi.resetOptions()
|
|
240
|
-
|
|
260
|
+
indigo_inchi_mol = indigo.loadMolecule(Chem.MolToMolBlock(inchi_mol, forceV3000=True))
|
|
261
|
+
indigo_inchi_str = indigo_inchi.getInchi(indigo_inchi_mol)
|
|
241
262
|
molecule["inchi"] = indigo_inchi_str
|
|
242
263
|
indigo_inchi_key_str = indigo_inchi.getInchiKey(indigo_inchi_str)
|
|
243
264
|
molecule["inchiKey"] = indigo_inchi_key_str
|
|
@@ -245,7 +266,6 @@ def mol_to_sapio_substance(mol: Mol, include_stereoisomers=False,
|
|
|
245
266
|
molecule["reg_hash"] = get_enhanced_stereo_reg_hash(mol, enhanced_stereo=enhanced_stereo)
|
|
246
267
|
molecule["cxsmiles_hash"] = get_cxs_smiles_hash(mol, enhanced_stereo=enhanced_stereo)
|
|
247
268
|
molecule["has_or_group"] = get_has_or_group(mol, enhanced_stereo=enhanced_stereo)
|
|
248
|
-
|
|
249
269
|
return molecule
|
|
250
270
|
|
|
251
271
|
|
|
@@ -824,7 +824,7 @@ class ExperimentHandler:
|
|
|
824
824
|
The record to remove from the given step.
|
|
825
825
|
The record may be provided as either a DataRecord, PyRecordModel, or WrappedRecordModel.
|
|
826
826
|
"""
|
|
827
|
-
self.
|
|
827
|
+
self.remove_eln_rows(step, [record])
|
|
828
828
|
|
|
829
829
|
def add_sample_details(self, step: Step, samples: list[RecordModel], wrapper_type: type[WrappedType]) \
|
|
830
830
|
-> list[PyRecordModel | WrappedType]:
|
|
@@ -2,9 +2,12 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import time
|
|
4
4
|
from datetime import datetime
|
|
5
|
+
from typing import Any
|
|
5
6
|
|
|
6
7
|
import pytz
|
|
7
8
|
|
|
9
|
+
from sapiopycommons.general.exceptions import SapioException
|
|
10
|
+
|
|
8
11
|
__timezone = None
|
|
9
12
|
"""The default timezone. Use TimeUtil.set_default_timezone in a global context before making use of TimeUtil."""
|
|
10
13
|
|
|
@@ -26,7 +29,7 @@ class TimeUtil:
|
|
|
26
29
|
with static date fields, use "UTC" as your input timezone.
|
|
27
30
|
"""
|
|
28
31
|
@staticmethod
|
|
29
|
-
def get_default_timezone():
|
|
32
|
+
def get_default_timezone() -> Any:
|
|
30
33
|
"""
|
|
31
34
|
Returns the timezone that TimeUtil is currently using as its default.
|
|
32
35
|
"""
|
|
@@ -45,7 +48,7 @@ class TimeUtil:
|
|
|
45
48
|
__timezone = TimeUtil.__to_tz(new_timezone)
|
|
46
49
|
|
|
47
50
|
@staticmethod
|
|
48
|
-
def __to_tz(timezone: str | int = None):
|
|
51
|
+
def __to_tz(timezone: str | int = None) -> Any:
|
|
49
52
|
"""
|
|
50
53
|
:param timezone: Either the name of a timezone, a UTC offset in seconds, or None if the default should be used.
|
|
51
54
|
:return: The timezone object to use for the given input. If the input is None, uses the default timezone.
|
|
@@ -55,11 +58,28 @@ class TimeUtil:
|
|
|
55
58
|
# because pytz may return timezones from strings in Local Mean Time instead of a timezone with a UTC offset.
|
|
56
59
|
# LMT may be a few minutes off of the actual time in that timezone right now.
|
|
57
60
|
# https://stackoverflow.com/questions/35462876
|
|
58
|
-
offset: int =
|
|
59
|
-
|
|
61
|
+
offset: int = TimeUtil.__get_timezone_offset(timezone)
|
|
62
|
+
# This function takes an offset in minutes, so divide the provided offset seconds by 60.
|
|
63
|
+
return pytz.FixedOffset(offset // 60)
|
|
60
64
|
if isinstance(timezone, int):
|
|
61
65
|
return pytz.FixedOffset(timezone // 60)
|
|
62
|
-
|
|
66
|
+
if timezone is None:
|
|
67
|
+
return TimeUtil.get_default_timezone()
|
|
68
|
+
raise SapioException(f"Unhandled timezone object of type {type(timezone)}: {timezone}")
|
|
69
|
+
|
|
70
|
+
@staticmethod
|
|
71
|
+
def __get_timezone_offset(timezone: str | int | None) -> int:
|
|
72
|
+
"""
|
|
73
|
+
:param timezone: Either the name of a timezone, a UTC offset in seconds, or None if the default should be used.
|
|
74
|
+
:return: The UTC offset in seconds of the provided timezone.
|
|
75
|
+
"""
|
|
76
|
+
if isinstance(timezone, int):
|
|
77
|
+
return timezone
|
|
78
|
+
if isinstance(timezone, str):
|
|
79
|
+
timezone = pytz.timezone(timezone)
|
|
80
|
+
if timezone is None:
|
|
81
|
+
timezone = TimeUtil.get_default_timezone()
|
|
82
|
+
return int(datetime.now(timezone).utcoffset().total_seconds())
|
|
63
83
|
|
|
64
84
|
@staticmethod
|
|
65
85
|
def current_time(timezone: str | int = None) -> datetime:
|
|
@@ -127,6 +147,64 @@ class TimeUtil:
|
|
|
127
147
|
tz = TimeUtil.__to_tz(timezone)
|
|
128
148
|
return int(datetime.strptime(time_point, time_format).replace(tzinfo=tz).timestamp() * 1000)
|
|
129
149
|
|
|
150
|
+
# FR-47296: Provide functions for shifting between timezones.
|
|
151
|
+
@staticmethod
|
|
152
|
+
def shift_now(to_timezone: str = "UTC", from_timezone: str | None = None) -> int:
|
|
153
|
+
"""
|
|
154
|
+
Take the current time in from_timezone and output the epoch timestamp that would display that same time in
|
|
155
|
+
to_timezone. A use case for this is when dealing with static date fields to convert a provided timestamp to the
|
|
156
|
+
value necessary to display that timestamp in the same way when viewed in the static date field.
|
|
157
|
+
|
|
158
|
+
:param to_timezone: The timezone to shift to. If not provided, uses UTC.
|
|
159
|
+
:param from_timezone: The timezone to shift from. If no timezone is provided, uses the global
|
|
160
|
+
timezone variable set by the TimeUtil. A list of valid timezones can be found at
|
|
161
|
+
https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. May also accept a UTC offset in seconds.
|
|
162
|
+
:return: The epoch timestamp that would display as the same time in to_timezone as the current time in
|
|
163
|
+
from_timezone.
|
|
164
|
+
"""
|
|
165
|
+
millis: int = TimeUtil.now_in_millis()
|
|
166
|
+
return TimeUtil.shift_millis(millis, to_timezone, from_timezone)
|
|
167
|
+
|
|
168
|
+
@staticmethod
|
|
169
|
+
def shift_millis(millis: int, to_timezone: str = "UTC", from_timezone: str | None = None) -> int:
|
|
170
|
+
"""
|
|
171
|
+
Take a number of milliseconds for a time in from_timezone and output the epoch timestamp that would display that
|
|
172
|
+
same time in to_timezone. A use case for this is when dealing with static date fields to convert a provided
|
|
173
|
+
timestamp to the value necessary to display that timestamp in the same way when viewed in the static date field.
|
|
174
|
+
|
|
175
|
+
:param millis: The time in milliseconds to convert from.
|
|
176
|
+
:param to_timezone: The timezone to shift to. If not provided, uses UTC.
|
|
177
|
+
:param from_timezone: The timezone to shift from. If no timezone is provided, uses the global
|
|
178
|
+
timezone variable set by the TimeUtil. A list of valid timezones can be found at
|
|
179
|
+
https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. May also accept a UTC offset in seconds.
|
|
180
|
+
:return: The epoch timestamp that would display as the same time in to_timezone as the given time in
|
|
181
|
+
from_timezone.
|
|
182
|
+
"""
|
|
183
|
+
to_offset: int = TimeUtil.__get_timezone_offset(to_timezone) * 1000
|
|
184
|
+
from_offset: int = TimeUtil.__get_timezone_offset(from_timezone) * 1000
|
|
185
|
+
return millis + from_offset - to_offset
|
|
186
|
+
|
|
187
|
+
@staticmethod
|
|
188
|
+
def shift_format(time_point: str, time_format: str, to_timezone: str = "UTC", from_timezone: str | None = None) \
|
|
189
|
+
-> int:
|
|
190
|
+
"""
|
|
191
|
+
Take a timestamp for a time in from_timezone and output the epoch timestamp that would display that same time
|
|
192
|
+
in to_timezone. A use case for this is when dealing with static date fields to convert a provided timestamp to
|
|
193
|
+
the value necessary to display that timestamp in the same way when viewed in the static date field.
|
|
194
|
+
|
|
195
|
+
:param time_point: The time in some date/time format to convert from.
|
|
196
|
+
:param time_format: The format that the time_point is in. Documentation for how the time formatting works
|
|
197
|
+
can be found at https://docs.python.org/3.10/library/datetime.html#strftime-and-strptime-behavior
|
|
198
|
+
:param to_timezone: The timezone to shift to. If not provided, uses UTC.
|
|
199
|
+
:param from_timezone: The timezone to shift from. If no timezone is provided, uses the global
|
|
200
|
+
timezone variable set by the TimeUtil. A list of valid timezones can be found at
|
|
201
|
+
https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. May also accept a UTC offset in seconds.
|
|
202
|
+
:return: The epoch timestamp that would display as the same time in to_timezone as the given time in
|
|
203
|
+
from_timezone.
|
|
204
|
+
"""
|
|
205
|
+
millis: int = TimeUtil.format_to_millis(time_point, time_format, from_timezone)
|
|
206
|
+
return TimeUtil.shift_millis(millis, to_timezone, from_timezone)
|
|
207
|
+
|
|
130
208
|
# FR-46154: Create a function that determines if a string matches a time format.
|
|
131
209
|
@staticmethod
|
|
132
210
|
def str_matches_format(time_point: str, time_format: str) -> bool:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/chem/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/eln/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/files/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/files/file_util.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/general/aliases.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/src/sapiopycommons/rules/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/tests/AF-A0A009IHW8-F1-model_v4.cif
RENAMED
|
File without changes
|
{sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/tests/_do_not_add_init_py_here
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/tests/chem_test_curation_queue.py
RENAMED
|
File without changes
|
{sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/tests/curation_queue_test.sdf
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/tests/flowcyto/8_color_ICS.wsp
RENAMED
|
File without changes
|
{sapiopycommons-2024.11.25a373 → sapiopycommons-2024.12.5a376}/tests/flowcyto/COVID19_W_001_O.fcs
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|