Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion client/src/components/Tool/ToolSourceSchema.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lib/galaxy/dependencies/conditional-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ ldap3==2.9.1
python-pam
galaxycloudrunner
pkce
total-perspective-vortex>=2.3.2,<3
total-perspective-vortex>=3.1.0,<4
openai
# upper version constraint because of https://github.com/galaxyproject/galaxy/issues/20600
redis>=5.3.0,<6
Expand Down
7 changes: 7 additions & 0 deletions lib/galaxy/dependencies/dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ boto3==1.40.18
botocore==1.40.18
build==1.3.0
cachecontrol==0.14.3
cachetools==5.5.2
cattrs==25.2.0
certifi==2025.8.3
cffi==2.0.0 ; (implementation_name != 'pypy' and os_name == 'nt') or platform_python_implementation != 'PyPy'
Expand Down Expand Up @@ -90,6 +91,7 @@ mistune==3.0.2
more-itertools==10.8.0 ; platform_machine != 'ppc64le' and platform_machine != 's390x'
msgpack==1.1.1
multidict==6.6.4
mypy==1.18.2
mypy-extensions==1.1.0
myst-parser==3.0.1 ; python_full_version < '3.10'
myst-parser==4.0.1 ; python_full_version >= '3.10'
Expand Down Expand Up @@ -197,11 +199,16 @@ text-unidecode==1.3
tinydb==4.8.2
toml==0.10.2
tomli==2.2.1 ; python_full_version <= '3.11'
total-perspective-vortex==3.1.0
trio==0.30.0
trio-websocket==0.12.2
tuspy==1.1.0
twill==3.3.1
twine==6.2.0
types-cachetools==6.2.0.20250827
types-requests==2.31.0.6 ; python_full_version < '3.10'
types-requests==2.32.4.20250913 ; python_full_version >= '3.10'
types-urllib3==1.26.25.14 ; python_full_version < '3.10'
typing-extensions==4.14.1
tzdata==2025.2 ; sys_platform == 'win32'
url-normalize==2.2.1
Expand Down
3 changes: 2 additions & 1 deletion lib/galaxy/dependencies/pinned-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ mypy-extensions==1.1.0
networkx==3.2.1 ; python_full_version < '3.10'
networkx==3.4.2 ; python_full_version == '3.10.*'
networkx==3.5 ; python_full_version >= '3.11'
nodejs-wheel==22.13.0
nodejs-wheel==22.20.0
nodejs-wheel-binaries==22.20.0
numpy==2.0.2 ; python_full_version < '3.10'
numpy==2.2.6 ; python_full_version == '3.10.*'
numpy==2.3.3 ; python_full_version >= '3.11'
Expand Down
8 changes: 8 additions & 0 deletions lib/galaxy/dependencies/pinned-test-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ backports-asyncio-runner==1.2.0 ; python_full_version < '3.11'
boto3==1.40.18
botocore==1.40.18
cachecontrol==0.14.3
cachetools==5.5.2
cattrs==25.2.0
certifi==2025.8.3
cffi==2.0.0 ; implementation_name != 'pypy' and os_name == 'nt'
Expand Down Expand Up @@ -66,6 +67,7 @@ mirakuru==2.6.1
mistune==3.0.2
msgpack==1.1.1
multidict==6.6.4
mypy==1.18.2
mypy-extensions==1.1.0
numpy==2.0.2 ; python_full_version < '3.10'
numpy==2.2.6 ; python_full_version == '3.10.*'
Expand All @@ -76,6 +78,7 @@ owlrl==6.0.2 ; python_full_version < '3.10'
owlrl==7.1.4 ; python_full_version >= '3.10'
packaging==24.2 ; python_full_version < '3.10'
packaging==25.0 ; python_full_version >= '3.10'
pathspec==0.12.1
pfzy==0.3.4
pillow==11.3.0
pkce==1.0.3
Expand Down Expand Up @@ -145,10 +148,15 @@ text-unidecode==1.3
tinydb==4.8.2
toml==0.10.2
tomli==2.2.1 ; python_full_version <= '3.11'
total-perspective-vortex==3.1.0
trio==0.30.0
trio-websocket==0.12.2
tuspy==1.1.0
twill==3.3.1
types-cachetools==6.2.0.20250827
types-requests==2.31.0.6 ; python_full_version < '3.10'
types-requests==2.32.4.20250913 ; python_full_version >= '3.10'
types-urllib3==1.26.25.14 ; python_full_version < '3.10'
typing-extensions==4.14.1
tzdata==2025.2 ; sys_platform == 'win32'
url-normalize==2.2.1
Expand Down
4 changes: 3 additions & 1 deletion lib/galaxy/tool_util/deps/requirements.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,9 @@ def resource_requirements_from_list(requirements: Iterable[Dict[str, Any]]) -> L
for key in valid_key_set.intersection(set(r.keys())):
value = r[key]
key = cast(ResourceType, cwl_to_galaxy.get(key, key))
rr.append(ResourceRequirement(value_or_expression=value, resource_type=key))
if value is not None:
# all resoure requirement fields are optional
rr.append(ResourceRequirement(value_or_expression=value, resource_type=key))
return rr


Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ dependencies = [
"mercurial>=6.8.2", # Python 3.13 support
"mrcfile",
"msal",
"nodejs-wheel==22",
"nodejs-wheel>=22,<23",
"numpy>=1.26.0", # Python 3.12 support
"numpy>=2.1.0 ; python_version>='3.10'", # Python 3.13 support
"openpyxl>=3.1.5", # Minimum version ever tested with
Expand Down Expand Up @@ -146,6 +146,7 @@ test = [
"seletools",
"statsd",
"testfixtures",
"total-perspective-vortex>=3.1.0,<4", # https://github.com/galaxyproject/total-perspective-vortex/pull/166
"tuspy",
"twill>=3.2.5", # Python 3.13 support
"watchdog",
Expand Down
44 changes: 44 additions & 0 deletions test/integration/embedded_pulsar_tpv_job_conf.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
runners:
local:
load: galaxy.jobs.runners.local:LocalJobRunner
pulsar_embed:
load: galaxy.jobs.runners.pulsar:PulsarEmbeddedJobRunner
pulsar_app_config: # this doesn't start without disabling - filelock problem
tool_dependency_dir: none
conda_auto_init: false
conda_auto_install: false

execution:
default: tpv
environments:
tpv:
runner: dynamic_tpv
tpv_configs:
- destinations:
local:
runner: local
env:
GALAXY_SLOTS: '{cores}'
user_defined:
runner: pulsar_embed
env:
GALAXY_SLOTS: '{cores}'
scheduling:
accept:
- support_user_defined
params:
remote_metadata: true
docker_enabled: true
require_container: true
docker_net: "none"
global:
default_inherits: default

tools:
default:
abstract: true
cores: 1
user_defined-*:
scheduling:
require:
- support_user_defined
52 changes: 51 additions & 1 deletion test/integration/test_user_defined_tool_job_conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import os

import yaml

from galaxy.tool_util_models import UserToolSource
from galaxy_test.api.test_tools import TestsTools
from galaxy_test.base.populators import (
Expand All @@ -12,18 +14,39 @@

SCRIPT_DIRECTORY = os.path.abspath(os.path.dirname(__file__))
EMBEDDED_PULSAR_JOB_CONFIG_FILE = os.path.join(SCRIPT_DIRECTORY, "embedded_pulsar_job_conf.yml")
EMBEDDED_PULSAR_TPV_JOB_CONFIG_FILE = os.path.join(SCRIPT_DIRECTORY, "embedded_pulsar_tpv_job_conf.yml")
TOOL_WITH_RESOURCE_SPECIFICATION = yaml.safe_load(
"""class: GalaxyUserTool
id: resource_requirement
version: "0.1"
name: resource_requirement
description: test resource requirement
container: busybox
requirements:
- type: resource
cores_min: 2
shell_command: |
echo $GALAXY_SLOTS > galaxy_cores.txt
outputs:
- name: output2
type: data
format: txt
from_work_dir: galaxy_cores.txt
"""
)


class TestUserDefinedToolRecommendedJobSetup(integration_util.IntegrationTestCase, TestsTools):
"""Exercies how user defined tools could be run in production."""

framework_tool_and_types = True
job_config_file = EMBEDDED_PULSAR_JOB_CONFIG_FILE
dataset_populator: DatasetPopulator

@classmethod
def handle_galaxy_config_kwds(cls, config):
super().handle_galaxy_config_kwds(config)
config["job_config_file"] = EMBEDDED_PULSAR_JOB_CONFIG_FILE
config["job_config_file"] = cls.job_config_file
config["enable_celery_tasks"] = False
config["metadata_strategy"] = "directory"
config["admin_users"] = "[email protected]"
Expand Down Expand Up @@ -57,3 +80,30 @@ def test_user_defined_runs_in_correct_destination(self):

assert destination_params["Runner"] == "pulsar_embed"
assert destination_params["require_container"]


class TestUserDefinedToolRecommendedJobSetupTPV(TestUserDefinedToolRecommendedJobSetup):

job_config_file = EMBEDDED_PULSAR_TPV_JOB_CONFIG_FILE

def test_user_defined_applies_resource_requirements(self):
with (
self.dataset_populator.test_history() as history_id,
self.dataset_populator.user_tool_execute_permissions(),
):
# Create a new dynamic tool.
# This is a shell command tool that will echo the input dataset.
dynamic_tool = self.dataset_populator.create_unprivileged_tool(
UserToolSource(**TOOL_WITH_RESOURCE_SPECIFICATION)
)
# Run tool.
response = self._run(
history_id=history_id,
tool_uuid=dynamic_tool["uuid"],
inputs={},
wait_for_job=True,
assert_ok=True,
)
cores = response["outputs"][0]
cores_content = self.dataset_populator.get_history_dataset_content(history_id, content_id=cores["id"])
assert cores_content == "2.0\n"
Loading