YAZ (Yet another z)
It's purpose is to easily expose python functions and classes, represented as tasks and plugins, on your console command line.
Yaz is inspired by
z, a scripting tool used by Zicht Online.
- expose python functions using
- expose type aware function parameters (string, integer, float, boolean, file, etc)
- group tasks together by extending
yaz.Plugin(nested classes provide further grouping)
- handling dependencies between plugins using
- asyncio aware
pip3 install --upgrade yaz
Expose a single function (task)
The simplest usage of
yaz is to expose a python function to be
executed from the shell. For example, when you want to run the file
hello_world.py from shell, you could use the following python code:
#!/usr/bin/env python3 # file: examples/01_say.py import yaz @yaz.task def say(message="Hello World!"): return message if __name__ == "__main__": yaz.main()
The above can be called using
./examples/01_say.py --help, resulting in a list
of options. The
message parameter is optional, just like it is in
the python code. For example:
usage: say.py [-h] [--message MESSAGE] optional arguments: -h, --help show this help message and exit --message MESSAGE defaults to message='Hello World!'
When multiple functions are decorated with
@yaz.task, all these functions
will be exposed to the console. This means that the desired function will
need to be specified when the script is run.
Expose functions in a class (plugin with tasks)
It is common to group functions, with the same subject, together in a class.
Such a class must extend the
yaz.Plugin class to allow, amongst other things,
for class initialization when the task is executed.
Furthermore, classes can have dependencies on each other which will be
yaz. This is shown in the example below with
#!/usr/bin/env python3 # file: examples/02_food.py import yaz class Helper(yaz.Plugin): def output(self, message, shout): if shout: print(message.upper()) else: print(message) class Food(yaz.Plugin): @yaz.dependency def set_helper(self, helper: Helper): self.helper = helper @yaz.task def breakfast(self, message="Breakfast is ready", shout: bool = False): """Say something in the morning""" self.helper.output(message, shout) @yaz.task def lunch(self, message="Time for lunch", shout: bool = False): """Say something in the afternoon""" self.helper.output(message, shout) @yaz.task def dinner(self, message="Dinner is served", shout: bool = False): """Say something in the evening""" self.helper.output(message, shout) if __name__ == "__main__": yaz.main()
The above can be called using
./examples/02_food.py lunch --shout, resulting in
DINNER IS SERVED. This is achieved using the following steps:
yaz.main()is called, all the plugins and tasks are collected, and it is determined that the
def lunch(...)function is to be called.
Foodclass is initiated.
- The dependencies for the
Foodclass are resolved, i.e. the
Helperclass is initiated and
def set_helperis called.
lunchmethod is called and
yaz.main()prints its return value.
- todo: explain multiple plugins
- todo: explain different argument types
- todo: explain @yaz.task(OPTIONS)
- todo: explain plugin inheritance
- todo: explain coroutines / asyncio
- todo: explain available base plugins: yaz_templating_plugin and yaz_scripting_plugin
- Boudewijn Schoon <firstname.lastname@example.org>