ecFlow's documentation is now on readthedocs!

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 9 Next »

As you have already seen, ecFlow has a ecFlow Python Api:

#!/usr/bin/env python2.5
import ecflow 
This allows the suite definition to be built with python.
It also allows communication with the ecf_server.
This is a very powerful feature, that helps to define very complex suites in a relatively compact way.
Consider the following suite
suite test
 family f1
     task a
     task b
     task c
     task d
     task e
 endfamily
 family f2
     task a
     task b
     task c
     task d
     task e
 endfamily
 family f3
     task a
     task b
     task c
     task d
     task e
 endfamily
 family f4
     task a
     task b
     task c
     task d
     task e
 endfamily
 family f5
     task a
     task b
     task c
     task d
     task e
 endfamily
 family f6
     task a
     task b
     task c
     task d
     task e
 endfamily
endsuite

This can be written in python as:

def create_suite(name) : 
    suite = ecflow.Suite(name)
    for i in range(1,7) :
        fam = suite.add_family("f" + str(i))
        for t in ( "a", "b", "c", "d", "e" ) :
            fam.add_task(t);
    return suite     
 
Python variables can be used to generate trigger dependencies.
Imagine that we want to chain the families f1 to f6, so that f2 runs after f1, f3 after f2 and so on.
The following will do the trick:
def create_seqeuntial_suite(name) :
    suite = ecflow.Suite(name)
    for i in range(1,7) :
        fam = suite.add_family("f" + str(i))
        if i != 1: 
            fam.add_trigger("f" + str(i-1) + " == complete")  #  or fam.add_family( "f%d == complete" % (i-1) )
        for t in ( "a", "b", "c", "d", "e" ) :
            fam.add_task(t) 
    return suite
 
The following python code shows examples of adding the various attributes to a node tree.
For a detailed explanation please consult the user manual.
# provides *examples* of add adding node attributes using the python API
# hence does *not* represent a real suite definition
from ecflow import *
    
def list_to_int_vec( thePythonList ):
    """Converts a python list to a C++ IntVec in ecflow extension """
    intvec = IntVec()
    for theInt in thePythonList:
        IntVec.append(intvec,theInt)
    return intvec
    
def list_to_str_vec( theList ):
    """Converts a python list to a C++ StrVec in ecflow extension"""
    strvec = StrVec()
    for theStr in theList:
        StrVec.append(strvec,theStr)
    return strvec; 

if __name__ == "__main__":

    # adding variables 
    suite = Suite("s1");
    suite.add_variable(Variable("ECF_HOME","/tmp/"))
    suite.add_variable("ECF_URL_CMD", "${BROWSER:=firefox} -remote 'openURL(%ECF_URL_BASE%/%ECF_URL%)'")
     
    # adding limits
    suite.add_limit(  Limit("limitName1", 10) )
    suite.add_limit(  "limitName3", 10 )
  
    # adding inlimits
    suite.add_inlimit( InLimit("limitName1","/s1/f1",2) )
    suite.add_inlimit( "limitName3","/s1/f1",2)
 
    # add short triggers and complete
    task = Task("task")
    task.add_trigger( "t2 == active" )
    task.add_complete( "t2 == complete" )
      
    # add long triggers and complete, in example below 'True' mean AND and 'False' means OR
    task = Task("trigger")
    task.add_part_trigger(  "t1 == complete" )
    task.add_part_trigger(  "t2 == active",True )  #  for long and/or expressions, subsequent expr must be and/or
    task.add_part_complete( "t3 == complete" )
    task.add_part_complete( "t4 == active",False)  #  for long and/or expressions, subsequent expr must be and/or
    
    # add events
    task.add_event( Event(1) )
    task.add_event( 2 )
    task.add_event( Event(10,"Eventname") )
    task.add_event( 10,"Eventname2" )
    task.add_event( "fred" )

    # add meter
    task.add_meter( Meter("metername1",0,100,50) )
    task.add_meter( "metername3",0,100 )
  
    # add label
    task.add_label( Label("label_name1", "value") )
    task.add_label( "label_name3", "value" )
 
    # add Repeat. A node can only have one repeat, hence we delete the repeat before, adding another
    task.add_repeat( RepeatInteger("integer",0,100,2) );  
    task.delete_repeat();      
    task.add_repeat( RepeatEnumerated("enum",list_to_str_vec( ["red", "green", "blue" ] )) ); 
    task.delete_repeat();      
    task.add_repeat( RepeatDate("date",20100111,20100115,2) )
    task.delete_repeat();          
    task.add_repeat( RepeatString("string", list_to_str_vec( ["a", "b", "c" ] )) )
    task.delete_repeat();          
    
    # create a time series, used for adding time and today and cron
    start = TimeSlot(0,0)
    finish = TimeSlot(23,0)
    incr = TimeSlot(0,30)
    time_series = TimeSeries( start, finish, incr, True); # True means relative to suite start
  
    # add a today
    task.add_today( "00:30" )
    task.add_today( "+00:30" )
    task.add_today( "+00:30 20:00 01:00" )
    task.add_today( Today( time_series) )
    task.add_today( Today( 0,10 ))
    task.add_today( 0, 59, True )
    task.add_today( Today(TimeSlot(20,10)) )
    task.add_today( Today(TimeSlot(20,20),False)) 
                    
    # add time
    task.add_time( "00:30" )
    task.add_time( "+00:30" )
    task.add_time( "+00:30 20:00 01:00" )
    task.add_time( Time(time_series ))
    task.add_time( Time( 0,10 ))
    task.add_time( 0, 59, True)
    task.add_time( Time(TimeSlot(20,10)) )
    task.add_time( Time(TimeSlot(20,20),False)) 
 
    # add date
    for i in [ 1,2,4,8,16 ] :
      task.add_date( i,0,0)    # day,month,year, where corresponding 0 means any possible day,month, year
    task.add_date( Date(1,1,2010))

    # add day
    task.add_day( Day(Days.sunday))
    task.add_day( Days.monday)
    task.add_day( "tuesday")
    
    # create cron, showing different ways adding the time, to a cron attribute
    cron = Cron()
    cron.set_week_days( list_to_int_vec( [0,1,2,3,4,5,6] ) )
    cron.set_days_of_month( list_to_int_vec( [1,2,3,4,5,6] ) )
    cron.set_months( list_to_int_vec( [1,2,3,4,5,6] ) )
    start = TimeSlot(0,0)
    finish = TimeSlot(23,0)
    incr = TimeSlot(0,30)
    ts = TimeSeries( start, finish, incr, True);  # True means relative to suite start
    cron.set_time_series( ts )

    cron1 = Cron()
    cron1.set_week_days( list_to_int_vec( [0,1,2,3,4,5,6] ) )
    cron1.set_time_series( 1,30,  True )
    
    cron2 = Cron()
    cron2.set_week_days( list_to_int_vec( [0,1,2,3,4,5,6] ) )
    cron2.set_time_series( "00:30 01:30 00:01" )
    
    cron3 = Cron()
    cron3.set_week_days( list_to_int_vec( [0,1,2,3,4,5,6] ) )
    cron3.set_time_series( "+00:30" )
    
    # add auto cancel
    t1 = Task("t1");
    t3 = Task("t3")
    t4 = Task("t4")
    t5 = Task("t5")
    t1.add_autocancel( 3 )                       # 3 days
    t3.add_autocancel( 20,10,True )              # hour,minutes,relative
    t4.add_autocancel( TimeSlot(10,10),True )    # hour,minutes,relative
    t5.add_autocancel( Autocancel(1,10,True) )   # hour,minutes,relative
    
    # add late
    late = Late()
    late.submitted( TimeSlot(20,10) )
    late.active(    TimeSlot(20,10))
    late.complete(  TimeSlot(20,10),True)
    task.add_late(  late )
    
    late = Late()
    late.submitted( 20,10 )
    late.active(    20,10 )
    late.complete(  20,10,True)
    t1.add_late( late )
    
    # add defstatus, last one set takes effect
    task.add_defstatus( DState.complete )
    task.add_defstatus( DState.queued )
    task.add_defstatus( DState.aborted )
    task.add_defstatus( DState.submitted )
    task.add_defstatus( DState.suspended )
    task.add_defstatus( DState.active )
    
    # add clock,
    clock = Clock(1,1,2010,False);      # day,month, year, hybrid(true), real(False)
    clock.set_gain(1,10,True);          # True means positive gain
    suite =  Suite("suite")
    suite.add_clock(clock);
    
    clock = Clock(1,1,2011,True);       # day,month,year,hybrid
    clock.set_gain_in_seconds(12,True);
    s1 =  Suite("s1")
    s1.add_clock(clock)    
  • No labels