Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions src/mavedb/lib/uniprot/utils.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from typing import Literal, Union

from mavedb.lib.validation.identifier import validate_refseq_identifier
from mavedb.lib.validation.identifier import validate_ensembl_identifier, validate_refseq_identifier


def infer_db_name_from_sequence_accession(
sequence_accession: str,
) -> Union[Literal["RefSeq_Nucleotide", "RefSeq_Protein"]]:
) -> Union[Literal["RefSeq_Nucleotide", "RefSeq_Protein", "Ensembl_Protein"]]:
"""
Infers the database name from a sequence accession.

Expand All @@ -15,11 +15,19 @@ def infer_db_name_from_sequence_accession(
Returns:
str: The inferred database name.
"""
# Ensembl protein accessions must be handled before validate_refseq_identifier,
# which raises on any non-RefSeq accession.
if sequence_accession.startswith("ENSP"):
validate_ensembl_identifier(sequence_accession)
return "Ensembl_Protein"

validate_refseq_identifier(sequence_accession)

if sequence_accession.startswith("NM_"):
return "RefSeq_Nucleotide"
if sequence_accession.startswith("NP_"):
return "RefSeq_Protein"

raise NotImplementedError("Only RefSeq NM and NP identifiers are currently supported for inference.")
raise NotImplementedError(
"Only RefSeq NM/NP and Ensembl protein (ENSP) identifiers are currently supported for inference."
)
8 changes: 7 additions & 1 deletion src/mavedb/lib/validation/identifier.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import re

import idutils

from mavedb.lib.validation.constants.identifier import valid_dbnames
Expand Down Expand Up @@ -52,6 +54,9 @@ def validate_ensembl_identifier(identifier: str):
"""
Validates whether the identifier is a valid Ensembl identifier.

Ensembl stable IDs may carry a version suffix (e.g. ``ENSP00000369497.3``), which
``idutils.is_ensembl`` does not accept; strip it before validating the stable ID.

Parameters
__________
identifier : str
Expand All @@ -62,7 +67,8 @@ def validate_ensembl_identifier(identifier: str):
ValidationError
If the identifier is not a valid Ensembl identifier.
"""
if not idutils.is_ensembl(identifier):
base_identifier = re.sub(r"\.\d+$", "", identifier)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove this line after updating idutils if/when this change gets incorporated:
inveniosoftware/idutils#149

if not idutils.is_ensembl(base_identifier):
raise ValidationError(f"'{identifier}' is not a valid Ensembl accession.")


Expand Down
8 changes: 8 additions & 0 deletions tests/lib/uniprot/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ def test_infer_db_name_from_sequence_accession_np():
assert result == "RefSeq_Protein"


# Both versioned and unversioned ENSP accessions must route to Ensembl_Protein; the versioned case
# guards that validate_ensembl_identifier's version handling continues to accept it.
@pytest.mark.parametrize("ensembl_protein_accession", ["ENSP00000418960", "ENSP00000418960.3"])
def test_infer_db_name_from_sequence_accession_ensp(ensembl_protein_accession):
result = infer_db_name_from_sequence_accession(ensembl_protein_accession)
assert result == "Ensembl_Protein"


@pytest.mark.parametrize("invalid_accession", ["XP_000000", VALID_CHR_ACCESSION])
def test_infer_db_name_from_sequence_accession_invalid(invalid_accession):
with pytest.raises(NotImplementedError):
Expand Down
4 changes: 4 additions & 0 deletions tests/validation/test_identifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ def test_ve_invalid_list(self):
def test_passes_valid_id(self):
validate_ensembl_identifier("ENSG00000143384")

def test_passes_valid_versioned_id(self):
validate_ensembl_identifier("ENSP00000369497.3")
validate_ensembl_list(["ENSG00000139618.15", "ENST00000380152.8"])


class TestRefSeqValidators(TestCase):
"""
Expand Down
Loading