Install & Compatibility
Where this runs
tested against v3.2.20260413085819 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.920 runs
installs and imports cleanly · install 0.0s · import 1.333s · 100.6MB
glibcpy 3.10–3.920 runs
installs and imports cleanly · install 8.7s · import 1.226s · 101MB
105MB installed
● package 105MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
main
✓ from cwltool.main import main
Primary entry point for CLI-like execution.
load_tool
✓ from cwltool.load_tool import load_tool
✗ from cwltool.workflow import Workflow # Or from cwltool.process import CommandLineTool
Use `load_tool` to correctly parse and validate CWL documents (workflows or tools) into their respective Python objects (`Workflow`, `CommandLineTool`). Directly importing and instantiating process classes from internal modules is generally not the recommended way to load CWL definitions.
LoadingContext
✓ from cwltool.context import LoadingContext
Used for configuring the loading environment, including base URIs and schema definitions.
This quickstart demonstrates how to programmatically load and validate a Common Workflow Language (CWL) CommandLineTool definition using `cwltool.load_tool`. This is the primary method for parsing CWL documents into Python objects for inspection or further processing.
import os
from cwltool.load_tool import load_tool
from cwltool.context import LoadingContext
# 1. Define a simple CWL CommandLineTool
cwl_content = """
cwlVersion: v1.0
class: CommandLineTool
id: my_echo_tool
baseCommand: echo
inputs:
message:
type: string
inputBinding:
position: 1
outputs:
output_message:
type: stdout
stdout: output.txt
"""
# 2. Save it to a temporary file
cwl_file_path = "simple_echo.cwl"
with open(cwl_file_path, "w") as f:
f.write(cwl_content)
try:
# 3. Load and validate the CWL document
# A LoadingContext is often required for proper resolution of includes/imports
# and setting the base URI.
loadingContext = LoadingContext({"$base": os.path.abspath(os.path.dirname(cwl_file_path))})
loadingContext.fileuri = f"file://{os.path.abspath(cwl_file_path)}"
# load_tool returns a Process object (CommandLineTool, Workflow, or ExpressionTool)
tool = load_tool(cwl_file_path, loadingContext)
print(f"Successfully loaded and validated CWL tool: {tool.tool_id}")
print(f"Tool class: {tool.class_}")
print(f"Inputs: {[i.id for i in tool.inputs]}")
print(f"Outputs: {[o.id for o in tool.outputs]}")
# To actually *run* it, you would typically use cwltool.main.main
# or a custom executor with an input object.
# The `load_tool` function is primarily for parsing and validation.
except Exception as e:
print(f"Error loading CWL tool: {e}")
finally:
# Clean up the temporary file
if os.path.exists(cwl_file_path):
os.remove(cwl_file_path)
cwltool --version
Debug
Known issues
breakingPython 3.9 support was dropped in `cwltool` version 3.1.20260108082145. Earlier, Python 3.8 support was removed in 3.1.20241024121129. Users must ensure their environment uses Python 3.10 or newer.fixUpgrade Python to version 3.10 or later.
affects: <3.1.20260108082145
gotchaProgrammatic execution of CWL workflows/tools with `cwltool` can be complex, often requiring the use of `cwltool.main.main` (mimicking CLI calls) or setting up specific `Executor` and `LoadingContext` objects. Directly instantiating `Process` objects (like `CommandLineTool` or `Workflow`) from internal modules is not the recommended or simplest path for execution.fixFor parsing and validation, use `cwltool.load_tool`. For execution, consider wrapping `cwltool.main.main` with appropriate arguments, or consult advanced documentation on `cwltool.executors` for fine-grained control.
affects: All
gotchaThe `cwltool` versioning scheme follows a `MAJOR.MINOR.DATE` pattern (e.g., `3.2.20260411152607`). The `MAJOR.MINOR` part typically corresponds to the supported CWL specification version (e.g., `3.2` implies CWL v1.2), while the date reflects the release date. This can sometimes be confusing when tracking API changes independently of CWL specification changes.fixRefer to the release notes and documentation for specific API changes. The `MAJOR.MINOR` segment is generally stable in terms of CWL spec compatibility, indicating the supported CWL version.
affects: All
gotcha`cwltool` heavily relies on external container runtimes (like Docker, Singularity/Apptainer, Podman) for executing containerized tools and workflows. Issues with container daemon availability, permissions, or image pulling are common troubleshooting points.fixEnsure Docker, Singularity, or another supported container engine is installed, running, and properly configured (e.g., user added to `docker` group). Verify container images can be pulled and run independently of `cwltool`.
affects: All
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'cwltool'
The `cwltool` package is not installed in the Python environment, or the Python interpreter cannot find it.
fixInstall the cwltool package using pip: `pip install cwltool`
Workflow error, try again with --debug for more information: ... Expression evaluation error: Syntax error in parameter reference '(inputs. sample-input)'. This could be due to using Javascript code without specifying InlineJavascriptRequirement.
There is a syntax error in a CWL expression, often related to how input parameters are referenced, or JavaScript code is used without explicitly declaring the `InlineJavascriptRequirement` in the CWL document.
fixCorrect the syntax of the parameter reference in the CWL expression or add `InlineJavascriptRequirement: {}` to the `requirements` section of your CWL document if you are using JavaScript expressions. Ensure identifiers (like `sample-input`) are valid in JavaScript if used in expressions (hyphens can cause issues, use `inputs['sample-input']` or rename the input). Workflow failed validation
The CWL workflow or tool definition file contains errors that prevent it from conforming to the Common Workflow Language specification.
fixRun `cwltool --validate your_workflow.cwl` to get detailed validation errors. Review the reported issues and correct the CWL syntax, schema, or structural problems in your workflow definition. Ensure all required fields are present and correctly typed.
could not run docker pull
cwltool could not pull the specified Docker image, possibly due to Docker not running, network issues, or incorrect image name/tag.
fixEnsure Docker is running and properly configured on your system. Verify your internet connection. Check the Docker image name and tag in your CWL file for typos. If it's a private repository, ensure you are logged in to Docker. You can also try pulling the image manually with `docker pull <image_name>`.
Upgrade
Version history
3.2.20260413085819latest on PyPI · released Apr 16, 2026
Audit
Dependencies
No dependency data recorded yet.