使用 python 脚本

前面已经看到,ecFlow 有 ecFlow Python Api

  1. import ecflow

允许我们使用 python 构建 suite definition,也可以使用 python 与 ecflow_server 通讯。 这是个强大的功能,可以帮助我们以相对简化的方式定义复杂的 suite。

考虑下面的 suite:

  1. suite test
  2. family f1
  3. task a
  4. task b
  5. task c
  6. task d
  7. task e
  8. endfamily
  9. family f2
  10. task a
  11. task b
  12. task c
  13. task d
  14. task e
  15. endfamily
  16. family f3
  17. task a
  18. task b
  19. task c
  20. task d
  21. task e
  22. endfamily
  23. family f4
  24. task a
  25. task b
  26. task c
  27. task d
  28. task e
  29. endfamily
  30. family f5
  31. task a
  32. task b
  33. task c
  34. task d
  35. task e
  36. endfamily
  37. family f6
  38. task a
  39. task b
  40. task c
  41. task d
  42. task e
  43. endfamily
  44. endsuite

用 python 可以写成:

  1. def create_suite(name) :
  2. suite = Suite(name)
  3. for i in range(1, 7) :
  4. fam = suite.add_family("f" + str(i))
  5. for t in ( "a", "b", "c", "d", "e" ) :
  6. fam.add_task(t)
  7. return suite

或者使用更新的构造函数方法:

  1. def create_suite(name) :
  2. return Suite(name,
  3. [ Family("f{0}".format(i),
  4. [ Task(t) for t in ( "a", "b", "c", "d", "e") ])
  5. for i in range(1,7) ])

Python 变量可以用于生成 trigger dependencies。

想象我们将 family f1 到 family f6 串联到一起,f2 在 f1 后运行,f3 接着 f2 运行,以此类推。下面实现这个功能。

  1. def create_sequential_suite(name) :
  2. suite = ecflow.Suite(name)
  3. for i in range(1, 7) :
  4. fam = suite.add_family("f" + str(i))
  5. if i != 1:
  6. fam.add_trigger("f" + str(i-1) + " == complete") # or fam.add_family( "f%d == complete" % (i-1) )
  7. for t in ( "a", "b", "c", "d", "e" ) :
  8. fam.add_task(t)
  9. return suite

添加节点属性

有多种添加节点属性的方式,属性包括:

  • Repeat
  • Time
  • Today
  • Date
  • Day
  • Cron
  • Clock
  • DefStatus
  • Meter
  • Event
  • Variable
  • Label
  • Trigger
  • Complete
  • Limit
  • InLimit
  • Zombie
  • Late

函数方式

使用添加特定属性的函数:

  1. # Functional style
  2. node.add_variable(home,'COURSE') # c++ style
  3. node.add_limit('limitX',10) # c++ style

使用 add 函数添加任意属性:

  1. # Using <node>.add(<attributes>)
  2. node.add(Edit(home=COURSE), # Notice that add() allows you adjust the indentation
  3. Limit('limitX',10)) # node.add(<attributes>)

原地添加

创建节点时,将属性作为额外的参数(推荐方式)。支持类似文本方式的缩进。

  1. # in place. When creating a Node, attributes are additional arguments (preferred)
  2. # This also allows indentation.
  3. # Task(name,<attributes>)
  4. # Family(name,Node | <attributes>)
  5. # Suite(name,Node | <attributes>)
  6. node = Family('t1',
  7. Edit(home=COURSE),
  8. Limit('limitX',10),
  9. Task('t1,
  10. Event('e')))

表达式

  1. # Using <node> += <attribute> adding a single attribute
  2. node += Edit(home=COURSE)
  3. # Using <node> += [ <attributes> ] - use list to add multiple attributes
  4. node += [ Edit(home=COURSE), Limit('limitX',10), Event(1) ]
  5. # Using node + <attributes> - A node container(suite | family) must appear on the left hand side. Use brackets to control scope.
  6. node + Edit(home=COURSE) + Limit('limitX',10)
  7. # In this example, variable 'name' is added to suite 's/' and not task 't3'
  8. suite = Suite("s") + Family("f") + Family("f2") + Task("t3") + Edit(name="value")

生成的 def 文件如下:

  1. suite s
  2. edit name 'value'
  3. family f
  4. endfamily
  5. family f2
  6. endfamily
  7. task t3
  8. endsuite

可以使用括号控制变量添加到哪个节点。

  1. # here we use parenthesis to control where the variable get added.
  2. suite = Suite("s") + Family("f") + Family("f2") + (Task("t3") + Edit(name="value"))

生成的 def 文件如下:

  1. suite s
  2. family f
  3. endfamily
  4. family f2
  5. endfamily
  6. task t3
  7. edit name 'value'
  8. endsuite