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

Reply via email to