foreach permalink

repeat step for each item in list permalink

Run the step once for each item in the list.

The iterator is context['i']. If you want to use the iterator value in your step with a substitution expression, you’d use {i}.

foreach is a list []. In your pipeline, you can specify this in two ways:

foreach: [item 1, item 2, item 3]

or

foreach:
  - item 1
  - item 2
  - item 3

loop static input list permalink

The foreach input is a list.

# ./foreach-example.yaml
steps:
  - name: pypyr.steps.echo
    foreach:
      - one
      - two
      - three at last
    in:
      echoMe: "{i}"
$ pypyr foreach-example
one
two
three at last

loop run-time list permalink

You can use substitutions to assign dynamic values to the list to iterate.

# ./foreach-substitution-example.yaml
context_parser: pypyr.parser.list
steps:
  - name: pypyr.steps.echo
    foreach: '{argList}'
    in:
      echoMe: "this time it's: {i}"

This example just uses the argList from the pypyr.parser.list context parser, but you can use any list you might have in your context.

$ pypyr foreach-substitution-example eggs bacon ham
this time it's: eggs
this time it's: bacon
this time it's: ham

run a sequence of steps in a loop permalink

You can loop on any step, whether it is your own or a built-in pypyr step. If you loop on a call step, you will run your foreach loop on the entire sequence of steps inside a step-group. This lets you loop over multiple steps as a unit. If you want to loop over an entire pipeline, use pype to invoke the pipeline and decorate the pype step in the same way.

# ./foreach-call.yaml
steps:
  - name: pypyr.steps.echo
    in:
      echoMe: begin
  - name: pypyr.steps.call
    comment: run entire sequence of steps
             in loop_me step-group in a loop.
    foreach:
      - item 1
      - item 2
      - item 3
    in:
      call: loop_me
  - name: pypyr.steps.echo
    in:
      echoMe: end

loop_me:
  - name: pypyr.steps.echo
    in:
      echoMe: this is foreach {i} executing like a boss.
  - name: pypyr.steps.cmd
    comment: you prob want to do something useful here
    in:
      cmd: echo yourcmd --dothing {i}

This results in:

$ pypyr foreach-call
begin
this is foreach item 1 executing like a boss.
yourcmd --dothing item 1
this is foreach item 2 executing like a boss.
yourcmd --dothing item 2
this is foreach item 3 executing like a boss.
yourcmd --dothing item 3
end

conditional execution inside loop permalink

The run, skip & swallow decorators evaluate dynamically on each iteration. So if during an iteration the step’s logic sets run=False, the step will not execute on the next iteration.

The loop will run to completion, though, so if a subsequent iteration sets run=True again, the step will execute again on the next loop iteration.

# ./foreach-run.yaml
steps:
  - name: pypyr.steps.echo
    in:
      echoMe: begin
  - name: pypyr.steps.contextsetf
    in:
      contextSetf:
        myThings:
          - name: thing 1
            isReady: True
          - name: thing 2
            isReady: False
          - name: thing 3
            isReady: True
  - name: pypyr.steps.echo
    comment: only run for thing when isReady.
    foreach: '{myThings}'
    run: '{i[isReady]}' 
    in:
      echoMe: do something with {i[name]}
  - name: pypyr.steps.echo
    in:
      echoMe: end!

When you run this pipeline, notice that the 2nd iteration skips execution, but it continues with the 3rd iteration:

$ pypyr foreach-run
begin
do something with thing 1
do something with thing 3
end!

see also

last updated on .