Merge pull request #17497 from mvdbeek/provide_working_url_for_to_every_request

[23.2] Provide working routes.url_for every ASGI request
This commit is contained in:
Marius van den Beek
2024-02-20 15:43:55 +01:00
committed by GitHub
10 changed files with 52 additions and 61 deletions
+1 -5
View File
@@ -138,10 +138,7 @@ from galaxy.util.tool_shed import tool_shed_registry
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 (
@@ -798,7 +795,6 @@ class UniverseApplication(StructuredApp, GalaxyManagerApplication):
# 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
+2 -2
View File
@@ -783,7 +783,7 @@ class Data(metaclass=DataMeta):
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
@@ -794,7 +794,7 @@ class Data(metaclass=DataMeta):
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(
@@ -53,8 +53,7 @@ class DisplayApplicationLink:
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,
@@ -62,7 +61,6 @@ class DisplayApplicationLink:
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):
@@ -274,8 +274,7 @@ class DisplayParameterValueWrapper:
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,
@@ -284,7 +283,6 @@ class DisplayParameterValueWrapper:
link_name=quote_plus(self.parameter.link.id),
app_action=self.action_name,
action_param=self._url,
environ=self.trans.request.environ,
),
)
+3 -5
View File
@@ -90,7 +90,7 @@ class GenomeGraphs(Tabular):
"""
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 angie@soe.ucsc.edu
a genome graphs call looks like this
@@ -114,9 +114,7 @@ class GenomeGraphs(Tabular):
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",
@@ -124,7 +122,7 @@ class GenomeGraphs(Tabular):
)
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,
)
+23 -19
View File
@@ -315,7 +315,7 @@ class Interval(Tabular):
},
)
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.
@@ -337,9 +337,7 @@ class Interval(Tabular):
# 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",
@@ -349,7 +347,7 @@ class Interval(Tabular):
"%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,
)
@@ -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,
)
@@ -969,7 +973,7 @@ class Gff(Tabular, _RemoteCallMixin):
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:
@@ -978,11 +982,11 @@ class Gff(Tabular, _RemoteCallMixin):
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:
@@ -991,7 +995,7 @@ class Gff(Tabular, _RemoteCallMixin):
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
@@ -1371,7 +1375,7 @@ class Wiggle(Tabular, _RemoteCallMixin):
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:
@@ -1380,11 +1384,11 @@ class Wiggle(Tabular, _RemoteCallMixin):
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:
@@ -1393,7 +1397,7 @@ class Wiggle(Tabular, _RemoteCallMixin):
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
@@ -1553,18 +1557,18 @@ class CustomTrack(Tabular):
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,
)
+4 -1
View File
@@ -642,7 +642,10 @@ class HDASerializer( # datasets._UnflattenedMetadataDatasetAssociationSerialize
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:
+1 -5
View File
@@ -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,
@@ -48,6 +45,5 @@ __all__ = (
"legacy_expose_api_raw_anonymous",
"require_admin",
"require_login",
"legacy_url_for",
"url_for",
)
-18
View File
@@ -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*"
@@ -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
View File
@@ -41,6 +41,10 @@ from fastapi_utils.cbv import cbv
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,
@@ -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,
@@ -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,