This is an automated email from the ASF dual-hosted git repository.
ephraimbuddy 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 2aa33971392 Extract Client factory from TriggerRunnerSupervisor into
overridable method (#65978)
2aa33971392 is described below
commit 2aa339713924051e5ccf62461a6eaafc50f85bfa
Author: Ephraim Anierobi <[email protected]>
AuthorDate: Thu Apr 30 09:00:59 2026 +0100
Extract Client factory from TriggerRunnerSupervisor into overridable method
(#65978)
* Extract Client factory from TriggerRunnerSupervisor into overridable
method
Splits the in-process Client construction out of the cached_property
into a separate make_client() method so subclasses can override how
the Client is built while still benefiting from the cached_property.
* Address review feedbacks
---
airflow-core/src/airflow/jobs/triggerer_job_runner.py | 12 ++++++++++++
airflow-core/tests/unit/jobs/test_triggerer_job.py | 18 ++++++++++++++++++
2 files changed, 30 insertions(+)
diff --git a/airflow-core/src/airflow/jobs/triggerer_job_runner.py
b/airflow-core/src/airflow/jobs/triggerer_job_runner.py
index e1c6f1ccb1c..122adb4974b 100644
--- a/airflow-core/src/airflow/jobs/triggerer_job_runner.py
+++ b/airflow-core/src/airflow/jobs/triggerer_job_runner.py
@@ -447,6 +447,18 @@ class TriggerRunnerSupervisor(WatchedSubprocess):
@functools.cached_property
def client(self) -> Client:
+ return self.make_client()
+
+ def make_client(self) -> Client:
+ """
+ Build the API client used to talk to the API server.
+
+ Subclasses may override this to substitute a different transport —
e.g. a
+ real HTTP client pointing at a remote API server — instead of the
default
+ in-process one. The returned client must have ``base_url`` set;
downstream
+ request handling (``self.client.variables``, ``.xcoms``, etc.) reads it
+ when issuing requests.
+ """
from airflow.sdk.api.client import Client
client = Client(base_url=None, token="", dry_run=True,
transport=in_process_api_server().transport)
diff --git a/airflow-core/tests/unit/jobs/test_triggerer_job.py
b/airflow-core/tests/unit/jobs/test_triggerer_job.py
index 8355fa13262..7f553b4b81e 100644
--- a/airflow-core/tests/unit/jobs/test_triggerer_job.py
+++ b/airflow-core/tests/unit/jobs/test_triggerer_job.py
@@ -261,6 +261,24 @@ def test_run_invokes_seams_in_order(supervisor_builder,
mocker):
assert events == ["enter", "tick-1", "tick-2", "tick-3", "exit"]
+def test_client_delegates_to_make_client_and_caches_result(supervisor_builder,
mocker):
+ """``supervisor.client`` delegates to ``make_client`` (the
subclass-override hook)
+ and caches the result across accesses."""
+ supervisor = supervisor_builder()
+ make_client = mocker.patch.object(
+ TriggerRunnerSupervisor,
+ "make_client",
+ autospec=True,
+ return_value=mocker.sentinel.client,
+ )
+
+ first = supervisor.client
+ second = supervisor.client
+
+ assert first is second is mocker.sentinel.client # cached — same object
+ make_client.assert_called_once_with(supervisor)
+
+
def test_run_context_exits_when_subprocess_dies(supervisor_builder, mocker):
"""Breaking out of the loop on a dead subprocess still unwinds
run_context."""
from contextlib import contextmanager