-
Notifications
You must be signed in to change notification settings - Fork 0
Show Intermediate Rapid resolver page before redirecting to Ensembl site #14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
2358436
f3845ce
f789110
2ee8e2c
77f0295
df6a4ab
a803fc5
4a67d08
b7558cf
e52fbb5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,14 @@ | ||
import os | ||
from urllib.parse import parse_qs | ||
from fastapi import APIRouter, Request, HTTPException, Query | ||
from fastapi.responses import RedirectResponse | ||
|
||
from dotenv import load_dotenv | ||
from fastapi import APIRouter, Request, Query, HTTPException | ||
|
||
from jinja2 import Environment, FileSystemLoader | ||
from starlette.responses import HTMLResponse | ||
|
||
import logging | ||
from api.models.resolver import ResolvedURLResponse | ||
from api.models.resolver import ResolvedURLResponse, RapidRedirectResponseType | ||
from core.logging import InterceptHandler | ||
from core.config import ENSEMBL_URL | ||
from api.utils.metadata import get_genome_id_from_assembly_accession_id | ||
|
@@ -15,14 +21,22 @@ | |
|
||
@router.get("/info/{subpath:path}", name="Resolve rapid help page") | ||
async def resolve_rapid_help(request: Request, subpath: str = ""): | ||
help_page_url = f"{ENSEMBL_URL}/help" | ||
return resolved_response(help_page_url, request) | ||
response = ResolvedURLResponse( | ||
response_type=RapidRedirectResponseType.HELP, | ||
code=308, | ||
resolved_url=f"{ENSEMBL_URL}/help", | ||
) | ||
return resolved_response(response, request) | ||
|
||
|
||
@router.get("/Blast", name="Resolve rapid blast page") | ||
async def resolve_rapid_blast(request: Request): | ||
blast_page_url = f"{ENSEMBL_URL}/blast" | ||
return resolved_response(blast_page_url, request) | ||
response = ResolvedURLResponse( | ||
response_type=RapidRedirectResponseType.BLAST, | ||
code=308, | ||
resolved_url=f"{ENSEMBL_URL}/blast", | ||
) | ||
return resolved_response(response, request) | ||
|
||
|
||
# Resolve rapid urls | ||
|
@@ -34,9 +48,15 @@ async def resolve_species( | |
assembly_accession_id = format_assembly_accession(species_url_name) | ||
|
||
if assembly_accession_id is None: | ||
raise HTTPException( | ||
status_code=422, detail="Unable to process input accession ID" | ||
input_error_response = ResolvedURLResponse( | ||
response_type=RapidRedirectResponseType.ERROR, | ||
code=422, | ||
resolved_url=ENSEMBL_URL, | ||
message="Invalid input accession ID", | ||
species_name=species_url_name, | ||
) | ||
return resolved_response(input_error_response, request) | ||
|
||
try: | ||
genome_object = get_genome_id_from_assembly_accession_id(assembly_accession_id) | ||
|
||
|
@@ -48,27 +68,63 @@ async def resolve_species( | |
query_params = parse_qs(query_string, separator=";") | ||
|
||
url = construct_url(genome_id, subpath, query_params) | ||
return resolved_response(url, request) | ||
response = ResolvedURLResponse( | ||
response_type=RapidRedirectResponseType.INFO, | ||
code=308, | ||
resolved_url=url, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The ticket also mentions the case of multiple resolved URLs (code 300), which is not addressed here. In principle an assembly accession ID can resolve to multiple genome UUIDs (if it's part of both partial and integrated release, like the human reference), but it shouldn't apply to rapid species so it's fine (assuming any rapid assembly won't become part of a partial release in the future). |
||
species_name=species_url_name, | ||
gene_id=query_params.get("g", [None])[0], | ||
location=query_params.get("r", [None])[0], | ||
) | ||
return resolved_response(response, request) | ||
else: | ||
raise HTTPException(status_code=404, detail="Genome not found") | ||
|
||
except HTTPException as e: | ||
logging.debug(e) | ||
raise HTTPException( | ||
status_code=e.status_code, detail="Unexpected error occured" | ||
response = ResolvedURLResponse( | ||
response_type=RapidRedirectResponseType.ERROR, | ||
code=e.status_code, | ||
resolved_url=ENSEMBL_URL, | ||
message=e.detail, | ||
species_name=species_url_name, | ||
) | ||
|
||
return resolved_response(response, request) | ||
except Exception as e: | ||
logging.debug(f"Unexpected error occurred: {e}") | ||
raise HTTPException(status_code=500, detail="Unexpected error occurred") | ||
response = ResolvedURLResponse( | ||
response_type=RapidRedirectResponseType.ERROR, | ||
code=500, | ||
resolved_url=ENSEMBL_URL, | ||
message="Unexpected error occurred", | ||
) | ||
return resolved_response(response, request) | ||
|
||
|
||
@router.get("/", name="Rapid Home") | ||
async def resolve_home(request: Request): | ||
return resolved_response(ENSEMBL_URL, request) | ||
response = ResolvedURLResponse( | ||
response_type=RapidRedirectResponseType.HOME, | ||
code=308, | ||
resolved_url=ENSEMBL_URL, | ||
) | ||
return resolved_response(response, request) | ||
|
||
|
||
def resolved_response(url: str, request: Request): | ||
def resolved_response(response: ResolvedURLResponse, request: Request): | ||
if "application/json" in request.headers.get("accept"): | ||
return ResolvedURLResponse(resolved_url=url) | ||
return RedirectResponse(url=url, status_code=301) | ||
if response.response_type == RapidRedirectResponseType.ERROR: | ||
raise HTTPException( | ||
status_code=response.status_code, | ||
detail=response.message or "An error occurred", | ||
) | ||
return ResolvedURLResponse(resolved_url=response.resolved_url) | ||
return HTMLResponse(generate_html_content(response)) | ||
|
||
|
||
def generate_html_content(response): | ||
load_dotenv() | ||
CURR_DIR = os.path.dirname(os.path.abspath(__file__)) | ||
env = Environment(loader=FileSystemLoader(os.path.join(CURR_DIR, "templates/rapid"))) | ||
rapid_redirect_page_template = env.get_template("main.html") | ||
rapid_redirect_page_html = rapid_redirect_page_template.render(response=response) | ||
return rapid_redirect_page_html |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<div class="footer"> | ||
<span> | ||
If you require data in Ensembl Rapid release archive, or need links to the Rapid Release ftp, please visit | ||
</span> | ||
</div> | ||
<div class="footer-link"> | ||
<a href="https://rapid-archive.ensembl.org" target="_blank" rel="noopener noreferrer"> | ||
rapid-archive.ensembl.org | ||
</a> | ||
</div> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" | ||
viewBox="0 0 32 32" style="enable-background:new 0 0 32 32;" xml:space="preserve" width="19px" height="19px" fill="#0099ff"> | ||
<path d="M26.4299088,18.9942322v7.4855804c0,0.6986561-0.4990387,1.2975006-1.2974987,1.2975006h-5.9884644 | ||
c-0.2994232,0-0.6986561-0.2994232-0.6986561-0.6986542v-5.7888489c0-0.2994232-0.2994213-0.6986561-0.6986542-0.6986561h-3.4932718 | ||
c-0.2994232,0-0.6986532,0.2994232-0.6986532,0.6986561v5.7888489c0,0.2994213-0.2994242,0.6986542-0.6986542,0.6986542H6.8675914 | ||
c-0.6986537,0-1.2975006-0.4990387-1.2975006-1.2975006v-7.4855804c0-0.1996155,0.0624285-0.3679199,0.1996155-0.4990387 | ||
l9.7811584-7.9846191c0.1996145-0.1996155,0.4990387-0.1996155,0.7984619,0l9.7811604,7.9846191 | ||
C26.3276825,18.6263123,26.3749332,18.7605743,26.4299088,18.9942322L26.4299088,18.9942322z"/> | ||
<path d="M15.6065302,8.5148048c0.1996155-0.1996155,0.4990396-0.1996155,0.798461,0l12.0700836,9.9158611 | ||
c0.4120693,0.3384781,0.9688454,0.2207394,1.2509117-0.1226521l1.0718441-1.304884 | ||
c0.3384781-0.4120693,0.2207394-0.9688473-0.1226501-1.2509108L17.6026859,5.0215335 | ||
c-0.9980774-0.7984619-2.295579-0.7984619-3.1938486,0L1.3248215,15.7522116 | ||
c-0.343391,0.2820635-0.4611307,0.8388414-0.1226532,1.2509108l1.0718439,1.3048859 | ||
c0.2820647,0.3433914,0.8388419,0.4611301,1.2509112,0.122654L15.6065302,8.5148048z"/> | ||
</svg> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<!-- Generator: Adobe Illustrator 23.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> | ||
<svg version="1.1" id="e_x5F_logotype" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" | ||
y="0px" viewBox="0 0 236 32" style="enable-background:new 0 0 236 32;" xml:space="preserve" height="12px" fill="#ffffff"> | ||
<path d="M234.1,26.2v4.3h-24V1.4h4.5v24.8C214.6,26.2,234.1,26.2,234.1,26.2z"/> | ||
<path d="M190.9,1.4c3.7,0,6.4,0.6,8.3,1.9c1.9,1.3,2.8,3.1,2.8,5.5c0,1.3-0.4,2.5-1.1,3.5c-0.8,1-1.9,1.8-3.4,2.4 | ||
c1.1,0.3,2.1,0.8,3,1.4c0.9,0.6,1.7,1.4,2.2,2.4c0.6,1,0.9,2.2,0.9,3.5c0,1.7-0.3,3.1-1,4.2s-1.6,2-2.7,2.6 | ||
c-1.1,0.6-2.4,1.1-3.7,1.4c-1.4,0.3-2.7,0.4-4.1,0.4h-17V1.4H190.9z M191.3,5.8h-11.8v7.5h12.3c1,0,1.9-0.2,2.8-0.5 | ||
c0.9-0.3,1.5-0.7,2.1-1.3c0.5-0.6,0.8-1.3,0.8-2.1c0-1.3-0.6-2.3-1.8-2.8C194.5,6,193,5.8,191.3,5.8z M192,17.6h-12.5v8.6h12.7 | ||
c2,0,3.6-0.4,4.9-1.1c1.3-0.7,1.9-1.8,1.9-3.3c0-1.1-0.4-2-1.1-2.6c-0.7-0.6-1.6-1-2.7-1.3C194.1,17.8,193.1,17.6,192,17.6z"/> | ||
<path d="M138.4,1.4l11.5,15.5l11.5-15.5h4.4v29.2h-4.5V18.2c0-1.8,0-3.5,0.1-5.1s0.2-3.2,0.4-4.9l-10.5,14h-2.7L138,8.2 | ||
c0.2,1.6,0.3,3.2,0.4,4.9c0.1,1.6,0.1,3.3,0.1,5.1v12.4H134V1.4H138.4z"/> | ||
<path d="M101.7,1.4h24.2v4.3h-19.7v7.7h17.4v4.3h-17.4v8.5h19.7v4.3h-24.2V1.4z"/> | ||
<path d="M69.9,21.6c1.6,1.7,3.4,3,5.2,4c1.8,0.9,4,1.4,6.6,1.4c1.4,0,2.8-0.2,4.2-0.5c1.3-0.3,2.4-0.9,3.3-1.6s1.3-1.6,1.3-2.7 | ||
c0-0.9-0.4-1.7-1.1-2.1c-0.8-0.5-1.9-0.9-3.3-1.1c-1.4-0.3-3.2-0.5-5.2-0.8c-2.5-0.3-4.7-0.8-6.5-1.5c-1.8-0.7-3.2-1.6-4.2-2.7 | ||
s-1.5-2.6-1.5-4.3c0-1.8,0.6-3.4,1.7-4.7c1-1.3,2.6-2.3,4.5-3c2-0.7,4.1-1,6.6-1c3,0,5.5,0.4,7.7,1.3s3.9,2.2,5.1,3.8l-3,3.3 | ||
c-1.1-1.3-2.5-2.4-4.1-3.2C85.5,5.4,83.6,5,81.4,5c-1.5,0-2.8,0.2-4,0.5s-2.1,0.8-2.8,1.4c-0.7,0.6-1,1.3-1,2.2c0,1,0.4,1.8,1.1,2.4 | ||
c0.7,0.6,1.8,1.1,3.1,1.4c1.3,0.3,2.9,0.6,4.7,0.8c1.7,0.2,3.3,0.4,4.8,0.7c1.6,0.3,3,0.7,4.2,1.3c1.2,0.5,2.2,1.3,2.9,2.2 | ||
c0.7,0.9,1.1,2.1,1.1,3.6c0,1.9-0.6,3.5-1.7,5c-1.1,1.4-2.7,2.5-4.8,3.3c-2.1,0.8-4.5,1.2-7.2,1.2c-3,0-5.7-0.4-8.2-1.3 | ||
c-2.4-0.9-4.6-2.3-6.4-4.3L69.9,21.6z"/> | ||
<path d="M56.2,1.4h4.5v29.2h-4.5L37.3,7.7c0.2,1.8,0.3,3.6,0.5,5.4s0.3,3.6,0.3,5.4v12.1h-4.5V1.4H38l18.9,23.5 | ||
c-0.2-1.4-0.3-2.8-0.4-4.5c-0.1-1.6-0.2-3.2-0.2-4.9c0-1.6-0.1-3.2-0.1-4.6V1.4z"/> | ||
<path d="M25.5,1.4v4.3H5.8v7.7h17.4v4.3H5.8l0.1,4.1c0,1.4,0.7,2.6,1.9,3.3c1.3,0.7,2.9,1.1,4.9,1.1h12.8v4.3H12.9 | ||
c-1.4,0-2.7-0.1-4.1-0.4s-2.6-0.7-3.7-1.4c-1.1-0.6-2-1.5-2.7-2.6s-1-2.5-1-4.2v-1.3V1.4H25.5z"/> | ||
</svg> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
<div class="topbar"> | ||
<div class="topbar-left"> | ||
<div class="home-link"> | ||
<a href="https://beta.ensembl.org/"> | ||
{% include "_home_icon.html" %} | ||
</a> | ||
</div> | ||
<div class="logotype-wrapper"> | ||
{% include "_logo.html" %} | ||
</div> | ||
<div class="topbar-left-text"> | ||
<div class="release"> | ||
<span class="light">Beta</span> | ||
</div> | ||
<div class="copyright"> | ||
<a href="https://www.ebi.ac.uk" target="_blank" rel="noopener noreferrer"> | ||
© EMBL-EBI | ||
</a> | ||
</div> | ||
</div> | ||
</div> | ||
<div class="topbar-right"> | ||
<span>Genome data & annotation</span> | ||
</div> | ||
</div> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
{% import "url.html" as url_helper %} | ||
|
||
<div class="redirect-content"> | ||
<div class="redirect-info"> | ||
{% if response.response_type == "BLAST" or response.response_type == "HELP" %} | ||
{{ url_helper.render_url(response.resolved_url) }} | ||
{% elif response.response_type == "INFO" %} | ||
<div class="search-param"> | ||
<span class="search-param-label">Species</span> {{ response.species_name }} | ||
</div> | ||
{% if response.gene_id %} | ||
<div class="search-param"> | ||
<span class="search-param-label">Gene</span> {{ response.gene_id }} | ||
</div> | ||
{% endif %} | ||
{% if response.location %} | ||
<div class="search-param"> | ||
<span class="search-param-label">Location</span> {{ response.location }} | ||
</div> | ||
{% endif %} | ||
{{ url_helper.render_url(response.resolved_url) }} | ||
{% elif response.response_type == "ERROR" %} | ||
<div class="search-param"> | ||
<span class="search-param-label">Species</span> {{ response.species_name }} | ||
</div> | ||
<div class="error-message"> | ||
{{ response.message }} | ||
</div> | ||
{{ url_helper.render_url("https://beta.ensembl.org/") }} | ||
|
||
{% else %} | ||
{{ url_helper.render_url("https://beta.ensembl.org/") }} | ||
{% endif %} | ||
</div> | ||
<div class="redirect-text"> | ||
<span> | ||
You will be redirected to the new Ensembl website, where you will find the latest genomic information | ||
</span> | ||
</div> | ||
</div> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<title>Ensembl Rapid Resolver</title> | ||
|
||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<!-- Automatically refresh/redirects to the target url (resolved rapid url) after 10 seconds --> | ||
<meta http-equiv="refresh" content="10;url={{ response.resolved_url }}" /> | ||
|
||
<link rel="icon" type="image/png" sizes="32x32" href="/static/icons/favicon-32x32.png" /> | ||
<link rel="icon" type="image/png" sizes="16x16" href="/static/icons/favicon-16x16.png" /> | ||
<link rel="preconnect" href="https://fonts.googleapis.com"> | ||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | ||
<link href="https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,100;0,300;0,400;0,700;0,900;1,100;1,300;1,400;1,700;1,900&display=swap" rel="stylesheet"> | ||
<link href="https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,100;0,300;0,400;0,700;0,900;1,100;1,300;1,400;1,700;1,900&family=Roboto:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet"> | ||
|
||
<link rel="stylesheet" type="text/css" href="/static/css/rapid_page.css"> | ||
</head> | ||
<body> | ||
{% include "appbar.html" %} | ||
<div class="container"> | ||
{% include "venn.html" %} | ||
{% include "content.html" %} | ||
{% include "_footer.html" %} | ||
</div> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{% macro render_url(url) %} | ||
<div> | ||
<span class="search-param-label">Redirecting to </span> | ||
<a class="link" href="{{ url }}"> | ||
{{ url }} | ||
</a> | ||
</div> | ||
{% endmacro %} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<div class="venn-header"> | ||
<span>Venn of the redirect</span> | ||
</div> | ||
<div class="venn"> | ||
<div class="circle a"> | ||
<span>Your URL has changed or gone...</span> | ||
</div> | ||
<div class="circle b"> | ||
<span>...we suggest this instead</span> | ||
</div> | ||
<div class="intersection"> | ||
<span>{{ response.code }}</span> | ||
</div> | ||
</div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we probably don't need this.