Package: ciak
ciakis a Python program to run executables according to a configuration file
(aciakfile) optionally containing user-declared variables that can be
adjusted at runtime.A ciakfile is a simple text file that describes a nested tree using asterisks
and that has placeholders for runtime-controllable variables, supporting
defaults. Thanks to the nested tree structure, the amount of typing required is
drastically reduced when the same commands have to be executed multiple times
but with different arguments. On the other hand, support for placeholders allows
for code reuse and the same ciakfile can be used for different situations. This
is facilitated by the fact that if you define an environmental variableCIAKFILES_DIR,ciakwill know where to look for your ciakfiles, so you can
call them from anywhere in your system. Finally, in ciakfiles, every line that
does not start with an asterisk (up to leading spaces) is treated as a comment.
With this feature, one can write extensive commentaries that perfectly blend in
with the configuration itself.For an example of use case, see the section"Complete explanation of a specific
use case". See
below for an example of what a configuration file looks like.Getting startedciakis available on PyPI. You can install it withpip:pip3installciakciakrequirespython >= 3.9and has no external runtime dependency.
Seeciak36for compatibility with previous
versions of Python.The best way to get started withciakis to check theexamplesout.ExamplesIn this Section, we are going to explore the various ways in whichciakcan be
used, form the simplest, to the most complex.Level 0: To run a list of command-line instructionsSuppose you want to execute a set of command-line instructions. For instance,
creating a folder, creating three empty files, and moving them inside the folder. (This is a contrived
example, but we are going to build upon this later.) A shell script for this
task might look like:mkdirmyfolder
touchmyfolder/first
touchmyfolder/second
touchmyfolder/thirdThis can be easily converted into a ciakfile by prepending asterisks in front of
each line:* mkdir myfolder
* touch first
* touch second
* touch third
* mv first second third myfolderNow, assuming this is saved into aciak0.org, it can be executed withciak-cciak0.orgOurciak0.orgcontains some redundancies: we runtouchthree times. Withciak,
we can express this more tersely by adding one nesting level* mkdir myfolder
* touch
** first
** second
** third
* mv first second third myfolderSaving this intociak01.organd executing withciak -c ciak1.orgwill produce
the same result as before. ciakfiles represent sequences of commands using nested trees,
so that similar commands can be executed with minimal variation. ciakfiles are meant to
be self-documenting: every line that does not start with an asterisk is a comment, so we
can expand our example:* mkdir myfolder
  First, we create our target folder. We will place everything inside here.
* touch
  Next, we create three files (`first`, `second`, `third`).
** first
** second
** third
* mv first second third myfolder
  We move the three files inside our target folder.Level 1: To parallelize the execution of certain instructionsBuilding upon our example,ciaksupports mixing parallel and serial blocks.
For instance, we can demand that the three filesfirst,second,thirdare
created in parallel. To do so, we add* # BEGIN_PARALLELand* # END_PARALLELclauses:* mkdir myfolder
  First, we create our target folder. We will place everything inside here.
* # BEGIN_PARALLEL
* touch
  Next, we create three files (`first`, `second`, `third`).
** first
** second
** third
* # END_PARALLEL
* mv first second third myfolder
  We move the three files inside our target folder.Saving this tociak1.org, and executing withciak -c ciak1.org,ciakwill
execute instructions serially, until it finds a parallel block, which is then executed
in parallel (with as many cores as available), and then it goes back to running commands
serially. The flag--no-paralleltransforms parallel blocks into serial ones.Level 2: To parametrize the execution of certain instructionsciakfiles are can contain placeholders values that are controlled at runtime.
This makesciakpowerful and promotes code reuse. The syntax for command-line
adjustable placeholders is{{key::default_value}}.Consider the simple ciakfile is* ls {{pwd::/tmp}}Assuming we save the file tociak2.org, we can then runciak-cciak2.org--pwd$HOMEThis will execute the commandls $HOME. If we were to runciak-cciak2.orgthen the default value forpwdis used and the commandls /tmpis run instead.We can extend our previous example:* mkdir {{dest::myfolder}}
  First, we create our target folder. We will place everything inside here.
* # BEGIN_PARALLEL
* touch
  Next, we create three files (`first`, `second`, `third`).
** first
** second
** third
* # END_PARALLEL
* mv first second third myfolder
  We move the three files inside our target folder.Now, we can control the destination folder when running with through the--destflag.Level 3: To write complex workflows once, and use them over and overWe saw that we can produce complex ciakfiles that can be controlled via the
command line. The last piece of the puzzle isCIAKFILES_DIR. If you set this
environmental variable to a folder,ciakwill try to find ciakfiles in that
folder (by default it is.). So, withciak, you can write complex and
general workflows and easily invoke them from anywhere in your filesystem. For
instance, if you have a ciakfile namedcompute_resultthat defined a{{datadir::.}}argument in yourCIAKFILES_DIR, you can navigate to the
folder where you have the data and executeciak compute_result. Check the
section onciak and
org-modeout to see a
real-life example.The ciakfile configuration syntaxValid ciakfiles are text files with the following characteristics:Lines that do no start with asterisk (up to initial spaces) are considered
comments.The number of asterisks defines the level in the three and the parent of an
item is the first item with fewer asterisk above it.Executables have to be on the first level of the tree.Placeholders can be defined with the syntax{{key::default_value}}. These
will be substituted at runtime with values specified via command-line or with
the default value.Indentation, leading/trailing spaces, and file extension do not matter.Parallel blocks must be at the top level (only one asterisk), they start with# BEGIN_PARALLELand end with# END_PARALLEL. Nested parallel blocks will
be ignored.Why should I use ciak instead of a shell script?At a first glance,ciakmay seem just a convoluted way to write a shell
script. This is not the case:ciakenables workflows that are impractical with
shell script. The main advantages ofciakare:Simplify repeated arguments across multiple scriptsEasily add keyword arguments with defaultsHave parallelization with no effortStrong emphasis on self-documentationHowever, by design,ciakdoes not support any shell feature (like input/output
redirection, for loops, variable assignment, ...).ciakcan trivially parallelize the execution of some commands. Hence, you can
use it as a replacement ofGNU
Parallelto parallelize commands
defined in a configuration file.ciak36ciakuses features available only with Python3.9 or later versions. For
convenience, an executableciak36is provided, compatible with Python3.6.
There is no difference in features available betweenciakandciak36.ciak36is automatically generated byciakwith thegenerate_ciak36.shscript.ciak36will be dropped in the future.ciak and org-modeciakborrows its syntax fromGNU Emacs'sorg-mode. As such, if you save your ciakfiles with
extension.organd you open them with Emacs, you gain access to a large number
of additional features (e.g., automatic coloring and indentation, subtree
folding, tables, exporting to different formats, ...). This is what an example
of a ciakfile will look like in (customized) EmacsUsing org-mode greatly enhancesciak's self-documenting capabilities.Options--fail-fast, if enabled,ciakstops as soon as a non-zero return code is
found.--no-parellel, if enabled, the commands are executed serially. By defaults,
commands are executed in parallel with a number of workers that is equal to the
number of available cores on the machine.--dry-run, if enabled,ciakwill print the command that would be executed,
without executing any.DevelopmentWe use:Poetryto manage dependencies, build, and publishmotionpicture.Blackfor formatting the code (with 89
columns).pytestfor unit tests.coveragefor test coverage.mypyfor static type analysis.isortto sort the import statements.flake8for general static analysis.pre-committo apply linting rules before commits.GitHub actions for continuous integration.We are happy to accept contributions.What does ciak mean?In Italian, the wordciakis an onomatopoeia that indicates the sound of the
clapperboard used by movie directors to kick off the recording of a scene. Along
the same lines, when you use this program, you are the script-writer and the
director: you define what needs to be run in the ciakfile and you start and
control its execution withciak, your clapperboard.Going over a specific use caseciakwas developed to run analysis ofEinstein
Toolkitsimulations usingkuibit.ciaksolves four problems:Simplification in writing the analysisReuse of the codeReproducibility and self-documentation in the analysisParallelization of analysisNormally, one runs several simulations of the same kind with only a handful of
parameters changed. The entire analysis can be condensed into a ciakfile which
takes as command-line input the folder with the simulation output.Moreover, distributing the ciakfile along with the scripts that are called
allows other people to easily reproduce the analysis. The comments in the
ciakfile are helpful to explain what is going on and why certain values are set
at the values they are set.