Coverage for /home/airflow/.local/lib/python3.12/site-packages/airflow/api_fastapi/core_api/datamodels/ui/deadline.py: 70%
38 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.
18from __future__ import annotations
20from collections.abc import Iterable
21from datetime import datetime
22from typing import Any
23from uuid import UUID
25from pydantic import AliasPath, Field, field_validator
27from airflow.api_fastapi.core_api.base import BaseModel
30class DeadlineResponse(BaseModel):
31 """Deadline serializer for responses."""
33 id: UUID
34 deadline_time: datetime
35 missed: bool
36 created_at: datetime
37 dag_id: str = Field(validation_alias=AliasPath("dagrun", "dag_id"))
38 dag_run_id: str = Field(validation_alias=AliasPath("dagrun", "run_id"))
39 alert_id: UUID | None = Field(validation_alias="deadline_alert_id", default=None)
40 alert_name: str | None = Field(validation_alias=AliasPath("deadline_alert", "name"), default=None)
43class DeadlineCollectionResponse(BaseModel):
44 """Deadline Collection serializer for responses."""
46 deadlines: Iterable[DeadlineResponse]
47 total_entries: int
50class DeadlineAlertResponse(BaseModel):
51 """DeadlineAlert serializer for responses."""
53 id: UUID
54 name: str | None = None
55 reference_type: str = Field(validation_alias=AliasPath("reference", "reference_type"))
56 interval: float | None = Field(
57 default=None,
58 description=(
59 "Interval in seconds between the reference time and the deadline. "
60 "Null for a dynamic interval (e.g. a VariableInterval) whose value is "
61 "only resolved at scheduler evaluation time."
62 ),
63 )
64 created_at: datetime
66 @field_validator("interval", mode="before")
67 @classmethod
68 def coerce_interval_to_seconds(cls, value: Any) -> float | None:
69 """
70 Coerce the stored ``interval`` into seconds.
72 ``interval`` is the Airflow-serialized SDK interval: a dict
73 ``{"__classname__": ..., "__data__": <seconds|dict>}``, not a plain number.
74 Return the seconds for a fixed ``timedelta``, or ``None`` for a dynamic
75 interval (resolved later by the scheduler). Without this, Pydantic 500s on the dict.
76 """
77 if value is None or isinstance(value, (int, float)):
78 return value
79 if isinstance(value, dict):
80 data = value.get("__data__")
81 if isinstance(data, (int, float)):
82 return float(data)
83 return None
86class DeadlineAlertCollectionResponse(BaseModel):
87 """DeadlineAlert Collection serializer for responses."""
89 deadline_alerts: Iterable[DeadlineAlertResponse]
90 total_entries: int