Skip mako for rendering tool help

Fixes

```
Traceback (most recent call last):
  File "galaxy/web/framework/decorators.py", line 340, in decorator
    rval = func(self, trans, *args, **kwargs)
  File "galaxy/webapps/galaxy/api/tools.py", line 446, in build
    return tool.to_json(trans, kwd.get("inputs", kwd), history=history)
  File "galaxy/tools/__init__.py", line 2945, in to_json
    tool_help = self.help.render(
  File "mako/template.py", line 434, in render
    return runtime._render(self, self.callable_, args, data)
  File "mako/runtime.py", line 874, in _render
    _render_context(
  File "mako/runtime.py", line 916, in _render_context
    _exec_template(inherit, lclcontext, args=args, kwargs=kwargs)
  File "mako/runtime.py", line 943, in _exec_template
    callable_(context, *args, **kwargs)
  File "memory:0x7fd82e70d0f0", line 22, in render_body
AttributeError: 'Undefined' object has no attribute 'name'
```
for https://github.com/galaxyproject/tools-iuc/blob/main/tools/teloscope/teloscope.xml#L220
This commit is contained in:
mvdbeek
2025-12-10 18:32:25 +01:00
parent ba7b28fd26
commit 534f60e927
3 changed files with 24 additions and 31 deletions
+16 -17
View File
@@ -25,7 +25,6 @@ from urllib.parse import unquote_plus
from uuid import UUID
import webob.exc
from mako.template import Template
from packaging.version import Version
from sqlalchemy import (
delete,
@@ -999,7 +998,6 @@ class Tool(UsesDictVisibleKeys, ToolParameterBundle):
tool_action: ToolAction
tool_type_local = False
dict_collection_visible_keys = ["id", "name", "version", "description", "labels"]
__help: Optional[Template]
job_search: "JobSearch"
version: str
@@ -1080,7 +1078,6 @@ class Tool(UsesDictVisibleKeys, ToolParameterBundle):
self.javascript_requirements: Optional[list[JavascriptRequirement]] = None
self.credentials: Optional[list[CredentialsRequirement]] = None
self._is_workflow_compatible = None
self.__help = None
self.__tests: Optional[str] = None
try:
self.parse(tool_source, guid=guid, dynamic=dynamic)
@@ -1947,20 +1944,24 @@ class Tool(UsesDictVisibleKeys, ToolParameterBundle):
)
@property
def help(self) -> Template:
def help_html(self) -> str:
"""Returns the help content converted from RST to HTML (without variable substitution)."""
help_content = self.raw_help
assert help_content
assert help_content.format == "restructuredtext"
try:
return Template(
rst_to_html(help_content.content),
input_encoding="utf-8",
default_filters=["decode.utf8"],
encoding_errors="replace",
)
return rst_to_html(help_content.content)
except Exception:
log.info("Exception while parsing help for tool with id '%s'", self.id)
return Template("", input_encoding="utf-8")
return ""
def render_help(self, static_path: str, host_url: str) -> str:
"""Renders the help HTML with variable substitution for static_path and host_url."""
help_html = self.help_html
# Replace Mako-style variables with actual values
help_html = help_html.replace("${static_path}", static_path)
help_html = help_html.replace("${host_url}", host_url)
return help_html
@property
def biotools_reference(self) -> Optional[str]:
@@ -2707,8 +2708,8 @@ class Tool(UsesDictVisibleKeys, ToolParameterBundle):
# Retrieve tool help images and rewrite the tool's xml into a temporary file with the path
# modified to be relative to the repository root.
image_found = False
if self.help is not None:
tool_help = self.help._source
if self.raw_help is not None and self.raw_help.format == "restructuredtext":
tool_help = self.help_html
# Check each line of the rendered tool help for an image tag that points to a location under static/
for help_line in tool_help.split("\n"):
image_regex = re.compile(r'img alt="[^"]+" src="\${static_path}/([^"]+)"')
@@ -2866,10 +2867,9 @@ class Tool(UsesDictVisibleKeys, ToolParameterBundle):
if help_content:
help_format = help_content.format
if help_format == "restructuredtext":
help_txt = self.help.render(
help_txt = self.render_help(
static_path=self.app.url_for("/static"), host_url=self.app.url_for("/", qualified=True)
)
help_txt = unicodify(help_txt)
tool_dict["help"] = help_txt
tool_dict["help_format"] = help_format
@@ -2942,10 +2942,9 @@ class Tool(UsesDictVisibleKeys, ToolParameterBundle):
tool_help = ""
tool_help_format = "restructuredtext"
if self.raw_help and self.raw_help.format == "restructuredtext":
tool_help = self.help.render(
tool_help = self.render_help(
static_path=self.app.url_for("/static"), host_url=self.app.url_for("/", qualified=True)
)
tool_help = unicodify(tool_help, "utf-8")
elif self.raw_help:
tool_help = self.raw_help.content
tool_help_format = self.raw_help.format
+1 -1
View File
@@ -2065,7 +2065,7 @@ class ToolModule(WorkflowModule):
if self.tool and self.tool.raw_help and self.tool.raw_help.format == "restructuredtext":
host_url = self.trans.url_builder("/")
static_path = self.trans.url_builder(static_path) if static_path else ""
return self.tool.help.render(host_url=host_url, static_path=static_path)
return self.tool.render_help(host_url=host_url, static_path=static_path)
# ---- Configuration time -----------------------------------------------
@@ -106,20 +106,14 @@
</form>
</div>
</div>
%if tool.help:
<div class="toolHelp">
<div class="toolHelpBody">
<%
tool_help = tool.help
# Help is Mako template, so render using current static path.
tool_help = tool_help.render( static_path=h.url_for( '/static' ) )
# Convert to unicode to display non-ascii characters.
tool_help = util.unicodify( tool_help, 'utf-8')
%>
${tool_help}
</div>
<div class="toolHelp">
<div class="toolHelpBody">
<%
tool_help = tool.render_help( host_url=h.url_for( '/' ), static_path=h.url_for( '/static' ) )
%>
${tool_help}
</div>
%endif
</div>
%else:
Tool not properly loaded.
%endif