Launching a Motoko Workflow

Motoko workflows can be run using the command line or within a Python script.

Command-line usage

Create or reset the BlackDynamite studies for a workflow:

motoko create workflow_dir

Start launcher daemons from inside the workflow directory:

cd workflow_dir
motoko launcher

Run the orchestrator in the foreground:

motoko orchestrator start --run_name test --inputs 2.1 3.2

Run the orchestrator detached with zdaemon:

motoko orchestrator start --detach --run_name test --inputs 2.1 3.2

Inspect workflow state:

motoko info
motoko info --verbose
motoko info --bd_study mult

Stop daemons:

motoko orchestrator stop
motoko kill

Clean BlackDynamite runs:

motoko clean
motoko clean --delete

Python interface

The command-line interface is a thin wrapper around the Python API. A workflow can also be created and executed directly from Python:

from motoko.workflow import Workflow


workflow = Workflow("motoko.yaml")
workflow.create()
workflow.start_launcher_daemons()
workflow.run_name = "test"
workflow.execute(inputs=[2.1, 3.1])

The Workflow constructor reads motoko.yaml, creates one TaskManager per entry in task_managers, and exposes each manager as an attribute.

Tasks can also be created manually outside the orchestrator function:

workflow = Workflow("motoko.yaml")
workflow.run_name = "manual"


async def submit_tasks():
    runs = await workflow.mult.createTask(x=[2.1, 3.1])
    finished = workflow.mult.select("state = FINISHED")
    return runs, finished

In a script, workflow.run_name must be set before creating tasks. Motoko stores it on every created run and uses it to scope later selections, so separate workflow executions do not accidentally interfere with one another’s runs.

Motoko loads orchestrator.py from the workflow directory and calls main(workflow, **params). Parameters come from CLI arguments and are also accepted by workflow.execute(**params) when running from Python.

For scripts that only need to add or inspect tasks, use the task managers directly:

workflow = Workflow("motoko.yaml")
workflow.run_name = "inspection"

selected = workflow.norm.select(["state = FINISHED"])
for run, job in selected:
    print(run.id, run.state)

When using the Python API outside the CLI, the caller is responsible for starting and stopping BlackDynamite launcher daemons if tasks should execute automatically:

subprocess.call("motoko kill", shell=True, cwd=workflow_dir)