1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
|
.. index::
single: Python (tutorial)
.. _tutorial-using-python-scripting:
Using python scripting
======================
.. toctree::
:maxdepth: 1
indentation
object-oriented-suites
As you have already seen, ecFlow has a :ref:`python_api`:
.. code-block:: python
import ecflow
This allows the :term:`suite definition` to be built with python. It also allows communication with the :term:`ecflow_server`.
This is a very powerful feature, that helps to define very complex suites in a relatively compact way. Consider the following :term:`suite`:
.. code-block:: shell
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:
.. code-block:: python
def create_suite(name) :
suite = 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
or as:
.. code-block:: python
def create_suite(name) :
return Suite(name,
[ Family("f{0}".format(i),
[ Task(t) for t in ( "a", "b", "c", "d", "e") ])
for i in range(1,7) ])
Python variables can be used to generate :term:`trigger` :term:`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:
.. code-block:: shell
def create_sequential_suite(name) :
suite = Suite(name)
for i in range(1, 7) :
fam = suite.add_family("f" + str(i))
if i != 1:
fam += 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
For a detailed explanation please consult the :ref:`user_manual`.
Adding Node attributes
-----------------------------
There are several styles for adding node attributes(Repeat,Time,Today,Date,Day,Cron,Clock,DefStatus,Meter,Event,Variable,Label,Trigger, Complete, Limit,Inlimit,Zombie,Late)
.. code-block:: python
# Functional style
node.add_variable(home,'COURSE') # c++ style
node.add_limit('limitX',10) # c++ style
# Using <node>.add(<attributes>)
node.add(Edit(home=COURSE), # Notice that add() allows you adjust the indentation
Limit('limitX',10)) # node.add(<attributes>)
# in place. When creating a Node, attributes are additional arguments (preferred)
# This also allows indentation.
# Task(name,<attributes>)
# Family(name,Node | <attributes>)
# Suite(name,Node | <attributes>)
node = Family('t1',
Edit(home='COURSE'),
Limit('limitX',10),
Task('t1',
Event('e')))
# Using <node> += <attribute> adding a single attribute
node += Edit(home='COURSE')
# Using <node> += [ <attributes> ] - use list to add multiple attributes
node += [ Edit(home='COURSE'), Limit('limitY',10), Event(1) ]
# Using node + <attributes> - A node container(suite | family) must appear on the left hand side. Use brackets to control scope.
node + Edit(home=COURSE) + Limit('limitZ',10)
# In this example, variable 'name' is added to suite 's/' and not task 't3'
suite = Suite("s") + Family("f") + Family("f2") + Task("t3") + Edit(name="value")
suite s
edit name 'value'
family f
endfamily
family f2
endfamily
task t3
endsuite
# here we use parenthesis to control where the variable gets added
suite = Suite("s") + Family("f") + Family("f2") + (Task("t3") + Edit(name="value"))
suite s
family f
endfamily
family f2
endfamily
task t3
edit name 'value'
endsuite
|