Skip to content

Commit

Permalink
Merge pull request #82 from TheJacksonLaboratory/G3-301-api-add-ontol…
Browse files Browse the repository at this point in the history
…ogy-term-to-gs

G3-301 endpoint to add ontology term to geneset
  • Loading branch information
bergsalex authored Jul 29, 2024
2 parents be0f083 + 6eeb599 commit 39a96f1
Show file tree
Hide file tree
Showing 7 changed files with 256 additions and 79 deletions.
143 changes: 69 additions & 74 deletions poetry.lock

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "geneweaver-api"
version = "0.7.0a10"
version = "0.7.0a11"
description = "The Geneweaver API"
authors = [
"Alexander Berger <alexander.berger@jax.org>",
Expand All @@ -20,7 +20,7 @@ python = "^3.9"
geneweaver-core = "^0.10.0a3"
fastapi = {extras = ["all"], version = "^0.111.0"}
uvicorn = {extras = ["standard"], version = "^0.30.0"}
geneweaver-db = "0.5.0a13"
geneweaver-db = "0.5.0a15"
psycopg-pool = "^3.1.7"
requests = "^2.32.3"
python-jose = {extras = ["cryptography"], version = "^3.3.0"}
Expand Down
30 changes: 30 additions & 0 deletions src/geneweaver/api/controller/genesets.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,3 +340,33 @@ def get_geneset_ontology_terms(
raise HTTPException(status_code=403, detail=api_message.ACCESS_FORBIDDEN)

return terms_resp


@router.put("/{geneset_id}/ontologies", status_code=204)
def put_geneset_ontology_term(
geneset_id: Annotated[
int, Path(format="int64", minimum=0, maxiumum=9223372036854775807)
],
ontology_ref_term_id: str,
user: UserInternal = Security(deps.full_user),
cursor: Optional[deps.Cursor] = Depends(deps.cursor),
) -> None:
"""Set geneset threshold for geneset owner."""
response = genset_service.add_geneset_ontology_term(
cursor=cursor,
geneset_id=geneset_id,
ref_term_id=ontology_ref_term_id,
user=user,
)

if "error" in response:
if response.get("message") == api_message.ACCESS_FORBIDDEN:
raise HTTPException(status_code=403, detail=api_message.ACCESS_FORBIDDEN)

if response.get("message") == api_message.RECORD_NOT_FOUND_ERROR:
raise HTTPException(
status_code=404, detail=api_message.RECORD_NOT_FOUND_ERROR
)

if response.get("message") == api_message.RECORD_EXISTS:
raise HTTPException(status_code=412, detail=api_message.RECORD_EXISTS)
58 changes: 56 additions & 2 deletions src/geneweaver/api/services/geneset.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@
from fastapi.logger import logger
from geneweaver.api.controller import message
from geneweaver.api.core.exceptions import UnauthorizedException
from geneweaver.api.schemas.auth import User
from geneweaver.api.schemas.auth import AppRoles, User
from geneweaver.core.enum import GeneIdentifier, GenesetTier, Species
from geneweaver.core.schema.score import GenesetScoreType
from geneweaver.db import gene as db_gene
from geneweaver.db import geneset as db_geneset
from geneweaver.db import geneset_value as db_geneset_value
from geneweaver.db import ontology as db_ontology
from geneweaver.db import threshold as db_threshold
from psycopg import Cursor
from psycopg import Cursor, errors

ONTO_GSO_REF_TYPE = "GeneWeaver Primary Annotation"


def determine_geneset_access(
Expand Down Expand Up @@ -434,3 +436,55 @@ def get_geneset_ontology_terms(
except Exception as err:
logger.error(err)
raise err


def add_geneset_ontology_term(
cursor: Cursor,
geneset_id: int,
ref_term_id: str,
user: User,
gso_ref_type: str = ONTO_GSO_REF_TYPE,
) -> dict:
"""Get geneset ontology terms by geneset id.
:param cursor: DB cursor
:param geneset_id: geneset identifier
:param ref_term_id ref term identifier
:param user: GW user
:param limit: Limit the number of results.
:param offset: Offset the results.
@return: persisted record (geneset id, ontology term id).
"""
try:
if user is None or user.id is None:
return {"error": True, "message": message.ACCESS_FORBIDDEN}

owner = db_geneset.user_is_owner(
cursor=cursor, user_id=user.id, geneset_id=geneset_id
)
curator = user.role is AppRoles.curator

if not owner and not curator:
return {"error": True, "message": message.ACCESS_FORBIDDEN}

onto_term = db_ontology.by_ontology_term(
cursor=cursor, onto_ref_term_id=ref_term_id
)

if onto_term is None:
return {"error": True, "message": message.RECORD_NOT_FOUND_ERROR}

results = db_ontology.add_ontology_term_to_geneset(
cursor=cursor,
geneset_id=geneset_id,
ontology_term_id=onto_term.get("onto_id"),
gso_ref_type=gso_ref_type,
)
return {"data": results}

except errors.UniqueViolation:
return {"error": True, "message": message.RECORD_EXISTS}

except Exception as err:
logger.error(err)
raise err
37 changes: 37 additions & 0 deletions tests/controllers/test_genesets.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,3 +310,40 @@ def test_get_geneset_ontology_terms_errors(mock_get_genenset_onto_terms, client)

response = client.get("/api/genesets/1234/ontologies")
assert response.status_code == 403


@patch("geneweaver.api.services.geneset.add_geneset_ontology_term")
def test_add_geneset_ontology_term_response(mock_add_genenset_onto_terms, client):
"""Test add geneset ontology_terms response."""
mock_resp = test_ontology_data.get("geneset_ontology_terms")
mock_add_genenset_onto_terms.return_value = mock_resp

response = client.put("/api/genesets/1234/ontologies?ontology_ref_term_id=D001921")
assert response.status_code == 204


@patch("geneweaver.api.services.geneset.add_geneset_ontology_term")
def test_add_geneset_ontology_terms_errors(mock_add_genenset_onto_terms, client):
"""Test add geneset ontology_terms errors."""
mock_resp = {
"error": True,
"message": message.ACCESS_FORBIDDEN,
}
mock_add_genenset_onto_terms.return_value = mock_resp

response = client.put("/api/genesets/1234/ontologies?ontology_ref_term_id=D001921")
assert response.status_code == 403

mock_add_genenset_onto_terms.return_value = {
"error": True,
"message": message.RECORD_NOT_FOUND_ERROR,
}
response = client.put("/api/genesets/1234/ontologies?ontology_ref_term_id=QEQWEWE")
assert response.status_code == 404

mock_add_genenset_onto_terms.return_value = {
"error": True,
"message": message.RECORD_EXISTS,
}
response = client.put("/api/genesets/1234/ontologies?ontology_ref_term_id=D001921")
assert response.status_code == 412
2 changes: 1 addition & 1 deletion tests/data/publications.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"volume": "3",
"pages": "565-76",
"month": null,
"year": 1975
"year": "1975"
},
"add_pubmed_resp": {
"pubmed_id": 1234,
Expand Down
61 changes: 61 additions & 0 deletions tests/services/test_genset.py
Original file line number Diff line number Diff line change
Expand Up @@ -472,3 +472,64 @@ def test_geneset_gene_value_w_gene_id_type_none_resp2(mock_db_geneset):
None, user=mock_user, geneset_id=1234, gene_id_type=GeneIdentifier(2)
)
assert response == {"data": None}


@patch("geneweaver.api.services.geneset.db_geneset")
@patch("geneweaver.api.services.geneset.db_ontology")
def test_add_genset_ontology_term(mock_db_ontology, mock_db_geneset):
"""Test geneset gene value data response."""
mock_reponse = {"data": {"gs_id": 1234, "ont_id": 1}}
mock_db_ontology.by_ontology_term.return_value = {"onto_id": 123123}
mock_db_geneset.user_is_owner.return_value = True
mock_db_ontology.add_ontology_term_to_geneset.return_value = mock_reponse.get(
"data"
)

response = geneset.add_geneset_ontology_term(
cursor=None, user=mock_user, geneset_id=1234, ref_term_id="D001921"
)
assert response == mock_reponse


@patch("geneweaver.api.services.geneset.db_geneset")
@patch("geneweaver.api.services.geneset.db_ontology")
def test_add_geneset_ontology_term_errors(mock_db_ontology, mock_db_geneset):
"""Test geneset gene value data response."""
mock_reponse = {"data": {"gs_id": 1234, "ont_id": 1}}
mock_db_ontology.by_ontology_term.return_value = {"onto_id": 123123}
mock_db_geneset.user_is_owner.return_value = False
mock_db_ontology.add_ontology_term_to_geneset.return_value = mock_reponse.get(
"data"
)

# user is not the geneset owner
response = geneset.add_geneset_ontology_term(
cursor=None, user=mock_user, geneset_id=1234, ref_term_id="D001921"
)
assert response.get("error") is True
assert response.get("message") == message.ACCESS_FORBIDDEN

# user is not logged-in
response = geneset.add_geneset_ontology_term(
cursor=None, user=None, geneset_id=1234, ref_term_id="D001921"
)
assert response.get("error") is True
assert response.get("message") == message.ACCESS_FORBIDDEN

# Ontology term is not found
mock_db_ontology.by_ontology_term.return_value = None
mock_db_geneset.user_is_owner.return_value = True
response = geneset.add_geneset_ontology_term(
cursor=None, user=mock_user, geneset_id=1234, ref_term_id="D001921"
)
assert response.get("error") is True
assert response.get("message") == message.RECORD_NOT_FOUND_ERROR

# db error
mock_db_geneset.user_is_owner.return_value = True
mock_db_ontology.by_ontology_term.return_value = {"onto_id": 123123}
mock_db_ontology.add_ontology_term_to_geneset.side_effect = Exception("ERROR")
with pytest.raises(expected_exception=Exception):
geneset.add_geneset_ontology_term(
cursor=None, user=mock_user, geneset_id=1234, ref_term_id="D001921"
)

0 comments on commit 39a96f1

Please sign in to comment.