Skip to content

Submit and Monitor a CWL Workflow

This tutorial walks through one complete WES interaction: submit a small CWL workflow, capture the returned run_id, poll its status, and inspect its logs.

The gateway implements the WES API contract. The execution layer is Toil, so the workflow body and engine parameters are the same kind of values you would send to a Toil WES runner.

Before You Start

You need a running WES endpoint. For a local Toil WES service, the base URL is normally:

export WES_URL=http://localhost:8080/ga4gh/wes/v1

If your deployment protects WES endpoints, also set credentials or a bearer token. The examples below use basic authentication because that is common in local Toil WES examples:

export WES_AUTH=test:test

Create a Tiny CWL Workflow

Create example.cwl:

cwlVersion: v1.0
class: CommandLineTool
baseCommand: echo
stdout: output.txt
inputs:
  message:
    type: string
    inputBinding:
      position: 1
outputs:
  output:
    type: stdout

This workflow writes the provided message input to output.txt.

Submit the Run

Submit the workflow to POST /runs as multipart form data:

curl --location --request POST "$WES_URL/runs" \
  --user "$WES_AUTH" \
  --form 'workflow_url=example.cwl' \
  --form 'workflow_type=CWL' \
  --form 'workflow_type_version=v1.0' \
  --form 'workflow_params={"message":"Hello from WES"}' \
  --form 'workflow_attachment=@example.cwl'

A successful response returns a WES run identifier:

{
  "run_id": "4deb8beb24894e9eb7c74b0f010305d1"
}

Keep that value. Every follow-up call uses it as {run_id}.

You can capture it in a shell variable if jq is available:

RUN_ID=$(
  curl --silent --location --request POST "$WES_URL/runs" \
    --user "$WES_AUTH" \
    --form 'workflow_url=example.cwl' \
    --form 'workflow_type=CWL' \
    --form 'workflow_type_version=v1.0' \
    --form 'workflow_params={"message":"Hello from WES"}' \
    --form 'workflow_attachment=@example.cwl' \
  | jq -r '.run_id'
)

Check the Run State

Use the fast status endpoint while the workflow is running:

curl --user "$WES_AUTH" "$WES_URL/runs/$RUN_ID/status"

Example response:

{
  "run_id": "4deb8beb24894e9eb7c74b0f010305d1",
  "state": "RUNNING"
}

Terminal states include COMPLETE, EXECUTOR_ERROR, SYSTEM_ERROR, CANCELED, and PREEMPTED.

Inspect the Run Log

Use GET /runs/{run_id} for the full run record:

curl --user "$WES_AUTH" "$WES_URL/runs/$RUN_ID"

The response includes the original request, the current state, workflow logs, output locations when available, and a task_logs_url if the deployment supports paginated task logs.

List Task Logs

If the deployment exposes task-level logs, list them with:

curl --user "$WES_AUTH" "$WES_URL/runs/$RUN_ID/tasks?page_size=50"

Use the returned next_page_token to request the next page.

Cancel If Needed

If the run is still active and should be stopped:

curl --location --request POST "$WES_URL/runs/$RUN_ID/cancel" \
  --user "$WES_AUTH"

The response echoes the run_id. Poll GET /runs/{run_id}/status until the state becomes CANCELING, CANCELED, or another terminal state.