Skip to content

Commit

Permalink
Merge pull request galaxyproject#17497 from mvdbeek/provide_working_u…
Browse files Browse the repository at this point in the history
…rl_for_to_every_request

[23.2] Provide working routes.url_for every ASGI request
  • Loading branch information
mvdbeek authored Feb 20, 2024
2 parents 877b5f6 + e9c9107 commit ea9e2fb
Show file tree
Hide file tree
Showing 10 changed files with 52 additions and 61 deletions.
6 changes: 1 addition & 5 deletions lib/galaxy/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,7 @@
from galaxy.visualization.data_providers.registry import DataProviderRegistry
from galaxy.visualization.genomes import Genomes
from galaxy.visualization.plugins.registry import VisualizationsRegistry
from galaxy.web import (
legacy_url_for,
url_for,
)
from galaxy.web import url_for
from galaxy.web.framework.base import server_starttime
from galaxy.web.proxy import ProxyManager
from galaxy.web.short_term_storage import (
Expand Down Expand Up @@ -798,7 +795,6 @@ def __init__(self, **kwargs) -> None:
# Inject url_for for components to more easily optionally depend
# on url_for.
self.url_for = url_for
self.legacy_url_for = legacy_url_for

self.server_starttime = server_starttime # used for cachebusting
# Limit lifetime of tool shed repository cache to app startup
Expand Down
4 changes: 2 additions & 2 deletions lib/galaxy/datatypes/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -783,7 +783,7 @@ def as_display_type(self, dataset: DatasetProtocol, type: str, **kwd) -> Union[F
return f"This display type ({type}) is not implemented for this datatype ({dataset.ext})."

def get_display_links(
self, dataset: DatasetProtocol, type: str, app, base_url: str, request, target_frame: str = "_blank", **kwd
self, dataset: DatasetProtocol, type: str, app, base_url: str, target_frame: str = "_blank", **kwd
):
"""
Returns a list of tuples of (name, link) for a particular display type. No check on
Expand All @@ -794,7 +794,7 @@ def get_display_links(
try:
if app.config.enable_old_display_applications and type in self.get_display_types():
return target_frame, getattr(self, self.supported_display_apps[type]["links_function"])(
dataset, type, app, base_url, request, **kwd
dataset, type, app, base_url, **kwd
)
except Exception:
log.exception(
Expand Down
4 changes: 1 addition & 3 deletions lib/galaxy/datatypes/display_applications/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,14 @@ def __init__(self, display_application):

def get_display_url(self, data, trans):
dataset_hash, user_hash = encode_dataset_user(trans, data, None)
return trans.app.legacy_url_for(
mapper=trans.app.legacy_mapper,
return trans.app.url_for(
controller="dataset",
action="display_application",
dataset_id=dataset_hash,
user_id=user_hash,
app_name=quote_plus(self.display_application.id),
link_name=quote_plus(self.id),
app_action=None,
environ=trans.request.environ,
)

def get_inital_values(self, data, trans):
Expand Down
4 changes: 1 addition & 3 deletions lib/galaxy/datatypes/display_applications/parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,7 @@ def url(self):
base_url = f"http{base_url[5:]}"
return "{}{}".format(
base_url,
self.trans.app.legacy_url_for(
mapper=self.trans.app.legacy_mapper,
self.trans.app.url_for(
controller="dataset",
action="display_application",
dataset_id=self._dataset_hash,
Expand All @@ -284,7 +283,6 @@ def url(self):
link_name=quote_plus(self.parameter.link.id),
app_action=self.action_name,
action_param=self._url,
environ=self.trans.request.environ,
),
)

Expand Down
8 changes: 3 additions & 5 deletions lib/galaxy/datatypes/genetics.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def as_ucsc_display_file(self, dataset: DatasetProtocol, **kwd) -> Union[FileObj
"""
return open(dataset.get_file_name(), "rb")

def ucsc_links(self, dataset: DatasetProtocol, type: str, app, base_url: str, request) -> List:
def ucsc_links(self, dataset: DatasetProtocol, type: str, app, base_url: str) -> List:
"""
from the ever-helpful angie hinrichs [email protected]
a genome graphs call looks like this
Expand All @@ -114,17 +114,15 @@ def ucsc_links(self, dataset: DatasetProtocol, type: str, app, base_url: str, re
for site_name, site_url in app.datatypes_registry.get_legacy_sites_by_build("ucsc", dataset.dbkey):
if site_name in app.datatypes_registry.get_display_sites("ucsc"):
site_url = site_url.replace("/hgTracks?", "/hgGenome?") # for genome graphs
internal_url = "%s" % app.legacy_url_for(
mapper=app.legacy_mapper,
environ=request.environ,
internal_url = app.url_for(
controller="dataset",
dataset_id=dataset.id,
action="display_at",
filename=f"ucsc_{site_name}",
)
display_url = "%s%s/display_as?id=%i&display_app=%s&authz_method=display_at" % (
base_url,
app.legacy_url_for(mapper=app.legacy_mapper, environ=request.environ, controller="root"),
app.url_for(controller="root"),
dataset.id,
type,
)
Expand Down
42 changes: 23 additions & 19 deletions lib/galaxy/datatypes/interval.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ def display_peek(self, dataset: DatasetProtocol) -> str:
},
)

def ucsc_links(self, dataset: DatasetProtocol, type: str, app, base_url: str, request) -> List:
def ucsc_links(self, dataset: DatasetProtocol, type: str, app, base_url: str) -> List:
"""
Generate links to UCSC genome browser sites based on the dbkey
and content of dataset.
Expand All @@ -337,9 +337,7 @@ def ucsc_links(self, dataset: DatasetProtocol, type: str, app, base_url: str, re
# Accumulate links for valid sites
ret_val = []
for site_name, site_url in valid_sites:
internal_url = app.legacy_url_for(
mapper=app.legacy_mapper,
environ=request.environ,
internal_url = app.url_for(
controller="dataset",
dataset_id=dataset.id,
action="display_at",
Expand All @@ -349,7 +347,7 @@ def ucsc_links(self, dataset: DatasetProtocol, type: str, app, base_url: str, re
"%s%s/display_as?id=%i&display_app=%s&authz_method=display_at"
% (
base_url,
app.legacy_url_for(mapper=app.legacy_mapper, environ=request.environ, controller="root"),
app.url_for(controller="root"),
dataset.id,
type,
)
Expand Down Expand Up @@ -768,20 +766,26 @@ class Bed12(BedStrict):

class _RemoteCallMixin:
def _get_remote_call_url(
self, redirect_url: str, site_name: str, dataset: HasId, type: str, app, base_url: str, request
self,
redirect_url: str,
site_name: str,
dataset: HasId,
type: str,
app,
base_url: str,
) -> str:
"""Retrieve the URL to call out to an external site and retrieve data.
This routes our external URL through a local galaxy instance which makes
the data available, followed by redirecting to the remote site with a
link back to the available information.
"""
internal_url = f"{app.legacy_url_for(mapper=app.legacy_mapper, environ=request.environ, controller='dataset', dataset_id=dataset.id, action='display_at', filename=f'{type}_{site_name}')}"
internal_url = f"{app.url_for(controller='dataset', dataset_id=dataset.id, action='display_at', filename=f'{type}_{site_name}')}"
base_url = app.config.get("display_at_callback", base_url)
display_url = quote_plus(
"%s%s/display_as?id=%i&display_app=%s&authz_method=display_at"
% (
base_url,
app.legacy_url_for(mapper=app.legacy_mapper, environ=request.environ, controller="root"),
app.url_for(controller="root"),
dataset.id,
type,
)
Expand Down Expand Up @@ -969,7 +973,7 @@ def get_estimated_display_viewport(
log.exception("Unexpected error")
return (None, None, None) # could not determine viewport

def ucsc_links(self, dataset: DatasetProtocol, type: str, app, base_url: str, request) -> List:
def ucsc_links(self, dataset: DatasetProtocol, type: str, app, base_url: str) -> List:
ret_val = []
seqid, start, stop = self.get_estimated_display_viewport(dataset)
if seqid is not None:
Expand All @@ -978,11 +982,11 @@ def ucsc_links(self, dataset: DatasetProtocol, type: str, app, base_url: str, re
redirect_url = quote_plus(
f"{site_url}db={dataset.dbkey}&position={seqid}:{start}-{stop}&hgt.customText=%s"
)
link = self._get_remote_call_url(redirect_url, site_name, dataset, type, app, base_url, request)
link = self._get_remote_call_url(redirect_url, site_name, dataset, type, app, base_url)
ret_val.append((site_name, link))
return ret_val

def gbrowse_links(self, dataset: DatasetProtocol, type: str, app, base_url: str, request) -> List:
def gbrowse_links(self, dataset: DatasetProtocol, type: str, app, base_url: str) -> List:
ret_val = []
seqid, start, stop = self.get_estimated_display_viewport(dataset)
if seqid is not None:
Expand All @@ -991,7 +995,7 @@ def gbrowse_links(self, dataset: DatasetProtocol, type: str, app, base_url: str,
if seqid.startswith("chr") and len(seqid) > 3:
seqid = seqid[3:]
redirect_url = quote_plus(f"{site_url}/?q={seqid}:{start}..{stop}&eurl=%s")
link = self._get_remote_call_url(redirect_url, site_name, dataset, type, app, base_url, request)
link = self._get_remote_call_url(redirect_url, site_name, dataset, type, app, base_url)
ret_val.append((site_name, link))
return ret_val

Expand Down Expand Up @@ -1371,7 +1375,7 @@ def get_estimated_display_viewport(
log.exception("Unexpected error")
return (None, None, None) # could not determine viewport

def gbrowse_links(self, dataset: DatasetProtocol, type: str, app, base_url: str, request) -> List:
def gbrowse_links(self, dataset: DatasetProtocol, type: str, app, base_url: str) -> List:
ret_val = []
chrom, start, stop = self.get_estimated_display_viewport(dataset)
if chrom is not None:
Expand All @@ -1380,11 +1384,11 @@ def gbrowse_links(self, dataset: DatasetProtocol, type: str, app, base_url: str,
if chrom.startswith("chr") and len(chrom) > 3:
chrom = chrom[3:]
redirect_url = quote_plus(f"{site_url}/?q={chrom}:{start}..{stop}&eurl=%s")
link = self._get_remote_call_url(redirect_url, site_name, dataset, type, app, base_url, request)
link = self._get_remote_call_url(redirect_url, site_name, dataset, type, app, base_url)
ret_val.append((site_name, link))
return ret_val

def ucsc_links(self, dataset: DatasetProtocol, type: str, app, base_url: str, request) -> List:
def ucsc_links(self, dataset: DatasetProtocol, type: str, app, base_url: str) -> List:
ret_val = []
chrom, start, stop = self.get_estimated_display_viewport(dataset)
if chrom is not None:
Expand All @@ -1393,7 +1397,7 @@ def ucsc_links(self, dataset: DatasetProtocol, type: str, app, base_url: str, re
redirect_url = quote_plus(
f"{site_url}db={dataset.dbkey}&position={chrom}:{start}-{stop}&hgt.customText=%s"
)
link = self._get_remote_call_url(redirect_url, site_name, dataset, type, app, base_url, request)
link = self._get_remote_call_url(redirect_url, site_name, dataset, type, app, base_url)
ret_val.append((site_name, link))
return ret_val

Expand Down Expand Up @@ -1553,18 +1557,18 @@ def get_estimated_display_viewport(
log.exception("Unexpected error")
return (None, None, None) # could not determine viewport

def ucsc_links(self, dataset: DatasetProtocol, type: str, app, base_url: str, request) -> List:
def ucsc_links(self, dataset: DatasetProtocol, type: str, app, base_url: str) -> List:
ret_val = []
chrom, start, stop = self.get_estimated_display_viewport(dataset)
if chrom is not None:
for site_name, site_url in app.datatypes_registry.get_legacy_sites_by_build("ucsc", dataset.dbkey):
if site_name in app.datatypes_registry.get_display_sites("ucsc"):
internal_url = f"{app.legacy_url_for(mapper=app.legacy_mapper, environ=request.environ, controller='dataset', dataset_id=dataset.id, action='display_at', filename='ucsc_' + site_name)}"
internal_url = f"{app.url_for(controller='dataset', dataset_id=dataset.id, action='display_at', filename='ucsc_' + site_name)}"
display_url = quote_plus(
"%s%s/display_as?id=%i&display_app=%s&authz_method=display_at"
% (
base_url,
app.legacy_url_for(mapper=app.legacy_mapper, environ=request.environ, controller="root"),
app.url_for(controller="root"),
dataset.id,
type,
)
Expand Down
5 changes: 4 additions & 1 deletion lib/galaxy/managers/hdas.py
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,10 @@ def serialize_old_display_applications(self, item, key, trans=None, **context):
display_link_fn = hda.datatype.get_display_links
for display_app in hda.datatype.get_display_types():
target_frame, display_links = display_link_fn(
hda, display_app, self.app, trans.request.base, request=trans.request
hda,
display_app,
self.app,
trans.request.base,
)

if len(display_links) > 0:
Expand Down
6 changes: 1 addition & 5 deletions lib/galaxy/web/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@
The Galaxy web application framework
"""

from .framework import (
legacy_url_for,
url_for,
)
from .framework import url_for
from .framework.base import httpexceptions
from .framework.decorators import (
do_not_cache,
Expand Down Expand Up @@ -48,6 +45,5 @@
"legacy_expose_api_raw_anonymous",
"require_admin",
"require_login",
"legacy_url_for",
"url_for",
)
18 changes: 0 additions & 18 deletions lib/galaxy/web/framework/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
"""
Galaxy web application framework
"""

from routes import request_config

from . import base

DEPRECATED_URL_ATTRIBUTE_MESSAGE = "*deprecated attribute, URL not filled in by server*"
Expand All @@ -21,19 +18,4 @@ def handle_url_for(*args, **kwargs) -> str:
return DEPRECATED_URL_ATTRIBUTE_MESSAGE


def legacy_url_for(mapper, *args, **kwargs) -> str:
"""
Re-establishes the mapper for legacy WSGI routes.
"""
rc = request_config()
environ = kwargs.pop("environ", None)
rc.mapper = mapper
if environ:
rc.environ = environ
if hasattr(rc, "using_request_local"):
rc.request_local = lambda: rc
rc = request_config()
return base.routes.url_for(*args, **kwargs)


url_for = handle_url_for
16 changes: 16 additions & 0 deletions lib/galaxy/webapps/galaxy/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@
from fastapi_utils.inferring_router import InferringRouter
from pydantic import ValidationError
from pydantic.main import BaseModel
from routes import (
Mapper,
request_config,
)
from starlette.datastructures import Headers
from starlette.routing import (
Match,
Expand Down Expand Up @@ -306,6 +310,15 @@ def get_current_history_from_session(galaxy_session: Optional[model.GalaxySessio
return None


def fix_url_for(mapper: Mapper, galaxy_request: GalaxyASGIRequest):
rc = request_config()
rc.environ = galaxy_request.environ
rc.mapper = mapper
if hasattr(rc, "using_request_local"):
rc.request_local = lambda: rc
rc = request_config()


def get_trans(
request: Request,
response: Response,
Expand All @@ -316,6 +329,9 @@ def get_trans(
url_builder = UrlBuilder(request)
galaxy_request = GalaxyASGIRequest(request)
galaxy_response = GalaxyASGIResponse(response)
mapper = getattr(app, "legacy_mapper", None)
if mapper:
fix_url_for(mapper, galaxy_request)
return SessionRequestContext(
app=app,
user=user,
Expand Down

0 comments on commit ea9e2fb

Please sign in to comment.