From 1420010d6ada531612f6aa89348370de1685b481 Mon Sep 17 00:00:00 2001 From: Albert Anguera Sempere Date: Mon, 10 Feb 2025 09:35:13 +0100 Subject: [PATCH 1/7] Added new reference functionality on CompoundStructure and Reaction --- enviPath_python/objects.py | 51 +++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/enviPath_python/objects.py b/enviPath_python/objects.py index 5c9f14e..bbf5233 100644 --- a/enviPath_python/objects.py +++ b/enviPath_python/objects.py @@ -20,8 +20,7 @@ from collections import namedtuple, defaultdict from io import BytesIO from typing import List, Optional, Union -from enviPath_python.enums import Endpoint, ClassifierType, FingerprinterType, AssociationType, EvaluationType, \ - Permission +from enviPath_python.enums import * class enviPathObject(ABC): @@ -1097,6 +1096,28 @@ def add_alias(self, alias): if hasattr(self, 'alias'): delattr(self, 'alias') + + def add_new_reference(self, referenceURL): + """ + Adds a new external database identifier to the Compound + + :param referenceURL: the new reference to an external database + :return: + """ + newReferenceSource = None + for valid_URL in SupportedCompoundExternalReferenceURLs: + if valid_URL.value in referenceURL: + newReferenceSource = valid_URL.name + break + if not newReferenceSource: + raise ValueError(f"The referenceURL ({referenceURL}) does not contain supported external reference URL!" + f" {[URL.value for URL in SupportedCompoundExternalReferenceURLs]}") + payload = { + 'newReferenceValue': "python-API;" + referenceURL, + 'newReferenceSource': newReferenceSource + } + self.requester.post_request(self.id, payload=payload, allow_redirects=False) + def get_charge(self) -> float: """ Retrieves the charge of the CompoundStructure @@ -1347,13 +1368,35 @@ def get_rule(self) -> Optional['Rule']: except ValueError: return None - def get_rhea_references(self) -> List[str]: + def get_external_references(self) -> List[str]: """ Retrieves the links to Rhea for the given reaction :return: A list of links to rhea with similar reactions """ - return self._get('rheaReferences') + return self._get('externalReferences') + + + def add_new_reference(self, referenceURL): + """ + Adds a new external database identifier to the Reaction + + :param referenceURL: the new reference to an external database + :return: + """ + newReferenceSource = None + for valid_URL in SupportedReactionExternalReferenceURLs: + if valid_URL.value in referenceURL: + newReferenceSource = valid_URL.name + break + if not newReferenceSource: + raise ValueError(f"The referenceURL ({referenceURL}) does not contain supported external reference URL!" + f" {[URL.value for URL in SupportedReactionExternalReferenceURLs]}") + payload = { + 'newReferenceValue': "python-API;" + referenceURL, + 'newReferenceSource': newReferenceSource + } + self.requester.post_request(self.id, payload=payload, allow_redirects=False) @staticmethod def create(package: Package, smirks: str = None, educt: CompoundStructure = None, product: CompoundStructure = None, From 1a474928d05a9abc7cbe4cf44df875e0d89fa188 Mon Sep 17 00:00:00 2001 From: Albert Anguera Sempere Date: Mon, 10 Feb 2025 09:35:35 +0100 Subject: [PATCH 2/7] Added support database URLs as enums --- enviPath_python/enums.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/enviPath_python/enums.py b/enviPath_python/enums.py index 4935074..5b0b0e2 100644 --- a/enviPath_python/enums.py +++ b/enviPath_python/enums.py @@ -78,3 +78,18 @@ class Permission(Enum): READ = 'read' WRITE = 'write' NONE = 'none' + +class SupportedCompoundExternalReferenceURLs(Enum): + """ + Class that stores the supported compound external reference URLs + """ + PUBCHEM = "https://pubchem.ncbi.nlm.nih.gov" + CHEBI = "https://www.ebi.ac.uk/chebi" + KEGG = "https://www.kegg.jp/entry" + +class SupportedReactionExternalReferenceURLs(Enum): + """ + Class that stores the supported reaction external reference URLs + """ + RHEA = "http://rdf.rhea-db.org" + UNIPROT = "https://www.uniprot.org/uniprotkb" \ No newline at end of file From 98533deb0d815d58128a989fc8fcbb18f5a4dfa7 Mon Sep 17 00:00:00 2001 From: Albert Anguera Sempere Date: Mon, 10 Feb 2025 12:50:48 +0100 Subject: [PATCH 3/7] Simplified base URLs for external references --- enviPath_python/enums.py | 18 +++++++++--------- enviPath_python/objects.py | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/enviPath_python/enums.py b/enviPath_python/enums.py index 5b0b0e2..d8456c4 100644 --- a/enviPath_python/enums.py +++ b/enviPath_python/enums.py @@ -79,17 +79,17 @@ class Permission(Enum): WRITE = 'write' NONE = 'none' -class SupportedCompoundExternalReferenceURLs(Enum): +class SupportedCompoundExternalReference(Enum): """ - Class that stores the supported compound external reference URLs + Class that stores the supported compound external reference base URLs """ - PUBCHEM = "https://pubchem.ncbi.nlm.nih.gov" - CHEBI = "https://www.ebi.ac.uk/chebi" - KEGG = "https://www.kegg.jp/entry" + PUBCHEM = "pubchem.ncbi.nlm.nih.gov" + CHEBI = "ebi.ac.uk/chebi" + KEGG = "kegg.jp/entry" -class SupportedReactionExternalReferenceURLs(Enum): +class SupportedReactionExternalReference(Enum): """ - Class that stores the supported reaction external reference URLs + Class that stores the supported reaction external reference base URLs """ - RHEA = "http://rdf.rhea-db.org" - UNIPROT = "https://www.uniprot.org/uniprotkb" \ No newline at end of file + RHEA = "rhea-db.org" + UNIPROT = "uniprot.org/uniprotkb" \ No newline at end of file diff --git a/enviPath_python/objects.py b/enviPath_python/objects.py index bbf5233..2d6b207 100644 --- a/enviPath_python/objects.py +++ b/enviPath_python/objects.py @@ -1105,13 +1105,13 @@ def add_new_reference(self, referenceURL): :return: """ newReferenceSource = None - for valid_URL in SupportedCompoundExternalReferenceURLs: + for valid_URL in SupportedCompoundExternalReference: if valid_URL.value in referenceURL: newReferenceSource = valid_URL.name break if not newReferenceSource: raise ValueError(f"The referenceURL ({referenceURL}) does not contain supported external reference URL!" - f" {[URL.value for URL in SupportedCompoundExternalReferenceURLs]}") + f" {[URL.value for URL in SupportedCompoundExternalReference]}") payload = { 'newReferenceValue': "python-API;" + referenceURL, 'newReferenceSource': newReferenceSource @@ -1385,13 +1385,13 @@ def add_new_reference(self, referenceURL): :return: """ newReferenceSource = None - for valid_URL in SupportedReactionExternalReferenceURLs: + for valid_URL in SupportedReactionExternalReference: if valid_URL.value in referenceURL: newReferenceSource = valid_URL.name break if not newReferenceSource: raise ValueError(f"The referenceURL ({referenceURL}) does not contain supported external reference URL!" - f" {[URL.value for URL in SupportedReactionExternalReferenceURLs]}") + f" {[URL.value for URL in SupportedReactionExternalReference]}") payload = { 'newReferenceValue': "python-API;" + referenceURL, 'newReferenceSource': newReferenceSource From b2d75b8ddc628d37492b2ab3ed656ca4a8522449 Mon Sep 17 00:00:00 2001 From: Albert Anguera Sempere Date: Tue, 11 Feb 2025 08:23:26 +0100 Subject: [PATCH 4/7] adjusted variable name to python syntax --- enviPath_python/objects.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/enviPath_python/objects.py b/enviPath_python/objects.py index 2d6b207..2cf554f 100644 --- a/enviPath_python/objects.py +++ b/enviPath_python/objects.py @@ -1384,17 +1384,17 @@ def add_new_reference(self, referenceURL): :param referenceURL: the new reference to an external database :return: """ - newReferenceSource = None + new_reference_source = None for valid_URL in SupportedReactionExternalReference: if valid_URL.value in referenceURL: - newReferenceSource = valid_URL.name + new_reference_source = valid_URL.name break - if not newReferenceSource: + if not new_reference_source: raise ValueError(f"The referenceURL ({referenceURL}) does not contain supported external reference URL!" f" {[URL.value for URL in SupportedReactionExternalReference]}") payload = { 'newReferenceValue': "python-API;" + referenceURL, - 'newReferenceSource': newReferenceSource + 'newReferenceSource': new_reference_source } self.requester.post_request(self.id, payload=payload, allow_redirects=False) From 0e03f1a2c6cc508bdb5b7aa41b9d51a5a424058c Mon Sep 17 00:00:00 2001 From: Albert Anguera Sempere Date: Tue, 11 Feb 2025 08:24:21 +0100 Subject: [PATCH 5/7] adjusted variable name to python syntax --- enviPath_python/objects.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/enviPath_python/objects.py b/enviPath_python/objects.py index 2cf554f..e67e874 100644 --- a/enviPath_python/objects.py +++ b/enviPath_python/objects.py @@ -1377,23 +1377,23 @@ def get_external_references(self) -> List[str]: return self._get('externalReferences') - def add_new_reference(self, referenceURL): + def add_new_reference(self, reference_url): """ Adds a new external database identifier to the Reaction - :param referenceURL: the new reference to an external database + :param reference_url: the new reference to an external database :return: """ new_reference_source = None for valid_URL in SupportedReactionExternalReference: - if valid_URL.value in referenceURL: + if valid_URL.value in reference_url: new_reference_source = valid_URL.name break if not new_reference_source: - raise ValueError(f"The referenceURL ({referenceURL}) does not contain supported external reference URL!" + raise ValueError(f"The referenceURL ({reference_url}) does not contain supported external reference URL!" f" {[URL.value for URL in SupportedReactionExternalReference]}") payload = { - 'newReferenceValue': "python-API;" + referenceURL, + 'newReferenceValue': "python-API;" + reference_url, 'newReferenceSource': new_reference_source } self.requester.post_request(self.id, payload=payload, allow_redirects=False) From b3615ee5c2c627bfe35ab253e5980a897410b346 Mon Sep 17 00:00:00 2001 From: Albert Anguera Sempere Date: Tue, 11 Feb 2025 08:25:05 +0100 Subject: [PATCH 6/7] adjusted variable name to python syntax --- enviPath_python/objects.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/enviPath_python/objects.py b/enviPath_python/objects.py index e67e874..c357afd 100644 --- a/enviPath_python/objects.py +++ b/enviPath_python/objects.py @@ -1097,24 +1097,24 @@ def add_alias(self, alias): delattr(self, 'alias') - def add_new_reference(self, referenceURL): + def add_new_reference(self, reference_url): """ Adds a new external database identifier to the Compound - :param referenceURL: the new reference to an external database + :param reference_url: the new reference to an external database :return: """ - newReferenceSource = None + new_reference_source = None for valid_URL in SupportedCompoundExternalReference: - if valid_URL.value in referenceURL: - newReferenceSource = valid_URL.name + if valid_URL.value in reference_url: + new_reference_source = valid_URL.name break - if not newReferenceSource: - raise ValueError(f"The referenceURL ({referenceURL}) does not contain supported external reference URL!" + if not new_reference_source: + raise ValueError(f"The referenceURL ({reference_url}) does not contain supported external reference URL!" f" {[URL.value for URL in SupportedCompoundExternalReference]}") payload = { - 'newReferenceValue': "python-API;" + referenceURL, - 'newReferenceSource': newReferenceSource + 'newReferenceValue': "python-API;" + reference_url, + 'newReferenceSource': new_reference_source } self.requester.post_request(self.id, payload=payload, allow_redirects=False) From 534550d4f8133e19b884f25b94db3d11897aca9d Mon Sep 17 00:00:00 2001 From: Albert Anguera Sempere Date: Thu, 20 Feb 2025 15:00:44 +0100 Subject: [PATCH 7/7] Allowed copy external references on compoundsstructure and reaction --- enviPath_python/objects.py | 41 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/enviPath_python/objects.py b/enviPath_python/objects.py index c357afd..fa331c5 100644 --- a/enviPath_python/objects.py +++ b/enviPath_python/objects.py @@ -19,7 +19,7 @@ from abc import ABC, abstractmethod from collections import namedtuple, defaultdict from io import BytesIO -from typing import List, Optional, Union +from typing import List, Dict, Optional, Union from enviPath_python.enums import * @@ -1071,6 +1071,11 @@ def copy(self, package: 'Package', debug=False) -> (dict, 'Compound', List['Comp for structure in self.get_structures(): copied_structure = CompoundStructure.create(copied_compound, structure.get_smiles(), structure.get_name(), structure.get_description()) + for pubchem_id in structure.get_pubchem_references(): + copied_structure.copy_new_reference(pubchem_id, "pubchem") + for dbs_id in structure.get_external_references().keys(): + for external_id in structure.get_external_references().get(dbs_id): + copied_structure.copy_new_reference(external_id, dbs_id) copied_structures.append(copied_structure) mapping[structure.get_id()] = copied_structure.get_id() @@ -1118,6 +1123,20 @@ def add_new_reference(self, reference_url): } self.requester.post_request(self.id, payload=payload, allow_redirects=False) + def copy_new_reference(self, reference_value, reference_source): + """ + Copies a new external database identifier to the Compound + + :param reference_value: a semicolon-separated string indicating ; + :param reference_source: the identifier for the external database + :return: + """ + payload = { + 'newReferenceValue': reference_value, + 'newReferenceSource': reference_source + } + self.requester.post_request(self.id, payload=payload, allow_redirects=False) + def get_charge(self) -> float: """ Retrieves the charge of the CompoundStructure @@ -1368,7 +1387,7 @@ def get_rule(self) -> Optional['Rule']: except ValueError: return None - def get_external_references(self) -> List[str]: + def get_external_references(self) -> Dict[str, List]: """ Retrieves the links to Rhea for the given reaction @@ -1398,6 +1417,20 @@ def add_new_reference(self, reference_url): } self.requester.post_request(self.id, payload=payload, allow_redirects=False) + def copy_new_reference(self, reference_value, reference_source): + """ + Copies a new external database identifier to the Compound + + :param reference_value: a semicolon-separated string indicating ; + :param reference_source: the identifier for the external database + :return: + """ + payload = { + 'newReferenceValue': reference_value, + 'newReferenceSource': reference_source + } + self.requester.post_request(self.id, payload=payload, allow_redirects=False) + @staticmethod def create(package: Package, smirks: str = None, educt: CompoundStructure = None, product: CompoundStructure = None, name: str = None, description: str = None, rule: 'Rule' = None) -> 'Reaction': @@ -1466,6 +1499,10 @@ def copy(self, package: 'Package', debug=False) -> (dict, 'Reaction'): r = Reaction.create(**params) + for dbs_id in self.get_external_references().keys(): + for external_id in self.get_external_references().get(dbs_id): + r.copy_new_reference(external_id, dbs_id) + mapping[self.get_id()] = r.get_id() return mapping, r