kaxil commented on code in PR #75423:
URL: https://github.com/apache/airflow/pull/75423#discussion_r4354770030
##########
airflow-core/newsfragments/75423.bugfix.rst:
##########
@@ -0,0 +1 @@
+A task that runs entirely in the triggerer (``start_from_trigger=True``) now
records its rendered template fields, so the Rendered Templates tab shows them
instead of staying empty for the whole run.
Review Comment:
Can you drop this? airflow-core only takes `significant` newsfragments now,
for changes users must read before upgrading, and never for an ordinary bug fix
(see `contributing-docs/18_contribution_workflow.rst`).
##########
airflow-core/src/airflow/jobs/triggerer_job_runner.py:
##########
@@ -1467,6 +1475,32 @@ def create_runtime_ti(
),
)
+ async def record_rendered_fields(self, runtime_ti: RuntimeTaskInstance,
context: Context) -> None:
+ """
+ Record the rendered template fields of a task that starts from the
triggerer.
+
+ Such a task never starts in a worker, so nothing else records them and
the Rendered
+ Templates tab stays empty for the whole run. Rendering is best effort:
a task whose
+ fields cannot be rendered here still has a trigger to run.
+ """
+ # Reused rather than reimplemented so core cannot drift from the
redaction the worker applies.
+ from airflow.sdk.execution_time.task_runner import
_serialize_rendered_fields # noqa: SDK001
+
+ try:
+ context["task"] = runtime_ti.task
+ runtime_ti.render_templates(context=context,
jinja_env=runtime_ti.task.dag.get_template_env())
Review Comment:
In production this never gets past this line. `create_runtime_ti` builds the
task with `DagSerialization.from_dict(...).get_task(...)`, so `runtime_ti.task`
is a core `SerializedBaseOperator` and `.dag` is a `SerializedDAG`, and neither
has `get_template_env` or `render_template_fields`. The `AttributeError` is
caught below, so every start-from-trigger task logs "Failed to render template
fields" with a traceback and nothing is sent. I ran `record_rendered_fields` on
a task built that way: `asend` was never awaited and the log had
`'SerializedDAG' object has no attribute 'get_template_env'`.
Adding those methods to the serialized classes wouldn't get there either.
Rendering an operator's fields needs things the serialized Dag doesn't carry
(`user_defined_macros`, `user_defined_filters`, `template_searchpath` for
`template_ext` files), and the triggerer doesn't load Dag bundles. #53071 had
the triggerer load the Dag to render task fields and was reverted in #55037 for
that reason.
What the triggerer can render is what it already renders: `BaseTrigger`
renders the operator template fields passed through
`start_trigger_args.trigger_kwargs` (`target_time` for `DateTimeSensorAsync`,
the case in the issue). Recording those after
`trigger.render_template_fields(context)` would work without the Dag file,
though it only covers the fields the trigger receives.
##########
airflow-core/tests/unit/jobs/test_triggerer_job.py:
##########
@@ -4007,3 +4007,65 @@ async def fake_run():
log.get("event") == "Trigger fired event payload" and
log.get("result") == TriggerEvent(payload)
for log in debug_logs
), "Full event payload must be logged at DEBUG level"
+
+
+class _TemplatedOperator(BaseOperator):
+ """Minimal operator with a templated field, for the start-from-trigger
rendering tests."""
+
+ template_fields = ("greeting",)
+
+ def __init__(self, *, greeting: str, **kwargs):
+ super().__init__(**kwargs)
+ self.greeting = greeting
+
+ def execute(self, context):
+ raise AssertionError("start_from_trigger tasks never execute in a
worker")
+
+
+def _runtime_ti_with_templated_task(greeting: str):
+ from airflow.sdk.execution_time.task_runner import RuntimeTaskInstance
+
+ with DAG("rendered_fields_dag", schedule=None,
start_date=timezone.datetime(2026, 1, 1)):
+ task = _TemplatedOperator(task_id="templated", greeting=greeting)
+
+ return RuntimeTaskInstance.model_construct(
Review Comment:
These tests hand `model_construct` an SDK `BaseOperator`, but production
builds the TI through `TriggerRunner.create_runtime_ti(ti,
DagSerialization.to_dict(dag), dag_run_data)`, which is why they pass while the
real path raises. Building it that way would have caught the problem above. The
new `SetRenderedFields` branch in `_handle_request` also has no test.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]