Native Python tasks

Here is an example of a script as a local native Python task: This example shows that we can still take advantage of pre-processing and variable substitution. This will work on the manual and comments section, these will also be pre-processed.

There are several ways of doing this. The following are examples.

  • There are two ways of accessing the ecFlow child commands (init, event, meter, label, abort, complete). We can either call the child commands directly using ecFlow extension, or we can call system command to access ecflow_client. The following examples will use the ecFlow Python extension. This requires that the PYTHONPATH is set to the directory where ecflow.so extension was installed.

  • definition file: The default ECF_MICRO is %, this may interfere with your Python scripts. In this case you either redefine it, in the task definition or directly in the Python script.

        task python
          edit ECF_MICRO '^'
          edit ECF_JOB_CMD '^ECF_JOB^ > ^ECF_JOBOUT^ 2>&1'
          label info "none"
          meter step -1 100 100
          event 1
          event 2
    

    Notice that the ECF_JOB_CMD calls Python. This allows us to change the Python version, within the viewer. Alternatively it can be omitted, providing we add “#!/usr/bin/env python” as th first line of our Python script.

  • headers:

    #!/usr/local/bin/python
    # head.py
    import os, sys, signal
    
    ECF_PORT = ^ECF_PORT:0^
    XSVR = "ecflow_client --port=%s --host=^ECF_HOST:0^ --" % ECF_PORT
    pid = os.getpid()
    
    def xinit(): 
        os.system(XSVR + "init %s"%pid)
    def xabort(): 
        os.system(XSVR + "abort %s"%pid)
    def xcomplete(): 
        os.system(XSVR + "complete")  
    def SigHandler(signum, frame): 
        xabort(); sys.exit(0)
    
    signal.signal (signal.SIGINT,  SigHandler); # ...
    os.environ['ECF_PORT'] = "^ECF_PORT:0^"
    os.environ['ECF_NAME'] = "^ECF_NAME:0^"
    os.environ['ECF_HOST'] = "^ECF_HOST:0^"
    os.environ['ECF_PASS'] = "^ECF_PASS:0^"
    
    def xmeter(name, step):
       os.system(XSVR + "meter %s %s"%(name,step))  
    def xevent(name):
       os.system(XSVR + "event %s"%name)  
    def xlabel(name, info):
       os.system(XSVR + "label %s %s"%(name,info))
    
    signal.signal (signal.SIGHUP,  SigHandler)
    signal.signal (signal.SIGQUIT, SigHandler)
    signal.signal (signal.SIGILL,  SigHandler)
    signal.signal (signal.SIGTRAP, SigHandler)
    signal.signal (signal.SIGIOT,  SigHandler)
    signal.signal (signal.SIGBUS,  SigHandler)
    signal.signal (signal.SIGFPE,  SigHandler)
    signal.signal (signal.SIGUSR1, SigHandler)
    signal.signal (signal.SIGUSR2, SigHandler)
    signal.signal (signal.SIGPIPE, SigHandler)
    signal.signal (signal.SIGTERM, SigHandler)
    signal.signal (signal.SIGXCPU, SigHandler)
    signal.signal (signal.SIGPWR,  SigHandler)
    
    print 'start'
    xinit()
    
    # tail.py
    xcomplete()
    
  • task wrapper:

    #!/usr/env python
    #python.ecf
    ^include <head.py>
    ^manual
    one liner manual ...
    ^end
    
    ^comment
    one liner
    ^end
    
    xlabel("info", "start")
    xevent("1")
    
    for step in range(0,101):
        print step
        xmeter("step", step)
    
    xevent("2")
    xlabel("info", "completion")
    ^include <tail.py>