execute

The uw mode for executing external drivers.

uw execute --help
usage: uw execute --module MODULE --classname CLASSNAME --task TASK [-h]
                  [--version] [--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
  --task TASK
      Driver task to execute

Optional arguments:
  -h, --help
      Show help and exit
  --version
      Show version info and exit
  --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. 2024-08-08T18)
  --leadtime LEADTIME
      The leadtime as hours[:minutes[:seconds]]
  --batch
      Submit run 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, @tasks, or @external.

Examples

These examples use the following inputs:

Module rand.py

from random import randint

from iotaa import asset, task

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

use_uwtools_logger()


class Rand(AssetsTimeInvariant):

    @task
    def randfile(self):
        """
        A file containing a random integer.
        """
        path = self.rundir / "randint"
        yield self.taskname("Random-integer file")
        yield asset(path, path.is_file)
        yield None
        path.parent.mkdir(parents=True)
        with open(path, "w", encoding="utf-8") as f:
            print(randint(self.config["lo"], self.config["hi"]), file=f)

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

Schema rand.jsonschema

{
  "properties": {
    "rand": {
      "additionalProperties": false,
      "properties": {
        "hi": {
          "type": "integer"
        },
        "lo": {
          "type": "integer"
        },
        "rundir": {
          "type": "string"
        }
      },
      "required": [
        "lo",
        "hi",
        "rundir"
      ],
      "type": "object"
    },
    "required": [
      "rand"
    ],
    "type": "object"
  }
}

Config rand.yaml

rand:
  hi: 100
  lo: 1
  rundir: /tmp/rand
  • Execute the external driver:

    rm -rf /tmp/rand
    uw execute --module rand.py --classname Rand --task randfile --config-file rand.yaml
    echo Random integer is $(cat /tmp/rand/randint)
    
    [2024-11-22T23:09:15]     INFO 0 schema-validation errors found in rand config
    [2024-11-22T23:09:16]     INFO rand Random-integer file: Executing
    [2024-11-22T23:09:16]     INFO rand Random-integer file: Ready
    Random integer is 6
    
  • If the external driver does not accept an argument that was provided on the command line, it will exit with error. In this case, Rand inherits from parent class AssetsTimeInvariant, which does not accept a cycle argument:

    uw execute --module rand.py --classname Rand --task randfile --config-file rand.yaml --cycle 2024-08-08T12
    
    [2024-08-08T23:46:07]    ERROR Rand 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. rand.jsonschema alongside rand.py) then the --schema-file argument is not required. However, --schema-file can be used to point to an alternate schema:

    rm -rf /tmp/rand-alt
    uw execute --module rand.py --classname Rand --task randfile --config-file alt.yaml --schema-file alt.schema
    echo Random integer is $(cat /tmp/rand-alt/randint)
    
    [2024-11-22T23:09:14]     INFO 0 schema-validation errors found in rand config
    [2024-11-22T23:09:15]     INFO rand Random-integer file: Executing
    [2024-11-22T23:09:16]     INFO rand Random-integer file: Ready
    Random integer is 5
    
  • Other arguments behave identically to the same-named arguments to internal uwtools drivers (see Drivers).