Skip to content

Commit fe4c9b6

Browse files
authored
Merge pull request #135 from VariantEffect/nick/check-hgvs-assembly-name
Tests & Fixups for /api/v1/hgvs endpoints
2 parents 5a3c1b6 + 3e28902 commit fe4c9b6

File tree

2 files changed

+156
-4
lines changed

2 files changed

+156
-4
lines changed

src/mavedb/routers/hgvs.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from cdot.hgvs.dataproviders import RESTDataProvider
88
from fastapi import APIRouter, Depends, HTTPException
99
from hgvs import parser, validator
10+
from hgvs.exceptions import HGVSDataNotAvailableError
1011

1112
from mavedb.deps import hgvs_data_provider
1213

@@ -22,7 +23,10 @@ def hgvs_fetch(accession: str, hdp: RESTDataProvider = Depends(hgvs_data_provide
2223
"""
2324
List stored sequences
2425
"""
25-
return hdp.seqfetcher.fetch_seq(accession)
26+
try:
27+
return hdp.seqfetcher.fetch_seq(accession)
28+
except HGVSDataNotAvailableError as e:
29+
raise HTTPException(404, str(e))
2630

2731

2832
@router.post("/validate", status_code=200, response_model=Any)
@@ -75,6 +79,9 @@ def list_accessions(assembly: str, hdp: RESTDataProvider = Depends(hgvs_data_pro
7579
"""
7680
List stored accessions
7781
"""
82+
if assembly not in hdp.assembly_maps:
83+
raise HTTPException(404, f"Assembly '{assembly}' Not Found")
84+
7885
return list(hdp.get_assembly_map(assembly_name=assembly).keys())
7986

8087

@@ -88,7 +95,7 @@ def list_genes():
8895
return list(chain.from_iterable(hgvs.dataproviders.uta.connect()._fetchall("select hgnc from gene")))
8996

9097

91-
@router.get("/genes/{gene}", status_code=200, response_model=list)
98+
@router.get("/genes/{gene}", status_code=200)
9299
def gene_info(gene: str, hdp: RESTDataProvider = Depends(hgvs_data_provider)):
93100
"""
94101
List stored gene information for a specified gene
@@ -104,15 +111,15 @@ def list_transcripts_for_gene(gene: str, hdp: RESTDataProvider = Depends(hgvs_da
104111
return set([tx_info["tx_ac"] for tx_info in hdp.get_tx_for_gene(gene)])
105112

106113

107-
@router.get("/transcripts/{transcript}", status_code=200, response_model=list)
114+
@router.get("/transcripts/{transcript}", status_code=200)
108115
def transcript_info(transcript: str, hdp: RESTDataProvider = Depends(hgvs_data_provider)):
109116
"""
110117
List transcript information for a particular transcript
111118
"""
112119
return hdp.get_tx_identity_info(transcript)
113120

114121

115-
@router.get("/transcripts/protein/{transcript}", status_code=200, response_model=str)
122+
@router.get("/transcripts/protein/{transcript}", status_code=200)
116123
def convert_to_protein(transcript: str, hdp: RESTDataProvider = Depends(hgvs_data_provider)):
117124
"""
118125
Convert a provided transcript from it's nucleotide accession identifier to its protein accession identifier

tests/routers/test_hgvs.py

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
VALID_MAJOR_ASSEMBLY = "GRCh38"
2+
VALID_MINOR_ASSEMBLY = "GRCh38.p3"
3+
INVALID_ASSEMBLY = "undefined"
4+
VALID_ACCESSION = "NC_000001.11"
5+
INVALID_ACCESSION = "NC_999999.99"
6+
SMALL_ACCESSION = "NM_002977.4"
7+
VALID_GENE = "BRCA1"
8+
INVALID_GENE = "fnord"
9+
VALID_TRANSCRIPT = 'NM_001408458.1'
10+
INVALID_TRANSCRIPT = 'NX_99999.1'
11+
VALID_VARIANT = VALID_ACCESSION + ":g.1_2insA"
12+
INVALID_VARIANT = VALID_ACCESSION + ":g.1delA"
13+
HAS_PROTEIN_ACCESSION = "NM_000014.4"
14+
PROTEIN_ACCESSION = "NP_000005.2"
15+
16+
17+
def test_hgvs_fetch_valid(client, setup_router_db):
18+
# VALID_ACCESSION is rather large so use a smaller one
19+
response = client.get(f"/api/v1/hgvs/fetch/{SMALL_ACCESSION}")
20+
assert response.status_code == 200
21+
22+
23+
def test_hgvs_fetch_invalid(client, setup_router_db):
24+
response = client.get(f"/api/v1/hgvs/fetch/{INVALID_ACCESSION}")
25+
assert response.status_code == 404
26+
27+
28+
def test_hgvs_validate_valid(client, setup_router_db):
29+
payload = {'variant': VALID_VARIANT}
30+
response = client.post("/api/v1/hgvs/validate", json=payload)
31+
assert response.status_code == 200
32+
33+
34+
def test_hgvs_validate_invalid(client, setup_router_db):
35+
payload = {'variant': INVALID_VARIANT}
36+
response = client.post("/api/v1/hgvs/validate", json=payload)
37+
assert response.status_code == 400
38+
assert 'does not agree' in response.json()['detail']
39+
40+
41+
def test_hgvs_list_assemblies(client, setup_router_db):
42+
response = client.get("/api/v1/hgvs/assemblies")
43+
assert response.status_code == 200
44+
assert VALID_MAJOR_ASSEMBLY in response.json()
45+
assert VALID_MINOR_ASSEMBLY in response.json()
46+
47+
48+
def test_hgvs_grouped_assemblies(client, setup_router_db):
49+
response = client.get("/api/v1/hgvs/grouped-assemblies")
50+
assert response.status_code == 200
51+
52+
groups = {group['type'] : group['assemblies'] for group in response.json()}
53+
assert 'Major Assembly Versions' in groups
54+
assert 'Minor Assembly Versions' in groups
55+
assert VALID_MAJOR_ASSEMBLY in groups['Major Assembly Versions']
56+
assert VALID_MINOR_ASSEMBLY in groups['Minor Assembly Versions']
57+
58+
59+
def test_hgvs_accessions_major(client, setup_router_db):
60+
response = client.get(f"/api/v1/hgvs/{VALID_MAJOR_ASSEMBLY}/accessions")
61+
assert response.status_code == 200
62+
assert VALID_ACCESSION in response.json()
63+
64+
65+
def test_hgvs_accessions_minor(client, setup_router_db):
66+
response = client.get(f"/api/v1/hgvs/{VALID_MINOR_ASSEMBLY}/accessions")
67+
assert response.status_code == 404
68+
69+
70+
def test_hgvs_accessions_invalid(client, setup_router_db):
71+
response = client.get(f"/api/v1/hgvs/{INVALID_ASSEMBLY}/accessions")
72+
assert response.status_code == 404
73+
74+
75+
def test_hgvs_genes(client, setup_router_db):
76+
response = client.get("/api/v1/hgvs/genes")
77+
assert response.status_code == 200
78+
assert VALID_GENE in response.json()
79+
80+
81+
def test_hgvs_gene_info_valid(client, setup_router_db):
82+
response = client.get(f"/api/v1/hgvs/genes/{VALID_GENE}")
83+
assert response.status_code == 200
84+
assert response.json()['hgnc'] == VALID_GENE
85+
assert response.json()['descr'] is not None
86+
87+
88+
def test_hgvs_gene_info_invalid(client, setup_router_db):
89+
response = client.get(f"/api/v1/hgvs/genes/{INVALID_GENE}")
90+
# XXX this probably SHOULD return a 404, but currently returns a 200 with None
91+
# assert response.status_code == 404
92+
assert response.status_code == 200
93+
assert response.json() is None
94+
95+
96+
def test_hgvs_gene_transcript_valid(client, setup_router_db):
97+
response = client.get(f"/api/v1/hgvs/transcripts/gene/{VALID_GENE}")
98+
assert response.status_code == 200
99+
assert VALID_TRANSCRIPT in response.json()
100+
101+
102+
def test_hgvs_gene_transcript_invalid(client, setup_router_db):
103+
response = client.get(f"/api/v1/hgvs/transcripts/gene/{INVALID_GENE}")
104+
# XXX this probably SHOULD return a 404, but currently returns a 200 with empty list
105+
# assert response.status_code == 404
106+
assert response.status_code == 200
107+
assert response.json() == []
108+
109+
110+
def test_hgvs_transcript_valid(client, setup_router_db):
111+
response = client.get(f"/api/v1/hgvs/transcripts/{VALID_TRANSCRIPT}")
112+
assert response.status_code == 200
113+
assert response.json()['hgnc'] == VALID_GENE
114+
115+
116+
def test_hgvs_transcript_invalid(client, setup_router_db):
117+
response = client.get(f"/api/v1/hgvs/transcripts/{INVALID_TRANSCRIPT}")
118+
# XXX this probably SHOULD return a 404, but currently returns a 200 with None
119+
# assert response.status_code == 404
120+
assert response.status_code == 200
121+
assert response.json() is None
122+
123+
124+
def test_hgvs_transcript_protein_valid(client, setup_router_db):
125+
response = client.get(f"/api/v1/hgvs/transcripts/protein/{HAS_PROTEIN_ACCESSION}")
126+
assert response.status_code == 200
127+
assert response.json() == PROTEIN_ACCESSION
128+
129+
130+
def test_hgvs_transcript_protein_no_protein(client, setup_router_db):
131+
response = client.get(f"/api/v1/hgvs/transcripts/protein/{SMALL_ACCESSION}")
132+
# XXX this probably SHOULD return a 404, but currently returns a 200 with None
133+
# assert response.status_code == 404
134+
assert response.status_code == 200
135+
assert response.json() is None
136+
137+
138+
def test_hgvs_transcript_protein_invalid(client, setup_router_db):
139+
response = client.get(f"/api/v1/hgvs/transcripts/protein/{INVALID_ACCESSION}")
140+
# XXX this probably SHOULD return a 400, but currently returns a 200 with None
141+
# assert response.status_code == 404
142+
assert response.status_code == 200
143+
assert response.json() is None
144+
145+

0 commit comments

Comments
 (0)