Warning

This document is for an old release of Galaxy. You can alternatively view this page in the latest release if it exists or view the top of the latest release's documentation.

Source code for galaxy.webapps.galaxy.controllers.tool_runner

"""
Controller handles external tool related requests
"""

import logging

from markupsafe import escape

import galaxy.util
from galaxy import web
from galaxy.tools import DataSourceTool
from galaxy.web import (
    error,
    url_for,
)
from galaxy.webapps.base.controller import BaseUIController

log = logging.getLogger(__name__)


[docs]class ToolRunner(BaseUIController): # Hack to get biomart to work, ideally, we could pass tool_id to biomart and receive it back
[docs] @web.expose def biomart(self, trans, tool_id="biomart", **kwd): """Catches the tool id and redirects as needed""" return self.index(trans, tool_id=tool_id, **kwd)
# test to get hapmap to work, ideally, we could pass tool_id to hapmap biomart and receive it back
[docs] @web.expose def hapmapmart(self, trans, tool_id="hapmapmart", **kwd): """Catches the tool id and redirects as needed""" return self.index(trans, tool_id=tool_id, **kwd)
[docs] @web.expose def default(self, trans, tool_id=None, **kwd): """Catches the tool id and redirects as needed""" return self.index(trans, tool_id=tool_id, **kwd)
def __get_tool(self, tool_id, tool_version=None, get_loaded_tools_by_lineage=False, set_selected=False): tool_version_select_field, tools, tool = self.get_toolbox().get_tool_components( tool_id, tool_version, get_loaded_tools_by_lineage, set_selected ) return tool
[docs] @web.expose def index(self, trans, tool_id=None, from_noframe=None, **kwd): def __tool_404__(): log.debug("index called with tool id '%s' but no such tool exists", tool_id) trans.log_event("Tool id '%s' does not exist" % tool_id) trans.response.status = 404 return trans.show_error_message("Tool '%s' does not exist." % (escape(tool_id))) # tool id not available, redirect to main page if tool_id is None: return trans.response.send_redirect(url_for(controller="root", action="welcome")) tool = self.__get_tool(tool_id) # tool id is not matching, display an error if not tool: return __tool_404__() if tool.require_login and not trans.user: redirect = url_for(controller="tool_runner", action="index", tool_id=tool_id, **kwd) return trans.response.send_redirect( url_for( controller="user", action="login", cntrller="user", status="info", message="You must be logged in to use this tool.", redirect=redirect, ) ) if not tool.allow_user_access(trans.user): return __tool_404__() # FIXME: Tool class should define behavior if tool.tool_type in ["default", "interactivetool"]: return trans.response.send_redirect(url_for(controller="root", tool_id=tool_id)) # execute tool without displaying form # (used for datasource tools, but note that data_source_async tools # are handled separately by the async controller) params = galaxy.util.Params(kwd, sanitize=False).__dict__ if tool.input_translator: # perform test translation of the incoming params without affecting originals # the actual translation will happen later # this is only for checking if we end up with required parameters test_params = params.copy() tool.input_translator.translate(test_params) else: test_params = params if tool.tool_type == "data_source": if "URL" not in test_params: error("Execution of `data_source` tools requires a `URL` parameter") # preserve original params sent by the remote server as extra dict # before in-place translation happens, then clean the incoming params params.update({"incoming_request_params": params.copy()}) if tool.input_translator and tool.wants_params_cleaned: for k in list(params.keys()): if k not in tool.input_translator.vocabulary and k not in ("URL", "incoming_request_params"): # the remote server has sent a param # that the tool is not expecting -> drop it del params[k] else: if "runtool_btn" not in test_params: error("Tool execution through the `tool_runner` requires a `runtool_btn` flag") # We may be visiting Galaxy for the first time ( e.g., sending data from UCSC ), # so make sure to create a new history if we've never had one before. history = tool.get_default_history_by_trans(trans, create=True) try: vars = tool.handle_input(trans, params, history=history) except Exception as e: error(galaxy.util.unicodify(e)) if len(params) > 0: trans.log_event(f"Tool params: {str(params)}", tool_id=tool_id) return trans.fill_template("root/tool_runner.mako", **vars)
[docs] @web.expose def rerun(self, trans, id=None, job_id=None, **kwd): """ Given a HistoryDatasetAssociation id, find the job and that created the dataset, extract the parameters, and display the appropriate tool form with parameters already filled in. """ if job_id is None: if not id: error("'id' parameter is required") try: id = int(id) except ValueError: # it's not an un-encoded id, try to parse as encoded try: id = trans.security.decode_id(id) except Exception: error("Invalid value for 'id' parameter") # Get the dataset object data = trans.sa_session.query(trans.app.model.HistoryDatasetAssociation).get(id) # only allow rerunning if user is allowed access to the dataset. if not ( trans.user_is_admin or trans.app.security_agent.can_access_dataset(trans.get_current_user_roles(), data.dataset) ): error("You are not allowed to access this dataset") # Get the associated job, if any. job = data.creating_job if job: job_id = trans.security.encode_id(job.id) else: raise Exception("Failed to get job information for dataset hid %d" % data.hid) return trans.response.send_redirect(url_for(controller="root", job_id=job_id))
[docs] @web.expose def data_source_redirect(self, trans, tool_id=None): """ Redirects a user accessing a Data Source tool to its target action link. This method will subvert mix-mode content blocking in several browsers when accessing non-https data_source tools from an https galaxy server. Tested as working on Safari 7.0 and FireFox 26 Subverting did not work on Chrome 31 """ if tool_id is None: return trans.response.send_redirect(url_for(controller="root", action="welcome")) tool = self.__get_tool(tool_id) # No tool matching the tool id, display an error (shouldn't happen) if not tool: log.error("data_source_redirect called with tool id '%s' but no such tool exists", tool_id) trans.log_event(f"Tool id '{tool_id}' does not exist") trans.response.status = 404 return trans.show_error_message(f"Tool '{escape(tool_id)}' does not exist.") if isinstance(tool, DataSourceTool): link = url_for(tool.action, **tool.get_static_param_values(trans)) else: link = url_for(controller="tool_runner", tool_id=tool.id) return trans.response.send_redirect(link)