This is an automated email from the ASF dual-hosted git repository.
ferruzzi pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new b2ee721a2cd Update Deadline Reference docs to match the code (#71469)
b2ee721a2cd is described below
commit b2ee721a2cd30181b2759c00f359d115e2859a8c
Author: D. Ferruzzi <[email protected]>
AuthorDate: Wed Aug 12 17:49:15 2026 -0700
Update Deadline Reference docs to match the code (#71469)
PR #66737 changed how registering custom Deadline References worked but
didn't update the docs.
---
.../docs/administration-and-deployment/plugins.rst | 1 +
airflow-core/docs/howto/deadline-alerts.rst | 25 +++++++++++++++++++---
airflow-core/src/airflow/serialization/encoders.py | 5 +++--
task-sdk/src/airflow/sdk/definitions/deadline.py | 23 ++++++++++++++++++--
4 files changed, 47 insertions(+), 7 deletions(-)
diff --git a/airflow-core/docs/administration-and-deployment/plugins.rst
b/airflow-core/docs/administration-and-deployment/plugins.rst
index 31c6f16fd0e..5612e523f8d 100644
--- a/airflow-core/docs/administration-and-deployment/plugins.rst
+++ b/airflow-core/docs/administration-and-deployment/plugins.rst
@@ -81,6 +81,7 @@ Airflow plugins can register the following components:
* *Macros* – Define reusable Python functions available in DAG templates.
* *Operator Extra Links* – Add custom buttons in the task details view.
* *Timetables & Listeners* – Implement custom scheduling logic and event hooks.
+* *Deadline References* – Register custom :doc:`Deadline Alert
</howto/deadline-alerts>` reference classes.
When are plugins (re)loaded?
----------------------------
diff --git a/airflow-core/docs/howto/deadline-alerts.rst
b/airflow-core/docs/howto/deadline-alerts.rst
index 7eb9ec76cf2..124b7d87040 100644
--- a/airflow-core/docs/howto/deadline-alerts.rst
+++ b/airflow-core/docs/howto/deadline-alerts.rst
@@ -424,13 +424,24 @@ The decorator may be used with or without parentheses.
Used bare, or with empty
reference is evaluated when a new Dag run is created; pass a
``DeadlineReference.TYPES`` value to
choose a different time.
+The class must also be registered as part of a :doc:`plugin
</administration-and-deployment/plugins>`
+by adding it to the plugin's ``deadline_references`` list, the same way custom
timetables are
+registered. The decorator makes the reference available to your Dag file as
+``DeadlineReference.<ClassName>``; the plugin registration is what lets the
scheduler resolve the
+class again when it deserializes the Dag. A custom reference that is not
registered in a plugin
+raises ``DeadlineReferenceNotRegistered`` at deserialization time.
-**Creating a Custom Reference**
+
+**Creating and Registering a Custom Reference**
+
+Place the reference classes and the plugin that registers them in your plugins
folder (e.g.
+``$AIRFLOW_HOME/plugins/deadline_references.py``):
.. code-block:: python
from sqlalchemy.orm import Session
+ from airflow.plugins_manager import AirflowPlugin
from airflow.sdk import BaseDeadlineReference, DeadlineReference,
deadline_reference
from airflow.sdk.timezone import datetime
@@ -460,9 +471,16 @@ choose a different time.
return your_datetime
+ # Register the classes so the scheduler can resolve them when it
deserializes the Dag.
+ class MyDeadlineReferencePlugin(AirflowPlugin):
+ name = "my_deadline_reference_plugin"
+ deadline_references = [MyCustomDecoratedReference, MyQueuedReference]
+
+
**Using a Custom Reference in a Dag**
-Once registered, use your custom references in Dag definitions like any other
reference:
+Once the classes are decorated and registered in a plugin, use them in Dag
definitions like any
+other reference:
.. code-block:: python
@@ -528,7 +546,8 @@ followed by a more urgent escalation if the Dag is still
running.
* **No-argument Construction**: Custom references are instantiated during
registration, so they must be
constructible with no arguments. If your reference takes parameters,
decorate it with ``@dataclass``
and give every field a default value.
-* **Plugin Placement**: One convenient place for custom references is in the
plugins directory.
+* **Plugin Registration**: Custom references must be listed in the
``deadline_references`` attribute
+ of an ``AirflowPlugin``, so the plugins directory is the natural home for
them.
* **API Server Restart**: Restart the Airflow API Server after adding or
modifying custom references.
* **Required Parameters**: ``required_kwargs`` declares which Dag run context
values Airflow should
forward to ``_evaluate_with()``. Only ``dag_id`` and ``run_id`` are
available; declaring anything
diff --git a/airflow-core/src/airflow/serialization/encoders.py
b/airflow-core/src/airflow/serialization/encoders.py
index ab37b78550d..b3aac16363d 100644
--- a/airflow-core/src/airflow/serialization/encoders.py
+++ b/airflow-core/src/airflow/serialization/encoders.py
@@ -277,9 +277,10 @@ def encode_deadline_reference(ref) -> dict[str, Any]:
serialized = ref.serialize_reference()
- # Custom types (not built-in) need __class_path so the decoder can import
them.
+ # Custom types (not built-in) need __class_path so the decoder can look
them up.
# Unlike built-in types which are looked up in SerializedReferenceModels,
- # custom types are discovered via import_string(__class_path) at
deserialization time.
+ # custom types are resolved at deserialization time from the classes
registered
+ # via the `deadline_references` attribute on an AirflowPlugin.
module = type(ref).__module__
if module not in _BUILTIN_DEADLINE_MODULES:
serialized["__class_path"] = qualname(ref)
diff --git a/task-sdk/src/airflow/sdk/definitions/deadline.py
b/task-sdk/src/airflow/sdk/definitions/deadline.py
index 6b895c2164e..f3a14aeb9cc 100644
--- a/task-sdk/src/airflow/sdk/definitions/deadline.py
+++ b/task-sdk/src/airflow/sdk/definitions/deadline.py
@@ -46,7 +46,9 @@ class BaseDeadlineReference(ABC):
The actual evaluation logic (``_evaluate_with``) is in Core's
``SerializedReferenceModels``.
For custom deadline references, users should inherit from this class and
implement
- ``_evaluate_with()`` with deferred Core imports (imports inside the method
body).
+ ``_evaluate_with()`` with deferred Core imports (imports inside the method
body). A custom
+ reference must be decorated with ``@deadline_reference`` and listed in the
``deadline_references``
+ attribute of an ``AirflowPlugin``; see
:external:doc:`howto/deadline-alerts`.
"""
@property
@@ -272,7 +274,19 @@ class DeadlineReference:
deadline_reference_type: DeadlineReferenceTypes | None = None,
) -> type[BaseDeadlineReference]:
"""
- Register a custom deadline reference class.
+ Register a custom deadline reference class for use in Dag files.
+
+ This makes the reference available to Dag authors as
``DeadlineReference.<ClassName>`` and
+ records when it should be evaluated.
+
+ .. warning::
+
+ Registering the reference is **not** the same as registering the
plugin, despite the
+ name of this method. This only affects the process that runs the
Dag file; it does not
+ make the class resolvable when the scheduler deserializes the Dag.
The class must
+ *also* be listed in the ``deadline_references`` attribute of an
``AirflowPlugin``, or
+ deserialization raises ``DeadlineReferenceNotRegistered``. See
+ :external:doc:`howto/deadline-alerts`.
:param reference_class: The custom reference class inheriting from
BaseDeadlineReference
:param deadline_reference_type: A DeadlineReference.TYPES for when the
deadline should be evaluated ("DAGRUN_CREATED",
@@ -337,6 +351,11 @@ def deadline_reference(deadline_reference_type=None):
May be used with or without parentheses. Without parentheses the reference
is evaluated when a
new dagrun is created; pass a ``DeadlineReference.TYPES`` value to choose
a different time.
+ The decorated class must also be registered in the ``deadline_references``
list of an
+ ``AirflowPlugin`` so that it can be resolved when the Dag is deserialized.
An unregistered
+ reference raises ``DeadlineReferenceNotRegistered``. See also
+ :external:doc:`howto/deadline-alerts`.
+
.. code-block:: python
@deadline_reference