Coverage for /home/airflow/.local/lib/python3.12/site-packages/airflow/api_fastapi/execution_api/datamodels/hitl.py: 94%
34 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 14:22 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 14:22 +0000
1# Licensed to the Apache Software Foundation (ASF) under one
2# or more contributor license agreements. See the NOTICE file
3# distributed with this work for additional information
4# regarding copyright ownership. The ASF licenses this file
5# to you under the Apache License, Version 2.0 (the
6# "License"); you may not use this file except in compliance
7# with the License. You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing,
12# software distributed under the License is distributed on an
13# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14# KIND, either express or implied. See the License for the
15# specific language governing permissions and limitations
16# under the License.
17from __future__ import annotations
19from collections.abc import Iterable
20from typing import Any
21from uuid import UUID
23from pydantic import Field
25from airflow.api_fastapi.common.types import UtcDateTime
26from airflow.api_fastapi.core_api.base import BaseModel
27from airflow.models.hitl import HITLDetail
30class HITLUser(BaseModel):
31 """Schema for a Human-in-the-loop users."""
33 id: str
34 name: str
37class HITLDetailRequest(BaseModel):
38 """Schema for the request part of a Human-in-the-loop detail for a specific task instance."""
40 ti_id: UUID
41 options: list[str] = Field(min_length=1)
42 subject: str
43 body: str | None = None
44 defaults: list[str] | None = None
45 multiple: bool = False
46 params: dict[str, Any] = Field(default_factory=dict)
47 assigned_users: list[HITLUser] = Field(default_factory=list)
50class UpdateHITLDetailPayload(BaseModel):
51 """Schema for writing the response part of a Human-in-the-loop detail for a specific task instance."""
53 ti_id: UUID
54 chosen_options: list[str] = Field(min_length=1)
55 params_input: dict[str, Any] = Field(default_factory=dict)
58class HITLDetailResponse(BaseModel):
59 """Schema for the response part of a Human-in-the-loop detail for a specific task instance."""
61 response_received: bool
62 responded_by_user: HITLUser | None = None
63 responded_at: UtcDateTime | None
64 # It's empty if the user has not yet responded.
65 chosen_options: Iterable[str] | None
66 params_input: dict[str, Any] = Field(default_factory=dict)
68 @classmethod
69 def from_hitl_detail_orm(cls, hitl_detail: HITLDetail) -> HITLDetailResponse:
70 hitl_user = (
71 HITLUser(
72 id=hitl_detail.responded_by_user_id,
73 name=hitl_detail.responded_by_user_name,
74 )
75 if hitl_detail.responded_by_user
76 else None
77 )
79 return HITLDetailResponse(
80 response_received=hitl_detail.response_received,
81 responded_at=hitl_detail.responded_at,
82 responded_by_user=hitl_user,
83 chosen_options=hitl_detail.chosen_options or (),
84 params_input=hitl_detail.params_input or {},
85 )