Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions app/api/resources/rapid_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
StableIdResolverResponse
from app.api.utils.commons import build_stable_id_resolver_content, is_json_request
from app.api.utils.metadata import get_genome_id_from_assembly_accession_id, get_metadata
from app.api.utils.rapid import format_assembly_accession, construct_rapid_archive_url, construct_url, \
generate_rapid_id_page, generate_rapid_page
from app.api.utils.rapid import format_assembly_accession, construct_url, \
generate_rapid_id_page, generate_rapid_page, construct_rapid_archive_url
from app.api.utils.search import get_search_results
from app.core.config import ENSEMBL_URL, RAPID_ARCHIVE_URL
from app.core.config import ENSEMBL_URL
from app.core.logging import InterceptHandler

logging.getLogger().handlers = [InterceptHandler()]
Expand All @@ -27,7 +27,7 @@ async def resolve_rapid_stable_id(request: Request, stable_id: str):
# Handle only gene stable id for now
params = SearchPayload(stable_id=stable_id, type="gene", per_page=10)
search_results = get_search_results(params)
rapid_archive_url = f"{RAPID_ARCHIVE_URL}/id/{stable_id}"
rapid_archive_url = construct_rapid_archive_url(request)

if not search_results or not search_results.get("matches"):
if is_json_request(request):
Expand Down Expand Up @@ -77,6 +77,7 @@ async def resolve_rapid_help(request: Request, subpath: str = ""):
response_type=RapidResolverHtmlResponseType.HELP,
code=308,
resolved_url=f"{ENSEMBL_URL}/help",
rapid_archive_url=construct_rapid_archive_url(request)
)
return rapid_resolved_response(response, request)

Expand All @@ -87,6 +88,7 @@ async def resolve_rapid_blast(request: Request):
response_type=RapidResolverHtmlResponseType.BLAST,
code=308,
resolved_url=f"{ENSEMBL_URL}/blast",
rapid_archive_url=construct_rapid_archive_url(request)
)
return rapid_resolved_response(response, request)

Expand All @@ -97,13 +99,15 @@ async def resolve_rapid_blast(request: Request):
async def resolve_species(
request: Request, species_url_name: str, subpath: str = "", r: str = Query(None)
):
rapid_archive_url = construct_rapid_archive_url(request)
# Check if its blast redirect
if "tools/blast" in subpath.lower():
response = RapidResolverResponse(
response_type=RapidResolverHtmlResponseType.BLAST,
code=308,
resolved_url=f"{ENSEMBL_URL}/blast",
species_name=species_url_name,
rapid_archive_url=rapid_archive_url
)
return rapid_resolved_response(response, request)

Expand All @@ -117,6 +121,7 @@ async def resolve_species(
resolved_url=f"{ENSEMBL_URL}/species-selector",
message="Invalid input accession ID",
species_name=species_url_name,
rapid_archive_url=rapid_archive_url
)
return rapid_resolved_response(input_error_response, request)

Expand All @@ -130,7 +135,6 @@ async def resolve_species(
query_params = parse_qs(query_string, separator=";")

url = construct_url(genome_id, subpath, query_params)
rapid_archive_url = construct_rapid_archive_url(species_url_name, subpath, query_params)
response = RapidResolverResponse(
response_type=RapidResolverHtmlResponseType.INFO,
code=308,
Expand All @@ -151,6 +155,7 @@ async def resolve_species(
resolved_url=f"{ENSEMBL_URL}/species-selector",
message=e.detail,
species_name=species_url_name,
rapid_archive_url=rapid_archive_url
)
return rapid_resolved_response(response, request)
except Exception as e:
Expand All @@ -161,6 +166,7 @@ async def resolve_species(
code=500,
resolved_url=f"{ENSEMBL_URL}/species-selector",
message=str(e),
rapid_archive_url=rapid_archive_url
)
return rapid_resolved_response(response, request)

Expand All @@ -171,6 +177,7 @@ async def resolve_home(request: Request):
response_type=RapidResolverHtmlResponseType.HOME,
code=308,
resolved_url=ENSEMBL_URL,
rapid_archive_url=construct_rapid_archive_url(request)
)
return rapid_resolved_response(response, request)

Expand Down
27 changes: 12 additions & 15 deletions app/api/utils/rapid.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from jinja2 import Environment, FileSystemLoader
from loguru import logger
from fastapi import Request
import requests
import re

Expand Down Expand Up @@ -90,23 +91,19 @@ def construct_url(genome_id, subpath, query_params):
raise ValueError("Invalid path")


def construct_rapid_archive_url(species_url_name, subpath, query_params):
url = f"{RAPID_ARCHIVE_URL}/{species_url_name}"
query_params = query_params or {}

params = []
for key, values in query_params.items():
value = values[0] if values else ""
if value:
params.append(f"{key}={value}")

if subpath:
url += f"/{subpath}"
def construct_rapid_archive_url(request: Request):
try:
rapid_archive_path = request.url.path.removeprefix("/rapid/")
if not rapid_archive_path:
return RAPID_ARCHIVE_URL

if params:
url += "?" + ";".join(params) # ; separator for rapid
if request.url.query:
rapid_archive_path = f"{rapid_archive_path}?{request.url.query}"

return url
return f"{RAPID_ARCHIVE_URL}/{rapid_archive_path}"
except Exception as e:
logger.warning(f"Error constructing rapid archive url: {e}")
return RAPID_ARCHIVE_URL


def generate_html_content(response, page):
Expand Down
29 changes: 29 additions & 0 deletions tests/test_rapid_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import unittest
from unittest.mock import MagicMock
from fastapi import Request

from app.api.utils.rapid import construct_rapid_archive_url
from app.core.config import RAPID_ARCHIVE_URL


class TestRapidUtils(unittest.TestCase):
def _assert_rapid_url(self, rapid_path, query_string=""):
req = MagicMock(spec=Request)
req.url.path = f"/rapid/{rapid_path}"
req.url.query = query_string
res = construct_rapid_archive_url(req)
expected_url = RAPID_ARCHIVE_URL if not rapid_path else f"{RAPID_ARCHIVE_URL}/{rapid_path}"
if query_string:
expected_url = f"{expected_url}?{query_string}"
self.assertEqual(res, expected_url)

def test_construct_rapid_archive_url(self):
self._assert_rapid_url("")
self._assert_rapid_url("info/index.html")
self._assert_rapid_url("Multi/Tools/Blast")
self._assert_rapid_url("Homo_sapiens_GCA_009914755.4/Tools/Blast")
self._assert_rapid_url("id/ENSG00000221914.11")
self._assert_rapid_url("Camarhynchus_parvulus_GCA_902806625.1")
self._assert_rapid_url("Camarhynchus_parvulus_GCA_902806625.1/Location/Genome")
self._assert_rapid_url("Homo_sapiens_GCA_009914755.4/Location/View", "r=1:56873660-58424710")
self._assert_rapid_url("Homo_sapiens_GCA_009914755.4/Gene/Summary", "r=1:56873660-58424710")