execute

The uw mode for executing external drivers.

uw execute --help
usage: uw execute --module MODULE --classname CLASSNAME [-h] [--version]
                  [--task TASK] [--config-file PATH] [--schema-file PATH]
                  [--cycle CYCLE] [--leadtime LEADTIME] [--batch] [--dry-run]
                  [--graph-file PATH] [--key-path KEY[.KEY...]] [--quiet]
                  [--verbose]

Execute external driver.

Required arguments:
  --module MODULE
      Path to driver module or name of module on sys.path
  --classname CLASSNAME
      Name of driver class

Optional arguments:
  -h, --help
      Show help and exit
  --version
      Show version info and exit
  --task TASK
      Task to execute
  --config-file PATH, -c PATH
      Path to UW YAML config file (default: read from stdin)
  --schema-file PATH
      Path to schema file to use for validation
  --cycle CYCLE
      The cycle in ISO8601 format (e.g. yyyy-mm-ddThh)
  --leadtime LEADTIME
      The leadtime as hours[:minutes[:seconds]]
  --batch
      Submit job to batch scheduler
  --dry-run
      Only log info, making no changes
  --graph-file PATH
      Path to Graphviz DOT output [experimental]
  --key-path KEY[.KEY...]
      Dot-separated path of keys to driver config block
  --quiet, -q
      Print no logging messages
  --verbose, -v
      Print all logging messages

For the three required arguments:

  • --module specifies the name of the module providing the driver. The name may be an absolute path (e.g. /path/to/driver.py); a path relative to the current directory (e.g. driver.py, ../driver.py, sub/dir/driver.py); or a name appropriate to the Python import statement (e.g. driver, my.package.driver), provided the directory containing the module is on PYTHONPATH / sys.path.

  • --class specifies the name of a class in the above module that implements the driver, which should use one of the classes exported by uwtools.api.driver as its base class.

  • --task specifies the name of a method in the above class that implements a task, decorated with @task, @collection, or @external.

Examples

These examples use the following inputs:

Module answer.py

from iotaa import Asset, task

from uwtools.api.driver import AssetsTimeInvariant
from uwtools.api.logging import use_uwtools_logger

use_uwtools_logger()


class Answer(AssetsTimeInvariant):

    @task
    def answerfile(self):
        """
        A file containing the answer.
        """
        path = self.rundir / "answer.txt"
        yield self.taskname("Answer file")
        yield Asset(path, path.is_file)
        yield None
        path.parent.mkdir(parents=True)
        with open(path, "w", encoding="utf-8") as f:
            print(self.config["n"], file=f)

    @classmethod
    def driver_name(cls):
        return "answer"

Schema answer.jsonschema

{
  "properties": {
    "answer": {
      "additionalProperties": false,
      "properties": {
        "n": {
          "type": "integer"
        },
        "rundir": {
          "type": "string"
        }
      },
      "required": [
        "n",
        "rundir"
      ],
      "type": "object"
    },
    "required": [
      "answer"
    ],
    "type": "object"
  }
}

Config answer.yaml

answer:
  n: 42
  rundir: tmp/answer
  • Execute the external driver:

    rm -rf tmp/answer
    uw execute --module answer.py --classname Answer --task answerfile --config-file answer.yaml
    echo The answer is: $(cat tmp/answer/answer.txt)
    
    [2025-01-02T03:04:05]     INFO Schema validation succeeded for answer config
    [2025-01-02T03:04:05]     INFO answer Answer file: Executing
    [2025-01-02T03:04:05]     INFO answer Answer file: Ready
    The answer is: 42
    
  • If the external driver does not accept an argument that was provided on the command line, it will exit with error. In this case, Answer inherits from parent class AssetsTimeInvariant, which does not accept a cycle argument:

    uw execute --module answer.py --classname Answer --task answerfile --config-file answer.yaml --cycle 2025-03-31T12
    
    [2025-01-02T03:04:05]    ERROR Answer does not accept argument 'cycle'
    
  • If the schema file for a driver resides in the same directory as its Python module and has the same filename prefix, as well as a .jsonschema suffix (e.g. answer.jsonschema alongside answer.py) then the --schema-file argument is not required. However, --schema-file can be used to point to an alternate schema:

    rm -rf tmp/answer-alt-schema
    uw execute --module answer.py --classname Answer --task answerfile --config-file answer-alt-schema.yaml --schema-file answer-alt-schema.txt
    echo The answer is: $(cat tmp/answer-alt-schema/answer.txt)
    
    [2025-01-02T03:04:05]     INFO Schema validation succeeded for answer config
    [2025-01-02T03:04:05]     INFO answer Answer file: Executing
    [2025-01-02T03:04:05]     INFO answer Answer file: Ready
    The answer is: 42
    
  • Other arguments behave identically to the same-named arguments to internal uwtools drivers (see Drivers).