.. _python_directive:
python_directive - execute a python script in current process
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.. versionadded:: 0.4
Execute a piece of python code as part of task execution. You can execute any
callable object imported from your external python file. The object is called
in the current task process.
Parameters
----------
.. raw:: html
parameter |
required |
description |
type |
default |
choices |
<kwarg> |
no |
arbitrarily named parameter with a value. All these key=value pairs will be passed to the python script as callable parameters. |
anything |
|
|
callable |
yes |
name of the object to call. This can be a function reference, a callable instance reference, or an instance.method reference. See examples. |
str |
|
|
file |
yes |
absolute or relative path to the python file to be executed (the task directory is considered the current working directory) |
str |
|
|
Return Values
-------------
The output of the python script, which must be either ``None`` or a
``basestring``.
If this python script is supposed to be the main check of the task, it is
supposed to provide output in a :ref:`resultyaml-format`. This format is then used in
the :ref:`resultsdb directive `. The easiest way to
create it is to use :class:`.CheckDetail` objects to construct your result (or
results), and then generate the YAML output with :func:`~.check.export_YAML`.
Read more in :ref:`writing-tasks-for-taskotron`.
Exceptions
----------
* :class:`.TaskotronDirectiveError`: if ``file`` can't be read, or if
``callable`` returns something else than ``None`` or ``basestring``
* anything that the python script raises itself
Examples
--------
This runs a rpmlint python-wrapper to process all RPMs in the workdir::
- name: run rpmlint on downloaded rpms
python:
file: run_rpmlint.py
callable: run
workdir: ${workdir}
export: rpmlint_output
You can pass complex python-structures as keyval parameters::
- name: run upgradepath
python:
file: upgradepath.py
callable: main
custom_args: [--debug, "${koji_tag}"]
export: upgradepath_output
.. note:: If you use JSON list syntax (``[a, b, c]``) inside the YAML file, you
must enclose any variables (and anything else containing curly braces) in
quotation marks. If your variable is not supposed to be a string, you have to
use YAML-native list syntax (dashes separated by line breaks). Example follows.
Depcheck uses a lot of keyval parameters, also uses both JSON list syntax and
YAML list syntax, depending on its needs (``${yumrepos}`` is not a string, but a
dictionary)::
- name: run depcheck
python:
file: run_depcheck.py
callable: taskotron_run
arch: ${arch}
rpms: [ "${workdir}/downloaded_tag/" ]
repos:
- ${yumrepos}
- workdir_repo: ${workdir}/downloaded_tag/
report_format: rpms
export: depcheck_output
There are several ways how to implement the callable object inside the python
script. Given a callable name ``do_this_thing``, possible implementations could
include:
A) function reference::
def do_this_thing(some, args):
return "I'm a function!"
B) instance method reference::
class TaskClass(object):
def my_task(self, some, args):
return "I'm a class method!"
_task_instance = TaskClass()
do_this_thing = _task_instance.my_task
C) callable instance reference::
class EmbeddedCallClass(object):
def __call__(self, some, args):
return "I'm a __call__ method in a class!"
do_this_thing = EmbeddedCallClass()