diff --git a/src/geneweaver/api/controller/genes.py b/src/geneweaver/api/controller/genes.py index f3352ed..3f4f34a 100644 --- a/src/geneweaver/api/controller/genes.py +++ b/src/geneweaver/api/controller/genes.py @@ -5,7 +5,7 @@ from geneweaver.api import dependencies as deps from geneweaver.api.schemas.apimodels import ( GeneIdHomologReq, - GeneIdHomologResp, + GeneIdMappingAonReq, GeneIdMappingReq, GeneIdMappingResp, ) @@ -14,11 +14,11 @@ router = APIRouter(prefix="/genes", tags=["genes"]) -@router.post("/homologs", response_model=GeneIdHomologResp) +@router.post("/homologs", response_model=GeneIdMappingResp) def get_related_gene_ids( gene_id_mapping: GeneIdHomologReq, cursor: Optional[deps.Cursor] = Depends(deps.cursor), -) -> GeneIdHomologResp: +) -> GeneIdMappingResp: """Get homologous gene ids given list of gene ids.""" response = genes_service.get_homolog_ids( cursor, @@ -30,7 +30,7 @@ def get_related_gene_ids( ) resp_id_map = response.get("ids_map") - gene_id_mapping_resp = GeneIdHomologResp(gene_ids_map=resp_id_map) + gene_id_mapping_resp = GeneIdMappingResp(gene_ids_map=resp_id_map) return gene_id_mapping_resp @@ -39,7 +39,7 @@ def get_related_gene_ids( def get_genes_mapping( gene_id_mapping: GeneIdMappingReq, cursor: Optional[deps.Cursor] = Depends(deps.cursor), -) -> GeneIdHomologResp: +) -> GeneIdMappingResp: """Get gene ids mapping.""" response = genes_service.get_gene_mapping( cursor, @@ -52,3 +52,19 @@ def get_genes_mapping( gene_id_mapping_resp = GeneIdMappingResp(gene_ids_map=resp_id_map) return gene_id_mapping_resp + + +@router.post("/mapping/aon", response_model=GeneIdMappingResp) +def get_genes_mapping_aon( + gene_id_mapping: GeneIdMappingAonReq, + cursor: Optional[deps.Cursor] = Depends(deps.cursor), +) -> GeneIdMappingResp: + """Get gene ids mapping given list of gene ids and target gene identifier type.""" + response = genes_service.get_gene_aon_mapping( + cursor, gene_id_mapping.source_ids, gene_id_mapping.species + ) + + resp_id_map = response.get("ids_map") + gene_id_mapping_resp = GeneIdMappingResp(gene_ids_map=resp_id_map) + + return gene_id_mapping_resp diff --git a/src/geneweaver/api/schemas/apimodels.py b/src/geneweaver/api/schemas/apimodels.py index e965a79..066339e 100644 --- a/src/geneweaver/api/schemas/apimodels.py +++ b/src/geneweaver/api/schemas/apimodels.py @@ -5,8 +5,8 @@ from pydantic import BaseModel -class GeneIdHomologResp(BaseModel): - """Model for homolog gene id mapping.""" +class GeneIdMappingResp(BaseModel): + """Model for gene id mapping response.""" gene_ids_map: list[dict] @@ -21,15 +21,16 @@ class GeneIdHomologReq(BaseModel): source_species: Optional[Species] = None -class GeneIdMappingResp(BaseModel): - """Model for gene id mapping.""" - - gene_ids_map: list[dict] - - class GeneIdMappingReq(BaseModel): """Model for gene id mapping request.""" source_ids: List[str] target_gene_id_type: GeneIdentifier species: Species + + +class GeneIdMappingAonReq(BaseModel): + """Model for AON gene id mapping request.""" + + source_ids: List[str] + species: Species diff --git a/src/geneweaver/api/services/genes.py b/src/geneweaver/api/services/genes.py index c5ec2e6..32c7062 100644 --- a/src/geneweaver/api/services/genes.py +++ b/src/geneweaver/api/services/genes.py @@ -72,3 +72,32 @@ def get_gene_mapping( raise err return {"ids_map": ids_map} + + +def get_gene_aon_mapping( + cursor: Cursor, + source_ids: List[str], + species: Species, +) -> dict: + """Get gene identifier AON mappings. + + Get gene id mappings based on species and default gene identifier type. + + @param cursor: DB Cursor + @param source_ids: list of gene ids to search + @param species: target species identifier + @return: dictionary with id mappings. + """ + ids_map = None + try: + ids_map = db_gene.aon_mapping( + cursor, + source_ids, + species, + ) + + except Exception as err: + logger.error(err) + raise err + + return {"ids_map": ids_map} diff --git a/tests/controllers/test_genes.py b/tests/controllers/test_genes.py index 6044e4b..fd1cefd 100644 --- a/tests/controllers/test_genes.py +++ b/tests/controllers/test_genes.py @@ -13,6 +13,8 @@ # gene id mapping test data gene_id_mapping_req_1 = test_gene_mapping_data.get("gene_mapping_req_1") gene_id_mapping_resp_1 = test_gene_mapping_data.get("gene_mapping_resp_1") +gene_id_aon_mapping_req_1 = test_gene_mapping_data.get("gene_aon_mapping_req_1") +gene_id_aon_mapping_resp_1 = test_gene_mapping_data.get("gene_aon_mapping_resp_1") @patch("geneweaver.api.services.genes.get_homolog_ids") @@ -119,3 +121,26 @@ def test_gene_mapping_invalid_post_data_(mock_gene_id_mapping, client): response = client.post(url="/api/genes/mapping", data=json.dumps({"test": "test"})) assert response.status_code == 422 + + +@patch("geneweaver.api.services.genes.get_gene_aon_mapping") +def test_gene_aon_mapping_valid_post_req(mock_gene_id_aon_mapping, client): + """Test genes mapping ids url and post request.""" + mock_gene_id_aon_mapping.return_value = { + "ids_map": gene_id_aon_mapping_resp_1.get("gene_ids_map") + } + + response = client.post( + url="/api/genes/mapping/aon", data=json.dumps(gene_id_aon_mapping_req_1) + ) + print(response) + assert response.status_code == 200 + assert response.json() == gene_id_aon_mapping_resp_1 + + +def test_gene_aon_mapping_invalid_post_data_(client): + """Test genes ids aon mapping url and invalid post data request.""" + response = client.post( + url="/api/genes/mapping/aon", data=json.dumps({"test": "test"}) + ) + assert response.status_code == 422 diff --git a/tests/data/__init__.py b/tests/data/__init__.py index f2a07d7..f9388c7 100644 --- a/tests/data/__init__.py +++ b/tests/data/__init__.py @@ -72,6 +72,12 @@ "gene_mapping_resp_2": json.loads(gene_id_mapping_json).get( "gene_mapping_response_2" ), + "gene_aon_mapping_req_1": json.loads(gene_id_mapping_json).get( + "gene_aon_mapping_request_1" + ), + "gene_aon_mapping_resp_1": json.loads(gene_id_mapping_json).get( + "gene_aon_mapping_response_1" + ), } # Publication test data diff --git a/tests/data/gene_maping.json b/tests/data/gene_maping.json index 12e0d60..ae637b1 100644 --- a/tests/data/gene_maping.json +++ b/tests/data/gene_maping.json @@ -39,5 +39,24 @@ "mapped_ref_id": "KLHL13" } ] + }, + "gene_aon_mapping_request_1": { + "source_ids": [ + "DAB1", + "SLC6A9" + ], + "species": "Homo Sapiens" + }, + "gene_aon_mapping_response_1": { + "gene_ids_map": [ + { + "original_ref_id": "DAB1", + "mapped_ref_id": "HGNC:2661" + }, + { + "original_ref_id": "SLC6A9", + "mapped_ref_id": "HGNC:11056" + } + ] } } \ No newline at end of file diff --git a/tests/services/test_gene.py b/tests/services/test_gene.py index 5144e08..087550e 100644 --- a/tests/services/test_gene.py +++ b/tests/services/test_gene.py @@ -27,6 +27,8 @@ gene_id_mapping_resp_1 = test_gene_mapping_data.get("gene_mapping_resp_1") gene_id_mapping_req_2 = test_gene_mapping_data.get("gene_mapping_req_2") gene_id_mapping_resp_2 = test_gene_mapping_data.get("gene_mapping_resp_2") +gene_id_aon_mapping_req_1 = test_gene_mapping_data.get("gene_aon_mapping_req_1") +gene_id_aon_mapping_resp_1 = test_gene_mapping_data.get("gene_aon_mapping_resp_1") @patch("geneweaver.api.services.genes.db_gene") @@ -147,7 +149,7 @@ def test_get_gene_map_mouse(mock_db_gene): response = genes.get_gene_mapping( None, gene_id_mapping_req_1.get("source_ids"), - gene_id_mapping_req_1.get("target_species"), + gene_id_mapping_req_1.get("species"), gene_id_mapping_req_1.get("target_gene_id_type"), ) @@ -165,7 +167,7 @@ def test_get_gene_map_human(mock_db_gene): response = genes.get_gene_mapping( None, gene_id_mapping_req_2.get("source_ids"), - gene_id_mapping_req_2.get("target_species"), + gene_id_mapping_req_2.get("species"), gene_id_mapping_req_2.get("target_gene_id_type"), ) @@ -182,6 +184,38 @@ def test_get_gene_map_error(mock_db_gene): genes.get_gene_mapping( None, gene_id_mapping_req_2.get("source_ids"), - gene_id_mapping_req_2.get("target_species"), + gene_id_mapping_req_2.get("species"), gene_id_mapping_req_2.get("target_gene_id_type"), ) + + +@patch("geneweaver.api.services.genes.db_gene") +def test_get_gene_aon_map(mock_db_gene): + """Test gene ids map by gene id type and species - Human.""" + mock_db_gene.aon_mapping.return_value = gene_id_aon_mapping_resp_1.get( + "gene_ids_map" + ) + + # Request: + # (source_ids, target gene id type, target species) + response = genes.get_gene_aon_mapping( + None, + gene_id_aon_mapping_req_1.get("source_ids"), + gene_id_aon_mapping_req_1.get("species"), + ) + + assert response.get("error") is None + assert response.get("ids_map") == gene_id_aon_mapping_resp_1.get("gene_ids_map") + + +@patch("geneweaver.api.services.genes.db_gene") +def test_get_aon_gene_map_error(mock_db_gene): + """Test error in DB call.""" + mock_db_gene.aon_mapping.side_effect = Exception("ERROR") + + with pytest.raises(expected_exception=Exception): + genes.get_gene_aon_mapping( + None, + gene_id_aon_mapping_req_1.get("source_ids"), + gene_id_aon_mapping_req_1.get("species"), + )