Variables

There are three kinds of variables in pyflow:

  • The variables that are used by ecFlow, like ECF_HOME or ECF_INCLUDE.

  • The variables that are defined by the user. It is a good practice to name these variables with capital letters.

  • The variables that are generated by ecFlow, and that you can use in your jobs, like ECF_DATE which contains the date of the suite.

Warning

Names of the user variables should not start with ECF_.

Variable Inheritance

When all the tasks of the same family share the same variable value, the value can be defined at the family level.

In the example below the variable SLEEP could have been defined at the level of the suite, achieving the same results.

[2]:
with pf.Suite('test') as s:
    with pf.Family('f1'):
        pf.Variable('SLEEP', 20)
        pf.Task('t1')
        pf.Task('t2')

s
[2]:
suite test
  edit ECF_JOB_CMD 'bash -c 'export ECF_PORT=%ECF_PORT%; export ECF_HOST=%ECF_HOST%; export ECF_NAME=%ECF_NAME%; export ECF_PASS=%ECF_PASS%; export ECF_TRYNO=%ECF_TRYNO%; export PATH=/usr/local/apps/ecflow/%ECF_VERSION%/bin:$PATH; ecflow_client --init="$$" && %ECF_JOB% && ecflow_client --complete || ecflow_client --abort ' 1> %ECF_JOBOUT% 2>&1 &'
  edit ECF_KILL_CMD 'pkill -15 -P %ECF_RID%'
  edit ECF_STATUS_CMD 'true'
  edit ECF_OUT '%ECF_HOME%'
  label exec_host "default"
  family f1
    edit SLEEP '20'
    task t1
    task t2
  endfamily
endsuite

Variables are inherited from the parent node. If a variable is redefined lower in the tree, it is said to be overridden. In this case, the new definition is the one being used. It is possible to override the generated variables.

[3]:
with pf.Suite('test') as s:
    pf.Variable('SLEEP', 100)
    with pf.Family('f1'):
        pf.Variable('SLEEP', 80)
        pf.Task('t1')
        with pf.Task('t2'):
            pf.Variable('SLEEP', 9)
        with pf.Family('g1'):
            pf.Variable('SLEEP', 89)
            with pf.Task('x1'):
                pf.Variable('SLEEP', 10)
            pf.Task('x2')
    with pf.Family('f2'):
        pf.Task('t1')
        with pf.Task('t2'):
            pf.Variable('SLEEP', 77)
        with pf.Family('g2'):
            with pf.Task('x1'):
                pf.Variable('SLEEP', 12)
            pf.Task('x2')

s
[3]:
suite test
  edit ECF_JOB_CMD 'bash -c 'export ECF_PORT=%ECF_PORT%; export ECF_HOST=%ECF_HOST%; export ECF_NAME=%ECF_NAME%; export ECF_PASS=%ECF_PASS%; export ECF_TRYNO=%ECF_TRYNO%; export PATH=/usr/local/apps/ecflow/%ECF_VERSION%/bin:$PATH; ecflow_client --init="$$" && %ECF_JOB% && ecflow_client --complete || ecflow_client --abort ' 1> %ECF_JOBOUT% 2>&1 &'
  edit ECF_KILL_CMD 'pkill -15 -P %ECF_RID%'
  edit ECF_STATUS_CMD 'true'
  edit ECF_OUT '%ECF_HOME%'
  edit SLEEP '100'
  label exec_host "default"
  family f1
    edit SLEEP '80'
    task t1
    task t2
      edit SLEEP '9'
    family g1
      edit SLEEP '89'
      task x1
        edit SLEEP '10'
      task x2
    endfamily
  endfamily
  family f2
    task t1
    task t2
      edit SLEEP '77'
    family g2
      task x1
        edit SLEEP '12'
      task x2
    endfamily
  endfamily
endsuite

Multiple Variables

To set multiple variables at the same time, you can use pf.Edit class.

[4]:
with pf.Suite('s') as s:
    with pf.Family('f'):
        pf.Edit(FOO='foo_value', BAR='bar_value')

s
[4]:
suite s
  edit ECF_JOB_CMD 'bash -c 'export ECF_PORT=%ECF_PORT%; export ECF_HOST=%ECF_HOST%; export ECF_NAME=%ECF_NAME%; export ECF_PASS=%ECF_PASS%; export ECF_TRYNO=%ECF_TRYNO%; export PATH=/usr/local/apps/ecflow/%ECF_VERSION%/bin:$PATH; ecflow_client --init="$$" && %ECF_JOB% && ecflow_client --complete || ecflow_client --abort ' 1> %ECF_JOBOUT% 2>&1 &'
  edit ECF_KILL_CMD 'pkill -15 -P %ECF_RID%'
  edit ECF_STATUS_CMD 'true'
  edit ECF_OUT '%ECF_HOME%'
  label exec_host "default"
  family f
    edit FOO 'foo_value'
    edit BAR 'bar_value'
  endfamily
endsuite