Skip to content

Commit

Permalink
Merge pull request #100 from geneontology/fix_ise
Browse files Browse the repository at this point in the history
add generic error handling, return specific ValueError for issue #99, fixes #93, fixes #97
  • Loading branch information
sierra-moxon authored Aug 12, 2024
2 parents ee56256 + 6e6f013 commit f9a749d
Show file tree
Hide file tree
Showing 10 changed files with 70 additions and 23 deletions.
31 changes: 30 additions & 1 deletion app/main.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
"""main application entry point."""

import logging

import uvicorn
from fastapi import FastAPI
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse

from app.middleware.logging_middleware import LoggingMiddleware
from app.routers import (
Expand All @@ -19,6 +22,8 @@
users_and_groups,
)

logger = logging.getLogger("uvicorn.error")

app = FastAPI(
title="GO API",
description="The Gene Ontology API.\n\n __Source:__ 'https://github.com/geneontology/go-fastapi'",
Expand Down Expand Up @@ -53,5 +58,29 @@
allow_headers=["*"],
)


# Global exception handler for ValueErrors
@app.exception_handler(ValueError)
async def value_error_handler(request: Request, exc: ValueError):
"""
Global exception handler for ValueErrors.
:param request:
:param exc:
:return:
"""
logger.error(f"Value error occurred: {exc}")
return JSONResponse(status_code=400, content={"message": f"Value error occurred: {exc}"})


@app.exception_handler(Exception)
async def general_exception_handler(request: Request, exc: Exception):
"""Global exception handler for all other exceptions."""
return JSONResponse(
status_code=500,
content={"message": "An unexpected error occurred. Please try again later."},
)


if __name__ == "__main__":
uvicorn.run("main:app", host="127.0.0.1", port=8080, log_level="info", reload=True)
3 changes: 0 additions & 3 deletions app/routers/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -555,9 +555,6 @@ async def get_model_details_by_model_id_json(
else:
replaced_id = id

print("id is replaced id:", replaced_id)
print("id is:", id)

path_to_s3 = "https://go-public.s3.amazonaws.com/files/go-cam/%s.json" % replaced_id
response = requests.get(path_to_s3, timeout=30, headers={"User-Agent": USER_AGENT})
response.raise_for_status() # This will raise an HTTPError if the HTTP request returned an unsuccessful status code
Expand Down
5 changes: 3 additions & 2 deletions app/routers/pathway_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ async def get_gocams_by_geneproduct_id(
(e.g. MGI:3588192, ZFIN:ZDB-GENE-000403-1).
"""
if ":" not in id:
raise ValueError("Invalid CURIE format")

if id.startswith("MGI:MGI:"):
id = id.replace("MGI:MGI:", "MGI:")

Expand All @@ -47,8 +50,6 @@ async def get_gocams_by_geneproduct_id(
si = SparqlImplementation(ont_r)
converter = Converter.from_prefix_map(cmaps, strict=False)
id = converter.expand(id)
print("in the method")
print(id)
logger.info("reformatted curie into IRI using identifiers.org from api/gp/%s/models endpoint", id)
query = (
"""
Expand Down
19 changes: 6 additions & 13 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion provision/production/PRODUCTION_PROVISION_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ DNS records are used for `go-fastapi`; they are typically the "production" recor

#### SSH Keys:

For testing purposes you can you your own ssh keys. But for production please ask for the go ssh keys.
For testing purposes you can use your own ssh keys. But for production please ask for the go ssh keys.
/tmp/go-ssh.pub
/tmp/go-ssh

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ uvicorn = ">=0.23.2"
python-multipart = "^0.0.6"
ontobio = ">=2.8.8"
gunicorn = ">=20.1.0"
prefixmaps = "^0.1.4"
prefixmaps = "^0.2.5"
linkml-runtime = ">=1.5.5"
sparqlwrapper = ">=2.0.0"
oaklib = ">=0.5.12"
Expand Down
24 changes: 24 additions & 0 deletions tests/unit/test_global_exception_handling.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from fastapi.testclient import TestClient
from app.main import app

test_client = TestClient(app)


def test_value_error_handler():
# Simulate an endpoint that raises a ValueError (e.g., by sending an invalid CURIE)
response = test_client.get("/api/ontol/labeler?id=@base:invalid")

# Verify that the global exception handler for ValueErrors, rewrites as an internal server error code.
assert response.status_code == 400
response = test_client.get(f"/api/gp/P05067/models")


def test_value_error_curie():
response = test_client.get(f"/api/gp/P05067/models")
assert response.status_code == 400
assert response.json() == {"message": "Value error occurred: Invalid CURIE format"}


def test_ncbi_taxon_error_handling():
response = test_client.get("/api/taxon/NCBITaxon%3A4896/models")
assert response.status_code == 200
1 change: 1 addition & 0 deletions tests/unit/test_models_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ def test_get_model_details_by_model_id_json_failure(self):
:return: None
"""

with self.assertRaises(HTTPError):
test_client.get("/api/go-cam/notatallrelevant")

Expand Down
3 changes: 2 additions & 1 deletion tests/unit/test_ontology_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

# Test data
gene_ids = ["ZFIN:ZDB-GENE-980526-388", "ZFIN:ZDB-GENE-990415-8", "MGI:3588192"]
go_ids = ["GO:0008150"]
go_ids = ["GO:0008150", "NCBITaxon:1"]
subsets = ["goslim_agr"]
shared_ancestors = [("GO:0006259", "GO:0046483")]
uris = ["http%3A%2F%2Fpurl.obolibrary.org%2Fobo%2FGO_0008150"]
Expand All @@ -27,6 +27,7 @@ def test_term_id_endpoint(self):
"""Test the endpoint to get the details of a Gene Ontology term by its identifier."""
for id in go_ids:
response = test_client.get(f"/api/ontology/term/{id}")
print(response.json())
self.assertEqual(response.status_code, 200)

def test_ontology_ancestors_shared_sub_obj(self):
Expand Down
3 changes: 2 additions & 1 deletion tests/unit/test_ribbon.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,8 @@ def test_wb_ribbon(self):
self.assertTrue(subject.get("groups").get("GO:0003674"))
self.assertTrue(subject.get("groups").get("GO:0003674").get("ALL").get("nb_annotations") >= 19)
self.assertTrue(subject.get("groups").get("GO:0008150").get("ALL").get("nb_annotations") >= 70)
self.assertTrue(subject.get("groups").get("GO:0008150").get("ALL").get("nb_annotations") >= 71)
print((subject.get("groups").get("GO:0008150").get("ALL").get("nb_annotations")))
self.assertTrue(subject.get("groups").get("GO:0008150").get("ALL").get("nb_annotations") >= 70)
self.assertTrue(subject.get("groups").get("GO:0005575").get("ALL").get("nb_annotations") >= 10)
assert response.status_code == 200

Expand Down

0 comments on commit f9a749d

Please sign in to comment.