Authoring User-Defined Tools

Create a Galaxy tool from a containerized command without waiting for an administrator to install it. Define its inputs and outputs here, then run it like any other tool.

Getting Started

Quick start

Paste this definition into the editor. It accepts a text dataset and writes a copy without lines beginning with #.

class: GalaxyUserTool
id: remove_comments
name: Remove Comment Lines
version: 0.1.0
description: from a text file
container: quay.io/biocontainers/grep:3.4--hf43ccf4_4
shell_command: grep -v '^#' '$(inputs.input_file.path)' > output.txt || test "$?" = 1
inputs:
  - name: input_file
    type: data
    format:
      - txt
outputs:
  - name: output_file
    type: data
    format_source: input_file
    from_work_dir: output.txt

Reference

Tool definition

A user-defined tool is a YAML document. class: GalaxyUserTool selects the user-defined tool format. container # selects a container image containing the program and everything it needs to run. shell_command # supplies the command line Galaxy runs inside that image, with inputs referenced as $(inputs.input_name) for scalar values and $(inputs.input_name.path) for files.

Field

Details

Required

class #

Selects the user-defined tool format. Must be GalaxyUserTool.

Yes

id

Stable lowercase identifier. Must start with a letter and may contain letters, digits, _, and -.

No

name

Name displayed in the tool menu.

Yes

version

Version of this wrapper. Change it when behavior or the container changes.

Yes

description

Short text displayed after the tool name.

No

container #

Fully qualified image supplying the program, interpreters, libraries, and utilities the tool needs.

Yes

shell_command #

Command line Galaxy evaluates and runs in the selected image, with inputs referenced through expressions.

Yes

configfiles #

Scripts and configuration files required by the software you are wrapping.

No

inputs #

Input parameters shown on the tool form.

No

outputs #

Datasets and collections Galaxy claims after the command finishes.

No

requirements #

JavaScript helpers and compute-resource requests.

No

help #

Longer help text shown below the tool form.

No

tests #

Tool test declarations.

No

citations #, license #, edam_operations #, edam_topics #, xrefs #

Publication and ontology metadata.

No

profile #

Galaxy tool profile controlling versioned tool behavior.

No

Compared with an equivalent Galaxy XML tool, three things differ:

  • class: GalaxyUserTool is required.

  • A top-level container # is required. XML tools may instead resolve dependencies through Conda.

  • The command lives under shell_command # and is templated with sandboxed JavaScript expressions rather than Cheetah, so it has no access to the Galaxy database or filesystem.

Every output must say where its bytes come from: a data output needs from_work_dir or discover_datasets #, and a collection output needs discover_datasets #. An output that declares neither is rejected, because nothing would ever be claimed from the working directory.

Config files

Use configfiles # for scripts and configuration files required by the software you are wrapping. Galaxy writes each file into the job working directory before it runs shell_command #. File content supports the same sandboxed ECMAScript expressions as the command.

Field

Details

Default

Required

filename

Name of the file in the job working directory.

No

content

File contents, including any input expressions.

Yes

name

Internal name for the config file.

No

eval_engine

Template engine; user-defined tools use ecmascript.

ecmascript

No

configfiles:
  - filename: message.txt
    content: |
      Selected motif: $(inputs.motif)
shell_command: cat message.txt

Input parameters

User-defined tools support the input types listed below. Unknown and unsupported fields are rejected.

Parameter type

Details

boolean #

A true-or-false input.

color #

A color-picker input.

conditional #

A control input that selects which nested inputs are displayed and supplied to the command.

data #

One dataset, or a list of datasets when multiple is true.

data_collection #

A dataset collection input.

float #

A numeric input with optional bounds and validators.

integer #

A whole-number input with optional bounds and validators.

repeat #

A group the user may add multiple times, with parameters defining one repeated entry.

section #

Related inputs that users can expand or collapse to reduce form complexity.

select #

A choice from a fixed list of options.

text #

A single-line or multiline text input.

Each type below has its own field table and example.

For data inputs, format lists accepted Galaxy datatype extensions. See the Datatypes page in your Galaxy instance for the extensions available there.

Types that exist in the XML tool vocabulary but are rejected here: hidden, drill_down, data_column, genomebuild, group_tag, baseurl, rules, directory. XML-only fields such as truevalue, falsevalue, argument, is_dynamic and parameter_type are likewise rejected on any parameter.

Validators

Validators reject parameter values before a job starts. Each parameter type’s field table lists the validators it supports.

Validator type

Details

empty_field #

Require a value that is neither an empty string nor null.

in_range #

Require a numeric value to fall within optional lower and upper bounds.

length #

Require the number of characters in a text value to fall within optional bounds.

no_options #

Require a select parameter to have at least one available option.

regex #

Require a regular expression to match from the start of the value.

Outputs

Each output declares a type and a name. Dataset outputs identify the produced file with from_work_dir; collection outputs use discover_datasets #.

Output type

Details

collection #

A user-defined tool collection populated only by matching produced filenames.

data #

A user-defined tool dataset discovered only from files inside the job working directory.

Each type below has a field table and example.

Tool help

Tool help is rendered below the input form. Declare its format and content together.

Field

Details

Required

format

One of markdown, restructuredtext, or plain_text.

Yes

content

Help shown to the user.

Yes

help:
  format: markdown
  content: |
    Finds lines containing the selected motif.

Citations and metadata

Use citations # for publications describing the wrapped tool, license # for the wrapper license, EDAM identifiers for topics and operations, and xrefs # for identifiers in other registries.

citations:
  - type: doi
    content: 10.1093/bioinformatics/bts611
license: MIT
edam_topics:
  - topic_0102
edam_operations:
  - operation_0308
xrefs:
  - type: bio.tools
    value: example_tool

Expression syntax

shell_command # is not handed to the shell unchanged. Galaxy first evaluates it with a sandboxed ECMAScript 5.1 engine, using the same parameter-reference syntax CWL uses, and only the evaluated result is written into the job script.

Form

Details

Example

$( ... )

Parameter reference or single expression.

$(inputs.num_lines), $(inputs.query.path)

${ ... }

Function body that must return a value.

${ return inputs.num_lines * 2 }

Substituted values are inserted literally; Galaxy does not shell-quote them. Quote any substitution that can contain spaces yourself, as '$(inputs.query.path)'.

Reusable helper functions can be declared with a javascript requirement, and are then available to every expression in the tool:

requirements:
  - type: javascript
    expression_lib:
      - |
        function basename(path) { return path.split('/').pop(); }

Resource requirements

Declare compute needs with a resource entry under requirements #:

requirements:
  - type: resource
    cores_min: 32
    ram_min: 8192
    cuda_device_count_min: 1
    cuda_device_count_max: 1
    gpu_memory_min: 40960

Field

Details

Required

type

Selects a resource requirement. Must be resource.

Yes

cores_min, cores_max

Minimum and maximum reserved CPU cores. Fractional values are allowed.

No

ram_min, ram_max

Minimum and maximum reserved RAM in MiB.

No

tmpdir_min, tmpdir_max

Minimum and maximum temporary-directory space in MiB.

No

cuda_version_min

Minimum required CUDA runtime version.

No

cuda_compute_capability

Minimum required CUDA compute capability.

No

gpu_memory_min

Minimum required GPU memory in MiB.

No

cuda_device_count_min, cuda_device_count_max

Minimum and maximum number of GPUs to reserve.

No

shm_size

Requested /dev/shm size in bytes.

No

timelimit

Maximum runtime in seconds. Galaxy terminates the job if it is exceeded.

No

Pass $GALAXY_SLOTS to threaded programs; Galaxy sets it to the number of CPU cores allocated to the job.

Use numbers or numeric strings. Other strings are reserved for runtime expressions, which are not supported yet: a non-numeric value such as 2g fails the create-time lint check (ResourceRequirementExpression), so the tool cannot be saved until it is corrected.

API endpoints

This editor is a client of a small API, so tools can also be created and managed programmatically, which is useful when registering many tools or many versions of one tool. All of these endpoints require the Custom Tool Execution role and operate only on the calling user’s own tools.

Endpoint

Purpose

POST /api/unprivileged_tools

Create a tool; returns its uuid.

GET /api/unprivileged_tools

List the calling user’s tools.

GET /api/unprivileged_tools/{uuid}

Show one tool and its representation.

DELETE /api/unprivileged_tools/{uuid}

Deactivate a tool.

POST /api/unprivileged_tools/build?history_id=...

Render the tool form without saving the tool.

POST /api/unprivileged_tools/runtime_model

Return an OpenAPI model of the tool’s inputs.

The create payload wraps the YAML document, converted to JSON, in a representation key. Keeping it in a file avoids complex shell quoting for shell_command #:

{
  "representation": {
    "class": "GalaxyUserTool",
    "id": "my-cool-tool",
    "name": "My Cool Tool",
    "version": "0.1.0",
    "container": "quay.io/biocontainers/python:3.13",
    "shell_command": "head -n '$(inputs.n_lines)' '$(inputs.data_input.path)' > out.txt",
    "inputs": [
      {"type": "integer", "name": "n_lines"},
      {"type": "data", "name": "data_input"}
    ],
    "outputs": [
      {"type": "data", "name": "out", "from_work_dir": "out.txt"}
    ]
  }
}
$ curl -X POST "$GALAXY_URL/api/unprivileged_tools" \
    -H "x-api-key: $GALAXY_API_KEY" \
    -H 'Content-Type: application/json' \
    -d @tool.json

Run the resulting tool by passing its uuid to the normal tool execution endpoint: POST /api/tools with tool_uuid instead of tool_id.

Your server publishes the request and response details at <galaxy_url>/api/docs under the dynamic_tools tag.

Detailed reference

Input parameter types

Field tables and examples for every input type supported by user-defined tools.

boolean parameter

A true-or-false input.

Field

Details

Default

Required

name

Identifier used to read this input from shell_command # and other expressions.

Yes

label

Label shown for the input on the tool form.

null

No

help #

Additional guidance shown on the tool form to help users choose a value.

null

No

optional

Set true when the command can run without the user supplying this input.

false

No

type

Presents a true-or-false choice and supplies the selected Boolean value to expressions.

Yes

value

Initial choice shown when the user first opens the tool form.

false

No

Add this boolean parameter under inputs #:

inputs:
  - label: Include a header line
    name: include_header
    type: boolean
    value: true

Use the parameter in shell_command # like this:

shell_command: |
  include_header="$(inputs.include_header)"

color parameter

A color-picker input.

Field

Details

Default

Required

name

Identifier used to read this input from shell_command # and other expressions.

Yes

label

Label shown for the input on the tool form.

null

No

help #

Additional guidance shown on the tool form to help users choose a value.

null

No

optional

Set true when the command can run without the user supplying this input.

false

No

type

Presents a color picker and supplies the selected hexadecimal color string.

Yes

value

Color initially selected in the picker, written in hexadecimal notation.

null

No

Add this color parameter under inputs #:

inputs:
  - label: Plot color
    name: plot_color
    type: color
    value: '#3366cc'

Use the parameter in shell_command # like this:

shell_command: |
  plot_color="$(inputs.plot_color)"

conditional parameter

A control input that selects which nested inputs are displayed and supplied to the command.

Field

Details

Default

Required

name

Identifier used to read this input from shell_command # and other expressions.

Yes

label

Label shown for the input on the tool form.

null

No

help #

Additional guidance shown on the tool form to help users choose a value.

null

No

optional

Set true when the command can run without the user supplying this input.

false

No

type

Shows one set of nested inputs at a time according to a Boolean or select control.

Yes

test_parameter

Boolean or select input whose submitted value chooses the active whens branch.

Yes

whens

Maps each control value to the nested parameters shown and supplied for that branch.

Yes

Add this conditional parameter under inputs #:

inputs:
  - name: search_options
    test_parameter:
      label: Search mode
      name: mode
      options:
      - label: Fast
        selected: true
        value: fast
      - label: Sensitive
        selected: false
        value: sensitive
      type: select
    type: conditional
    whens:
    - discriminator: fast
      parameters: []
    - discriminator: sensitive
      parameters:
      - name: iterations
        type: integer
        value: 3

Use the parameter in shell_command # like this:

shell_command: |
  mode="$(inputs.search_options.mode)"
  iterations="$(inputs.search_options.iterations)"

data parameter

One dataset, or a list of datasets when multiple is true.

Field

Details

Default

Required

name

Identifier used to read this input from shell_command # and other expressions.

Yes

label

Label shown for the input on the tool form.

null

No

help #

Additional guidance shown on the tool form to help users choose a value.

null

No

optional

Set true when the command can run without the user supplying this input.

false

No

type

Lets the user select history datasets and exposes their paths and metadata to expressions.

Yes

format

Limits selectable datasets to these Galaxy datatype extensions.

["data"]

No

multiple

Set true to accept several datasets (a list) for this input instead of one.

false

No

Add this data parameter under inputs #:

inputs:
  - format:
    - txt
    - tabular
    label: Input file
    name: input_file
    type: data

Use the parameter in shell_command # like this:

shell_command: |
  input_file='$(inputs.input_file.path)'

data_collection parameter

A dataset collection input.

Field

Details

Default

Required

name

Identifier used to read this input from shell_command # and other expressions.

Yes

label

Label shown for the input on the tool form.

null

No

help #

Additional guidance shown on the tool form to help users choose a value.

null

No

optional

Set true when the command can run without the user supplying this input.

false

No

type

Lets the user select a history collection and exposes its elements to expressions.

Yes

collection_type

Limits selectable collections to this structure, such as list or paired.

null

No

format

Requires every selectable collection element to use one of these datatype extensions.

["data"]

No

Add this data_collection parameter under inputs #:

inputs:
  - collection_type: paired
    format:
    - fastqsanger
    label: Paired reads
    name: reads
    type: data_collection

Use the parameter in shell_command # like this:

shell_command: |
  forward='$(inputs.reads.elements.forward.path)'
  reverse='$(inputs.reads.elements.reverse.path)'

float parameter

A numeric input with optional bounds and validators.

Field

Details

Default

Required

name

Identifier used to read this input from shell_command # and other expressions.

Yes

label

Label shown for the input on the tool form.

null

No

help #

Additional guidance shown on the tool form to help users choose a value.

null

No

optional

Set true when the command can run without the user supplying this input.

false

No

type

Accepts a number, including decimal values, and supplies it to expressions.

Yes

value

Number prefilled when the user first opens the tool form.

null

No

min

Rejects submitted values smaller than this inclusive lower bound.

null

No

max

Rejects submitted values larger than this inclusive upper bound.

null

No

validators #

Additional validation rules; supports in_range.

[]

No

Add this float parameter under inputs #:

inputs:
  - label: Score threshold
    max: 1.0
    min: 0.0
    name: threshold
    type: float
    value: 0.5

Use the parameter in shell_command # like this:

shell_command: |
  threshold="$(inputs.threshold)"

integer parameter

A whole-number input with optional bounds and validators.

Field

Details

Default

Required

name

Identifier used to read this input from shell_command # and other expressions.

Yes

label

Label shown for the input on the tool form.

null

No

help #

Additional guidance shown on the tool form to help users choose a value.

null

No

optional

Set true when the command can run without the user supplying this input.

false

No

type

Accepts a whole number and supplies it as a numeric value to expressions.

Yes

value

Number prefilled when the user first opens the tool form.

null

No

min

Rejects submitted values smaller than this inclusive lower bound.

null

No

max

Rejects submitted values larger than this inclusive upper bound.

null

No

validators #

Additional validation rules; supports in_range.

[]

No

Add this integer parameter under inputs #:

inputs:
  - label: Number of lines
    max: 1000
    min: 1
    name: num_lines
    type: integer
    value: 10

Use the parameter in shell_command # like this:

shell_command: |
  num_lines="$(inputs.num_lines)"

repeat parameter

A group the user may add multiple times, with parameters defining one repeated entry.

Field

Details

Default

Required

name

Identifier used to read this input from shell_command # and other expressions.

Yes

label

Label shown for the input on the tool form.

null

No

help #

Additional guidance shown on the tool form to help users choose a value.

null

No

optional

Set true when the command can run without the user supplying this input.

false

No

type

Lets the user add multiple entries that all contain the same nested inputs.

Yes

parameters

Nested inputs that make up one entry in the repeated group.

[]

No

min

Keeps at least this many entries in the group and creates them when the form opens.

null

No

max

Prevents the user from adding more than this many entries.

null

No

Add this repeat parameter under inputs #:

inputs:
  - label: Additional files
    max: 3
    min: 0
    name: extra_files
    parameters:
    - format:
      - txt
      name: input_file
      type: data
    type: repeat

Use the parameter in shell_command # like this:

shell_command: |
  files='$(inputs.extra_files.map((item) => item.input_file.path).join(" "))'

section parameter

Related inputs that users can expand or collapse to reduce form complexity.

Field

Details

Default

Required

name

Identifier used to read this input from shell_command # and other expressions.

Yes

label

Label shown for the input on the tool form.

null

No

help #

Additional guidance shown on the tool form to help users choose a value.

null

No

optional

Set true when the command can run without the user supplying this input.

false

No

type

Places related inputs in a collapsible group to simplify the tool form.

Yes

parameters

Nested inputs displayed together inside the section.

[]

No

Add this section parameter under inputs #:

inputs:
  - label: Advanced options
    name: advanced
    parameters:
    - max: 1.0
      min: 0.0
      name: threshold
      type: float
      value: 0.5
    type: section

Use the parameter in shell_command # like this:

shell_command: |
  threshold="$(inputs.advanced.threshold)"

select parameter

A choice from a fixed list of options.

Field

Details

Default

Required

name

Identifier used to read this input from shell_command # and other expressions.

Yes

label

Label shown for the input on the tool form.

null

No

help #

Additional guidance shown on the tool form to help users choose a value.

null

No

optional

Set true when the command can run without the user supplying this input.

false

No

type

Lets the user choose from the declared options and supplies the selected value.

Yes

options

Choices presented on the tool form, each with a display label and value.

Yes

multiple

Set true to let the user select and supply several option values instead of one.

false

No

validators #

Additional validation rules; supports no_options.

[]

No

Add this select parameter under inputs #:

inputs:
  - label: Search mode
    name: mode
    options:
    - label: Fast
      selected: true
      value: fast
    - label: Sensitive
      selected: false
      value: sensitive
    type: select

Use the parameter in shell_command # like this:

shell_command: |
  mode="$(inputs.mode)"

text parameter

A single-line or multiline text input.

Field

Details

Default

Required

name

Identifier used to read this input from shell_command # and other expressions.

Yes

label

Label shown for the input on the tool form.

null

No

help #

Additional guidance shown on the tool form to help users choose a value.

null

No

optional

Set true when the command can run without the user supplying this input.

false

No

type

Accepts user-entered text and supplies the resulting string to expressions.

Yes

value

Text prefilled when the user first opens the tool form.

null

No

area

Set true to use a multiline editor instead of a single-line text box.

false

No

validators #

Additional validation rules; supports length, regex, and empty_field.

[]

No

Add this text parameter under inputs #:

inputs:
  - area: false
    label: Sequence motif
    name: motif
    type: text
    value: ACGT

Use the parameter in shell_command # like this:

shell_command: |
  motif="$(inputs.motif)"

Validator types

Field tables and examples for every validator supported by user-defined tool inputs.

empty_field validator

Require a value that is neither an empty string nor null.

Field

Details

Default

Required

type

Fails validation when the submitted value is an empty string or null.

"empty_field"

No

message

Error message shown when validation fails; %s is replaced with the rejected value.

null

No

implicit

Set internally when Galaxy added the validator automatically; tool authors normally leave this false.

false

No

negate

Require the value to be empty or null instead.

false

No

Use this validator on a compatible input:

inputs:
  - label: Sample name
    name: sample_name
    type: text
    validators:
    - type: empty_field

in_range validator

Require a numeric value to fall within optional lower and upper bounds.

Field

Details

Default

Required

type

Enforces the numeric boundaries configured by min and max.

"in_range"

No

message

Error message shown when validation fails; %s is replaced with the rejected value.

null

No

implicit

Set internally when Galaxy added the validator automatically; tool authors normally leave this false.

false

No

min

Rejects smaller values; omit to leave the range without a lower bound.

null

No

max

Rejects larger values; omit to leave the range without an upper bound.

null

No

exclude_min

Whether a value equal to min is rejected.

false

No

exclude_max

Whether a value equal to max is rejected.

false

No

negate

Reject values inside the configured range instead of values outside it.

false

No

Use this validator on a compatible input:

inputs:
  - label: Score threshold
    name: threshold
    type: float
    validators:
    - max: 1
      min: 0
      type: in_range
    value: 0.5

length validator

Require the number of characters in a text value to fall within optional bounds.

Field

Details

Default

Required

type

Enforces character-count boundaries on a submitted text value.

"length"

No

message

Error message shown when validation fails; %s is replaced with the rejected value.

null

No

implicit

Set internally when Galaxy added the validator automatically; tool authors normally leave this false.

false

No

min

Rejects text with fewer characters; omit to leave the length without a lower bound.

null

No

max

Rejects text with more characters; omit to leave the length without an upper bound.

null

No

negate

Reject values whose length is inside the configured range instead of outside it.

false

No

Use this validator on a compatible input:

inputs:
  - label: Sample name
    name: sample_name
    type: text
    validators:
    - max: 20
      min: 1
      type: length

no_options validator

Require a select parameter to have at least one available option.

Field

Details

Default

Required

type

Fails validation when a select input has no choices available.

"no_options"

No

message

Error message shown when validation fails; %s is replaced with the rejected value.

null

No

implicit

Set internally when Galaxy added the validator automatically; tool authors normally leave this false.

false

No

negate

Require the select parameter to have no available options instead.

false

No

Use this validator on a compatible input:

inputs:
  - label: Reference database
    name: database
    options:
    - label: Human
      value: human
    type: select
    validators:
    - type: no_options

regex validator

Require a regular expression to match from the start of the value.

End the expression with $ to require a full-value match. Each option of a select parameter is checked separately.

Field

Details

Default

Required

type

Applies the regular expression in expression to each submitted text value.

"regex"

No

message

Error message shown when validation fails; %s is replaced with the rejected value.

null

No

implicit

Set internally when Galaxy added the validator automatically; tool authors normally leave this false.

false

No

negate

Reject matching values instead of values that do not match.

false

No

expression

Regular expression matched from the start of the value. Add $ at the end to require a complete-value match.

Yes

Use this validator on a compatible input:

inputs:
  - label: DNA motif
    name: motif
    type: text
    validators:
    - expression: ^[ACGT]+$
      type: regex

Output types

Field tables and examples for dataset and dataset collection outputs.

collection output

A user-defined tool collection populated only by matching produced filenames.

Field

Details

Default

Required

name

Identifier used to connect this output in workflows and address it in tool tests.

null

No

label

Name shown for the produced dataset or collection in the history.

null

No

hidden

Hide the output in the history. The dataset is still created and usable by other tools and workflows.

null

No

type

Creates one history dataset collection populated from files produced by the command.

Yes

format_source

Input whose datatype supplies the default format for collection elements.

null

No

metadata_source

Dataset input whose metadata supplies defaults for collection elements.

null

No

format

Default datatype extension assigned to collection elements.

null

No

collection_type #

Fixed structure Galaxy creates for this output, such as list, paired, or a nested type such as list:paired.

null

No

collection_type_source #

Declared data-collection input whose runtime structure determines this output’s collection type.

null

No

structured_like #

Declared input whose element count, identifiers, and nesting this output mirrors. Use this when each produced element corresponds to an input element.

null

No

discover_datasets #

Filename pattern used to discover and populate collection elements.

null

No

Add this collection output under outputs #:

outputs:
  - collection_type: list
    discover_datasets:
    - format: txt
      pattern: (?P<name>.+)\.txt
    label: Results
    name: results
    type: collection
collection_type

collection_type can be used to declare a fixed output structure. A list contains an ordered set of discovered elements; paired requires forward and reverse identifiers.

inputs: []
shell_command: mkdir reports && printf 'sample\tvalue\nA\t1\n' > reports/A.tsv && printf 'sample\tvalue\nB\t2\n' > reports/B.tsv
outputs:
  - collection_type: list
    discover_datasets:
      - directory: reports
        format: tabular
        pattern: (?P<name>.+)\.tsv
    name: reports
    type: collection
collection_type_source

collection_type_source can be used when the output has the same runtime collection type as a declared data-collection input, including when that input accepts more than one structure.

inputs:
  - collection_type: paired
    format:
      - fastqsanger
    name: reads
    type: data_collection
shell_command: mkdir copied && cp '$(inputs.reads.elements.forward.path)' copied/forward.fastq && cp '$(inputs.reads.elements.reverse.path)' copied/reverse.fastq
outputs:
  - collection_type_source: reads
    discover_datasets:
      - directory: copied
        format: fastqsanger
        pattern: (?P<name>forward|reverse)\.fastq
    name: copied_reads
    type: collection
structured_like

structured_like can be used when each produced element corresponds to an element of a declared input. Galaxy mirrors that input’s element identifiers and nesting in the output.

inputs:
  - collection_type: paired
    format:
      - fastqsanger
    name: reads
    type: data_collection
shell_command: mkdir trimmed && head -n 400 '$(inputs.reads.elements.forward.path)' > trimmed/forward.fastq && head -n 400 '$(inputs.reads.elements.reverse.path)' > trimmed/reverse.fastq
outputs:
  - collection_type: paired
    discover_datasets:
      - directory: trimmed
        format: fastqsanger
        pattern: (?P<name>forward|reverse)\.fastq
    name: trimmed_reads
    structured_like: reads
    type: collection

data output

A user-defined tool dataset discovered only from files inside the job working directory.

Field

Details

Default

Required

name

Identifier used to connect this output in workflows and address it in tool tests.

null

No

label

Name shown for the produced dataset or collection in the history.

null

No

hidden

Hide the output in the history. The dataset is still created and usable by other tools and workflows.

null

No

type

Creates one history dataset from a file produced by the command.

Yes

format #

Galaxy datatype extension assigned when the command always produces a fixed representation. Use format_source instead when the datatype depends on an input.

null

No

format_source #

Data or collection input whose datatype extension this output inherits. Use this when the command preserves the input representation, such as filtering reads without changing their format.

null

No

metadata_source #

Data input whose datatype-specific metadata this output copies as defaults. Use this when the command preserves metadata Galaxy cannot infer from the output, such as interval column assignments.

null

No

discover_datasets #

Filename pattern used to discover additional datasets produced by the command.

null

No

from_work_dir #

Relative path, inside the job working directory, that the command writes for this output. Galaxy claims that file after the command finishes.

null

No

precreate_directory #

Set true when from_work_dir names a produced directory for a composite datatype. Galaxy copies the directory contents into the output dataset’s extra-files area.

false

No

Add this data output under outputs #:

outputs:
  - format: txt
    from_work_dir: result.txt
    label: Result
    name: result
    type: data
format

format can be used to assign a fixed Galaxy datatype when every run writes the same representation. The value is a datatype extension, not a filename suffix.

inputs: []
shell_command: printf 'gene\tscore\nBRCA1\t0.95\n' > scores.tsv
outputs:
  - format: tabular
    from_work_dir: scores.tsv
    name: scores
    type: data
format_source

format_source can be used to assign an output the selected input dataset’s datatype when the command preserves its representation.

inputs:
  - format:
      - fastq
      - fastqsanger
    name: reads
    type: data
shell_command: head -n 400 '$(inputs.reads.path)' > first.fastq
outputs:
  - format_source: reads
    from_work_dir: first.fastq
    name: first_reads
    type: data
metadata_source

metadata_source can be used to copy datatype-specific metadata from an input when the command preserves information Galaxy cannot infer from the produced file, such as interval column assignments.

inputs:
  - format:
      - interval
    name: intervals
    type: data
shell_command: awk '$3 > $2' '$(inputs.intervals.path)' > filtered.interval
outputs:
  - format: interval
    from_work_dir: filtered.interval
    metadata_source: intervals
    name: filtered_intervals
    type: data
from_work_dir

from_work_dir can be used to claim a file written by the command. The relative path must match the command’s destination and remain inside the job working directory.

inputs:
  - label: Message
    name: message
    type: text
shell_command: printf '%s\n' '$(inputs.message)' > message.txt
outputs:
  - format: txt
    from_work_dir: message.txt
    name: message_file
    type: data
precreate_directory

precreate_directory can be used with a directory-backed composite datatype. The command creates the directory named by from_work_dir; Galaxy then copies its contents into the output dataset’s extra-files area.

inputs:
  - format:
      - fasta
    name: reference
    type: data
shell_command: mkdir index && bwa-mem2 index -p index/reference '$(inputs.reference.path)'
outputs:
  - format: bwa_mem2_index
    from_work_dir: index
    name: index
    precreate_directory: true
    type: data

Discover datasets

Use discover_datasets # when a command creates a variable set of files. User-defined tools discover them by matching filenames produced in the job working directory.

Pattern discovery matches a regular expression against filenames. Named groups such as name, designation, ext, and dbkey set the corresponding dataset metadata. Use directory to search below the job working directory, and set recurse: true to include nested directories. With recursion, match_relative_path: true applies the pattern to each path relative to directory instead of only the filename.

The format field sets the Galaxy datatype extension when the pattern does not provide ext. See the Datatypes page in your Galaxy instance for the extensions it supports. Set visible: true to show discovered datasets individually in the history. For a data output, assign_primary_output: true assigns the first match to the declared primary output.

Results default to lexical filename order. Choose sort_key from filename, name, designation, or dbkey; choose sort_comp as lexical or numeric; and set sort_reverse: true for descending order.

inputs: []
shell_command: |
  mkdir reports
  printf 'sample\tvalue\nA\t1\n' > reports/A.tsv
  printf 'sample\tvalue\nB\t2\n' > reports/B.tsv
outputs:
  - name: reports
    type: collection
    collection_type: list
    discover_datasets:
      - pattern: "(?P<name>.+)\\.tsv"
        directory: reports
        format: tabular
        visible: true
        sort_key: name

Common questions

Why do some shell constructs fail?

The expression evaluator interprets $( and ${ as expression delimiters, so shell constructs using them are not passed to the shell:

Written in shell_command #

Result

$(date +%s)

Evaluated as JavaScript; the job fails with an expression evaluation error.

${HOME}, ${f%.txt}, ${VAR:-default}

Evaluated as JavaScript; normally a syntax error.

$(( 1 + 2 ))

Evaluated as JavaScript and replaced by 3, changing the command’s meaning without an error.

$GALAXY_SLOTS, $HOME, $1

Passed through untouched. A $ not followed by ( or { is ignored.

An unbraced shell variable is therefore the safe form, and $GALAXY_SLOTS in particular works as it does in XML tools.

To emit a literal $( or ${, escape the dollar with a backslash: \$(date +%s) reaches the shell as $(date +%s).

Backslash handling has one more consequence worth knowing. Escape processing only runs when the command contains $( or ${ somewhere; a command with no expression at all is passed through byte for byte. In a command that does contain an expression, \\ collapses to a single \ everywhere in that command, so a literal backslash pair has to be written as \\\\. Lone backslashes such as \;, \. and \t are left alone.

How should I structure a command?

Keep shell_command # to a short invocation. When a command needs a script, put it in configfiles #; each file’s content is evaluated with the same expression syntax as shell_command #. Within a shell script, evaluate each input once into a variable and use plain, unbraced shell variables below.

CPU allocation is not a tool input: declare it with a resource requirement and pass the allocated $GALAXY_SLOTS value to the program.

requirements:
  - type: resource
    cores_min: 4
configfiles:
  - filename: run.sh
    content: |
      set -eu
      query='$(inputs.query.path)'
      db='$(inputs.database.path)'

      foldseek easy-search "$query" "$db" result.m8 tmp --threads "$GALAXY_SLOTS"
shell_command: sh run.sh

User-defined tool commands run under set -e, so the first failing command ends the job.

Why is a command missing from the container?

container # is required, and the image it names is the only environment the command gets. Every binary, interpreter and library referenced by shell_command #, including utilities used to sort, reformat or rename outputs, has to already exist in that image.

A single-tool BioContainer is built to be small. Many do ship a Python interpreter, since they are conda environments, but a given image may not, and may equally lack utilities like jq or bc. Check before relying on one:

$ docker run --rm quay.io/biocontainers/foldseek:10.941cd33 sh -c 'command -v python3 awk sort'

If a command needs several packages, use a multi-package (mulled) image or an image you build and publish yourself, rather than assuming a single-tool image also carries the others.

How should I write the container image reference?

Use a fully qualified registry/repository:tag reference:

container: quay.io/biocontainers/foldseek:10.941cd33

A bare foldseek:10.941cd33 is not resolved by Galaxy against BioContainers. The identifier is passed to the container runtime as written, and the runtime applies its own default registry, which for Docker is docker.io/library, where the image almost certainly does not exist. The failure surfaces at job runtime as an image pull error, not at tool creation.

Do not prefix the value with docker://. Galaxy stores a container # string as a Docker container description and adds the docker:// prefix itself when the destination executes through Singularity or Apptainer; writing the prefix yourself produces a doubled docker://docker://... identifier.

Author user-defined tools with the top-level container # field. Which container runtime executes that image, and whether images are converted and cached ahead of time, depends on the server.

What does Galaxy check for me?

Galaxy checks a user-defined tool at several points before it ever runs:

  • Schema validation. Unknown keys are rejected anywhere in the document, including inside inputs, outputs, requirements, config files and citations, so a misspelled or XML-only field fails immediately rather than being ignored.

  • Cross-field validation. Every $(inputs.input_name) referenced from shell_command # or a config file must correspond to a declared input, and every output must declare where its bytes come from.

  • Linting. Creating or editing a tool runs Galaxy’s tool linters and refuses the tool if any of them reports a problem. This includes a check that the container reference has a recognizable shape. Linters that call external services are skipped so that authoring does not depend on third-party availability.

Two endpoints check a draft without saving it: POST /api/unprivileged_tools/build renders the tool form, which is the quickest way to confirm the input interface is what you intended, and POST /api/unprivileged_tools/runtime_model returns an OpenAPI model of the tool’s inputs.

None of this checks that the tool produces correct results. A tool that validates, lints and runs to completion can still be wrong: a misquoted path, a flag that silently changes meaning between tool versions, or a container whose tool version differs from the one the command was written against.

Can Galaxy run the declared tests?

A user-defined tool may declare a tests # block, using the same test syntax as other YAML-format Galaxy tools:

tests:
  - inputs:
      input1:
        class: File
        path: simple_line.txt
    outputs:
      output1: simple_line.txt

Galaxy stores and returns these tests, but does not currently run them for a tool held in the database. There is no in-application “run this tool’s tests” action, and a database-stored tool has no tool directory, so file-based test inputs such as the simple_line.txt above cannot be resolved. Declared tests become executable once the tool is exported to disk and loaded like a regular tool, at which point the usual tool-test tooling applies.

Until in-platform testing exists, validate correctness by running the tool on inputs whose answer you already know, and comparing the outputs against a run of the same command outside Galaxy. This is worth doing once per registered version, since a version bump usually means a new container image as well.