airflow.providers.standard.operators.hitl¶
Classes¶
Base class for all Human-in-the-loop Operators to inherit from. |
|
Human-in-the-loop Operator that has only 'Approval' and 'Reject' options. |
|
BranchOperator based on Human-in-the-loop Response. |
|
Human-in-the-loop Operator that is used to accept user input through TriggerForm. |
Functions¶
|
Ask a person for input from inside a running Python task, and return their answer. |
Module Contents¶
- airflow.providers.standard.operators.hitl.request_input(*, subject, options, body=None, defaults=None, multiple=False, params=None, notifiers=None, assigned_users=None, timeout=None, key=None)[source]¶
Ask a person for input from inside a running Python task, and return their answer.
The first time a question is asked, the request appears on the Required Actions page, the same as one from
HITLOperator, and the task stops there: it waits in theawaiting_inputstate without holding a worker slot. Once the request is answered, the task runs again from the start of its callable, and this call returns the answer instead of asking again. Save anything the second run should not redo (for example an agent framework’s run state) totask_state_storebefore calling this.It works in
@taskandPythonOperatorcallables (sync or async), including@task.branchand@task.short_circuit. It can’t pause tasks that run their callable in another process, such as@task.virtualenv,@task.external_python,@task.dockeror@task.kubernetes. Ask one question at a time from the task’s own code, not from worker threads or from severalasynccalls running at once: a task instance has a single Required Actions request.Needs Airflow 3.4+. Earlier versions keep the first request’s subject, body and options when a task asks again, after a resume or on a retry, so the reviewer would answer a question they were not shown.
- Parameters:
subject (str) – Headline shown to the reviewer.
body (str | None) – Details the reviewer needs to decide (Markdown).
defaults (str | list[str] | None) – Options applied if
timeoutpasses without an answer. Without defaults, the task fails withHITLTimeoutErrorat the timeout.multiple (bool) – Whether the reviewer can choose more than one option.
params (airflow.sdk.definitions.param.ParamsDict | dict[str, Any] | None) – Form fields for the reviewer to fill in, defined like Dag params.
notifiers (collections.abc.Sequence[airflow.sdk.bases.notifier.BaseNotifier] | airflow.sdk.bases.notifier.BaseNotifier | None) – Notifiers called with the task context once the request is written.
assigned_users (airflow.sdk.execution_time.hitl.HITLUser | list[airflow.sdk.execution_time.hitl.HITLUser] | None) – Users allowed to answer. Anyone with access can answer if not set.
timeout (datetime.timedelta | None) – How long to wait for an answer. Waits indefinitely if not set.
key (str | None) – Which question this is, so a resumed task gets each answer back at the right call. Defaults to
subject. Each key is asked at most once per try. Set it when the subject can change between runs, or when the task can ask the same subject more than once, for example one approval per agent tool call (use the call’s id).
- class airflow.providers.standard.operators.hitl.HITLOperator(*, subject, options, body=None, defaults=None, multiple=False, params=None, notifiers=None, assigned_users=None, response_timeout=None, **kwargs)[source]¶
Bases:
airflow.providers.standard.version_compat.BaseOperatorBase class for all Human-in-the-loop Operators to inherit from.
- Parameters:
subject (str) – Headline/subject presented to the user for the interaction task.
options (list[str]) – List of options that the an user can select from to complete the task.
body (str | None) – Descriptive text (with Markdown support) that gives the details that are needed to decide.
defaults (str | list[str] | None) – The default options and the options that are taken if timeout is passed.
multiple (bool) – Whether the user can select one or multiple options.
params (airflow.sdk.definitions.param.ParamsDict | dict[str, Any] | None) – dictionary of parameter definitions that are in the format of Dag params such that a Form Field can be rendered. Entered data is validated (schema, required fields) like for a Dag run and added to XCom of the task result.
response_timeout (datetime.timedelta | None) – Maximum time to wait for a human response. On Airflow 3.3+ this is enforced by the scheduler’s
awaiting_inputtimeout sweep; on older versions it is passed to the triggerer. This is separate fromexecution_timeout, which controls the execution phase before the task starts waiting. If not set, no timeout is applied to the human response wait.
- template_fields: collections.abc.Collection[str] = ('subject', 'body')[source]¶
- notifiers: collections.abc.Sequence[airflow.sdk.bases.notifier.BaseNotifier][source]¶
- property hitl_summary: dict[str, Any][source]¶
Summary of the Human-in-the-loop request, for listeners/observability.
A property so the
subject/bodytemplate fields are read after rendering, not captured as un-rendered Jinja in__init__. Each access builds a fresh snapshot, so mutating the returned dict has no effect — runtime code and subclasses extend the summary by adding entries tohitl_summary_extrainstead.
- validate_options()[source]¶
Validate the options attribute of the instance.
- Raises:
ValueError: If options is empty.
- validate_params()[source]¶
Validate the params attribute of the instance.
Note: Value validation (e.g., required fields, schema) is intentionally skipped here because HITLOperator params represent form fields that are filled by a human at runtime. Values do not exist at Dag parse time, so validating them in
__init__would cause aParamValidationErrorfor any param without a default. Value validation happens invalidate_params_inputafter the human submits the form.- Raises:
ValueError: If
"_options"key is present inparams, which is not allowed.
- validate_defaults()[source]¶
Validate whether the given defaults pass the following criteria.
Default options should be the subset of options.
When multiple is False, there should only be one option.
- execute(context)[source]¶
Write the Human-in-the-loop request, then wait for a user response.
On Airflow 3.3+ the task waits in the
awaiting_inputstate with no trigger or triggerer involved; on older versions it defers toHITLTrigger. Either way it resumes inexecute_completeonce a response (or timeout default) arrives.
- generate_link_to_ui(*, task_instance, base_url=None, options=None, params_input=None)[source]¶
Generate a URL link to the “required actions” page for a specific task instance.
This URL includes query parameters based on allowed options and parameters.
- Args:
task_instance: The task instance to generate the link for. base_url: Optional base URL to use. Defaults to
api.base_urlfrom config. options: Optional subset of allowed options to include in the URL. params_input: Optional subset of allowed params to include in the URL.- Raises:
ValueError: If any provided option or parameter is invalid. ValueError: If no base_url can be determined.
- Returns:
The full URL pointing to the required actions page with query parameters.
- static generate_link_to_ui_from_context(*, context, base_url=None, options=None, params_input=None)[source]¶
Generate a “required actions” page URL from a task context.
Delegates to
generate_link_to_uiusing the task and task_instance extracted from the provided context.- Args:
context: The Airflow task context containing ‘task’ and ‘task_instance’. base_url: Optional base URL to use. options: Optional list of allowed options to include. params_input: Optional dictionary of allowed parameters to include.
- Returns:
The full URL pointing to the required actions page with query parameters.
- class airflow.providers.standard.operators.hitl.ApprovalOperator(*, ignore_downstream_trigger_rules=False, fail_on_reject=False, **kwargs)[source]¶
Bases:
HITLOperator,airflow.providers.common.compat.sdk.SkipMixinHuman-in-the-loop Operator that has only ‘Approval’ and ‘Reject’ options.
- class airflow.providers.standard.operators.hitl.HITLBranchOperator(*, options_mapping=None, **kwargs)[source]¶
Bases:
HITLOperator,airflow.providers.common.compat.sdk.BranchMixInBranchOperator based on Human-in-the-loop Response.
- inherits_from_skipmixin = True[source]¶
Used to determine if an Operator is inherited from SkipMixin or its subclasses (e.g., BranchMixin).
- class airflow.providers.standard.operators.hitl.HITLEntryOperator(**kwargs)[source]¶
Bases:
HITLOperatorHuman-in-the-loop Operator that is used to accept user input through TriggerForm.