-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.xml
359 lines (359 loc) · 125 KB
/
index.xml
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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>task-runner for automation pipelines defined in yaml on pypyr</title><link>https://pypyr.io/</link><description>Recent content in task-runner for automation pipelines defined in yaml on pypyr</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Sun, 26 May 2024 14:37:13 -0700</lastBuildDate><atom:link href="https://pypyr.io/index.xml" rel="self" type="application/rss+xml"/><item><title>custom module name resolution</title><link>https://pypyr.io/docs/api/custom-module-search-path/</link><pubDate>Mon, 15 Nov 2021 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/api/custom-module-search-path/</guid><description>reference custom modules in your pipeline permalink TLDR:
Custom modules resolve relative to the current pipeline.
Although you can also resolve from the current directory as a fallback, this will make your pipeline less portable than it should be.
Prefer only using absolute names relative to the pipeline itself.
Each custom step, parser, loader &amp; retry algo you write lives in a .py file. In Python speak, this .py file is known as a &ldquo;module&rdquo;.</description></item><item><title>install pypyr</title><link>https://pypyr.io/docs/getting-started/installation/</link><pubDate>Thu, 13 Aug 2020 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/getting-started/installation/</guid><description>install pypyr permalink pip permalink $ pip install pypyr upgrades permalinkUse the standard pip upgrade switch:
$ pip install --upgrade pypyr supported o/s permalinkpypyr runs on Linux, MacOS &amp; Windows.
The automated CI process with 100% test coverage checks for cross-platform compatibility.
pypyr also runs on CI servers &amp; containers - pretty much anywhere with a Python run-time will work.
Windows users, please don&rsquo;t feel left out!
pypyr does run on Windows and the full automated test suite with 100% test coverage ensures Windows compatibility on every code change going into the main branch, same as for POSIX systems.</description></item><item><title>run your first pipeline</title><link>https://pypyr.io/docs/getting-started/run-your-first-pipeline/</link><pubDate>Thu, 13 Aug 2020 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/getting-started/run-your-first-pipeline/</guid><description>run your first pipeline permalink run a built-in pipeline permalinkRun one of the built-in pipelines to get a feel for it:
$ pypyr echo &#34;Ceci n&#39;est pas une pipe&#34; echo is the name of a built-in pypyr pipeline. The pipeline simply echoes the input string back to console output using the built-in echo step.
The actual pipeline looks like this:
# To execute this pipeline, shell something like: # pypyr echo text goes here context_parser: pypyr.</description></item><item><title>basic concepts</title><link>https://pypyr.io/docs/getting-started/basic-concepts/</link><pubDate>Thu, 13 Aug 2020 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/getting-started/basic-concepts/</guid><description>basic concepts permalink pipeline permalinkA pipeline is a sequence of steps. A pypyr pipeline is a simple human-readable and human-authored yaml file that defines your sequence of steps. pypyr interprets and runs the pipeline for you.
# ./arb-example-pipeline.yaml # optional context_parser: my.custom.parser # how you pass cli arguments to the pipeline. # mandatory steps: # step-group - step1 # run ./step1.py - step2 # run ./step2.py # optional. on_success: # step-group - my.</description></item><item><title>variables</title><link>https://pypyr.io/docs/getting-started/variables/</link><pubDate>Mon, 06 Sep 2021 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/getting-started/variables/</guid><description>how to use variables in a pypyr pipeline permalinkYou can use variables to parameterize your pypyr pipelines and pass values between steps. pypyr lets you pass values seamlessly between the pipeline yaml, the cli (or api) and the steps in the pipeline.
pypyr stores variables in the context. The context is a dictionary that stays in scope for the duration of the entire pipeline.
Variables can be simple types like string or int, and they can also contain complex nested structures like dictionaries or lists.</description></item><item><title>conditional logic</title><link>https://pypyr.io/docs/getting-started/conditional-logic/</link><pubDate>Wed, 08 Sep 2021 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/getting-started/conditional-logic/</guid><description>conditional logic permalink selectively run or skip step permalinkYou can control the flow of execution in your pipeline by selectively running or skipping a step based upon whether a conditional statement evaluates to True.
You use the run or skip decorators on any step to set your condition whether to execute the step.
By default, unless you explicitly tell pypyr differently, every step will run.
# getting-started/basic-conditional.yaml steps: - name: pypyr.</description></item><item><title>loops</title><link>https://pypyr.io/docs/getting-started/loops/</link><pubDate>Thu, 09 Sep 2021 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/getting-started/loops/</guid><description>loops permalinkYou can loop (or iterate) over any given step in a pypyr pipeline.
This means you can repeatedly run or loop over your own custom commands without writing any code.
Looping happens on the step-level, using the following step decorators:
foreach while The difference is that foreach iterates over every element in an iterable (such as a list), whereas while keeps on looping until a stop condition evaluates True.</description></item><item><title>error handling</title><link>https://pypyr.io/docs/getting-started/error-handling/</link><pubDate>Thu, 13 Aug 2020 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/getting-started/error-handling/</guid><description>error handling permalink stop all processing on error permalinkpypyr runs pipelines. . . and a pipeline is a sequence of steps. By default subsequent steps in the sequence should not run if a previous step failed.
If your desired behavior is for pipeline processing to stop and subsequent steps NOT to run once an error occurs somewhere, you don&rsquo;t have to do anything special, because this is what pypyr does by default.</description></item><item><title>config</title><link>https://pypyr.io/docs/getting-started/config/</link><pubDate>Sun, 14 Feb 2021 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/getting-started/config/</guid><description>configuration permalinkYou can configure pypyr run-time settings &amp; defaults using environment variables and configuration files.
This is entirely optional - by default pypyr runs out-of-box without any extra configuration necessary. If you&rsquo;re just getting started with pypyr, don&rsquo;t bother reading the rest of this, it&rsquo;s not essential - just be aware that you can configure pypyr if the need does arise.
Rather than use config to change run-time settings, you&rsquo;re more likely to use the config file(s) for extra functionality like injecting variables or defining your own shortcuts to longer pypyr command sequences.</description></item><item><title>pipeline yaml structure</title><link>https://pypyr.io/docs/pipelines/pipeline-structure/</link><pubDate>Thu, 13 Aug 2020 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/pipelines/pipeline-structure/</guid><description>pipeline yaml structure permalink pypyr pipeline format permalinkA pipeline is a .yaml file. pypyr uses YAML version 1.2.
Save pipelines wherever you please. To run a pipeline, execute pypyr pipelinename from the directory where you saved pipelinename.yaml
# This is an example showing the anatomy of a pypyr pipeline # A pipeline should be saved as {working dir}/mypipelinename.yaml. # Run the pipeline from {working dir} like this: pypyr mypipelinename # optional.</description></item><item><title>pipeline look-up order</title><link>https://pypyr.io/docs/pipelines/lookup-order/</link><pubDate>Thu, 13 Aug 2020 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/pipelines/lookup-order/</guid><description>pipeline look-up order permalink absolute vs relative paths permalinkYou can pass absolute or relative paths to pypyr.
posix term $ pypyr pipeline-name # relative path: ./pipeline-name.yaml $ pypyr subdir/pipeline-name # relative path: ./subdir/pipeline-name.yaml $ pypyr /subdir/pipeline-name # absolute path: /subdir/pipeline-name.yaml $ pypyr ~/subdir/pipeline-name # absolute path: /Users/username/subdir/pipeline-name.yaml _ windows term $ pypyr pipeline-name # relative path: .\pipeline-name.yaml $ pypyr subdir/pipeline-name # relative path: .\subdir\pipeline-name.yaml $ pypyr c:/subdir/pipeline-name # absolute path: c:\subdir\pipeline-name.</description></item><item><title>composability</title><link>https://pypyr.io/docs/pipelines/composability/</link><pubDate>Fri, 07 Oct 2022 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/pipelines/composability/</guid><description>composability permalinkYou can encapsulate your automation tasks as modular components that you can re-use and re-combine in different ways in other places.
Here are some common patterns for how to achieve modular &amp; composable pipelines. You can mix and match ideas from each in the same pipeline or suite of pipelines depending on what works for you, you don&rsquo;t exclusively have to stick to one way.
groups permalink have a single pipeline with multiple step-groups.</description></item><item><title>run a pipeline with the pypyr cli</title><link>https://pypyr.io/docs/cli/run-a-pipeline/</link><pubDate>Thu, 13 Aug 2020 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/cli/run-a-pipeline/</guid><description>run a pipeline from the cli permalink pass arguments &amp; command line switches to the cli permalinkpypyr runs the pipeline specified by the name that you pass to the cli.
To make your pipelines edit easier in your favorite yaml editor, use a .yaml extension, but to save on typing you don&rsquo;t need to enter the .yaml bit at the command line.
You can use your usual directory separators if you&rsquo;re running a pipeline in a sub-directory, like $ pypyr subdir/subsubdir/pipeline</description></item><item><title>pypyr.loaders.file</title><link>https://pypyr.io/docs/loaders/file/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/loaders/file/</guid><description>file loader permalinkThis is pypyr&rsquo;s default loader. It searches for pipelines on local disk based on the pipeline-name and loads the pipeline when it finds it.
The important thing to understand with this loader is how pypyr matches the pipeline name and the look-up order in which it traverses the filesystem to resolve a pipeline name.
The loader&rsquo;s fully qualified name is pypyr.loaders.file. You&rsquo;re very unlikely to have to specify this manually yourself, because if you don&rsquo;t specify any value for loader in the input args of the api pypyr will use this loader by default.</description></item><item><title>pypyr.loaders.string</title><link>https://pypyr.io/docs/loaders/string/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/loaders/string/</guid><description> string loader permalinkUse the string loader to inject a pipeline directly into pypyr without needing to save it to file first.
Specify pypyr.loaders.string for loader, and pass the pipeline body as a string to the pipeline_name argument.
from pypyr import pipelinerunner pipeline = &#34;&#34;&#34;\ steps: - name: pypyr.steps.set in: set: test: 1 &#34;&#34;&#34; context = pipelinerunner.run(pipeline_name=pipeline, loader=&#39;pypyr.loaders.string&#39;) assert context[&#39;test&#39;] == 1 print(context)</description></item><item><title>pipeline shortcuts</title><link>https://pypyr.io/docs/pipelines/shortcuts/</link><pubDate>Mon, 07 Mar 2022 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/pipelines/shortcuts/</guid><description>shortcuts permalinkYou can create shortcuts to complex command inputs in pypyr config.
A shortcut allows you to save longer command sequences so you can use a friendly short alias to run a pipeline with complex input arguments.
As with all pypyr config, you can create your shortcut in any of the yaml config files or in pyproject.toml.
config.yaml shortcuts: sc1: pipeline_name: /mydir/my-pipeline args: akey: a value anotherkey: 123 sc2: pipeline_name: /mydir/another-pipeline args: boolinput: true mylist: - one - two pyproject.</description></item><item><title>pypyr release v5.9.1</title><link>https://pypyr.io/updates/releases/v5.9.1/</link><pubDate>Fri, 22 Sep 2023 03:13:53 +0000</pubDate><guid>https://pypyr.io/updates/releases/v5.9.1/</guid><description>pypyr release v5.9.1 permalink upgrade yaml lib dep permalinkRelease Date: 2023-09-22T03:13:53Z
overview permalinkNo functional change.
This change forces the ruamel yaml library dependency to upgrade - as of version 5.9.0 pypyr depends on ruamel.yaml &gt;= 0.17.32.
If you do not have the latest version of ruamel and you use !jsonify, you will see:
AttributeError: &lsquo;RoundTripConstructor&rsquo; object has no attribute &lsquo;construct_unknown&rsquo;
what&rsquo;s changed permalink fix venv flaky test by @yaythomas in https://github.</description></item><item><title>pypyr release v5.9.0</title><link>https://pypyr.io/updates/releases/v5.9.0/</link><pubDate>Thu, 21 Sep 2023 08:21:12 +0000</pubDate><guid>https://pypyr.io/updates/releases/v5.9.0/</guid><description>pypyr release v5.9.0 permalink string loader permalinkRelease Date: 2023-09-21T08:21:12Z
summary permalink Add new pypyr.loaders.string loader that loads pipelines directly from strings. from pypyr import pipelinerunner pipeline = &#34;&#34;&#34;\ steps: - name: pypyr.steps.set in: set: test: 1 &#34;&#34;&#34; context = pipelinerunner.run(pipeline_name=pipeline, loader=&#34;pypyr.loaders.string&#34;) assert context[&#34;test&#34;] == 1 Fix bug with !jsonify custom tags failing to load with error &ldquo;ruamel.yaml.constructor.ConstructorError: could not determine a constructor for the tag &lsquo;!jsonify&rsquo;&rdquo;. this was due to a regression in the ruamel dependency what&rsquo;s changed permalink fix jsonify tag ruamel by @yaythomas in https://github.</description></item><item><title>pypyr release v5.8.0</title><link>https://pypyr.io/updates/releases/v5.8.0/</link><pubDate>Mon, 13 Mar 2023 01:40:33 +0000</pubDate><guid>https://pypyr.io/updates/releases/v5.8.0/</guid><description>pypyr release v5.8.0 permalink no_cache &amp; clear_all permalinkRelease Date: 2023-03-13T01:40:33Z
summary permalink convenience function to clear all caches in one call. import pypyr.cache.admin as cache_admin cache_admin.clear_all() disable caching entirely with new no_cache mode. from pypyr.config import config from pypyr import pipelinerunner # disable all caching config.no_cache = True # This will NOT save `my-pipe` to cache once its loaded. context = pipelinerunner.run(pipeline_name=&#39;my-pipe&#39;) what&rsquo;s changed permalink clear all cache, codecov token, tox 4 by @yaythomas in https://github.</description></item><item><title>pypyr release v5.7.1</title><link>https://pypyr.io/updates/releases/v5.7.1/</link><pubDate>Tue, 25 Oct 2022 13:36:29 +0000</pubDate><guid>https://pypyr.io/updates/releases/v5.7.1/</guid><description>pypyr release v5.7.1 permalink python 3.11 maintenance release permalinkRelease Date: 2022-10-25T13:36:29Z
summary permalink maintenance release, no new features bug fix for pypyr.steps.filereplace to honor flat format :ff directive python 3.11 compatibility confirmed on python 3.11 runtimes, the tomli dependency won&rsquo;t install separately anymore since it&rsquo;s part of stdlib now what&rsquo;s changed permalink pypyr.steps.filereplace get_formatted X2 by @yaythomas in https://github.com/pypyr/pypyr/pull/304 new codecov uploader by @yaythomas in https://github.com/pypyr/pypyr/pull/305 py 3.11 &amp; conditional tomli dep by @yaythomas in https://github.</description></item><item><title>pypyr release v5.7.0</title><link>https://pypyr.io/updates/releases/v5.7.0/</link><pubDate>Thu, 20 Oct 2022 15:00:13 +0000</pubDate><guid>https://pypyr.io/updates/releases/v5.7.0/</guid><description>pypyr release v5.7.0 permalink switch &amp; argskwargs permalinkRelease Date: 2022-10-20T15:00:13Z
summary permalink New switch step for IF-ELSE style branching in your pipelines! New argskwargs parser to combine plain args and key-value pairs (key=value) from the cli. keyvaluepairs and dict parsers now support having = in the value, so you can have key=one+one=two parse to {'key': 'one+one=two'} these parsers now also support passing args with no =, in which case arg1 becomes {'arg1': ''} what&rsquo;s changed permalink switch by @yaythomas in https://github.</description></item><item><title>pypyr.parser.argskwargs</title><link>https://pypyr.io/docs/context-parsers/argskwargs/</link><pubDate>Thu, 20 Oct 2022 10:26:36 +0100</pubDate><guid>https://pypyr.io/docs/context-parsers/argskwargs/</guid><description>pypyr.parser.argskwargs permalink parse list of args &amp; key=value pairs from cli permalinkPuts input cli arguments into a list argList. If an argument has a =, will save the key=value pair as a dictionary/mapping element.
term $ pypyr my-pipeline arg1 arg2 k1=value1 k2=value2 $ pypyr my-pipeline arg1 &#34;arg 2&#34; k1=&#34;value1&#34; k2=&#34;value 2&#34; The second example will result in your pipeline context looking like this:
{ &#39;argList&#39;: [&#39;arg1&#39;, &#39;arg 2&#39;], &#39;k1&#39;: &#39;value1&#39;, &#39;k2&#39;: &#39;value 2&#39; } This gives you cli input syntax very similar to makefile.</description></item><item><title>pypyr.steps.switch</title><link>https://pypyr.io/docs/steps/switch/</link><pubDate>Wed, 19 Oct 2022 13:54:25 +0100</pubDate><guid>https://pypyr.io/docs/steps/switch/</guid><description>pypyr.steps.switch permalink conditional branching permalinkControl-of-flow statement that lets you conditionally select between execution branches depending on whether the controlling case expression evaluates to True.
You can conceptualize this as an IF-THEN-ELSE or IF-ELIF-ELSE style conditional branch. If you&rsquo;re not branching between different execution paths, but instead just want to control whether an individual step runs, you can use the run or skip decorators instead.
# ./my-pipeline.yaml context_parser: pypyr.parser.string steps: - name: pypyr.</description></item><item><title>pypyr release v5.6.0</title><link>https://pypyr.io/updates/releases/v5.6.0/</link><pubDate>Wed, 05 Oct 2022 17:43:44 +0000</pubDate><guid>https://pypyr.io/updates/releases/v5.6.0/</guid><description>pypyr release v5.6.0 permalink venv create &amp; new flit build internals permalinkRelease Date: 2022-10-05T17:43:44Z
summary permalink Use a custom error message when pypyr.steps.assert raises an exception. new pypyr.steps.venv step to create venvs in parallel from yaml or toml config. new venv-create built-in pipeline so you can provision venvs concurrently from declarative config without having to write your own pipeline or script. pypyr is now built &amp; packaged by the excellent PEP517 compliant flit.</description></item><item><title>venv-create built-in pipeline</title><link>https://pypyr.io/docs/pipelines/built-in/venv-create/</link><pubDate>Wed, 05 Oct 2022 14:16:54 +0100</pubDate><guid>https://pypyr.io/docs/pipelines/built-in/venv-create/</guid><description>venv-create permalinkCreate virtual environments from a yaml or toml config file and install extra dependencies. To speed things up, the pipeline creates multiple venvs concurrently in parallel.
This pipeline uses the pypyr.steps.venv step under the covers, so check the step&rsquo;s documentation for further detail on the config inputs.
This pipeline creates Python stdlib virtual environments (venv) from declarative config without writing any script yourself. The underlying mechanism is pretty much the equivalent of $ python -m venv my-dir.</description></item><item><title>config-show built-in pipeline</title><link>https://pypyr.io/docs/pipelines/built-in/config-show/</link><pubDate>Wed, 05 Oct 2022 14:11:11 +0100</pubDate><guid>https://pypyr.io/docs/pipelines/built-in/config-show/</guid><description>config-show permalinkShow pypyr&rsquo;s current configuration settings and sources. This is useful to troubleshoot your configuration settings.
Run me like this:
$ pypyr config-show See troubleshooting config for details.</description></item><item><title>echo built-in pipeline</title><link>https://pypyr.io/docs/pipelines/built-in/echo/</link><pubDate>Wed, 05 Oct 2022 14:07:42 +0100</pubDate><guid>https://pypyr.io/docs/pipelines/built-in/echo/</guid><description> echo permalinkEchoes input args to output.
Run me like this:
$ pypyr echo hello there! hello there!</description></item><item><title>pypyrversion built-in pipeline</title><link>https://pypyr.io/docs/pipelines/built-in/pypyrversion/</link><pubDate>Wed, 05 Oct 2022 14:07:29 +0100</pubDate><guid>https://pypyr.io/docs/pipelines/built-in/pypyrversion/</guid><description> pypyrversion permalinkPrint the pypyr &amp; current Python version numbers to stdout.
Run me like this:
$ pypyr pypyrversion pypyr 5.6.0 python 3.10.6 The pipeline uses pypyr.steps.pypyrversion under the hood.
Running this pipeline does the same thing as the cli --version switch:
$ pypyr --version</description></item><item><title>magritte built-in pipeline</title><link>https://pypyr.io/docs/pipelines/built-in/magritte/</link><pubDate>Wed, 05 Oct 2022 14:05:19 +0100</pubDate><guid>https://pypyr.io/docs/pipelines/built-in/magritte/</guid><description>magritte permalinkVery serious ontological statement about pipes.
Run me like this:
$ pypyr magritte Deep Lore: I tend to use this as a quick smoke test to verify pypyr installed as expected. If this seemingly silly pipeline works, you know pypyr can run, find pipelines and that built-ins installed as expected.</description></item><item><title>pypyr.steps.venv</title><link>https://pypyr.io/docs/steps/venv/</link><pubDate>Tue, 04 Oct 2022 15:27:43 +0100</pubDate><guid>https://pypyr.io/docs/steps/venv/</guid><description>pypyr.steps.venv permalinkCreate Python stdlib virtual environments (venv) from config without writing any script yourself. This is the equivalent of running $ python -m venv my-dir.
This step lets you create venvs from within your automation pipeline.
If you just want to create a bunch of venvs but you don&rsquo;t want to write your own pipeline to do so, check out the built-in venv-create pipeline.
This steps creates multiple venvs in parallel concurrently, making for faster processing on what is usually a pretty slow process.</description></item><item><title>pypyr release v5.5.0</title><link>https://pypyr.io/updates/releases/v5.5.0/</link><pubDate>Thu, 26 May 2022 13:18:48 +0000</pubDate><guid>https://pypyr.io/updates/releases/v5.5.0/</guid><description>pypyr release v5.5.0 permalink concurrent cmds &amp; cmdOut dot notation permalinkRelease Date: 2022-05-26T13:18:48Z
Introduce pypyr.steps.cmds &amp; pypyr.steps.shells to run programs or shell statements asynchronously as parallel (concurrent) sub-processes. This means all the parallel commands start at the same time and run concurrently, rather than run serially one after the other. - name: pypyr.steps.cmds comment: copy 3 files concurrently in: cmds: - cp file1.ext /media/vol1/ - cp file2.ext /media/vol2/file2-archive.ext - cp file3.</description></item><item><title>pypyr.steps.shells</title><link>https://pypyr.io/docs/steps/shells/</link><pubDate>Mon, 23 May 2022 08:35:53 +0100</pubDate><guid>https://pypyr.io/docs/steps/shells/</guid><description>pypyr.steps.shells permalink run shell statements concurrently permalinkRuns shell statements in parallel in the default shell. The default shell is usually /bin/sh on POSIX, and on Windows it&rsquo;s cmd.exe.
Where the cmds step runs programs or executables, shells passes the commands through to the system shell. This means all your usual shell expressions are available, such as ~ expansions and your favorite bashisms.
If you just want to run parallel programs, scripts or executables with arguments, you do NOT need to use shells, you can use pypyr.</description></item><item><title>pypyr.steps.cmds</title><link>https://pypyr.io/docs/steps/cmds/</link><pubDate>Mon, 23 May 2022 08:35:40 +0100</pubDate><guid>https://pypyr.io/docs/steps/cmds/</guid><description>pypyr.steps.cmds permalink run programs concurrently permalinkRun programs, external scripts, applications or commands in parallel. This step launches executables as asynchronous subprocesses that run concurrently in parallel.
Step input can take two forms: simple syntax or expanded syntax. Simple syntax is just a list of strings. This will run the commands in parallel with the default options.
posix # simple syntax - name: pypyr.steps.cmds comment: copy 3 files concurrently in: cmds: - cp file1.</description></item><item><title>pypyr release v5.4.0</title><link>https://pypyr.io/updates/releases/v5.4.0/</link><pubDate>Thu, 14 Apr 2022 17:44:08 +0000</pubDate><guid>https://pypyr.io/updates/releases/v5.4.0/</guid><description>pypyr release v5.4.0 permalink run multiple commands &amp; shell statements in same step permalinkRelease Date: 2022-04-14T17:44:08Z
summary permalink pypyr.steps.cmd &amp; pypyr.steps.shell now also takes a list input to run multiple commands/shell statements in the same step! - name: pypyr.steps.cmd in: cmd: echo 0 - name: pypyr.steps.cmd in: cmd: - echo 1 - echo 2 - name: pypyr.steps.cmd in: cmd: run: - echo 3 - echo 4 save: False cwd: mydir/subdir Both the cmd and shell steps expanded to allow: decode output in different encodings save output as raw bytes or as encoded text.</description></item><item><title>pypyr release v5.3.0</title><link>https://pypyr.io/updates/releases/v5.3.0/</link><pubDate>Wed, 09 Mar 2022 16:38:06 +0000</pubDate><guid>https://pypyr.io/updates/releases/v5.3.0/</guid><description>pypyr release v5.3.0 permalink shortcuts permalinkRelease Date: 2022-03-09T16:38:06Z
Create shortcuts to your pypyr run commands &amp; their input args.
This is handy for creating short &amp; sweet aliases for longer pipeline run commands.
So if you have a pipeline you normally run like this: term $ pypyr arb/my-pipeline arg1=1234 arg2=&#34;/path/to long/annoying path to type/x&#34; arg3=&#34;arb&#39;hello&#34; You can create a shortcut alias for this like so: config.yaml shortcuts: my-shortcut: pipeline: arb/my-pipeline args: arg1: 1234 arg2: /path/to long/annoying path to type/x arg3: &#34;arb&#39;hello&#34; pyproject.</description></item><item><title>pypyr release v5.2.0</title><link>https://pypyr.io/updates/releases/v5.2.0/</link><pubDate>Sat, 19 Feb 2022 18:41:22 +0000</pubDate><guid>https://pypyr.io/updates/releases/v5.2.0/</guid><description>pypyr release v5.2.0 permalink encoding &amp; config permalinkRelease Date: 2022-02-19T18:41:22Z
pypyr is now configurable with yaml or pyproject.toml! See pypyr config for details. You can now use variables from a config file like pyproject.toml in your pipeline with pypyr.steps.configvars. You can now explicitly over-ride the default system encoding on any filesystem operations. On the steps with in and out files, you can seamlessly convert between different encodings - so you can have an input file in one encoding, and the output file in another.</description></item><item><title>pypyr.steps.python</title><link>https://pypyr.io/docs/steps/python/</link><pubDate>Sat, 19 Feb 2022 16:04:49 +0000</pubDate><guid>https://pypyr.io/docs/steps/python/</guid><description>pypyr.steps.python permalinkGet the full path of the executable binary of the Python interpreter running the current pypyr session.
The step writes the absolute path as a string to the python key in context.
This means that wherever you would&rsquo;ve invoked python or python3 as a subprocess, you can instead use {python}. This will replace the {python} token with the absolute path of the Python executable that is currently running pypyr.</description></item><item><title>pypyr.steps.configvars</title><link>https://pypyr.io/docs/steps/configvars/</link><pubDate>Sun, 13 Feb 2022 13:54:20 +0000</pubDate><guid>https://pypyr.io/docs/steps/configvars/</guid><description>pypyr.steps.configvars permalinkUse the configvars step to inject variables that you set in pyproject.toml or in the pypyr yaml config files into your pipeline. This allows you to get populate your pipeline variables dynamically from project configuration specific to your repo, or to use user or global settings in your pipeline.
configvars is a simple step that doesn&rsquo;t take any inputs - it just looks for vars in the pypyr config files.</description></item><item><title>pypyr release v5.1.0</title><link>https://pypyr.io/updates/releases/v5.1.0/</link><pubDate>Sun, 12 Dec 2021 19:57:55 +0000</pubDate><guid>https://pypyr.io/updates/releases/v5.1.0/</guid><description>pypyr release v5.1.0 permalink toml &amp; text+binary file read/write permalinkRelease Date: 2021-12-12T19:57:55Z
Finally, toml, has come, to pypyr! 🎆
pypyr.parser.tomlfile to initialize pipeline context with a toml file pypyr.steps.fetchtoml to read toml file into context as an object with typing pypyr.steps.filewritetoml to write specified context to output toml file - lets you create toml files on-the-fly programmatically. pypyr.steps.fileformattoml to read input toml file(s) specified by path, glob or list of paths, replace {formatting expressions} and write to output file(s).</description></item><item><title>pypyr.steps.fileread</title><link>https://pypyr.io/docs/steps/fileread/</link><pubDate>Sun, 12 Dec 2021 15:02:21 +0100</pubDate><guid>https://pypyr.io/docs/steps/fileread/</guid><description>pypyr.steps.fileread permalink read file into context permalinkLoad a file into the the pypyr context.
fileread works like this:
- name: pypyr.steps.fileread comment: read file in into context in: fileRead: path: path/to/file.ext # path to file key: arb # save file contents to this context key binary: False # Optional. Default False. Set True to read file as bytes. encoding: utf-8 # Optional. Default None (platform default). If path is relative, it resolves relative to the current working directory.</description></item><item><title>pypyr.steps.filewrite</title><link>https://pypyr.io/docs/steps/filewrite/</link><pubDate>Sun, 12 Dec 2021 11:38:51 +0100</pubDate><guid>https://pypyr.io/docs/steps/filewrite/</guid><description>pypyr.steps.filewrite permalink create file from any context object permalinkFormat &amp; write a payload to a file.
filewrite works like this:
- name: pypyr.steps.filewrite comment: write payload out to file at path. in: fileWrite: path: /path/to/output.ext # destination path payload: file content here # payload to write to path append: False # (optional) Default False to overwrite existing binary: False # (optional) Default False for text mode. True for bytes/binary. encoding: utf-8 # Optional.</description></item><item><title>pypyr.steps.filewritetoml</title><link>https://pypyr.io/docs/steps/filewritetoml/</link><pubDate>Sat, 11 Dec 2021 11:38:51 +0100</pubDate><guid>https://pypyr.io/docs/steps/filewritetoml/</guid><description>pypyr.steps.filewritetoml permalink create toml file from any context object permalinkFormat &amp; write a payload to a toml file on disk. This is useful for generating toml files from your pipeline, such as when you want to create configuration files dynamically on the fly.
filewritetoml works like this:
- name: pypyr.steps.filewritetoml comment: write context payload out to toml in: fileWriteToml: path: /path/to/output.toml # destination file payload: # (optional) payload to write to path key1: value1 # output a string key2: value2 key3: 124 # output int key4: false # output bool table: mylist: - 1 - 2 myvalue: arb value This will generate the following toml to /path/to/output.</description></item><item><title>pypyr.steps.fetchtoml</title><link>https://pypyr.io/docs/steps/fetchtoml/</link><pubDate>Thu, 09 Dec 2021 19:02:21 +0100</pubDate><guid>https://pypyr.io/docs/steps/fetchtoml/</guid><description>pypyr.steps.fetchtoml permalink load &amp; parse toml permalinkParse a toml fie and load it into the pypyr context.
This step requires the following key in the pypyr context:
- name: pypyr.steps.fetchtoml comment: fetch toml from path and store result in key. in: fetchToml: path: ./path.toml # required. path to file on disk. can be relative. key: destinationKey # optional. write toml to this context key. If you do not specify key, the toml structure writes directly to context root.</description></item><item><title>pypyr.parser.tomlfile</title><link>https://pypyr.io/docs/context-parsers/tomlfile/</link><pubDate>Thu, 09 Dec 2021 11:19:55 +0100</pubDate><guid>https://pypyr.io/docs/context-parsers/tomlfile/</guid><description>pypyr.parser.tomlfile permalink read toml file into context permalinkTake a path from the cli input argument, and read the toml file at that path into context. Strongly typed values in the source toml will translate into the pipeline context (in other words, integers will be integers, booleans will be booleans etc.). This lets you initialize the pipeline context from a toml file.
The input path can be relative or absolute. Relative paths are relative to the current working directory.</description></item><item><title>pypyr release v5.0.0</title><link>https://pypyr.io/updates/releases/v5.0.0/</link><pubDate>Sat, 20 Nov 2021 13:17:39 +0000</pubDate><guid>https://pypyr.io/updates/releases/v5.0.0/</guid><description>pypyr release v5.0.0 permalinkRelease Date: 2021-11-20T13:17:39Z
Implement adr2 relative pipelines + api changes.
In brief, this release lets pipelines reference custom modules &amp; child pipelines relative to the pipeline itself, rather than the current directory. This lets you create portable, re-usable &amp; composable pipeline libraries.
breaking changes permalinkThis is a major version increment because it comes with BREAKING CHANGES:
API: pipelinerunner.run() replaces both pipelinerunner.main() and pipelinerunner.main_with_context() API: def get_pipeline_definition(pipeline_name, working_directory) signature for custom pype loaders changes to def get_pipeline_definition(pipeline_name, parent) CLI: the —dir flag now only sets the directory for ad hoc custom Python modules, it does NOT also set the directory for pipelines anymore Final removal of deprecated get_formatted_iterable, get_formatted_string #195 &amp; pypyr.</description></item><item><title>pypyr release v4.6.0</title><link>https://pypyr.io/updates/releases/v4.6.0/</link><pubDate>Wed, 06 Oct 2021 11:20:21 +0000</pubDate><guid>https://pypyr.io/updates/releases/v4.6.0/</guid><description>pypyr release v4.6.0 permalink set, add, append. permalinkRelease Date: 2021-10-06T11:20:21Z
contextsetf now has a simpler, shorter alias set. The old, longer form contextsetf will keep on working, so you don&rsquo;t HAVE to change your pipelines. But hopefully the new shorter set syntax saves you some typing in the future! Create lists &amp; append items to it with pypyr.steps.append Create sets &amp; add items to it with pypyr.steps.add Since Python 3.</description></item><item><title>pypyr-slack release v1.2.0</title><link>https://pypyr.io/updates/releases/pypyr-slack/v1.2.0/</link><pubDate>Wed, 06 Oct 2021 10:01:18 +0000</pubDate><guid>https://pypyr.io/updates/releases/pypyr-slack/v1.2.0/</guid><description>pypyr-slack release v1.2.0 permalink Retire py 3.6. Add py 3.10 trove classifiers permalinkRelease Date: 2021-10-06T10:01:18Z
No functional change.
Just updates trove classifiers for pypi.
source permalinkYou can find pypyr-slack release v1.2.0 on github, where you can click through to associated Issues, Pull Requests and Users.
Released by yaythomas.</description></item><item><title>pypyr-aws release v1.3.0</title><link>https://pypyr.io/updates/releases/pypyr-aws/v1.3.0/</link><pubDate>Wed, 06 Oct 2021 10:01:15 +0000</pubDate><guid>https://pypyr.io/updates/releases/pypyr-aws/v1.3.0/</guid><description>pypyr-aws release v1.3.0 permalink Retire py 3.6. Add py 3.10 trove classifiers. permalinkRelease Date: 2021-10-06T10:01:15Z
No functional change.
Just updates trove classifiers for pypi.
source permalinkYou can find pypyr-aws release v1.3.0 on github, where you can click through to associated Issues, Pull Requests and Users.
Released by yaythomas.</description></item><item><title>pypyr.steps.add</title><link>https://pypyr.io/docs/steps/add/</link><pubDate>Tue, 05 Oct 2021 16:53:21 +0100</pubDate><guid>https://pypyr.io/docs/steps/add/</guid><description>pypyr.steps.add permalink add item to a set permalinkAdd item(s) to a set.
The difference between a set and a list is that a list allows duplicate elements, whereas every item in a set is unique. If you&rsquo;re looking to work with a list, use append instead. Sets are unordered, lists are ordered.
- name: pypyr.steps.add comment: add item to a set in: add: set: my_set # required. Name of set.</description></item><item><title>pypyr.steps.append</title><link>https://pypyr.io/docs/steps/append/</link><pubDate>Tue, 05 Oct 2021 14:42:26 +0100</pubDate><guid>https://pypyr.io/docs/steps/append/</guid><description>pypyr.steps.append permalink append item to a list permalinkAppend item(s) to the end of a list.
The full input for the append step looks like this:
- name: pypyr.steps.append comment: append item to list in: append: list: my_list # required. Name of list. addMe: list item # required. Append this to the list unpack: False # optional. Defaults False. If True, enumerate addMe &amp; append each item individually. Use the list argument to specify the name of the list.</description></item><item><title>pypyr release v4.5.0</title><link>https://pypyr.io/updates/releases/v4.5.0/</link><pubDate>Tue, 02 Feb 2021 11:18:53 +0000</pubDate><guid>https://pypyr.io/updates/releases/v4.5.0/</guid><description>pypyr release v4.5.0 permalink retry backoff &amp; cleaner api init permalinkRelease Date: 2021-02-02T11:18:53Z
Add retry backoff strategies. You can now use retry backoff algorithms like exponential or linear to control the sleep interval in between retries. The default fixed retry sleep interval now supports a list input, so the next sleep interval between retries can come from a list you provide yourself. Ref #216. For API consumers: Prevent duplicates in sys.</description></item><item><title>custom retry backoff</title><link>https://pypyr.io/docs/api/retry-backoff/</link><pubDate>Mon, 18 Jan 2021 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/api/retry-backoff/</guid><description>create a custom retry backoff algorithm permalink custom retry backoff algorithms permalinkA retry backoff strategy is an algorithm that varies the backoff interval between retries. If you do not want to use one of the builtin common backoff retry strategies, you can implement your own by deriving a callable from BackoffBase, which lives in pypyr.retries.
For real life inspiration, you can see all of pypyr&rsquo;s builtin retry backoff implementations on github.</description></item><item><title>pypyr release v4.4.1</title><link>https://pypyr.io/updates/releases/v4.4.1/</link><pubDate>Fri, 01 Jan 2021 14:54:19 +0000</pubDate><guid>https://pypyr.io/updates/releases/v4.4.1/</guid><description>pypyr release v4.4.1 permalink context parser initialize to empty rather than None permalinkRelease Date: 2021-01-01T14:54:19Z
Context parsers that create an entry in context now initialize to empty rather than None. This means you can directly use something like {argList}, {argDict} and argString (initializing respectively to [], {}, '') directly for things like foreach loops without having to worry about None checks. Your existing truthy checks for these values will work as before.</description></item><item><title>pypyr release v4.4.0</title><link>https://pypyr.io/updates/releases/v4.4.0/</link><pubDate>Sat, 26 Dec 2020 15:50:27 +0000</pubDate><guid>https://pypyr.io/updates/releases/v4.4.0/</guid><description>pypyr release v4.4.0 permalink simplified py step syntax &amp; imports for !py strings. permalinkRelease Date: 2020-12-26T15:50:27Z
New step pypyr.steps.pyimport to import references to the !py string namespace. This includes an underlying api signature change by removal of pypyr.utils.expressions.eval_string(), but this is sufficiently far down the call-chain that it shouldn’t affect any normal pipeline operator or api consumer. pypyr.steps.contextclearall wipes pyimport imported references in addition to the key/values inside context. Simplify pypyr.</description></item><item><title>pypyr.steps.pyimport</title><link>https://pypyr.io/docs/steps/pyimport/</link><pubDate>Wed, 25 Nov 2020 18:20:22 +0000</pubDate><guid>https://pypyr.io/docs/steps/pyimport/</guid><description>pypyr.steps.pyimport permalink import references for py strings permalinkImport module &amp; object references to the !py string namespace.
This allows you to use any importable Python code in your !py strings.
- name: pypyr.steps.pyimport comment: any subsequent !py strings can use these objects in: pyImport: | import itertools as itools import math import urllib.parse from pathlib import Path from fractions import Fraction as myfraction - name: pypyr.steps.set comment: use your pyimports anywhere you can use a formatting expression.</description></item><item><title>pypyr release v4.3.0</title><link>https://pypyr.io/updates/releases/v4.3.0/</link><pubDate>Thu, 12 Nov 2020 20:36:36 +0000</pubDate><guid>https://pypyr.io/updates/releases/v4.3.0/</guid><description>pypyr release v4.3.0 permalink streamlined api main() entry-point permalinkRelease Date: 2020-11-12T20:36:36Z
This one is for all the API consumers! The new API entry-point is likely to be useful to anyone who wants to pass regular Python objects directly to pypyr, rather than have to mediate through a string-based cli-orientated context_parser first.
Streamline main entrypoint API. close #201. main() allows consumer to set pype loader, rather than having to drop further down into api to load_and_run_pipeline() new main_with_context() allows you to use a standard Python dict to initialize context and bypass the pipeline&rsquo;s context_parser entirely.</description></item><item><title>pypyr release v4.2.0</title><link>https://pypyr.io/updates/releases/v4.2.0/</link><pubDate>Fri, 30 Oct 2020 00:27:59 +0000</pubDate><guid>https://pypyr.io/updates/releases/v4.2.0/</guid><description>pypyr release v4.2.0 permalink flat &amp; recursive format, !jsonify, parsejson permalinkRelease Date: 2020-10-30T00:27:59Z
python 3.9 compatibility officially confirmed &amp; enforced in CI. All good. Woo! 🎉 New Flat ff and Recursive rf formatting specifiers. #195 Check recursive vs flat format expressions for full documentation. Maintain backwards compatibility for all current formatting functionality. The get_formatted_string, get_formatted_iterable &amp; get_processed_string methods on Context() are now all deprecated. Use get_formatted_value instead. All of the deprecated functions will keep on working as before, but will print a WARN to the output.</description></item><item><title>pypyr.steps.jsonparse</title><link>https://pypyr.io/docs/steps/jsonparse/</link><pubDate>Mon, 26 Oct 2020 13:12:12 +0000</pubDate><guid>https://pypyr.io/docs/steps/jsonparse/</guid><description>pypyr.steps.jsonparse permalink parse json string into context object permalinkParse an input json string into the pypyr context as an object. This allows you to work with the deserialized objects from the json string like you would normally work with any data structures in the pypyr context - so you can use all the usual context handling functionality to set, edit &amp; manipulate context keys and values.
This step requires the jsonParse key in the pypyr context:</description></item><item><title>pypyr.steps.set</title><link>https://pypyr.io/docs/steps/set/</link><pubDate>Mon, 05 Oct 2020 13:28:46 +0100</pubDate><guid>https://pypyr.io/docs/steps/set/</guid><description>pypyr.steps.set permalink set context values with formatting &amp; dynamic expressions permalinkSet context keys with arbitrary values of different types. You can also use formatting expressions for assigning dynamic run-time values with substitutions.
This is roughly the equivalent of instantiating and assigning a variable in traditional programming.
Requires the set key in context. set is a dictionary of items to set in context. For example, here is how you can set arbitrary values with different types to arbitrary keys:</description></item><item><title>new site launch with hugo</title><link>https://pypyr.io/updates/news/new-site-launch-hugo/</link><pubDate>Wed, 09 Sep 2020 13:44:57 +0100</pubDate><guid>https://pypyr.io/updates/news/new-site-launch-hugo/</guid><description>new technical documentation website permalink📣 pypyr.io has a shiny new website. 📣
You&rsquo;re reading it right now! Hopefully, your eyeballs are relaaaaxing with that delicious dark mode.
If you want to learn more about the journey to create this site, check out technical documentation built with hugo.</description></item><item><title>technical documentation built with hugo</title><link>https://pypyr.io/docs/thank-you/built-with-hugo/</link><pubDate>Mon, 07 Sep 2020 12:09:06 +0100</pubDate><guid>https://pypyr.io/docs/thank-you/built-with-hugo/</guid><description>technical documentation built with hugo permalinkThis website builds on top of the popular open source static site generator hugo.
I was hoping to create a friendly &amp; helpful product site more so than just a cut-and-dry API technical information sheet. There are many great no- to low-code frameworks for publishing technical documentation out there, but generally these are more constrained when you need to step outside of the prescribed boundaries of the given layouts.</description></item><item><title>release v4.1.0</title><link>https://pypyr.io/updates/releases/v4.1.0/</link><pubDate>Sun, 30 Aug 2020 19:04:37 +0000</pubDate><guid>https://pypyr.io/updates/releases/v4.1.0/</guid><description>pypyr release v4.1.0 permalink step description (skipping) when skipping. permalinkRelease Date: 2020-08-30T19:04:37Z
Better description output - add (skipping) to output if the step is not running because run is False or skip is True. Ref #158. First release published from shiny new GitHub Action CI/CD! Add License to wheel published to pypi You can find pypyr release v4.1.0 on github, where you can click through to associated Issues, Pull Requests and Users.</description></item><item><title>pypyr-aws release v1.1.2</title><link>https://pypyr.io/updates/releases/pypyr-aws/v1.1.2/</link><pubDate>Sun, 30 Aug 2020 14:39:52 +0000</pubDate><guid>https://pypyr.io/updates/releases/pypyr-aws/v1.1.2/</guid><description>pypyr-aws release v1.1.2 permalink updated readme permalinkRelease Date: 2020-08-30T14:39:52Z
no functional change updated README for pypi to point to new https://pypyr.io/docs/plugins/aws/ documentation site remove shippable ci add GitHub Actions ci fix linting errors You can find pypyr-aws release v1.1.2 on github, where you can click through to associated Issues, Pull Requests and Users.
Released by yaythomas.</description></item><item><title>pypyr-slack release v1.1.1</title><link>https://pypyr.io/updates/releases/pypyr-slack/v1.1.1/</link><pubDate>Sun, 30 Aug 2020 13:25:13 +0000</pubDate><guid>https://pypyr.io/updates/releases/pypyr-slack/v1.1.1/</guid><description>pypyr-slack release v1.1.1 permalink slack api 2: no functional change permalinkRelease Date: 2020-08-30T13:25:13Z
no functional change update slack api to 2.x update pypyr docs to point to new https://pypyr.io website pypi author change move from shippable to GitHub Actions. You can find pypyr-slack release v1.1.1 on github, where you can click through to associated Issues, Pull Requests and Users.
Released by yaythomas.</description></item><item><title>pypyraws.steps.ecswaitprep</title><link>https://pypyr.io/docs/plugins/aws/steps/ecswaitprep/</link><pubDate>Thu, 20 Aug 2020 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/plugins/aws/steps/ecswaitprep/</guid><description>pypyraws.steps.ecswaitprep permalink wait for ecs state changes permalinkRun me after an ecs task run or stop to prepare an ecs waiter.
Prepares the awsWaitIn context key for pypyraws.steps.wait.
Available ecs waiters are:
ServicesInactive ServicesStable TasksRunning TasksStopped Full details here: http://boto3.readthedocs.io/en/latest/reference/services/ecs.html#waiters
Use this step after any of the following ecs client methods if you want to use one of the ecs waiters to wait for a specific state:
describe_services describe_tasks list_services specify awsEcsWaitPrepCluster if you don&rsquo;t want default list_tasks specify awsEcsWaitPrepCluster if you don&rsquo;t want default run_task start_task stop_task update_service input context permalinkYou don&rsquo;t have to use this step, you could always just construct the awsWaitIn dictionary in context yourself.</description></item><item><title>pypyraws.steps.s3fetchjson</title><link>https://pypyr.io/docs/plugins/aws/steps/s3fetchjson/</link><pubDate>Thu, 20 Aug 2020 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/plugins/aws/steps/s3fetchjson/</guid><description>pypyraws.steps.s3fetchjson permalinkFetch a json file from s3 and put the json values into context.
input permalinkRequired input context is:
s3Fetch: clientArgs: # optional arg1Name: arg1Value methodArgs: # mandatory Bucket: &#39;{bucket}&#39; Key: arb.json key: &#39;destination pypyr context key&#39; # optional clientArgs go to the aws s3 client constructor. These are optional. methodArgs go to the the s3 get_object call. The minimum required values are: Bucket Key key writes fetched json to this context key.</description></item><item><title>pypyraws.steps.s3fetchyaml</title><link>https://pypyr.io/docs/plugins/aws/steps/s3fetchyaml/</link><pubDate>Thu, 20 Aug 2020 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/plugins/aws/steps/s3fetchyaml/</guid><description>pypyraws.steps.s3fetchyaml permalinkFetch a yaml file from s3 and put the yaml structure into context.
input permalinkRequired input context is:
s3Fetch: clientArgs: # optional arg1Name: arg1Value methodArgs: # mandatory Bucket: &#39;{bucket}&#39; Key: arb.yaml key: &#39;destination pypyr context key&#39; # optional clientArgs go to the aws s3 client constructor. These are optional. methodArgs go to the the s3 get_object call. The minimum required values are: Bucket Key key writes fetched yaml to this context key.</description></item><item><title>pypyrslack.steps.send</title><link>https://pypyr.io/docs/plugins/slack/steps/send/</link><pubDate>Thu, 20 Aug 2020 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/plugins/slack/steps/send/</guid><description>pypyrslack.steps.send permalinkSend a message to slack.
input permalinkRequires the following context items:
slackToken your slack api token. Keep this secure. slackChannel send to this slack channel (include # in front) slackText the body of your message. Use your usual slack formatting chars. substitutions permalinkFor all inputs you can use substitution tokens, aka string interpolation. This substitutes anything between curly braces with the context value for that key. For example, if your context looked like this:</description></item><item><title>pypyraws.steps.wait</title><link>https://pypyr.io/docs/plugins/aws/steps/wait/</link><pubDate>Thu, 20 Aug 2020 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/plugins/aws/steps/wait/</guid><description>pypyraws.steps.wait permalink wait for aws state changes permalinkWait for things in AWS to complete before continuing pipeline.
Run any low-level boto3 client wait() from get_waiter.
Waiters use a client&rsquo;s service operations to poll the status of an AWS resource and suspend execution until the AWS resource reaches the state that the waiter is polling for or a failure occurs while polling.
http://boto3.readthedocs.io/en/latest/guide/clients.html#waiters
input permalinkThe input context requires:
awsWaitIn: serviceName: &#39;service name&#39; # Available services here: http://boto3.</description></item><item><title>pypyraws.steps.waitfor</title><link>https://pypyr.io/docs/plugins/aws/steps/waitfor/</link><pubDate>Thu, 20 Aug 2020 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/plugins/aws/steps/waitfor/</guid><description>pypyraws.steps.waitfor permalink custom waiter for aws state changes permalinkCustom waiter for any aws client operation. Where pypyraws.steps.wait uses the official AWS waiters from the low-level client api, this step allows you to execute any aws low-level client method and wait for a specified field in the response to become the value you want it to be.
AWS does not have waiters for all state changes. Use this to create your own waiter for any property state change.</description></item><item><title>authentication</title><link>https://pypyr.io/docs/plugins/aws/authentication/</link><pubDate>Wed, 19 Aug 2020 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/plugins/aws/authentication/</guid><description>aws authentication permalink configuring credentials permalinkpypyr-aws pretty much just uses the underlying boto3 authentication mechanisms. More info here: http://boto3.readthedocs.io/en/latest/guide/configuration.html
This means any of the following will work. The authentication settings lookup order is as follows:
IAM credentials when inside AWS permalinkIf you are running inside of AWS - on EC2 or inside an ECS container, it will automatically use IAM role credentials if it does not find credentials in any of the other places listed below.</description></item><item><title>authentication</title><link>https://pypyr.io/docs/plugins/slack/authentication/</link><pubDate>Wed, 19 Aug 2020 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/plugins/slack/authentication/</guid><description>slack authentication permalink Get slack api token permalinkTo authenticate against your slack, you need to create an api key. There&rsquo;re various ways of going about this, using legacy tokens, test tokens or a bot.
I generally create a bot. Given you&rsquo;re likely to use it just to send notifications to slack, rather than consume events from slack, it&rsquo;s a pretty simple setup just to get your api key.
Remember to invite and add the bot you create to the slack channel(s) to which you want to post.</description></item><item><title>pypyraws.steps.client</title><link>https://pypyr.io/docs/plugins/aws/steps/client/</link><pubDate>Wed, 19 Aug 2020 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/plugins/aws/steps/client/</guid><description>pypyraws.steps.client permalink use any low-level aws service client permalinkThis step provides an easy way of getting at the low-level AWS api from the pypyr pipeline runner. So in short, pretty much anything you can do with the AWS api you got it as the Big O might have said.
This step lets you specify the service name and the service method you want to execute dynamically. You can also control the service header arguments and the method arguments themselves.</description></item><item><title>substitutions</title><link>https://pypyr.io/docs/plugins/aws/substitutions/</link><pubDate>Wed, 19 Aug 2020 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/plugins/aws/substitutions/</guid><description>substitutions permalinkYou can use substitution tokens, aka string interpolation, where specified for context items. This substitutes anything between {curly braces} with the context value for that key.
This also works where you have dictionaries/lists inside dictionaries/lists. For example, if your context looked like this:
bucketValue: the.bucket keyValue: dont.kick moreArbText: wild awsClientIn: serviceName: s3 methodName: get_object methodArgs: Bucket: &#39;{bucketValue}&#39; Key: &#39;{keyValue}&#39; This will run s3 get_object to retrieve file dont.kick from the.</description></item><item><title>release v4.0.0</title><link>https://pypyr.io/updates/releases/v4.0.0/</link><pubDate>Mon, 17 Aug 2020 19:27:51 +0000</pubDate><guid>https://pypyr.io/updates/releases/v4.0.0/</guid><description>pypyr release v4.0.0 permalink Stop in failure handlers. in context cleanup default. permalinkRelease Date: 2020-08-17T19:27:51Z
BREAKING CHANGE: final deprecation of in args scope persisting after step execution. For full discussion please see #177. Preview functionality where setting environment variable $PYPYR_IN_CLEAN = 1 is now the default. You can remove the $PYPYR_IN_CLEAN variable from this release onwards. Henceforth pypyr removes in args from context after step completes. If you want to persist values in context beyond the current step, use pypyr.</description></item><item><title>pypyr.steps.contextcopy</title><link>https://pypyr.io/docs/steps/contextcopy/</link><pubDate>Sat, 15 Aug 2020 20:28:42 +0100</pubDate><guid>https://pypyr.io/docs/steps/contextcopy/</guid><description>pypyr.steps.contextcopy permalink copy values &amp; structures from one part of context to another permalinkCopies context values from already existing context values.
This is handy if you need to prepare certain keys in context where a next step might need a specific key. If you already have the value in context, you can create a new key (or update existing key) with that value.
contextcopy and set overwrite existing keys. If you want to merge new values into an existing destination hierarchy, use contextmerge instead.</description></item><item><title>release v3.2.2</title><link>https://pypyr.io/updates/releases/v3.2.2/</link><pubDate>Thu, 13 Aug 2020 19:34:08 +0000</pubDate><guid>https://pypyr.io/updates/releases/v3.2.2/</guid><description>pypyr release v3.2.2 permalink line + col no., repo rename, readme updates. permalinkRelease Date: 2020-08-13T19:34:08Z
Line + Column Number count from 1 not 0. fix #151 update README to point at new website pypyr.io. update CONTRIBUTING to point at new website. update documentation and pypi setup with new repo name. You can find pypyr release v3.2.2 on github, where you can click through to associated Issues, Pull Requests and Users.</description></item><item><title>pypyr.steps.assert</title><link>https://pypyr.io/docs/steps/assert/</link><pubDate>Thu, 13 Aug 2020 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/steps/assert/</guid><description>pypyr.steps.assert permalink stop pipeline execution if condition false permalinkAssert that something is True or equal to something else. The step raises an exception of type AssertionError if the assertion fails.
You can express an assert in three different ways:
- name: pypyr.steps.assert comment: evaluates `assert` as truthy in: assert: &#39;{evaluateMe}&#39; - name: pypyr.steps.assert comment: evaluate `this` as truthy in: assert: this: &#39;{evaluateMe}&#39; - name: pypyr.steps.assert comment: assert that two things are equal in: assert: this: &#39;{complexThing1}&#39; equals: &#39;{complexThing2}&#39; The first two mostly do the same thing, so use whichever pleases your eye more.</description></item><item><title>pypyr.steps.call</title><link>https://pypyr.io/docs/steps/call/</link><pubDate>Thu, 13 Aug 2020 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/steps/call/</guid><description>pypyr.steps.call permalink call another step in pipeline permalinkCall (invoke) another step-group in the same pipeline. Once the called group(s) are complete, pypyr continues processing from the point where you initiated the call.
If you want to jump to a different step-group and ignore the rest of the step-group you&rsquo;re in, use pypyr.steps.jump instead.
If you want to switch between calling different step-groups based on an input expression in IF-THEN-ELSE branch style, use pypyr.</description></item><item><title>custom context parser</title><link>https://pypyr.io/docs/api/context-parser/</link><pubDate>Thu, 13 Aug 2020 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/api/context-parser/</guid><description>create a custom context parser permalink parse custom cli arguments permalinkA context_parser parses the pypyr cli input arguments. Simply put, this is all the positional arguments after the pipeline-name in the cli.
$ pypyr pipelinename this is the args input In this example, ['this', 'is', 'the', 'args', 'input'] will go to the pipeline&rsquo;s context parser as input.
Generally, a context_parser is likely to take the input args list and create a dict with it somehow.</description></item><item><title>contribute to pypyr</title><link>https://pypyr.io/docs/contributing/contribute-to-pypyr/</link><pubDate>Thu, 13 Aug 2020 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/contributing/contribute-to-pypyr/</guid><description>contribute to pypyr permalinkpypyr is open source. Your contributions are most welcome.
Feel free to join the pypyr discussion on the pypyr community discussion forum.
bugs permalinkWell, you know. No one&rsquo;s perfect. Feel free to create an issue.
documentation permalinkYou don&rsquo;t have to code to contribute to open source software. Improving &amp; expanding documentation is a very important part of the process!
All content lives in markdown (.md) files, so you don&rsquo;t have to be particularly code orientated to interact with the copy editing.</description></item><item><title>custom args</title><link>https://pypyr.io/docs/cli/custom-args/</link><pubDate>Thu, 13 Aug 2020 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/cli/custom-args/</guid><description>pass custom optional arguments from the cli permalinkYou can pass your own arguments to your pipelines from the cli without writing any code. You can decide per pipeline what style of arguments work better for that specific pipeline, for example key-value pairs, or a single string, or boolean switches.
See context parsers for more information on how to pass your own arguments to a pipeline and how to use those runtime values in the pipeline.</description></item><item><title>custom pype loader</title><link>https://pypyr.io/docs/api/pipeline-loader/</link><pubDate>Thu, 13 Aug 2020 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/api/pipeline-loader/</guid><description>create a custom pipeline loader permalink load pipeline not on the local filesystem permalinkA pype loader is responsible for loading a pipeline.
The default pype loader is pypyr.loaders.file. You can change this default in config for default_loader.
This default loader loads pipelines from the local file-system, following the usual pypyr pipeline look-up sequence.
You can find all of pypyr&rsquo;s built-in loaders here.
If you want to load pipelines from somewhere else, like maybe a shared pipeline library, or implement your own caching, or maybe if you want to load a pipeline from something like s3 or consul, you can roll your own pype loader.</description></item><item><title>developer's guide for pypyr</title><link>https://pypyr.io/docs/contributing/developers-guide/</link><pubDate>Thu, 13 Aug 2020 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/contributing/developers-guide/</guid><description>developer&rsquo;s guide permalink coding style permalinkYou&rsquo;ve read pep8? pypyr uses flake8 as a quality gate during ci.
testing without worrying about dependencies permalinkRun tox to test the packaging cycle inside a tox virtual env, plus run all tests:
# run tests &amp; flake 8 linter $ tox -- ops/build # run tests, flake 8 linter, test packaging &amp; validate README.rst $ tox -- ops/build package This of course assumes you have tox installed in your current active Python environment.</description></item><item><title>pypyr.steps.echo</title><link>https://pypyr.io/docs/steps/echo/</link><pubDate>Thu, 13 Aug 2020 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/steps/echo/</guid><description>pypyr.steps.echo permalink write dynamic values to console output stdout permalinkEcho (i.e print) the context value echoMe to the output.
For example, if you had a pipeline like this:
# ./mypipeline.yaml context_parser: pypyr.parser.keyvaluepairs steps: - name: pypyr.steps.echo You can run:
$ pypyr mypipeline &#34;echoMe=Ceci n&#39;est pas une pipe&#34; Alternatively, if you had a pipeline like this:
# ./look-ma-no-params.yaml steps: - name: pypyr.steps.echo comment: Output echoMe in: echoMe: Ceci n&#39;est pas une pipe You can run:</description></item><item><title>privacy notice</title><link>https://pypyr.io/legal/privacy-notice/</link><pubDate>Thu, 13 Aug 2020 00:00:00 +0000</pubDate><guid>https://pypyr.io/legal/privacy-notice/</guid><description>privacy notice permalink cookie notice permalinkThis website uses Google Analytics. This is to see which pages are popular, and get a better understanding of which features you use most &amp; where we can improve documentation. Without it, we have no idea which browsing paths you are taking to find what you are looking for, how much time it takes for you to find what you need and as such whether the documentation is actually useful to you or not.</description></item><item><title>run pipeline api</title><link>https://pypyr.io/docs/api/run-pipeline/</link><pubDate>Thu, 13 Aug 2020 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/api/run-pipeline/</guid><description>run a pipeline from the api permalinkYou can run a pypyr automation pipeline programmatically from your own code using the python api.
Here&rsquo;s a silly pipeline:
# ./pipeline-dir/my-pipe.yaml context_parser: pypyr.parser.keyvaluepairs steps: - name: pypyr.steps.echo in: echoMe: piper {arbkey} that {anotherkey} again - name: pypyr.steps.set in: set: myoutput: I was set in the pipeline! input_values: - &#39;{arbkey}&#39; - &#39;{anotherkey}&#39; some_nesting: down_level: arb_number: 123 arb_bool: False Run this pipeline from the cli like this:</description></item><item><title>custom step</title><link>https://pypyr.io/docs/api/step/</link><pubDate>Thu, 13 Aug 2020 00:00:00 +0000</pubDate><guid>https://pypyr.io/docs/api/step/</guid><description>create a custom step permalinkIf you can&rsquo;t find a ready-made step that quite scratches your particular itch, don&rsquo;t hesitate to code your own step - it&rsquo;s easy, and very much the philosophy of pypyr that if you can write a quick couple of lines of python rather than contort your pipeline with clumsy step sequences, then do so! I know some frameworks don&rsquo;t really encourage you to stray outside the prescribed features, but not so pypyr - your custom steps are first-class citizens of the pypyrverse.</description></item><item><title>dependencies</title><link>https://pypyr.io/docs/thank-you/dependencies/</link><pubDate>Mon, 10 Aug 2020 14:18:44 +0100</pubDate><guid>https://pypyr.io/docs/thank-you/dependencies/</guid><description>dependencies permalinkpypyr is fortunate to stand on the shoulders of giants in the shape of the excellent open-source software that makes everything that much easier. With great thanks &amp; gratitude to:
dependency license description bumpversion MIT Release semantic version increments. coverage Apache 2.0 Code test coverage analysis. docutils BSD Documentation processing for setup.py flake8 MIT Code quality check &amp; linting. flit BSD 3-Clause Build &amp; packaging. pyfakefs Apache 2.0 Fake file-system for mocking during testing.</description></item><item><title>press kit</title><link>https://pypyr.io/press-kit/</link><pubDate>Sat, 08 Aug 2020 20:06:45 +0100</pubDate><guid>https://pypyr.io/press-kit/</guid><description>press kit permalink what is pypyr? permalinkpypyr is an open source task-runner for automation pipelines. pypyr lets you script sequential tasks in a simple yaml format with conditional execution, loops, error handling and retries for any step in your pipeline.
Like a turbo-charged shell script, but less finicky. Less tricky than a makefile.
You can run loops, conditionally execute steps based on conditions you specify, wait for status changes before continuing, break on failure conditions or swallow errors.</description></item><item><title>copyright & licensing</title><link>https://pypyr.io/legal/licensing/</link><pubDate>Sat, 08 Aug 2020 15:04:34 +0100</pubDate><guid>https://pypyr.io/legal/licensing/</guid><description>copyright &amp; licensing permalinkCode and documentation copyright 2017 - 2024, the pypyr contributors.
pypyr code is licensed under the Apache 2.0 license.
pypyr is free and open source software.</description></item><item><title>while loop decorator</title><link>https://pypyr.io/docs/decorators/while/</link><pubDate>Tue, 14 Jul 2020 13:09:24 +0100</pubDate><guid>https://pypyr.io/docs/decorators/while/</guid><description>while permalink repeat step(s) in while loop permalinkRepeat step until stop is True, or until you reach a configurable maximum iterations. You have to specify at least one of either max or stop.
If you specify both max and stop, the loop exits when stop is True as long as it&rsquo;s still under max iterations.
max will exit the loop even if stop is still False. If you want to error and stop processing when max exhausts set errorOnMax to True.</description></item><item><title>skip decorator</title><link>https://pypyr.io/docs/decorators/skip/</link><pubDate>Tue, 14 Jul 2020 11:38:26 +0100</pubDate><guid>https://pypyr.io/docs/decorators/skip/</guid><description>skip permalink selectively skip step permalinkSkip this step if True, run step if False. Evaluates after the run decorator. This means that if run is False, the step will never run, regardless of skip.
Default is False. This means by default pypyr will not skip a step.
If this looks like it&rsquo;s merely the inverse of run, that&rsquo;s because it is. Use whichever suits your pipeline better, or combine run and skip in the same pipeline to toggle at runtime which steps you want to execute.</description></item><item><title>run decorator</title><link>https://pypyr.io/docs/decorators/run/</link><pubDate>Tue, 14 Jul 2020 11:02:07 +0100</pubDate><guid>https://pypyr.io/docs/decorators/run/</guid><description>run permalink selectively run step permalinkRuns this step if True, skips step if False.
Default is True. The means by default pypyr will run a step unless you tell it otherwise.
You&rsquo;ll almost always use run with substitutions, so you set the value at run-time from context.
set run with substitution expressions permalinkYou can use truthy expressions with run, skip and swallow. This means you can selectively run a step depending on if an object is not null and evaluates truthy.</description></item><item><title>retry decorator</title><link>https://pypyr.io/docs/decorators/retry/</link><pubDate>Mon, 13 Jul 2020 13:37:06 +0100</pubDate><guid>https://pypyr.io/docs/decorators/retry/</guid><description>retry permalink automatic retries permalinkRetries the step until it succeeds. If you do not set retry, pypyr will not retry the step automatically. When you do set retry, pypyr will retry whatever step it is without you having to do anything else.
The retry iteration counter is retryCounter. You can use this as usual for any context value in a formatting string expression as {retryCounter}.
These are all the available configuration parameters for retry:</description></item><item><title>swallow decorator</title><link>https://pypyr.io/docs/decorators/swallow/</link><pubDate>Sat, 11 Jul 2020 22:04:10 +0100</pubDate><guid>https://pypyr.io/docs/decorators/swallow/</guid><description>swallow permalink ignore pipeline step error permalinkIf True, catch any errors raised by the step and continue to the next step. pypyr logs the error both the output and to runErrors in context, so you&rsquo;ll know what happened, but processing continues. When you set swallow to True, pypyr will NOT go to the step-group&rsquo;s failure handler.
You could think of this as on error resume next for your pipeline.</description></item><item><title>onError decorator</title><link>https://pypyr.io/docs/decorators/onerror/</link><pubDate>Sat, 11 Jul 2020 21:42:31 +0100</pubDate><guid>https://pypyr.io/docs/decorators/onerror/</guid><description>onError permalink add custom data to exception permalinkProvide custom error information if the step raises an exception. This lets you add extra information to the error itself.
If this step errors, write the contents of onError to runErrors[n].customError in context. Steps inside a failure handler then can use this information. Alternatively, subsequent steps can also use this information, assuming you&rsquo;ve got a swallow somewhere in the call chain.
onError can be a simple string, or your your own dict, or any given object.</description></item><item><title>description decorator</title><link>https://pypyr.io/docs/decorators/description/</link><pubDate>Sat, 11 Jul 2020 20:35:07 +0100</pubDate><guid>https://pypyr.io/docs/decorators/description/</guid><description>description permalink provide step status output permalinkdescription is text that prints to the output when the pipeline runs. This is useful to provide operators with visibility of pipeline progress, especially where steps themselves do not provide any output.
The description outputs at NOTIFY - 25 level. This means you will see it by default. If you want to suppress description output, run pypyr with --log higher than 25.
If you are looking to annotate your pipeline in a way that does not print to runtime output use comment instead.</description></item><item><title>comment decorator</title><link>https://pypyr.io/docs/decorators/comment/</link><pubDate>Sat, 11 Jul 2020 20:13:51 +0100</pubDate><guid>https://pypyr.io/docs/decorators/comment/</guid><description>comment permalink comment your pipeline code permalinkSimilar to code comments, comment is for pipeline authors to annotate a pipeline step for the usual reasons. Like remembering why on earth you did something in a certain way two weeks later.
comment does not output at run-time ever. If you&rsquo;re looking to add descriptive text that prints to output for pipeline consumer visibility, use description instead.
- name: pypyr.steps.set comment: this comment is for pipeline authors.</description></item><item><title>pypyr.steps.fileformattoml</title><link>https://pypyr.io/docs/steps/fileformattoml/</link><pubDate>Sat, 11 Jul 2020 17:23:36 +0100</pubDate><guid>https://pypyr.io/docs/steps/fileformattoml/</guid><description>pypyr.steps.fileformattoml permalink find &amp; replace tokens in toml file permalinkParses input toml file and creates an output toml file while substituting {tokens} in the source toml from the pypyr context.
Pretty much does the same thing as pypyr.steps.fileformat, only it makes it easier to work with curly braces for substitutions without tripping over any structural curly braces in the source toml.
This step does not preserve comments or whitespace. Use fileformat or filereplace if you want to preserve comments/whitespace.</description></item><item><title>in decorator</title><link>https://pypyr.io/docs/decorators/in/</link><pubDate>Sat, 11 Jul 2020 12:56:32 +0100</pubDate><guid>https://pypyr.io/docs/decorators/in/</guid><description>in permalink add input arguments to step context permalinkin sets the input arguments for a step. pypyr adds anything in in to the context so that the decorated step can use these key-value pairs.
in is a mapping, also known as a dict {}. You can use complex, nested structures. pypyr will honor the data types of the yaml values you set in your pipeline.
# arbitrarily complex nested input args, # with different data types, # just to make a point.</description></item><item><title>foreach loop decorator</title><link>https://pypyr.io/docs/decorators/foreach/</link><pubDate>Fri, 10 Jul 2020 19:07:51 +0100</pubDate><guid>https://pypyr.io/docs/decorators/foreach/</guid><description>foreach permalink repeat step for each item in list permalinkRun 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&rsquo;d use {i}.
foreach takes any iterable. In your pipeline yaml, you can specify this as a list [] in two ways:
foreach: [item 1, item 2, item 3] or
foreach: - item 1 - item 2 - item 3 loop static input list permalinkThe foreach input here is a standard list.</description></item><item><title>pypyr.parser.yamlfile</title><link>https://pypyr.io/docs/context-parsers/yamlfile/</link><pubDate>Thu, 09 Jul 2020 17:42:16 +0100</pubDate><guid>https://pypyr.io/docs/context-parsers/yamlfile/</guid><description>pypyr.parser.yamlfile permalink read yaml file into context permalinkOpens a yaml file from the input path and use it to initialize the pypyr context dictionary. Strongly typed values in the source yaml will translate into the pipeline context with the correct type. This lets you initialize pipeline context from a yaml file.
The input path can be relative or absolute. Relative paths are relative to the current working directory.
example permalinkGiven a yaml file like this, saved as .</description></item><item><title>pypyr.parser.string</title><link>https://pypyr.io/docs/context-parsers/string/</link><pubDate>Thu, 09 Jul 2020 16:52:56 +0100</pubDate><guid>https://pypyr.io/docs/context-parsers/string/</guid><description>pypyr.parser.string permalink put all cli input args into a single string permalinkTakes any arbitrary input from the cli input args and concatenate into a single string argString to initialize context.
If you have multiple sequential literal spaces right next to each other, escape these with single or double quotes.
Given a pipeline like this, arbitrarily saved as ./string-parser.yaml:
# ./string-parser.yaml context_parser: pypyr.parser.string steps: - pypyr.steps.debug # prints at log level &lt;=20 - name: pypyr.</description></item><item><title>pypyr.parser.list</title><link>https://pypyr.io/docs/context-parsers/list/</link><pubDate>Thu, 09 Jul 2020 16:34:56 +0100</pubDate><guid>https://pypyr.io/docs/context-parsers/list/</guid><description>pypyr.parser.list permalink parse cli input args into list permalinkAppend each input argument into a list argList to initialize context.
Escape literal spaces with single or double quotes.
Given a pipeline like this, arbitrarily saved as ./list-parser.yaml:
# ./list-parser.yaml context_parser: pypyr.parser.list steps: - pypyr.steps.debug # prints at log level &lt;=20 - name: pypyr.steps.echo comment: the args passed into the pypyr with list parser end up as a list in context under key argList in: echoMe: &#34;the 2nd thing on the input list is: {argList[1]}&#34; Each argument you pass via the cli will now be in the argList list:</description></item><item><title>pypyr.parser.keyvaluepairs</title><link>https://pypyr.io/docs/context-parsers/keyvaluepairs/</link><pubDate>Thu, 09 Jul 2020 12:26:36 +0100</pubDate><guid>https://pypyr.io/docs/context-parsers/keyvaluepairs/</guid><description>pypyr.parser.keyvaluepairs permalink pass key-value pairs from cli to pipeline permalinkTakes key=value pairs from cli arg input and initialize context with a dictionary where each pair becomes a dictionary element.
term $ pypyr my-pipeline key1=value1 key2=2 key3=&#34;value 3&#34; _ This will parse to context like this:
{ &#39;key1&#39;: &#39;value1&#39;, &#39;key2&#39;: &#39;2&#39;, &#39;key3&#39;: &#39;value 3&#39; } Escape literal spaces with single or double quotes.
Any arg without an = will parse to key: ''.</description></item><item><title>pypyr.parser.keys</title><link>https://pypyr.io/docs/context-parsers/keys/</link><pubDate>Thu, 09 Jul 2020 12:06:01 +0100</pubDate><guid>https://pypyr.io/docs/context-parsers/keys/</guid><description> pypyr.parser.keys permalink custom boolean switches from the cli permalinkFor each input argument, initialize context with a dictionary where each argument becomes the key, with value set to True.
Escape literal spaces with single or double quotes.
Given a pipeline like this, arbitrarily saved as ./keys-parser.yaml:
# ./keys-parser.yaml context_parser: pypyr.parser.keys steps: - pypyr.steps.debug # prints at log level &lt;=20 Running the pipeline with different inputs:
$ pypyr keys-parser --log 20 {} $ pypyr keys-parser a b c --log 20 {&#39;a&#39;: True, &#39;b&#39;: True, &#39;c&#39;: True} $ pypyr keys-parser &#34;a with space&#34; &#39; b&#39; c --log 20 {&#39; b&#39;: True, &#39;a with space&#39;: True, &#39;c&#39;: True}</description></item><item><title>pypyr.parser.jsonfile</title><link>https://pypyr.io/docs/context-parsers/jsonfile/</link><pubDate>Thu, 09 Jul 2020 11:19:55 +0100</pubDate><guid>https://pypyr.io/docs/context-parsers/jsonfile/</guid><description>pypyr.parser.jsonfile permalink read json file into context permalinkTakes a path from the cli input argument, and read the json file at that path into context. Strongly typed values in the source json will translate into the pipeline context. This lets you initialize pipeline context from a json file.
The input path can be relative or absolute. Relative paths are relative to the current working directory.
example permalinkGiven a json file like this, saved as .</description></item><item><title>pypyr.parser.json</title><link>https://pypyr.io/docs/context-parsers/json/</link><pubDate>Wed, 08 Jul 2020 19:18:15 +0100</pubDate><guid>https://pypyr.io/docs/context-parsers/json/</guid><description>pypyr.parser.json permalink parse json input string from cli permalinkTakes a json string from the cli argument input, parses it into a type-safe json object, and puts the object into the pypyr context.
pypyr honors the input json data types. In other words, bools are bools, numbers are numbers, nulls are nulls.
example permalinkGiven a pipeline like this, arbitrarily saved as ./json-parser.yaml:
# ./json-parser.yaml context_parser: pypyr.parser.json steps: # echoMe will be set in the input json str - pypyr.</description></item><item><title>pypyr.parser.dict</title><link>https://pypyr.io/docs/context-parsers/dict/</link><pubDate>Wed, 08 Jul 2020 18:44:23 +0100</pubDate><guid>https://pypyr.io/docs/context-parsers/dict/</guid><description>pypyr.parser.dict permalink create a dict from key=value pair string permalinkTakes a key=value pair string and returns a dictionary (aka a map) where each pair becomes a dictionary element inside a dict with name argDict.
Escape literal spaces with single or double quotes.
Any arg without an = will parse to key: ''. term $ pypyr my-pipeline arg0 key1=value1 key2=2 key3=&#34;value 3&#34; _ This will parse to context like this:</description></item><item><title>pypyr.steps.tar</title><link>https://pypyr.io/docs/steps/tar/</link><pubDate>Tue, 07 Jul 2020 17:42:21 +0100</pubDate><guid>https://pypyr.io/docs/steps/tar/</guid><description>pypyr.steps.tar permalink archive &amp; extract tar files with compression permalinkArchive and extract tars with or without compression.
- name: pypyr.steps.tar comment: extract &amp; archive tar in: tar: extract: - in: /path/my.tar out: /out/path archive: - in: /dir/to/archive out: /out/destination.tar format: &#39;&#39; # optional. &#39;&#39; | gz | bz2 | xz Either extract or archive should exist, or both. But not neither.
Optionally, you can also specify the tar compression format with format.</description></item><item><title>pypyr.steps.stopstepgroup</title><link>https://pypyr.io/docs/steps/stopstepgroup/</link><pubDate>Tue, 07 Jul 2020 17:36:13 +0100</pubDate><guid>https://pypyr.io/docs/steps/stopstepgroup/</guid><description>pypyr.steps.stopstepgroup permalinkStop current step-group. Doesn&rsquo;t run any success or failure handlers, it just stops the current step-group.
This is handy if you are using pypyr.steps.call or pypyr.steps.jump to run different step-groups, allowing you to stop just a child step-group but letting the calling parent step-group continue.
You can always use pypyr.steps.stopstepgroup as a simple step, because it doesn&rsquo;t need any input context properties.
If you use a Stop step-group instruction inside a failure handler it will stop processing at that point AND not quit reporting failure.</description></item><item><title>pypyr.steps.stoppipeline</title><link>https://pypyr.io/docs/steps/stoppipeline/</link><pubDate>Tue, 07 Jul 2020 17:26:12 +0100</pubDate><guid>https://pypyr.io/docs/steps/stoppipeline/</guid><description>pypyr.steps.stoppipeline permalink stop current pipeline immediately permalinkStop current pipeline. Doesn&rsquo;t run any success or failure handlers, it just stops the current pipeline.
This is handy if you are using pypyr.steps.pype to call child pipelines from a parent pipeline, allowing you to stop just a child pipeline but letting the parent pipeline continue.
You can always use pypyr.steps.stoppipeline as a simple step, because it doesn&rsquo;t need any input context properties.</description></item><item><title>pypyr.steps.stop</title><link>https://pypyr.io/docs/steps/stop/</link><pubDate>Tue, 07 Jul 2020 17:19:20 +0100</pubDate><guid>https://pypyr.io/docs/steps/stop/</guid><description>pypyr.steps.stop permalink stop pypyr immediately permalinkStop all pypyr processing immediately. Doesn&rsquo;t run any success or failure handlers, it just stops everything in its tracks, even when you&rsquo;re nested in child pipelines or a step-group call-chain.
You can always use pypyr.steps.stop as a simple step, because it doesn&rsquo;t need any input context properties.
If you use a Stop instruction inside a failure handler it will stop processing at that point AND not quit reporting failure.</description></item><item><title>pypyr.steps.shell</title><link>https://pypyr.io/docs/steps/shell/</link><pubDate>Tue, 07 Jul 2020 11:53:28 +0100</pubDate><guid>https://pypyr.io/docs/steps/shell/</guid><description>pypyr.steps.shell permalink run shell statements permalinkRuns the context value cmd in the default shell. On a sensible O/S, this is /bin/sh.
Where the cmd step runs a program or executable, shell passes the command through to the system shell. This means all your usual shell expressions are available, such as ~ expansions and your favorite bashisms.
If you are just looking to run a command or executable with arguments, you do not need to use shell, you can use pypyr.</description></item><item><title>pypyr.steps.safeshell</title><link>https://pypyr.io/docs/steps/safeshell/</link><pubDate>Tue, 07 Jul 2020 11:17:29 +0100</pubDate><guid>https://pypyr.io/docs/steps/safeshell/</guid><description> pypyr.steps.safeshell permalinkDeprecated alias for cmd.
Example pipeline yaml:
steps: - name: pypyr.steps.safeshell in: cmd: ls -a</description></item><item><title>pypyr.steps.nowutc</title><link>https://pypyr.io/docs/steps/nowutc/</link><pubDate>Tue, 07 Jul 2020 10:19:23 +0100</pubDate><guid>https://pypyr.io/docs/steps/nowutc/</guid><description>pypyr.steps.nowutc permalink get current utc timestamp permalinkWrites the current UTC date &amp; time to context nowUtc.
If you want local or wall time, check out pypyr.steps.now instead.
If you run this step as a simple step (with no input nowUtcIn formatting), the default datetime format is ISO8601. For example: YYYY-MM-DDTHH:MM:SS.ffffff+00:00
You can use explicit format strings to control the datetime representation. For a full list of available formatting codes, check python date &amp; time formatting</description></item><item><title>pypyr.steps.now</title><link>https://pypyr.io/docs/steps/now/</link><pubDate>Tue, 07 Jul 2020 10:14:55 +0100</pubDate><guid>https://pypyr.io/docs/steps/now/</guid><description>pypyr.steps.now permalink get current local timestamp permalinkWrites the current local date &amp; time to context now. Local time is also known as wall time.
If you want UTC time, check out pypyr.steps.nowutc instead.
If you run this step as a simple step (with no input formatting specified in nowIn), the default datetime format is ISO8601. For example: YYYY-MM-DDTHH:MM:SS.ffffff+00:00.
You can use explicit format strings to control the datetime representation. For a full list of available formatting codes, check python date &amp; time formatting</description></item><item><title>pypyr.steps.pypyrversion</title><link>https://pypyr.io/docs/steps/pypyrversion/</link><pubDate>Tue, 07 Jul 2020 10:10:38 +0100</pubDate><guid>https://pypyr.io/docs/steps/pypyrversion/</guid><description>pypyr.steps.pypyrversion permalink get current installed version permalinkOutput the same as:
pypyr --version This is an actual pipeline, though, so unlike --version, it&rsquo;ll use the standard pypyr logging format.
Example pipeline yaml:
steps: - pypyr.steps.pypyrversion Since this step does not have any input context, you can always run it as a simple step by just specifying the step-name as a string.</description></item><item><title>pypyr.steps.pype</title><link>https://pypyr.io/docs/steps/pype/</link><pubDate>Mon, 06 Jul 2020 18:44:14 +0100</pubDate><guid>https://pypyr.io/docs/steps/pype/</guid><description>pypyr.steps.pype permalink call another pipeline from current pipeline permalinkRun another pipeline from this step. This allows pipelines to invoke other pipelines. Why pype? Because the pypyr can pipe that song again.
pype is handy if you want to split a larger, cumbersome pipeline into smaller units. This helps testing, in that you can test smaller units as separate pipelines without having to re-run the whole big all-encompassing parent pipeline each time.</description></item><item><title>pypyr.steps.py</title><link>https://pypyr.io/docs/steps/py/</link><pubDate>Mon, 06 Jul 2020 13:17:22 +0100</pubDate><guid>https://pypyr.io/docs/steps/py/</guid><description>pypyr.steps.py permalink run inline python permalinkExecutes the context value py as a dynamically interpreted python code block.
This is useful for adding inline Python code right in your pipeline.
You can use all the usual Python built-ins like len, abs and so forth. You can import standard libraries or your own custom modules &amp; objects using the standard Python import syntax (e.g import x as y, from x import y).</description></item><item><title>pypyr.steps.pathcheck</title><link>https://pypyr.io/docs/steps/pathcheck/</link><pubDate>Mon, 06 Jul 2020 13:06:55 +0100</pubDate><guid>https://pypyr.io/docs/steps/pathcheck/</guid><description>pypyr.steps.pathcheck permalink check if paths exist permalinkCheck if a path exists on the filesystem. Supports globbing. A path can point to a file or a directory.
input permalinkThe pathCheck context key must exist.
- name: pypyr.steps.pathcheck in: pathCheck: ./do/i/exist.arb # single literal path - name: pypyr.steps.pathcheck in: pathCheck: ./**/*.py # single glob expression If you want to check for the existence of multiple paths, you can pass a list instead.</description></item><item><title>pypyr.steps.jump</title><link>https://pypyr.io/docs/steps/jump/</link><pubDate>Mon, 06 Jul 2020 12:43:39 +0100</pubDate><guid>https://pypyr.io/docs/steps/jump/</guid><description>pypyr.steps.jump permalink jump to another step in pipeline permalinkJump to another step-group. This effectively stops processing on the current step-group from which you are jumping.
If you want to return to the point of origin after the step-group you jumped to completes, use call instead.
input permalinkjump expects a context item jump. It can take one of two forms:
- name: pypyr.steps.jump comment: simple string means just call the step-group named &#34;jumphere&#34; in: jump: jumphere - name: pypyr.</description></item><item><title>pypyr.steps.glob</title><link>https://pypyr.io/docs/steps/glob/</link><pubDate>Mon, 06 Jul 2020 12:26:50 +0100</pubDate><guid>https://pypyr.io/docs/steps/glob/</guid><description>pypyr.steps.glob permalink get all matching existing paths from glob permalinkResolve a glob and get all the paths that exist on the filesystem for the input glob.
Any given path can point to a file or a directory.
The glob context key must exist in input context:
- name: pypyr.steps.glob in: glob: ./**/*.py # single glob If you want to resolve multiple globs simultaneously and combine the results, you can pass a list instead.</description></item><item><title>pypyr.steps.filewriteyaml</title><link>https://pypyr.io/docs/steps/filewriteyaml/</link><pubDate>Mon, 06 Jul 2020 12:07:43 +0100</pubDate><guid>https://pypyr.io/docs/steps/filewriteyaml/</guid><description>pypyr.steps.filewriteyaml permalink create yaml file from any context object permalinkFormat &amp; write a payload to a yaml file on disk. This is useful for generating yaml files from your pipeline such as when you want to create configuration files dynamically on the fly.
filewriteyaml works like this:
- name: pypyr.steps.filewriteyaml comment: write context payload out to yaml in: fileWriteYaml: path: /path/to/output.yaml # destination file payload: # (optional) payload to write to path key1: value1 # output yaml will have key2: value2 # key1 and key2 as string.</description></item><item><title>pypyr.steps.filewritejson</title><link>https://pypyr.io/docs/steps/filewritejson/</link><pubDate>Mon, 06 Jul 2020 11:38:51 +0100</pubDate><guid>https://pypyr.io/docs/steps/filewritejson/</guid><description>pypyr.steps.filewritejson permalink create json file from any context object permalinkFormat &amp; write a payload to a json file on disk. This is useful for generating json files from your pipeline such as when you want to create configuration files dynamically on the fly.
filewritejson works like this:
- name: pypyr.steps.filewritejson comment: write context payload out to json in: fileWriteJson: path: /path/to/output.json # destination file payload: # (optional) payload to write to path key1: value1 # output json will have key2: value2 # key1 and key2 as string key3: 124 # output int key4: false # output bool This will generate the following json to /path/to/output.</description></item><item><title>pypyr.steps.filereplace</title><link>https://pypyr.io/docs/steps/filereplace/</link><pubDate>Fri, 03 Jul 2020 18:00:13 +0100</pubDate><guid>https://pypyr.io/docs/steps/filereplace/</guid><description>pypyr.steps.filereplace permalink find &amp; replace arbitrary strings in a file permalinkParses input text file and replaces any given search strings.
The other fileformat steps, by way of contradistinction, uses string formatting expressions inside {braces} to format values against the pypyr context.
This step, however, lets you find any arbitrary search string and replace it with any replacement string. This is especially handy if you are working with a file where curly braces aren&rsquo;t helpful for a formatting expression - e.</description></item><item><title>pypyr.steps.fileformatyaml</title><link>https://pypyr.io/docs/steps/fileformatyaml/</link><pubDate>Thu, 02 Jul 2020 17:23:36 +0100</pubDate><guid>https://pypyr.io/docs/steps/fileformatyaml/</guid><description>pypyr.steps.fileformatyaml permalink find &amp; replace tokens in yaml file permalinkParses input yaml file and substitutes {tokens} from the pypyr context.
Pretty much does the same thing as pypyr.steps.fileformat, only it makes it easier to work with curly braces for substitutions without tripping over the yaml&rsquo;s structural braces.
If your yaml doesn&rsquo;t use curly braces that aren&rsquo;t meant for {token} substitutions, you can happily use pypyr.steps.fileformat instead - it&rsquo;s more memory efficient.</description></item><item><title>pypyr.steps.fileformatjson</title><link>https://pypyr.io/docs/steps/fileformatjson/</link><pubDate>Thu, 02 Jul 2020 17:23:30 +0100</pubDate><guid>https://pypyr.io/docs/steps/fileformatjson/</guid><description>pypyr.steps.fileformatjson permalink find &amp; replace tokens in json permalinkParses input json file and substitutes {tokens} from the pypyr context.
Pretty much does the same thing as pypyr.steps.fileformat, only it makes it easier to work with curly braces for substitutions without tripping over the json&rsquo;s structural braces.
Given input json like this:
{ &#34;k1&#34;: &#34;v1&#34;, &#34;k2&#34;: { &#34;k2.1&#34;: &#34;v2.1&#34;, &#34;k2.2&#34;: [ &#34;2.2.1&#34;, &#34;START {replaceMeNested} END&#34; ] }, &#34;k3&#34;: &#34;{replaceMeString}&#34;, &#34;k4&#34;: &#34;{replaceMeInt}&#34;, &#34;k5&#34;: &#34;{replaceMeBool}&#34;, &#34;{replaceMeKey}&#34;: &#34;this will replace the key&#34; } And a pipeline like this:</description></item><item><title>pypyr.steps.fileformat</title><link>https://pypyr.io/docs/steps/fileformat/</link><pubDate>Wed, 01 Jul 2020 20:17:37 +0100</pubDate><guid>https://pypyr.io/docs/steps/fileformat/</guid><description>pypyr.steps.fileformat permalink find &amp; replace tokens in text files permalinkParses input text file, substitutes {tokens} in the text of the file from the pypyr context and writes the result to an output file.
- name: pypyr.steps.fileformat comment: read a file from disk, do some substitutions, write back to disk. in: fileFormat: in: ./in/arb.txt # required out: ./out/arb.txt # optional So if you had a text file in/arb.txt like this:</description></item><item><title>pypyr.steps.fetchyaml</title><link>https://pypyr.io/docs/steps/fetchyaml/</link><pubDate>Wed, 01 Jul 2020 20:02:35 +0100</pubDate><guid>https://pypyr.io/docs/steps/fetchyaml/</guid><description>pypyr.steps.fetchyaml permalink load &amp; parse yaml permalinkLoads a yaml file into the pypyr context.
This step requires the following key in the pypyr context:
- name: pypyr.steps.fetchyaml description: fetch yaml from path in: fetchYaml: path: ./path.yaml # required. path to file on disk. can be relative. key: destinationKey # optional. write yaml to this context key. If you do not specify key, yaml writes directly to context root.
If you do not want to specify a key, you can also use the streamlined format:</description></item><item><title>pypyr.steps.fetchjson</title><link>https://pypyr.io/docs/steps/fetchjson/</link><pubDate>Wed, 01 Jul 2020 19:02:21 +0100</pubDate><guid>https://pypyr.io/docs/steps/fetchjson/</guid><description>pypyr.steps.fetchjson permalink load &amp; parse json permalinkLoads a json file into the pypyr context.
This step requires the following key in the pypyr context:
- name: pypyr.steps.fetchjson comment: fetch json from path in: fetchJson: path: ./path.json # required. path to file on disk. can be relative. key: destinationKey # optional. write json to this context key. If you do not specify key, json writes directly to context root.
If you do not want to specify a key, you can also use the streamlined format:</description></item><item><title>pypyr.steps.envget</title><link>https://pypyr.io/docs/steps/envget/</link><pubDate>Wed, 01 Jul 2020 17:19:44 +0100</pubDate><guid>https://pypyr.io/docs/steps/envget/</guid><description>pypyr.steps.envget permalink get environment variables into context permalinkGet environment variables, and assign an optional default value to context if the sought environment variables do not exist.
The difference between pypyr.steps.envget and pypyr.steps.env , is that pypyr.steps.envget won&rsquo;t raise an error if the $ENV doesn&rsquo;t exist.
The envget context key must exist.
All inputs support substitutions.
See a worked example for getting environment variables with defaults here.
get an environment variable with a default fallback permalink - name: pypyr.</description></item><item><title>pypyr.steps.env</title><link>https://pypyr.io/docs/steps/env/</link><pubDate>Wed, 01 Jul 2020 17:11:02 +0100</pubDate><guid>https://pypyr.io/docs/steps/env/</guid><description>pypyr.steps.env permalink use environment variables in your pipeline permalinkGet, set or unset environment variables.
The env context key must exist. env can contain a combination of get, set and unset keys. You must specify at least one of get, set and unset.
env: get: contextkey1: env1 contextkey2: env2 set: env1: value1 env2: value2 unset: - env1 - env2 This step will run whatever combination of Get, Set and Unset you specify.</description></item><item><title>pypyr.steps.default</title><link>https://pypyr.io/docs/steps/default/</link><pubDate>Wed, 01 Jul 2020 12:22:55 +0100</pubDate><guid>https://pypyr.io/docs/steps/default/</guid><description>pypyr.steps.default permalink initialize the context with default values permalinkSets values in context if they do not exist already. Does not overwrite existing values. Supports nested hierarchies.
This is especially useful for setting default values in context, for example when using optional arguments from the cli.
This step sets the contents of the context key defaults into context where keys in defaults do not exist in context already. The contents of the defaults key must be a dictionary.</description></item><item><title>pypyr.steps.debug</title><link>https://pypyr.io/docs/steps/debug/</link><pubDate>Wed, 01 Jul 2020 12:03:17 +0100</pubDate><guid>https://pypyr.io/docs/steps/debug/</guid><description>pypyr.steps.debug permalink debug the context permalinkPretty print the context to output.
Print the pypyr context to the pypyr output. This is likely to be the console. This may assist in debugging when trying to see what values are what.
debug prints to the INFO (20) log-level. This means you won&rsquo;t see debug output unless you specify pypyr mypype --log 20 or lower value for log. If you have values you that always want to print to output, echo is the more natural step to use.</description></item><item><title>pypyr.steps.contextsetf</title><link>https://pypyr.io/docs/steps/contextsetf/</link><pubDate>Tue, 30 Jun 2020 20:28:46 +0100</pubDate><guid>https://pypyr.io/docs/steps/contextsetf/</guid><description>pypyr.steps.contextsetf permalinkUse pypyr.steps.set instead - it does the same thing but the name is shorter so less typing, woo! Your keyboard will thank you in the long run.
Although contextsetf is not going anywhere, new updates &amp; fixes will only go to set.</description></item><item><title>pypyr.steps.contextmerge</title><link>https://pypyr.io/docs/steps/contextmerge/</link><pubDate>Tue, 30 Jun 2020 19:51:26 +0100</pubDate><guid>https://pypyr.io/docs/steps/contextmerge/</guid><description>pypyr.steps.contextmerge permalink merging context values permalinkMerges values into context, preserving the existing hierarchy while only updating the differing values as specified in the contextMerge input.
By comparison, contextcopy and set overwrite the destination hierarchy that is in context already.
This step merges the contents of the context key contextMerge into context. The contents of the contextMerge key must be a dictionary.
examples permalinkFor example, say input context is:
key1: value1 key2: value2 key3: k31: value31 k32: value32 contextMerge: key2: &#39;aaa_{key1}_zzz&#39; key3: k33: value33_{key1} key4: &#39;bbb_{key2}_yyy&#39; This will result in return context:</description></item><item><title>pypyr.steps.contextclearall</title><link>https://pypyr.io/docs/steps/contextclearall/</link><pubDate>Tue, 30 Jun 2020 19:04:00 +0100</pubDate><guid>https://pypyr.io/docs/steps/contextclearall/</guid><description>pypyr.steps.contextclearall permalinkWipe the entire context. No input context arguments required.
You can always use contextclearall as a simple step, since it does not require any input context.
Sample pipeline yaml:
steps: - my.arb.step - pypyr.steps.contextclearall - another.arb.step contextclearall also wipes all the imports from any preceding pyimport steps.</description></item><item><title>pypyr.steps.contextclear</title><link>https://pypyr.io/docs/steps/contextclear/</link><pubDate>Tue, 30 Jun 2020 19:03:21 +0100</pubDate><guid>https://pypyr.io/docs/steps/contextclear/</guid><description>pypyr.steps.contextclear permalinkRemove the specified items from the context.
Will iterate contextClear and remove those keys from context.
steps: - name: pypyr.steps.contextclear description: delete these 2 context keys in: contextClear: - removeMe - removeMeToo For example, say input context is:
key1: value1 key2: value2 key3: value3 key4: value4 contextClear: - key2 - key4 - contextClear This will result in return context:
key1: value1 key3: value3 Notice how contextClear also cleared itself in this example.</description></item><item><title>pypyr.steps.cmd</title><link>https://pypyr.io/docs/steps/cmd/</link><pubDate>Sat, 13 Jun 2020 21:38:57 +0100</pubDate><guid>https://pypyr.io/docs/steps/cmd/</guid><description>pypyr.steps.cmd permalink execute external commands, applications &amp; scripts permalinkRun a program, run an external script, application or command. Execute an executable as a sub-process.
cmd runs an executable, it does not invoke the shell. You cannot use shell features like exit, return, shell pipes, filename wildcards, environment variable expansion, and expansion of ~ to a user&rsquo;s home directory. Use pypyr.steps.shell for that instead.
This step runs executables serially one after the other.</description></item><item><title>format string interpolation</title><link>https://pypyr.io/docs/substitutions/format-string/</link><pubDate>Sat, 13 Jun 2020 21:38:57 +0100</pubDate><guid>https://pypyr.io/docs/substitutions/format-string/</guid><description>string interpolation permalink formatting expressions with replacement tokens permalinkYou can use substitution tokens, aka string interpolation, to format strings where specified for context items. This substitutes anything between {curly braces} with the context value for that key. This also works with nested values where you have dictionaries/lists inside dictionaries/lists.
For example, if your context looked like this:
key1: down key2: valleys key3: value3 key4: Piping {key1} the {key2} wild # key4 == &#39;Piping down the valleys wild&#39; nested values permalinkYou can reference keys nested deeper in the context hierarchy, in cases where you have a dictionary that contains lists/dictionaries that might contain other lists/dictionaries and so forth.</description></item><item><title>jsonify</title><link>https://pypyr.io/docs/substitutions/jsonify/</link><pubDate>Sat, 13 Jun 2020 21:38:57 +0100</pubDate><guid>https://pypyr.io/docs/substitutions/jsonify/</guid><description>jsonify permalink convert object to json string permalinkUse jsonify to serialize a pypyr context object to a json string.
- name: pypyr.steps.set in: set: myJsonDict: !jsonify k1: v1 k2: 123 k3: False k4: - 1 - 2 - a: b c: d myJsonList: !jsonify - zero - one - two myJsonNull: !jsonify null myJsonNumber: !jsonify 99 myJsonQuotedString: !jsonify &#34;0123&#34; myJsonBareString: !jsonify arbitrary string - name: pypyr.steps.echo in: echoMe: | myJsonDict: {myJsonDict} myJsonList: {myJsonList} myJsonNull: {myJsonNull} myJsonNumber: {myJsonNumber} myJsonQuotedString: {myJsonQuotedString} myJsonBareString: {myJsonBareString} This gives output:</description></item><item><title>py string - dynamic python expressions</title><link>https://pypyr.io/docs/substitutions/py-strings/</link><pubDate>Sat, 13 Jun 2020 21:38:57 +0100</pubDate><guid>https://pypyr.io/docs/substitutions/py-strings/</guid><description>py strings permalink dynamic python expressions permalinkpy strings allow you to execute python expressions dynamically. This lets you use a python expression wherever you can use a string formatting expression.
A py string looks like this:
!py &lt;&lt;your python expression here&gt;&gt; Context keys exist as variables of the same name.
For example, if context['key'] is &lsquo;abc&rsquo;, the following will return True: !py len(key) == 3&quot;
Notice that you can use the context keys directly as variables.</description></item><item><title>sic string - literal strings</title><link>https://pypyr.io/docs/substitutions/sic-strings/</link><pubDate>Sat, 13 Jun 2020 21:38:57 +0100</pubDate><guid>https://pypyr.io/docs/substitutions/sic-strings/</guid><description>sic strings permalink literal string values permalinkIf a string is NOT to have {substitutions} run on it, it&rsquo;s sic erat scriptum, or sic for short. This is handy especially when you are dealing with json as a string, rather than an actual json object, so you don&rsquo;t have to use escape sequences to double curly all the structural braces and it simplifies the need for escape sequences.
A sic string looks like this:</description></item><item><title>release v3.2.1</title><link>https://pypyr.io/updates/releases/v3.2.1/</link><pubDate>Tue, 14 Apr 2020 02:20:27 +0000</pubDate><guid>https://pypyr.io/updates/releases/v3.2.1/</guid><description>pypyr release v3.2.1 permalink Support non-string keys in context on Formatting &amp; Merge permalinkRelease Date: 2020-04-14T02:20:27Z
Allow non-string keys on context.get_formatted_iterable and context merge (including the step pypyr.steps.contextmerge). Resolves #179. Much thanks to @Reskov for a detailed &amp; helpful bug report! You can find pypyr release v3.2.1 on github, where you can click through to associated Issues, Pull Requests and Users.
Released by yaythomas.</description></item><item><title>release v3.2.0</title><link>https://pypyr.io/updates/releases/v3.2.0/</link><pubDate>Sat, 04 Apr 2020 13:33:40 +0000</pubDate><guid>https://pypyr.io/updates/releases/v3.2.0/</guid><description>pypyr release v3.2.0 permalink nested call inside loops &amp; in context clearing preview permalinkRelease Date: 2020-04-04T13:33:40Z
ATTENTION: Please start preparing all your pipelines to be ready for the next major release where in context arguments will be removed from context on step completion. This shouldn&rsquo;t be too much of an issue. For any steps where you need to set enduring context, use contextsetf or contextset.
Allow using a call control-of-flow instruction nested inside while/for/retry loops.</description></item><item><title>release v3.1.0</title><link>https://pypyr.io/updates/releases/v3.1.0/</link><pubDate>Tue, 11 Feb 2020 19:24:11 +0000</pubDate><guid>https://pypyr.io/updates/releases/v3.1.0/</guid><description>pypyr release v3.1.0 permalink API change to main entrypoint for logging permalinkRelease Date: 2020-02-11T19:24:11Z
pypyr.log.logger.set_root_logger(log_level, log_path) call moved from pipelinerunner.main() to cli.main()
this has the side-effect that pipelinerunner.main() signature has changed, with log_level and log_path removed. API consumers should update.
Reason being API consumers should set their own log handlers, since handler configuration should be the prerogative of the calling application, not the invoked library.
Re #172, #173
You can find pypyr release v3.</description></item><item><title>release v3.0.3</title><link>https://pypyr.io/updates/releases/v3.0.3/</link><pubDate>Wed, 29 Jan 2020 01:03:12 +0000</pubDate><guid>https://pypyr.io/updates/releases/v3.0.3/</guid><description>pypyr release v3.0.3 permalink Retry Decorator handles original errors when calling Groups permalinkRelease Date: 2020-01-29T01:03:12Z
Retry Decorator correctly handles errors raised from .call or .jump steps when checking error type with retryOn and stopOn. Close #170 - thanks to @Reskov for reporting! add tarball to PyPI deploy artefacts. You can find pypyr release v3.0.3 on github, where you can click through to associated Issues, Pull Requests and Users.
Released by yaythomas.</description></item><item><title>release v3.0.2</title><link>https://pypyr.io/updates/releases/v3.0.2/</link><pubDate>Mon, 18 Nov 2019 19:30:27 +0000</pubDate><guid>https://pypyr.io/updates/releases/v3.0.2/</guid><description>pypyr release v3.0.2 permalink Better error messages on failing import modules permalinkRelease Date: 2019-11-18T19:30:27Z
When importing a step that does exist (mystep.blah), a failing import mymodule.blah inside mystep.blah would give a misleading error and hide the actual source of the problem. Fixes #166. Eternal thanks to @irancati for raising the issue! You can find pypyr release v3.0.2 on github, where you can click through to associated Issues, Pull Requests and Users.</description></item><item><title>release v3.0.1</title><link>https://pypyr.io/updates/releases/v3.0.1/</link><pubDate>Fri, 13 Sep 2019 20:11:13 +0000</pubDate><guid>https://pypyr.io/updates/releases/v3.0.1/</guid><description>pypyr release v3.0.1 permalink pypyr.steps.debug &amp; context merge support all types permalinkRelease Date: 2019-09-13T20:11:13Z
With a million thank yous 🙏 to @Reskov for these much needed fixes/enhancements! 🎆
Resolves issue #149. pypyr.steps.debug now supports outputting any type, including PyString &amp; SicString Resolve pypyr.steps.contextmerge issue to support merging any type, including PyString &amp; SicString. You can find pypyr release v3.0.1 on github, where you can click through to associated Issues, Pull Requests and Users.</description></item><item><title>release v3.0.0</title><link>https://pypyr.io/updates/releases/v3.0.0/</link><pubDate>Thu, 22 Aug 2019 17:47:35 +0000</pubDate><guid>https://pypyr.io/updates/releases/v3.0.0/</guid><description>pypyr release v3.0.0 permalink Major version, with BREAKING CHANGES: features custom step groups, caching &amp; no more ./pipelines dir permalinkRelease Date: 2019-08-22T17:47:35Z
BREAKING CHANGE: Remove deprecated step input context for (ref #118) assert env fetchjson fetchyaml fileformat fileformatjson fileformatyaml filereplace tar BREAKING CHANGE: cli context input now uses standard cli spacing rather than needing to str close everything. Closes #94 So where you had: pypyr mypipeline &quot;key1=value1,key2=value2” Now instead: pypyr mypipeline key1=value1 key2=value2 BREAKING CHANGE: Big API changes to pipelinerunner, stepsrunner and Step BREAKING CHANGE: pypyr.</description></item><item><title>release v2.11.0</title><link>https://pypyr.io/updates/releases/v2.11.0/</link><pubDate>Tue, 06 Aug 2019 21:16:03 +0000</pubDate><guid>https://pypyr.io/updates/releases/v2.11.0/</guid><description>pypyr release v2.11.0 permalink less confusing logging with NOTIFY permalinkRelease Date: 2019-08-06T21:16:03Z
This one is all @Reskov 🎉 eternal gratitude!
new NOTIFY logging level added. this level is much less verbose than even INFO, and only displays explicits echos that you specify in your pipeline, and also the description from the step decorator. This should make it much easier to see what your pipeline is doing without the extra detail that can make things confusing and harder to follow.</description></item><item><title>release v2.10.0</title><link>https://pypyr.io/updates/releases/v2.10.0/</link><pubDate>Wed, 10 Jul 2019 08:48:32 +0000</pubDate><guid>https://pypyr.io/updates/releases/v2.10.0/</guid><description>pypyr release v2.10.0 permalink Better Errors - line numbers, save errors permalinkRelease Date: 2019-07-10T08:48:32Z
With eternal thanks to @Reskov 🎉 for next level super useful improved error handling! 🙇
#139 - pypyr now saves all run-time errors to context under runErrors. This means subsequent steps can use error information from previous steps. #135 - error information now include the pipeline source yaml line+col numbers You can find pypyr release v2.</description></item><item><title>release v2.9.0</title><link>https://pypyr.io/updates/releases/v2.9.0/</link><pubDate>Fri, 14 Jun 2019 18:51:28 +0000</pubDate><guid>https://pypyr.io/updates/releases/v2.9.0/</guid><description>pypyr release v2.9.0 permalink glob step and special tag merge permalinkRelease Date: 2019-06-14T18:51:28Z
pypyr.steps.glob lets you get a list of paths from a glob, and combine different globs into a combined output result list. Issue #145 with much thanks to @Reskov 🎉 , resolves issue #143 - merge step now supports special tag directives You can find pypyr release v2.9.0 on github, where you can click through to associated Issues, Pull Requests and Users.</description></item><item><title>release v2.8.0</title><link>https://pypyr.io/updates/releases/v2.8.0/</link><pubDate>Sun, 24 Mar 2019 01:22:01 +0000</pubDate><guid>https://pypyr.io/updates/releases/v2.8.0/</guid><description>pypyr release v2.8.0 permalink Retry Decorator and until-style While Loops permalinkRelease Date: 2019-03-24T01:22:01Z
new Retry decorator allows steps to retry automatically when step encounters an error. ref #130 fix run_step AttributeError might have caught or hidden AttributeErrors in the step code itself, rather than just when the step module didn&rsquo;t contain a run_step function. ref #129 while loop checks stop condition only at end of each iteration. previously if a stop condition evaluated True even before the loop started the loop wouldn&rsquo;t run at all.</description></item><item><title>release v2.7.0</title><link>https://pypyr.io/updates/releases/v2.7.0/</link><pubDate>Thu, 21 Mar 2019 15:09:21 +0000</pubDate><guid>https://pypyr.io/updates/releases/v2.7.0/</guid><description>pypyr release v2.7.0 permalink pypyr.steps.pype inputs now support string interpolation permalinkRelease Date: 2019-03-21T15:09:21Z
add string interpolation to pypyr.steps.pype input. You can find pypyr release v2.7.0 on github, where you can click through to associated Issues, Pull Requests and Users.
Released by yaythomas.</description></item><item><title>release v2.6.0</title><link>https://pypyr.io/updates/releases/v2.6.0/</link><pubDate>Fri, 08 Feb 2019 16:20:23 +0000</pubDate><guid>https://pypyr.io/updates/releases/v2.6.0/</guid><description>pypyr release v2.6.0 permalink pypyr.steps.now and pypyr.steps.nowutc permalinkRelease Date: 2019-02-08T16:20:23Z
get the current datetime stamp into the pypyr context as a formattable string, where you can specify your own datetime formats using the standard python date time replacement tokens like %Y-%m-%d for YYYY-MM-DD. You can find pypyr release v2.6.0 on github, where you can click through to associated Issues, Pull Requests and Users.
Released by yaythomas.</description></item><item><title>release v2.5.0</title><link>https://pypyr.io/updates/releases/v2.5.0/</link><pubDate>Wed, 30 Jan 2019 19:08:54 +0000</pubDate><guid>https://pypyr.io/updates/releases/v2.5.0/</guid><description>pypyr release v2.5.0 permalink change the current working directory for cmd and shell permalinkRelease Date: 2019-01-30T19:08:54Z
use the new cwd input on pypyr.steps.cmd and pypyr.steps.shell to set the current working directory for the program/shell that you want to execute. Supports relative paths.
You can find pypyr release v2.5.0 on github, where you can click through to associated Issues, Pull Requests and Users.
Released by yaythomas.</description></item><item><title>release v2.4.0</title><link>https://pypyr.io/updates/releases/v2.4.0/</link><pubDate>Thu, 24 Jan 2019 23:04:20 +0000</pubDate><guid>https://pypyr.io/updates/releases/v2.4.0/</guid><description>pypyr release v2.4.0 permalink pypyr.steps.pathcheck &amp; deprecation of old style fetchjson/fetchyaml args permalinkRelease Date: 2019-01-24T23:04:20Z
The new pypyr.steps.pathcheck step allows you see if a path exists on the filesystem. It supports literal paths and glob expansions. It writes handy values into pathCheckOutwith bool for existence and count of files found for the given path. #114 deprecate old style multi context inputs for fetchjson and fetchyaml, #118. this is not just arbitrary: reason is when step is used multiple times in same pipeline, it becomes easy to have left-over values from previous step run left in context that then cause surprising behaviour with the downstream step.</description></item><item><title>release v2.3.0</title><link>https://pypyr.io/updates/releases/v2.3.0/</link><pubDate>Thu, 24 Jan 2019 02:18:47 +0000</pubDate><guid>https://pypyr.io/updates/releases/v2.3.0/</guid><description>pypyr release v2.3.0 permalink pypyr.steps.getenv permalinkRelease Date: 2019-01-24T02:18:47Z
add new step pypyr.steps.getenv Whereas pypyr.steps.env raises an error if you are getting an environment variable that doesn&rsquo;t exist, the new envget allows you to specify a default value to use instead. ref #111 some documentation updates to demonstrate how to use py strings for ternary assignments built-in pypes use comment rather than description where output is not meant for operator consumption ref #109 alias the --loglevel switch with --log, so you can now do pypyr mypipe --log 10 think of the savings just on keyboard wear and tear!</description></item><item><title>release v2.2.0</title><link>https://pypyr.io/updates/releases/v2.2.0/</link><pubDate>Fri, 18 Jan 2019 10:34:45 +0000</pubDate><guid>https://pypyr.io/updates/releases/v2.2.0/</guid><description>pypyr release v2.2.0 permalink Dynamic pype loading and KeyNotInContextError == KeyError permalinkRelease Date: 2019-01-18T10:34:45Z
This release is all @Reskov! 🎉 Much thanks for your excellent contributions to some tricky bits of the pypyr core!
Context KeyNotInContextError now also derives from KeyError. This makes it easier to catch missing key exceptions in scenarios where Context keys contain other dicts. Allow dynamic loading of pipeline loaders. This allows core extensibility to load pipelines differently and from other places than the default file loader.</description></item><item><title>release v2.1.1</title><link>https://pypyr.io/updates/releases/v2.1.1/</link><pubDate>Fri, 04 Jan 2019 11:32:19 +0000</pubDate><guid>https://pypyr.io/updates/releases/v2.1.1/</guid><description>pypyr release v2.1.1 permalink Write step description to logger INFO on step execution permalinkRelease Date: 2019-01-04T11:32:19Z
write step description to INFO output on step execution, if it exists. this should help with debugging. minor bug fix: legacy support for envs, recreate env key on legacy key found You can find pypyr release v2.1.1 on github, where you can click through to associated Issues, Pull Requests and Users.
Released by yaythomas.</description></item><item><title>release v2.1.0</title><link>https://pypyr.io/updates/releases/v2.1.0/</link><pubDate>Thu, 03 Jan 2019 00:55:09 +0000</pubDate><guid>https://pypyr.io/updates/releases/v2.1.0/</guid><description>pypyr release v2.1.0 permalink globs, save cmd out, backwards compatible context change for multi-key steps permalinkRelease Date: 2019-01-03T00:55:09Z
ATTENTION, FUTURE WARNING: all built-in steps that used to take multiple input keys now instead take a dict input. This makes life significantly easier if you re-run the step in the same pipeline in that you don&rsquo;t have to clear down context before the subsequent step runs anymore. The old-style is now deprecated - for the moment pypyr will make the old-style work seamlessly for you by creating the new keys under the hood for you and raising a warning without stopping, but be aware legacy support will be removed on the next major release.</description></item><item><title>release v2.0.0</title><link>https://pypyr.io/updates/releases/v2.0.0/</link><pubDate>Sun, 16 Dec 2018 20:19:49 +0000</pubDate><guid>https://pypyr.io/updates/releases/v2.0.0/</guid><description>pypyr release v2.0.0 permalink Sic Strings, Py Strings, Fetch into Key and file write yaml/json permalinkRelease Date: 2018-12-16T20:19:49Z
pypyr v2.0.0 release! BREAKING CHANGES: [sic] strings are now a lot better. Instead of relying on string-parsing on &ldquo;[sic]&rdquo; and the tricky use of quotes and double-quotes, now a structural yam tag identifies sic string, making it a whole lot simpler to write sic strings with special characters in them without escape sequences or having to deal with {blah} style eye-bleeding messes.</description></item><item><title>release v1.2.1</title><link>https://pypyr.io/updates/releases/v1.2.1/</link><pubDate>Mon, 05 Nov 2018 11:07:17 +0000</pubDate><guid>https://pypyr.io/updates/releases/v1.2.1/</guid><description>pypyr release v1.2.1 permalink no functional change: fix pype bug permalinkRelease Date: 2018-11-05T11:07:17Z
regression problem with pypyr.steps.pype from previous release fixed no functional change You can find pypyr release v1.2.1 on github, where you can click through to associated Issues, Pull Requests and Users.
Released by yaythomas.</description></item><item><title>release v1.2.0</title><link>https://pypyr.io/updates/releases/v1.2.0/</link><pubDate>Mon, 05 Nov 2018 09:26:15 +0000</pubDate><guid>https://pypyr.io/updates/releases/v1.2.0/</guid><description>pypyr release v1.2.0 permalink no functional change: api update permalinkRelease Date: 2018-11-05T09:26:15Z
improve API call-ability of pypyr by splitting the pipeline loading from running, allowing consumer to manage pipeline cache themselves. With great thanks for the excellent idea and implementation by @Reskov! no functional change introduced with this version You can find pypyr release v1.2.0 on github, where you can click through to associated Issues, Pull Requests and Users.</description></item><item><title>release v1.1.1</title><link>https://pypyr.io/updates/releases/v1.1.1/</link><pubDate>Thu, 18 Oct 2018 22:43:18 +0000</pubDate><guid>https://pypyr.io/updates/releases/v1.1.1/</guid><description>pypyr release v1.1.1 permalink no functional change permalinkRelease Date: 2018-10-18T22:43:18Z
no functional change, only devops deployment update supersedes the v1.1.0 release. note that v1.1.0 is not on pypi because of a deployment issue that 1.1.1 rectifies. You can find pypyr release v1.1.1 on github, where you can click through to associated Issues, Pull Requests and Users.
Released by yaythomas.</description></item><item><title>release v1.1.0</title><link>https://pypyr.io/updates/releases/v1.1.0/</link><pubDate>Thu, 18 Oct 2018 22:01:10 +0000</pubDate><guid>https://pypyr.io/updates/releases/v1.1.0/</guid><description>pypyr release v1.1.0 permalink cli: &ndash;logpath + py 3.7 permalinkRelease Date: 2018-10-18T22:01:10Z
cli option to log to a file path in addition to the console using --logpath. With great thanks to @rickardcronholm! slight BREAKING CHANGE for --loglevel: The previous shortening to pypyr mypipe --log 10 won&rsquo;t work anymore. Use pypyr mypipe --logl 10 if you don&rsquo;t want to type out --loglevel python 3.7 compatibility README help with shell examples You can find pypyr release v1.</description></item><item><title>release v1.0.0</title><link>https://pypyr.io/updates/releases/v1.0.0/</link><pubDate>Thu, 26 Jul 2018 20:17:17 +0000</pubDate><guid>https://pypyr.io/updates/releases/v1.0.0/</guid><description>pypyr release v1.0.0 permalink step decorator: while permalinkRelease Date: 2018-07-26T20:17:17Z
while loop decorator README help with examples for all decorators You can find pypyr release v1.0.0 on github, where you can click through to associated Issues, Pull Requests and Users.
Released by yaythomas.</description></item></channel></rss>