Skip to content

Commit 589c050

Browse files
committed
Add error handling to api map function
1 parent 20ea78b commit 589c050

File tree

1 file changed

+91
-38
lines changed

1 file changed

+91
-38
lines changed

src/api/routers/map.py

Lines changed: 91 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,26 @@
1+
""""Provide mapping router"""
12
from cool_seq_tool.schemas import AnnotationLayer
2-
from fastapi import APIRouter
3+
from fastapi import APIRouter, HTTPException
4+
from requests import HTTPError
35

4-
from dcd_mapping.align import align
6+
from dcd_mapping.align import AlignmentError, BlatNotFoundError, align
57
from dcd_mapping.annotate import (
68
_get_computed_reference_sequence,
79
_get_mapped_reference_sequence,
810
_set_scoreset_layer,
911
annotate,
1012
)
13+
from dcd_mapping.lookup import DataLookupError
1114
from dcd_mapping.mavedb_data import (
15+
ScoresetNotSupportedError,
1216
get_raw_scoreset_metadata,
1317
get_scoreset_metadata,
1418
get_scoreset_records,
1519
)
16-
from dcd_mapping.schemas import ScoreAnnotation, ScoresetMapping
17-
from dcd_mapping.transcripts import select_transcript
18-
from dcd_mapping.vrs_map import vrs_map
20+
from dcd_mapping.resource_utils import ResourceAcquisitionError
21+
from dcd_mapping.schemas import ScoreAnnotation, ScoresetMapping, VrsVersion
22+
from dcd_mapping.transcripts import TxSelectError, select_transcript
23+
from dcd_mapping.vrs_map import VrsMapError, vrs_map
1924

2025
router = APIRouter(
2126
prefix="/api/v1", tags=["mappings"], responses={404: {"description": "Not found"}}
@@ -24,48 +29,98 @@
2429

2530
@router.post(path="/map/{urn}", status_code=200, response_model=ScoresetMapping)
2631
async def map_scoreset(urn: str) -> ScoresetMapping:
27-
metadata = get_scoreset_metadata(urn)
28-
records = get_scoreset_records(urn, True)
32+
"""Perform end-to-end mapping for a scoreset.
2933
30-
alignment_result = align(metadata, True)
34+
:param urn: identifier for a scoreset.
35+
:param output_path: optional path to save output at
36+
:param vrs_version: version of VRS objects to output (1.3 or 2)
37+
:param silent: if True, suppress console information output
38+
"""
39+
try:
40+
metadata = get_scoreset_metadata(urn)
41+
records = get_scoreset_records(urn, True)
42+
except ScoresetNotSupportedError as e:
43+
return ScoresetMapping(
44+
metadata=None,
45+
error_message=str(e).strip("'"),
46+
)
47+
except ResourceAcquisitionError as e:
48+
msg = f"Unable to acquire resource from MaveDB: {e}"
49+
raise HTTPException(status_code=500, detail=msg) from e
3150

32-
transcript = await select_transcript(metadata, records, alignment_result)
51+
try:
52+
alignment_result = align(metadata, True)
53+
except BlatNotFoundError as e:
54+
msg = "BLAT command appears missing. Ensure it is available on the $PATH or use the environment variable BLAT_BIN_PATH to point to it. See instructions in the README prerequisites section for more."
55+
raise HTTPException(status_code=500, detail=msg) from e
56+
except ResourceAcquisitionError as e:
57+
msg = f"BLAT resource could not be acquired: {e}"
58+
raise HTTPException(status_code=500, detail=msg) from e
59+
except AlignmentError as e:
60+
return ScoresetMapping(metadata=metadata, error_message=str(e).strip("'"))
3361

34-
vrs_results = vrs_map(metadata, alignment_result, records, transcript, True)
62+
try:
63+
transcript = await select_transcript(metadata, records, alignment_result)
64+
except (TxSelectError, KeyError, ValueError) as e:
65+
return ScoresetMapping(metadata=metadata, error_message=str(e).strip("'"))
66+
except HTTPError as e:
67+
msg = f"HTTP error occurred during transcript selection: {e}"
68+
raise HTTPException(status_code=500, detail=msg) from e
69+
except DataLookupError as e:
70+
msg = f"Data lookup error occurred during transcript selection: {e}"
71+
raise HTTPException(status_code=500, detail=msg) from e
3572

36-
# TODO raise server error if vrs_results is None
73+
try:
74+
vrs_results = vrs_map(metadata, alignment_result, records, transcript, True)
75+
except VrsMapError as e:
76+
return ScoresetMapping(metadata=metadata, error_message=str(e).strip("'"))
3777
if vrs_results is None:
38-
return None
78+
return ScoresetMapping(
79+
metadata=metadata,
80+
error_message="No variant mappings available for this score set",
81+
)
3982

40-
vrs_results = annotate(vrs_results, transcript, metadata)
83+
try:
84+
vrs_results = annotate(vrs_results, transcript, metadata, VrsVersion.V_2)
85+
except Exception as e:
86+
return ScoresetMapping(metadata=metadata, error_message=str(e).strip("'"))
87+
if vrs_results is None:
88+
return ScoresetMapping(
89+
metadata=metadata,
90+
error_message="No annotated variant mappings available for this score set",
91+
)
4192

42-
raw_metadata = get_raw_scoreset_metadata(urn)
43-
# TODO change vrs map back to always use only the preferred layer
44-
# preferred_layers = {mapping.annotation_layer for mapping in vrs_results}
45-
preferred_layers = {
46-
_set_scoreset_layer(urn, vrs_results),
47-
}
93+
try:
94+
raw_metadata = get_raw_scoreset_metadata(urn)
95+
preferred_layers = {
96+
_set_scoreset_layer(urn, vrs_results),
97+
}
4898

49-
reference_sequences = {
50-
layer: {"computed_reference_sequence": None, "mapped_reference_sequence": None}
51-
for layer in AnnotationLayer
52-
}
99+
reference_sequences = {
100+
layer: {
101+
"computed_reference_sequence": None,
102+
"mapped_reference_sequence": None,
103+
}
104+
for layer in AnnotationLayer
105+
}
53106

54-
for layer in preferred_layers:
55-
reference_sequences[layer][
56-
"computed_reference_sequence"
57-
] = _get_computed_reference_sequence(urn, layer, transcript)
58-
reference_sequences[layer][
59-
"mapped_reference_sequence"
60-
] = _get_mapped_reference_sequence(layer, transcript, alignment_result)
107+
for layer in preferred_layers:
108+
reference_sequences[layer][
109+
"computed_reference_sequence"
110+
] = _get_computed_reference_sequence(urn, layer, transcript)
111+
reference_sequences[layer][
112+
"mapped_reference_sequence"
113+
] = _get_mapped_reference_sequence(layer, transcript, alignment_result)
61114

62-
mapped_scores: list[ScoreAnnotation] = []
63-
for m in vrs_results:
64-
if m.annotation_layer in preferred_layers:
65-
# drop annotation layer from mapping object
66-
mapped_scores.append(ScoreAnnotation(**m.model_dump()))
115+
mapped_scores: list[ScoreAnnotation] = []
116+
for m in vrs_results:
117+
if m.annotation_layer in preferred_layers:
118+
# drop annotation layer from mapping object
119+
mapped_scores.append(ScoreAnnotation(**m.model_dump()))
120+
except Exception as e:
121+
return ScoresetMapping(metadata=metadata, error_message=str(e).strip("'"))
67122

68-
output = ScoresetMapping(
123+
return ScoresetMapping(
69124
metadata=raw_metadata,
70125
computed_protein_reference_sequence=reference_sequences[
71126
AnnotationLayer.PROTEIN
@@ -81,5 +136,3 @@ async def map_scoreset(urn: str) -> ScoresetMapping:
81136
],
82137
mapped_scores=mapped_scores,
83138
)
84-
85-
return output

0 commit comments

Comments
 (0)