ecflow.Node

class ecflow.Node

Bases: instance

A Node class is the abstract base class for Suite, Family and Task

Every Node instance has a name, and a path relative to a suite

Node.add()
object add(tuple args, dict kwds) :

add(..) provides a way to append Nodes and attributes

This is best illustrated with an example:

defs = Defs().add(
    Suite('s1').add(
        Clock(1, 1, 2010, False),
        Autocancel(1, 10, True),
        Task('t1').add(
            Edit({'a':'12', 'b':'bb'}, c='v',d='b'),
            Edit(g='d'),
            Edit(h=1),
            Event(1),
            Event(11,'event'),
            Meter('meter',0,10,10),
            Label('label','c'),
            Trigger('1==1'),
            Complete('1==1'),
            Limit('limit',10),Limit('limit2',10),
            InLimit('limitName','/limit',2),
            Defstatus(DState.complete),
            Today(0,30),Today('00:59'),Today('00:00 11:30 00:01'),
            Time(0,30),Time('00:59'),Time('00:00 11:30 00:01'),
            Day('sunday'),Day(Days.monday),
            Date(1,1,0),Date(28,2,1960),
            Autocancel(3)
            ),
        [ Family('f{}'.format(i)) for i in range(1,6)]))

We can also use ‘+=’ with a list here are a few examples:

defs = Defs();
defs += [ Suite('s2'),Edit({ 'x1':'y', 'aa1':'bb'}, a='v',b='b') ]
defs += [ Suite('s{}'.format(i)) for i in range(1,6) ]
defs = Defs()
defs += [ Suite('suite').add(
             Task('x'),
             Family('f').add( [ Task('t{}'.format(i)) for i in range(1,6)] ),
             Task('y'),
             [ Family('f{}'.format(i)) for i in range(1,6) ],
             Edit(a='b'),
             [ Task('t{}'.format(i)) for i in range(1,6) ],
             )]

It is also possible to use ‘+’

defs = Defs() + Suite('s1')
defs.s1 += Autocancel(1, 10, True)
defs.s1 += Task('t1') + Edit({ 'e':1, 'f':'bb'}) +\
           Event(1) + Event(11,'event') + Meter('meter',0,10,10) + Label('label','c') + Trigger('1==1') +\
           Complete('1==1') + Limit('limit',10) + Limit('limit2',10) + InLimit('limitName','/limit',2) +\
           Defstatus(DState.complete) + Today(0,30) + Today('00:59') + Today('00:00 11:30 00:01') +\
           Time(0,30) + Time('00:59') + Time('00:00 11:30 00:01') + Day('sunday') + Day(Days.monday) +\
           Date(1,1,0) + Date(28,2,1960) + Autocancel(3)

Warning

We can only use ‘+’ when the left most object is a node, i.e Task(‘t1’) in this case

Node.add_autoarchive((Node)arg1, (int)days[, (bool)idle=False]) Node :

Add a autoarchive attribute. See ecflow.Autoarchive

Provides a way to automatically archive a suite/family which has completed.(i.e remove children) This is required when dealing with super large suite/families, they can be archived off, and then restored later. The node can be recovered using ‘autorestore’,begin,re-queue and manually via ecflow_client –restore. The archived node is written to disk, as ECF_HOME/<host>.<port>.ECF_NAME.check, where ‘/’ is replaced with ‘:’ in ECF_NAME. The removal may be delayed by an amount of time in hours and minutes or expressed as days Node removal is not immediate. The nodes are checked once a minute A Node may only have one autoarchive attribute

Exception:

  • Throws a RuntimeError if more than one auto archive is added

Usage:

t1 = Task('t1')
t1.add_autoarchive( Autoarchive(20,10,False) )  # hour,min, relative
t2 = Task('t2')
t2.add_autoarchive( 3 )                        # 3 days
t3 = Task('t3')
t3.add_autoarchive( 20,10,True )               # hour,minutes,relative
t4 = Task('t4')
t4.add_autoarchive( TimeSlot(20,10),True )     # hour,minutes,relative

# we can also create a Autoarchive in the Task constructor like any other attribute
t2 = Task('t2',
          Autoarchive(20,10,False))

add_autoarchive( (Node)arg1, (int)hour, (int)min, (bool)relative [, (bool)idle=False]) -> Node

add_autoarchive( (Node)arg1, (TimeSlot)TimeSlot, (bool)relative [, (bool)idle=False]) -> Node

add_autoarchive( (Node)arg1, (Autoarchive)arg2) -> Node

Node.add_autocancel((Node)arg1, (int)arg2) Node :

Add a autocancel attribute. See ecflow.Autocancel

This will delete the node on completion. The deletion may be delayed by an amount of time in hours and minutes or expressed as days Node deletion is not immediate. The nodes are checked once a minute and expired auto cancel nodes are deleted A node may only have one auto cancel attribute

Exception:

  • Throws a RuntimeError if more than one auto cancel is added

Usage:

t1 = Task('t1')
t1.add_autocancel( Autocancel(20,10,False) )  # hour,min, relative
t2 = Task('t2')
t2.add_autocancel( 3 )                        # 3 days
t3 = Task('t3')
t3.add_autocancel( 20,10,True )               # hour,minutes,relative
t4 = Task('t4')
t4.add_autocancel( TimeSlot(20,10),True )     # hour,minutes,relative

# we can also create a Autocancel in the Task constructor like any other attribute
t2 = Task('t2',
          Autocancel(20,10,False))

add_autocancel( (Node)arg1, (int)arg2, (int)arg3, (bool)arg4) -> Node

add_autocancel( (Node)arg1, (TimeSlot)arg2, (bool)arg3) -> Node

add_autocancel( (Node)arg1, (Autocancel)arg2) -> Node

Node.add_autorestore((Node)arg1, (Autorestore)arg2) Node :

Add a autorestore attribute. See ecflow.Autorestore

Auto-restore is used to automatically restore a previously auto-archived node. The restore will fail if:

  • The node has not been archived

  • The node has children.

  • The file ECF_HOME/<host>.<port>.ECF_NAME.check does not exist

Exception:

  • Throws a RuntimeError if more than one autorestore is added

Usage:

t1 = Task('t1')
t1.add_autorestore( ['/s1/f1'] )
t2 = Task('t2')
t2.add_autorestore( Autorestore(['/s2/f1','/s1/f2']) )
# we can also create a Autorestore in the Task constructor like any other attribute
t2 = Task('t2', Autorestore(['/s2/f1','/s1/f2'] ))

add_autorestore( (Node)arg1, (list)arg2) -> Node

Node.add_aviso((Node)arg1, (AvisoAttr)arg2) Node :

Adds an aviso to a node. See ecflow.Aviso

Node.add_complete((Node)arg1, (str)arg2) Node :

Add a trigger or complete expression.Also see ecflow.Trigger

This defines a dependency for a node. There can only be one trigger or complete expression dependency per node. A node with a trigger can only be activated when the trigger has expired. A trigger holds a node as long as the expression returns false.

Exception:

  • Will throw RuntimeError if multiple trigger or complete expression are added

  • Will throw RuntimeError if first expression is added as ‘AND’ or ‘OR’ expression Like wise second and subsequent expression must have ‘AND’ or ‘OR’ booleans set

Usage:

Note we cannot make multiple add_trigger(..) calls on the same task! to add a simple trigger:

task1.add_trigger( 't2 == active' )
task2.add_trigger( 't1 == complete or t4 == complete' )
task3.add_trigger( 't5 == active' )

Long expression can be broken up using add_part_trigger:

task2.add_part_trigger( 't1 == complete or t4 == complete')
task2.add_part_trigger( 't5 == active',True)  # True means  AND
task2.add_part_trigger( 't7 == active',False) # False means OR

The trigger for task2 is equivalent to: ‘t1 == complete or t4 == complete and t5 == active or t7 == active’

add_complete( (Node)arg1, (Expression)arg2) -> Node

Node.add_cron((Node)arg1, (Cron)arg2) Node :

Add a cron time dependency. See ecflow.Cron

Usage:

start = TimeSlot(0,0)
finish = TimeSlot(23,0)
incr = TimeSlot(0,30)
time_series = TimeSeries( start, finish, incr, True)
cron = Cron()
cron.set_week_days( [0,1,2,3,4,5,6] )
cron.set_days_of_month( [1,2,3,4,5,6] )
cron.set_months( [1,2,3,4,5,6] )
cron.set_time_series( time_series )
t1 = Task('t1')
t1.add_cron( cron )

# we can also create a Cron in the Task constructor like any other attribute
t2 = Task('t2',
          Cron('+00:00 23:00 00:30',days_of_week=[0,1,2,3,4,5,6],days_of_month=[1,2,3,4,5,6],months=[1,2,3,4,5,6]))
Node.add_date((Node)arg1, (int)arg2, (int)arg3, (int)arg4) Node :

Add a date time dependency. See ecflow.Date

A value of zero for day,month,year means every day, every month, every year

Exception:

  • Throws RuntimeError if an invalid date is added

Usage:

t1 = Task('t1',
          Date('1.*.*'),
          Date(1,1,2010)))    # Create Date in place

t1.add_date( Date(1,1,2010) ) # day,month,year
t1.add_date( 2,1,2010)        # day,month,year
t1.add_date( 1,0,0)           # day,month,year, the first of each month for every year

add_date( (Node)arg1, (Date)arg2) -> Node

Node.add_day((Node)arg1, (Days)arg2) Node :

Add a day time dependency. See ecflow.Day

Usage:

t1 = Task('t1',
          Day('sunday'))  # Create Day on Task creation

t1.add_day( Day(Days.sunday) )
t1.add_day( Days.monday)
t1.add_day( 'tuesday' )

add_day( (Node)arg1, (str)arg2) -> Node

add_day( (Node)arg1, (Day)arg2) -> Node

Node.add_defstatus((Node)arg1, (DState)arg2) Node :

Set the default status( defstatus ) of node at begin or re queue. See ecflow.Defstatus

A defstatus is useful in preventing suites from running automatically once begun, or in setting Task’s complete so they can be run selectively

Usage:

t1 = Task('t1') + Defstatus('complete')
t2 = Task('t2').add_defstatus( DState.suspended )

# we can also create a Defstatus in the Task constructor like any other attribute
t2 = Task('t3',
          Defstatus('complete'))
add_defstatus( (Node)arg1, (Defstatus)arg2) -> Node :

Set the default status( defstatus ) of node at begin or re queue. See ecflow.Defstatus

A defstatus is useful in preventing suites from running automatically once begun, or in setting Task’s complete so they can be run selectively

Usage:

t1 = Task('t1') + Defstatus('complete')
t2 = Task('t2').add_defstatus( DState.suspended )

# we can also create a Defstatus in the Task constructor like any other attribute
t2 = Task('t3',
          Defstatus('complete'))
Node.add_event((Node)arg1, (Event)arg2) Node :
Add a event. See ecflow.Event

Events can be referenced in trigger and complete expressions

Exception:

  • Throws RuntimeError if a duplicate is added

Usage:

t1 = Task('t1',
          Event(12),
          Event(11,'eventx'))             # Create events on Task creation

t1.add_event( Event(10) )                 # Create with function on Task
t1.add_event( Event(11,'Eventname') )
t1.add_event( 12 )
t1.add_event( 13, 'name')

To reference event ‘flag’ in a trigger:

t1.add_event('flag')
t2 = Task('t2',
          Trigger('t1:flag == set'))

add_event( (Node)arg1, (int)arg2) -> Node

add_event( (Node)arg1, (int)arg2, (str)arg3) -> Node

add_event( (Node)arg1, (str)arg2) -> Node

Node.add_generic((Node)arg1, (Generic)arg2) Node

add_generic( (Node)arg1, (str)arg2, (list)arg3) -> Node

Node.add_inlimit((Node)arg1, (str)limit_name[, (str)path_to_node_containing_limit=''[, (int)tokens=1[, (bool)limit_this_node_only=False]]]) Node :

Adds a inlimit to a node. See ecflow.InLimit

InLimit reference a limit/ecflow.Limit. Duplicate InLimits are not allowed

Exception:

  • Throws RuntimeError if a duplicate is added

Usage:

task2.add_inlimit( InLimit('limitName','/s1/f1',2) )
task2.add_inlimit( 'limitName','/s1/f1',2 )

add_inlimit( (Node)arg1, (InLimit)arg2) -> Node

Node.add_label((Node)arg1, (str)arg2, (str)arg3) Node :

Adds a label to a node. See ecflow.Label

Labels can be updated from the jobs files, via child command

Exception:

  • Throws RuntimeError if a duplicate label name is added

Usage:

task.add_label( Label('TEA','/me/'))
task.add_label( 'Joe','/me/')

The corresponding child command in the .ecf script file might be:

ecflow_client --label=TEA time
ecflow_client --label=Joe ninety

add_label( (Node)arg1, (Label)arg2) -> Node

Node.add_late((Node)arg1, (Late)arg2) Node :

Add a late attribute. See ecflow.Late

Exception:

  • Throws a RuntimeError if more than one late is added

Usage:

late = Late()
late.submitted( 20,10 )     # hour,minute
late.active(    20,10 )     # hour,minute
late.complete(  20,10,True) # hour,minute,relative
t1 = Task('t1')
t1.add_late( late )

# we can also create a Late in the Task constructor like any other attribute
t2 = Task('t2',
          Late(submitted='20:10',active='20:10',complete='+20:10'))
Node.add_limit((Node)arg1, (str)arg2, (int)arg3) Node :

Adds a limit to a node for simple load management. See ecflow.Limit

Multiple limits can be added, however the limit name must be unique. For a node to be in a limit, a inlimit must be used.

Exception:

  • Throws RuntimeError if a duplicate limit name is added

Usage:

family.add_limit( Limit('load',12) )
family.add_limit( 'load',12 )

add_limit( (Node)arg1, (Limit)arg2) -> Node

Node.add_meter((Node)arg1, (Meter)arg2) Node :
Add a meter. See ecflow.Meter

Meters can be referenced in trigger and complete expressions

Exception:

  • Throws RuntimeError if a duplicate is added

Usage:

t1 = Task('t1',
          Meter('met',0,50))                   # create Meter on Task creation
t1.add_meter( Meter('metername',0,100,50) )  # create Meter using function
t1.add_meter( 'meter',0,200)

To reference in a trigger:

t2 = Task('t2')
t2.add_trigger('t1:meter >= 10')

add_meter( (Node)arg1, (str)arg2, (int)arg3, (int)arg4 [, (int)arg5]) -> Node

Node.add_mirror((Node)arg1, (MirrorAttr)arg2) Node :

Adds a mirror to a node. See ecflow.Mirror

Node.add_part_complete((Node)arg1, (PartExpression)arg2) Node :

Add a trigger or complete expression.Also see ecflow.Trigger

This defines a dependency for a node. There can only be one trigger or complete expression dependency per node. A node with a trigger can only be activated when the trigger has expired. A trigger holds a node as long as the expression returns false.

Exception:

  • Will throw RuntimeError if multiple trigger or complete expression are added

  • Will throw RuntimeError if first expression is added as ‘AND’ or ‘OR’ expression Like wise second and subsequent expression must have ‘AND’ or ‘OR’ booleans set

Usage:

Note we cannot make multiple add_trigger(..) calls on the same task! to add a simple trigger:

task1.add_trigger( 't2 == active' )
task2.add_trigger( 't1 == complete or t4 == complete' )
task3.add_trigger( 't5 == active' )

Long expression can be broken up using add_part_trigger:

task2.add_part_trigger( 't1 == complete or t4 == complete')
task2.add_part_trigger( 't5 == active',True)  # True means  AND
task2.add_part_trigger( 't7 == active',False) # False means OR

The trigger for task2 is equivalent to: ‘t1 == complete or t4 == complete and t5 == active or t7 == active’

add_part_complete( (Node)arg1, (str)arg2) -> Node

add_part_complete( (Node)arg1, (str)arg2, (bool)arg3) -> Node

Node.add_part_trigger((Node)arg1, (PartExpression)arg2) Node :

Add a trigger or complete expression.Also see ecflow.Trigger

This defines a dependency for a node. There can only be one trigger or complete expression dependency per node. A node with a trigger can only be activated when the trigger has expired. A trigger holds a node as long as the expression returns false.

Exception:

  • Will throw RuntimeError if multiple trigger or complete expression are added

  • Will throw RuntimeError if first expression is added as ‘AND’ or ‘OR’ expression Like wise second and subsequent expression must have ‘AND’ or ‘OR’ booleans set

Usage:

Note we cannot make multiple add_trigger(..) calls on the same task! to add a simple trigger:

task1.add_trigger( 't2 == active' )
task2.add_trigger( 't1 == complete or t4 == complete' )
task3.add_trigger( 't5 == active' )

Long expression can be broken up using add_part_trigger:

task2.add_part_trigger( 't1 == complete or t4 == complete')
task2.add_part_trigger( 't5 == active',True)  # True means  AND
task2.add_part_trigger( 't7 == active',False) # False means OR

The trigger for task2 is equivalent to: ‘t1 == complete or t4 == complete and t5 == active or t7 == active’

add_part_trigger( (Node)arg1, (str)arg2) -> Node

add_part_trigger( (Node)arg1, (str)arg2, (bool)arg3) -> Node

Node.add_queue((Node)arg1, (Queue)arg2) Node

add_queue( (Node)arg1, (str)arg2, (list)arg3) -> Node

Node.add_repeat((Node)arg1, (RepeatDate)arg2) Node :

Add a RepeatDate attribute. See ecflow.RepeatDate

A node can only have one repeat Reference to a RepeatDate in a trigger will use date arithmetic in a sub expression. i.e. Here (/suite/family:YMD + 1) uses date arithmetic only, the result is still an integer

trigger /suite/family:YMD + 1 > 20190101

Exception:

  • Throws a RuntimeError if more than one repeat is added

Usage:

t1 = Task('t1')
t1.add_repeat( RepeatDate('YMD',20100111,20100115) )

# we can also create a repeat in Task constructor like any other attribute
t2 = Task('t2',
          RepeatDate('YMD',20100111,20100115))
add_repeat( (Node)arg1, (RepeatDateTime)arg2) -> Node :

Add a RepeatDateTime attribute. See ecflow.RepeatDateTime

A node can only have one repeat. When a RepeatDateTime is used in a trigger expression, the arithmetic value of the Repeat decays to second. For example, the expression /suite/family:DATETIME + 1 is evaluated as the number of seconds represented by /suite/family:DT (since the reference epoch, i.e. 19700101T000000) plus 1.The result is an integer.

trigger /suite/family:DT + 1 > 123456

Exception:

  • Throws a RuntimeError if more than one repeat is added

Usage:

t1 = Task('t1')
t1.add_repeat(RepeatDateTime('DT', '20100111T120000', '20100115T000000', '12:00:00'))

# we can also create a repeat in Task constructor like any other attribute
t2 = Task('t2',
          RepeatDateTime('DT', '20100101T000000', '20100115T000000', '1:00:00'))
add_repeat( (Node)arg1, (RepeatDateList)arg2) -> Node :

Add a RepeatDateList attribute. See ecflow.RepeatDateList

A node can only have one repeat Reference to a RepeatDateList in a trigger will use date arithmetic. i.e. Here (/suite/family:YMD + 1) uses date arithmetic only, the result is still an integer:

trigger /suite/family:YMD + 1 > 20190101

Exception:

  • Throws a RuntimeError if more than one repeat is added

Usage:

t1 = Task('t1')
t1.add_repeat( RepeatDateList('YMD',[20100111,20100115]) )

# we can also create a repeat in Task constructor like any other attribute
t2 = Task('t2',
          RepeatDateList('YMD',[20100111,20100115]))
add_repeat( (Node)arg1, (RepeatInteger)arg2) -> Node :

Add a RepeatInteger attribute. See ecflow.RepeatInteger

A node can only have one repeat

Exception:

  • Throws a RuntimeError if more than one repeat is added

Usage:

t1 = Task('t1')
t1.add_repeat( RepeatInteger('testInteger',0,100,2) )

# we can also create a repeat in Task constructor like any other attribute
t2 = Task('t2',
          RepeatInteger('testInteger',0,100,2))
add_repeat( (Node)arg1, (RepeatString)arg2) -> Node :

Add a RepeatString attribute. See ecflow.RepeatString

A node can only have one repeat

Exception:

  • Throws a RuntimeError if more than one repeat is added

Usage:

t1 = Task('t1')
t1.add_repeat( RepeatString('test_string',['a', 'b', 'c' ] ) )

# we can also create a repeat in Task constructor like any other attribute
t2 = Task('t2',
          RepeatString('test_string',['a', 'b', 'c' ] ) )
add_repeat( (Node)arg1, (RepeatEnumerated)arg2) -> Node :

Add a RepeatEnumerated attribute. See ecflow.RepeatEnumerated

A node can only have one repeat

Exception:

  • Throws a RuntimeError if more than one repeat is added

Usage:

t1 = Task('t1')
t1.add_repeat( RepeatEnumerated('test_string', ['red', 'green', 'blue' ] ) )

# we can also create a repeat in Task constructor like any other attribute
t2 = Task('t2',
          RepeatEnumerated('test_string', ['red', 'green', 'blue' ] ) )
add_repeat( (Node)arg1, (RepeatDay)arg2) -> Node :

Add a RepeatDay attribute. See ecflow.RepeatDay

A node can only have one repeat

Exception:

  • Throws a RuntimeError if more than one repeat is added

Usage:

t2 = Task('t2',
          RepeatDay(1))
Node.add_time((Node)arg1, (int)arg2, (int)arg3) Node :

Add a time dependency. See ecflow.Time

Usage:

t1 = Task('t1', Time('+00:30 20:00 01:00')) # Create Time in Task constructor
t1.add_time( '00:30' )
t1.add_time( '+00:30' )
t1.add_time( '+00:30 20:00 01:00' )
t1.add_time( Time( 0,10 ))      # hour,min,relative =false
t1.add_time( Time( 0,12,True )) # hour,min,relative
t1.add_time( Time(TimeSlot(20,20),False))
t1.add_time( 0,1 ))              # hour,min,relative=false
t1.add_time( 0,3,False ))        # hour,min,relative=false
start = TimeSlot(0,0)
finish = TimeSlot(23,0)
incr = TimeSlot(0,30)
ts = TimeSeries( start, finish, incr, True)
task2.add_time( Time(ts) )

add_time( (Node)arg1, (int)arg2, (int)arg3, (bool)arg4) -> Node

add_time( (Node)arg1, (str)arg2) -> Node

add_time( (Node)arg1, (Time)arg2) -> Node

Node.add_today((Node)arg1, (int)arg2, (int)arg3) Node :

Add a today time dependency. See ecflow.Today

Usage:

t1 = Task('t1',
          Today('+00:30 20:00 01:00')) # Create Today in Task constructor

t1.add_today( '00:30' )
t1.add_today( '+00:30' )
t1.add_today( '+00:30 20:00 01:00' )
t1.add_today( Today( 0,10 ))      # hour,min,relative =false
t1.add_today( Today( 0,12,True )) # hour,min,relative
t1.add_today( Today(TimeSlot(20,20),False))
t1.add_today( 0,1 ))              # hour,min,relative=false
t1.add_today( 0,3,False ))        # hour,min,relative=false
start = TimeSlot(0,0)
finish = TimeSlot(23,0)
incr = TimeSlot(0,30)
ts = TimeSeries( start, finish, incr, True)
task2.add_today( Today(ts) )

add_today( (Node)arg1, (int)arg2, (int)arg3, (bool)arg4) -> Node

add_today( (Node)arg1, (str)arg2) -> Node

add_today( (Node)arg1, (Today)arg2) -> Node

Node.add_trigger((Node)arg1, (str)arg2) Node :

Add a trigger or complete expression.Also see ecflow.Trigger

This defines a dependency for a node. There can only be one trigger or complete expression dependency per node. A node with a trigger can only be activated when the trigger has expired. A trigger holds a node as long as the expression returns false.

Exception:

  • Will throw RuntimeError if multiple trigger or complete expression are added

  • Will throw RuntimeError if first expression is added as ‘AND’ or ‘OR’ expression Like wise second and subsequent expression must have ‘AND’ or ‘OR’ booleans set

Usage:

Note we cannot make multiple add_trigger(..) calls on the same task! to add a simple trigger:

task1.add_trigger( 't2 == active' )
task2.add_trigger( 't1 == complete or t4 == complete' )
task3.add_trigger( 't5 == active' )

Long expression can be broken up using add_part_trigger:

task2.add_part_trigger( 't1 == complete or t4 == complete')
task2.add_part_trigger( 't5 == active',True)  # True means  AND
task2.add_part_trigger( 't7 == active',False) # False means OR

The trigger for task2 is equivalent to: ‘t1 == complete or t4 == complete and t5 == active or t7 == active’

add_trigger( (Node)arg1, (Expression)arg2) -> Node

Node.add_variable((Node)arg1, (str)arg2, (str)arg3) Node :

Adds a name value variable. Also see ecflow.Edit

This defines a variable for use in variable substitution in a ecf script file. There can be any number of variables. The variables are names inside a pair of ‘%’ characters in an ecf script. The name are case sensitive. Special character in the value, must be placed inside single quotes if misinterpretation is to be avoided. The value of the variable replaces the variable name in the ecf script at job creation time. The variable names for any given node must be unique. If duplicates are added then the the last value added is kept.

Exception:

  • Writes warning to standard output, if a duplicate variable name is added

Usage:

task.add_variable( Variable('ECF_HOME','/tmp/'))
task.add_variable( 'TMPDIR','/tmp/')
task.add_variable( 'COUNT',2)
a_dict = { 'name':'value', 'name2':'value2', 'name3':'value3' }
task.add_variable(a_dict)

add_variable( (Node)arg1, (str)arg2, (int)arg3) -> Node

add_variable( (Node)arg1, (Variable)arg2) -> Node

add_variable( (Node)arg1, (dict)arg2) -> Node

Node.add_verify((Node)arg1, (Verify)arg2) None :

Add a Verify attribute.

Used in python simulation used to assert that a particular state was reached. t2 = Task(‘t2’,

Verify(State.complete, 6)) # verify task completes 6 times during simulation

Node.add_zombie((Node)arg1, (ZombieAttr)arg2) Node :

The zombie attribute defines how a zombie should be handled in an automated fashion

Very careful consideration should be taken before this attribute is added as it may hide a genuine problem. It can be added to any node. But is best defined at the suite or family level. If there is no zombie attribute the default behaviour is to block the init,complete,abort child command. and fob the event,label,and meter child command This attribute allows the server to make a automated response. Please see: ecflow.ZombieType, ecflow.ChildCmdType, ecflow.ZombieUserActionType

Constructor:

ZombieAttr(ZombieType,ChildCmdTypes, ZombieUserActionType, lifetime)
   ZombieType            : Must be one of ZombieType.ecf, ZombieType.path, ZombieType.user
   ChildCmdType          : A list(ChildCmdType) of Child commands. Can be left empty in
                           which case the action affect all child commands
   ZombieUserActionType  : One of [ fob, fail, block, remove, adopt ]
   int lifetime<optional>: Defines the life time in seconds of the zombie in the server.
                           On expiration, zombie is removed automatically

Usage:

# Add a zombie attribute so that child commands(i.e ecflow_client --init)
# will fail the job if it is a zombie process.
s1 = Suite('s1')
child_list = [ ChildCmdType.init, ChildCmdType.complete, ChildCmdType.abort ]
s1.add_zombie( ZombieAttr(ZombieType.ecf, child_list, ZombieUserActionType.fob))

# create the zombie as part of the node constructor
s1 = Suite('s1',
           ZombieAttr(ZombieType.ecf, child_list, ZombieUserActionType.fail))
property Node.avisos

Returns a list of avisos

Node.change_complete((Node)arg1, (str)arg2) None
Node.change_trigger((Node)arg1, (str)arg2) None
property Node.crons

Returns a list of crons

property Node.dates

Returns a list of dates

property Node.days

Returns a list of days

Node.delete_complete((Node)arg1) None
Node.delete_cron((Node)arg1, (str)arg2) None

delete_cron( (Node)arg1, (Cron)arg2) -> None

Node.delete_date((Node)arg1, (str)arg2) None

delete_date( (Node)arg1, (Date)arg2) -> None

Node.delete_day((Node)arg1, (str)arg2) None

delete_day( (Node)arg1, (Day)arg2) -> None

Node.delete_event((Node)arg1, (str)arg2) None
Node.delete_generic((Node)arg1, (str)arg2) None
Node.delete_inlimit((Node)arg1, (str)arg2) None
Node.delete_label((Node)arg1, (str)arg2) None
Node.delete_limit((Node)arg1, (str)arg2) None
Node.delete_meter((Node)arg1, (str)arg2) None
Node.delete_queue((Node)arg1, (str)arg2) None
Node.delete_repeat((Node)arg1) None
Node.delete_time((Node)arg1, (str)arg2) None

delete_time( (Node)arg1, (Time)arg2) -> None

Node.delete_today((Node)arg1, (str)arg2) None

delete_today( (Node)arg1, (Today)arg2) -> None

Node.delete_trigger((Node)arg1) None
Node.delete_variable((Node)arg1, (str)arg2) None
Node.delete_zombie((Node)arg1, (str)arg2) None

delete_zombie( (Node)arg1, (ZombieType)arg2) -> None

Node.evaluate_complete((Node)arg1) bool :

evaluate complete expression

Node.evaluate_trigger((Node)arg1) bool :

evaluate trigger expression

property Node.events

Returns a list of events

Node.find_event((Node)arg1, (str)arg2) Event :

Find the event on the node only. Returns a object

Node.find_gen_variable((Node)arg1, (str)arg2) Variable :

Find generated variable on the node only. Returns an object

Node.find_generic((Node)arg1, (str)arg2) Generic :

Find the generic on the node only. Returns a Generic object

Node.find_label((Node)arg1, (str)arg2) Label :

Find the label on the node only. Returns a object

Node.find_limit((Node)arg1, (str)arg2) Limit :

Find the limit on the node only. returns a limit ptr

Node.find_meter((Node)arg1, (str)arg2) Meter :

Find the meter on the node only. Returns an object

Node.find_node_up_the_tree((Node)arg1, (str)arg2) Node :

Search immediate node, then up the node hierarchy

Node.find_parent_variable((Node)arg1, (str)arg2) Variable :

Find user variable variable up the parent hierarchy. Returns an object

Node.find_parent_variable_sub_value((Node)arg1, (str)arg2) str :

Find user variable up node tree, then variable substitute the value, otherwise return empty string

Node.find_queue((Node)arg1, (str)arg2) Queue :

Find the queue on the node only. Returns a queue object

Node.find_variable((Node)arg1, (str)arg2) Variable :

Find user variable on the node only. Returns an object

property Node.generics

Returns a list of generics

Node.get_abs_node_path((Node)arg1) str :

returns a string which holds the path to the node

Node.get_all_nodes((Node)arg1) NodeVec :

Returns all the child nodes

Node.get_autoarchive((Node)arg1) Autoarchive
Node.get_autocancel((Node)arg1) Autocancel
Node.get_autorestore((Node)arg1) Autorestore
Node.get_complete((Node)arg1) Expression
Node.get_defs((Node)arg1) Defs
Node.get_defstatus((Node)arg1) DState
Node.get_dstate((Node)arg1) DState :

Returns the state of node. This will include suspended state

Node.get_flag((Node)arg1) Flag :

Return additional state associated with a node.

Node.get_generated_variables((Node)arg1) list :

Returns the list of generated variables.

get_generated_variables( (Node)arg1, (VariableList)arg2) -> None :

Retrieves the list of generated variables. Pass in ecflow.VariableList as argument to hold variables.

Node.get_late((Node)arg1) Late
Node.get_parent((Node)arg1) Node
Node.get_repeat((Node)arg1) Repeat
Node.get_state((Node)arg1) State :

Returns the state of the node. This excludes the suspended state

Node.get_state_change_time((Node)arg1[, (str)format='iso_extended']) str :

Returns the time of the last state change as a string. Default format is iso_extended, (iso_extended, iso, simple)

Node.get_trigger((Node)arg1) Expression
Node.has_time_dependencies((Node)arg1) bool
property Node.inlimits

Returns a list of inlimits

Node.is_suspended((Node)arg1) bool :

Returns true if the node is in a suspended state

property Node.labels

Returns a list of labels

property Node.limits

Returns a list of limits

property Node.meters

Returns a list of meters

property Node.mirrors

Returns a list of mirrors

Node.name((Node)arg1) str
property Node.queues

Returns a list of queues

Node.remove((Node)arg1) Node :

Remove the node from its parent. and returns it

Node.replace_on_server((Node)arg1[, (bool)suspend_node_first=True[, (bool)force=True]]) None :

replace node on the server.

replace_on_server( (Node)arg1, (str)arg2, (str)arg3 [, (bool)suspend_node_first=True [, (bool)force=True]]) -> None :

replace node on the server.

replace_on_server( (Node)arg1, (str)arg2 [, (bool)suspend_node_first=True [, (bool)force=True]]) -> None :

replace node on the server.

replace_on_server( (Node)arg1, (Client)arg2 [, (bool)suspend_node_first=True [, (bool)force=True]]) -> None :

replace node on the server.

Node.sort_attributes((Node)arg1, (AttrType)arg2) None

sort_attributes( (Node)arg1, (AttrType)arg2, (bool)arg3) -> None

sort_attributes( (Node)arg1, (AttrType)arg2, (bool)arg3, (list)arg4) -> None

sort_attributes( (Node)arg1, (str)attribute_type [, (bool)recursive=True [, (list)no_sort=[]]]) -> None

sort_attributes( (Node)arg1, (AttrType)arg2, (bool)attribute_type [, (object)recursive=True]) -> None

property Node.times

Returns a list of times

property Node.todays

Returns a list of todays

Node.update_generated_variables((Node)arg1) None
property Node.variables

Returns a list of user defined variables

property Node.verifies

Returns a list of Verify’s

property Node.zombies

Returns a list of zombies