Commands¶
To CommandGraph, a Command
is an object that writes files to a directory, based on a configuration and/or the outputs of other commands.
Defining commands¶
A minimal command with input and output looks like this:
import cmdgraph as cg
class SayHello(cg.Command):
output_path = 'greetings/{name}' # Config fields are substituted automatically
# (though using this shorthand is optional).
def run(self):
self.output['message'] = ( # Records provide a concurrency-safe,
f'Hello, {self.conf.name}!') # array-friendly view into the filesystem.
SayHello(name='Sven')() # This writes "Hello, Sven!" to /greetins/Sven/message.h5,
# and writes metadata to /greetings/Sven/_cmd-spec.yaml
# and /greetings/Sven/_cmd-status.yaml.
Accessing command metadata¶
cmd.spec
returns a command’s specification—its configuration, augmented with a field encoding its type—as a JSON-like object (an arbitrarily nested combination of bool
, int
, float
, str
, NoneType
, list
, and Namespace
instances).
cmd.status
returns the command’s execution status: “running”, “done”, “stopped”, or “unbegun”.
Executing commands¶
Calling a command (cmd()
) invokes it unconditionally.
require
invokes the command if necessary and blocks until it has finished executing. It does nothing if the command’s status is “done”.
class WarpCatPictures(cg.Command):
output_path = 'warped-cats'
def run(self):
cats = cg.require(GetCats(source='the-internet')) # `require` returns the dependent
self.output['result'] = warp_thoroughly(cats) # command's output record.