Using the transpiler-mate plugin
Available since cwl2click 0.9.0
Since 0.9.0, command-line conversion is provided by
transpiler-mate cwl2click. The standalone cwl2click command was removed.
The Python library remains available independently of the runtime.
The plugin bootstraps a Python CLI using Click from CWL CommandLineTool
definitions. It generates command definitions and input options, with imports
for callback functions that you implement separately. It does not execute the
CWL tools or generate their processing logic.
Installation
Install the runtime and plugin in the same Python environment (Python 3.10 or later):
pip install transpiler-mate-runtime "cwl2click>=0.9.0"
The plugin depends on transpiler-mate-api. The separate
transpiler-mate-runtime package provides the command and discovers installed
plugins automatically.
transpiler-mate --help
transpiler-mate cwl2click --help
Your generated application also needs click as a dependency.
Convert a CWL document
Generate a separate CLI for each CommandLineTool available in the resolved document:
transpiler-mate cwl2click --output ./src/my_app application.cwl
Select specific tools by repeating --clt-id:
transpiler-mate cwl2click \
--clt-id crop \
--clt-id norm_diff \
--output ./src/my_app \
application.cwl
Use the tool IDs in the resolved document. The runtime loads the source and
supplies the context; the plugin requests CommandLineTool processes, optionally
filtered by these IDs. Workflows themselves are not converted into commands.
Options
| Option | Default | Description |
|---|---|---|
--clt-id TEXT |
All CommandLineTools | Repeat to select multiple tool IDs. |
--bundle |
Disabled | Generate one module with the existing command/group structure. |
--output PATH |
Required; no default | Root directory for generated output. |
Source loading and application metadata validation are handled by the runtime.
See transpiler-mate cwl2click --help for shared authentication options and
Execution for a remote-source example.
Generated output
By default, each selected tool is generated as a direct Click command at
<output>/<clt.id>/src/<clt.id_in_snake_case>/cli.py. Any subcommand derived
from baseCommand or arguments is omitted; input options belong directly to
the command. For example, tool crop-tool generates
<output>/crop-tool/src/crop_tool/cli.py, imports its callback from
crop_tool.crop_tool_impl, and can use this entry point:
[project.scripts]
crop-tool = "crop_tool.cli:runner"
Here runner is the tool's first baseCommand item, converted to snake case.
Provide the callback implementation and packaging files for each project.
With --bundle, the plugin preserves the previous behavior described below.
For example: transpiler-mate cwl2click --bundle --output ./src/my_app application.cwl.
The plugin writes one Python file directly into the output directory, containing
all selected tools. The filename comes from the source URL or path's filename,
with its extension replaced by .py and its stem converted to snake case.
For example, pattern-12.cwl produces:
src/
└── my_app/
└── pattern_12.py
Missing directories are created. An existing file with the same name is
overwritten, and other files are retained. Generation errors are reported as
PluginExecutionError; because the target is opened before rendering, a failure
can leave an empty or incomplete output file.
The generated module uses the output directory's final name (my_app above) as
the package name in callback imports. Choose an output directory whose name is
a valid Python package name and make that package importable in your application.
For a tool with ID crop, the generated import is:
from my_app.crop_impl import execute as crop_command
Create my_app/crop_impl.py yourself and provide an execute function accepting
the generated input names as keyword arguments. Tool IDs and callback parameter
names are converted to snake case. The plugin does not create implementation
modules, __init__.py, or project packaging files.
Command structure and application setup
In bundled mode, each selected tool must define baseCommand. Its first item (or the whole value
when it is a string) determines the generated command or group variable, converted
to snake case. A second baseCommand item supplies a subcommand name; otherwise,
the first arguments item is used when present. Tools with subcommands and the
same base command share a Click group.
Inputs become Click options using inputBinding.prefix, or --<input-id> when
no prefix is supplied. CWL types determine the Click types, required status,
repeatable options, and boolean flags. Tool labels and documentation supply help
text. See the crosswalk for mapping details.
To expose the generated CLI, add a script entry point to your application's
pyproject.toml. For example, if application.cwl defines a tool with
baseCommand: runner and you generated src/my_app/application.py, use:
[project.scripts]
my-cli = "my_app.application:runner"
Use the actual generated module filename and command or group variable in this entry point. The generated comments contain entry-point suggestions based on tool IDs, which can differ from the source-based module filename.
After providing the callback implementations, declaring the click dependency,
and installing your application, inspect its commands with:
my-cli --help
Migrating from the former CLI
Install the runtime alongside the plugin and replace cwl2click with
transpiler-mate cwl2click. Supply the required --output directory and use
repeated --clt-id options to restrict generation to particular tools.
Plugin registration
The package declares this entry point:
[project.entry-points."transpiler_mate.plugins"]
cwl2click = "cwl2click.plugin:cwl2click"
The plugin validates options with Cwl2ClickOptions and receives a
TranspilerContext from the runtime. Unknown option fields are rejected.
See the API reference for the registration and options model, and for
the to_click function if you want to render to a stream directly.