airflow.providers.common.ai.mixins.approval¶
Attributes¶
Classes¶
Protocol for defer for approval mixin. |
|
Mixin that pauses an operator for human review before returning output. |
Module Contents¶
- class airflow.providers.common.ai.mixins.approval.DeferForApprovalProtocol[source]¶
Bases:
ProtocolProtocol for defer for approval mixin.
- approval_timeout: datetime.timedelta | None[source]¶
- approval_notifiers: collections.abc.Sequence[airflow.providers.common.compat.notifier.BaseNotifier][source]¶
- class airflow.providers.common.ai.mixins.approval.LLMApprovalMixin[source]¶
Mixin that pauses an operator for human review before returning output.
When
require_approval=Trueon the operator, the generated output is presented to a human reviewer via the Airflow Human-in-the-Loop (HITL) interface. The task waits (awaiting_inputon Airflow 3.3+, deferred on older versions) until the reviewer approves or rejects.If
allow_modifications=True, the reviewer can also edit the output before approving. The (possibly modified) output is then returned as the task result.on_approval_timeoutdecides what happens whenapproval_timeoutexpires without a response:"fail"raisesHITLTimeoutError, while"approve"and"reject"answer the review with that option so the task resumes as if a reviewer had chosen it. The chosen option is also pre-highlighted for the reviewer in the HITL form.approval_notifiersare called once the review is open, so a reviewer learns about it without watching the Required Actions page, the wayHITLOperatordoes withnotifiers. The reviewsubjectandbodyare exposed as{{ task.subject }}and{{ task.body }}in notifier templates. A notifier whose delivery raises is logged without failing the task, while a template error fails the task. A retry re-runs the LLM and re-notifies with the regenerated output, while the open review keeps the original subject and body.approval_assigned_usersrestricts the review to the named users, the wayHITLOperatordoes withassigned_users. Leaving it empty lets any user with the permission respond. The list is stored when the review is first created; clearing the task re-runs it against the existing review row, so a changed list does not take effect.Operators that use this mixin must set the following attributes:
require_approval(bool)allow_modifications(bool)approval_timeout(timedelta | None)on_approval_timeout(Literal["fail", "approve", "reject"])approval_notifiers(Sequence[BaseNotifier])approval_assigned_users(list[HITLUser])prompt(str)
- validate_approval_prompt()[source]¶
Fail fast when the prompt cannot be rendered as text in the approval review body.
- defer_for_approval(context, output, *, subject=None, body=None, modification_schema=None, decision=None)[source]¶
Write HITL detail, then pause the task for human review.
On Airflow 3.3+ the task parks in the
awaiting_inputstate (no trigger or triggerer involved); on older versions it defers toHITLTrigger. Either way it resumes inexecute_completeonce a response (or timeout default) arrives.on_approval_timeoutsupplies that timeout default;"fail"supplies none, so the review times out as an error.- Parameters:
context (airflow.sdk.Context) – Airflow task context.
output (Any) – The generated output to present for review.
subject (str | None) – Headline shown on the Required Actions page. Defaults to
"Review output for task `<task_id>`".body (str | None) – Markdown body shown below the headline. Defaults to the prompt and output wrapped in a code block.
modification_schema (dict[str, Any] | None) – JSON schema for the editable
outputparam whenallow_modifications=True. Defaults to{"type": "string"}. Pass e.g.{"type": "string", "enum": [...]}to render a dropdown of valid values in the review form, or{"type": "array", "items": {"type": "string", "enum": [...]}, "examples": [...]}to render a multi-select (JSON Schema forbidsenumat the array level, so the options come fromexamples); a list submitted by the reviewer is returned fromexecute_completere-serialized as a compact JSON string.decision (dict[str, Any] | None) – The pending decision record, when the operator wrote one. It is carried in the continuation the task resumes from, next to
generated_output, soexecute_completefinalizes the record from what was checkpointed with the pause and not from a copy a reader could have edited or deleted in the meantime.
- execute_complete(context, generated_output, event, decision=None)[source]¶
Resume after human review.
Called automatically by Airflow when the HITL trigger fires. Returns the original or reviewer-modified output on approval.
- Parameters:
context (airflow.sdk.Context) – Airflow task context.
generated_output (str) – The output that was deferred for review.
event (dict[str, Any]) – Trigger event payload containing
chosen_options,params_input,responded_by_user, andtimedout.decision (dict[str, Any] | None) – The pending decision record passed to
defer_for_approval, if any. The mixin does not read it; an operator that writes a record finalizes it.
- Raises:
HITLRejectException – If the reviewer, or the
on_approval_timeout="reject"default, rejected the output.HITLTriggerEventError – If the trigger reported an error.
HITLTimeoutError – If the approval timed out.