.. _task-input-fields:

=================
Task input fields
=================

Tasks can declaratively define *input fields* to express what extra information
they need from Debusine, other than what is in the task's data, in order to run.

Task input fields can be used to reference things like artifact lookups,
collection lookups, configuration lookups, and so on.

Values computed by resolving task input fields are automatically stored in the
task's dynamic data, and will be available as the fields' values both
server-side (once dynamic data is available) and worker-side, for external
tasks.

.. todo::

   Task input fields are currently only available for worker tasks, but the
   plan is to extend them to all kinds of tasks. See :issue:`1357`.

Input fields are resolved in two stages:

* ``PENDING``, when the task becomes *pending*, in order to use field values to
  look up task configuration and scheduler tags.
* ``RUNNING``, before the task becomes *running*, in order to compute dynamic
  task data and have all fields available for computing dynamic task data and
  actually running the task.

An input field can be marked with ``step=Stage.PENDING`` to be made available
during the ``CONFIG`` stage, otherwise it will only be available during the
``ALL`` stage.

Most input fields use a value from the task data as input, specified by the
``field=`` argument, which defaults to the field name. The field argument is a
dotted-separated path identifying the right element of the task data structure.
For example:

* ``source = SingleInput()``: treats ``task.data.source`` as a ``LookupSingle``
  and stores the lookup as ``task.source``.
* ``source = SingleInput(field="input.source")``: treats
  ``task.data.input.source`` as a ``LookupSingle`` and stores the lookup as
  ``task.source``.

Accessing an input field that has not yet been resolved will raise a
:py:exc:`TaskConfigError` exception.

For the full list of task input fields, see :ref:`api-task-input-fields`.
