bbovenzi commented on code in PR #74278:
URL: https://github.com/apache/airflow/pull/74278#discussion_r4198228595
##########
airflow-core/docs/administration-and-deployment/plugins.rst:
##########
@@ -404,52 +406,107 @@ relevant instead of appearing on every Dag:
.. code-block:: python
"applies_to": {
- "dag_tags": ["ml"], # Dag carries any of these tags
- "dag_ids": ["train_pipeline"], # exact dag_id
- "task_ids": ["train_model"], # exact task_id
- "operators": ["KubernetesPodOperator"], # operator class name
+ "state": ["failed", "upstream_failed"], # the entity's own field
+ "dag.tags.name": ["ml"], # a related record, array-aware
+ "dag.dag_id": ["train_pipeline"],
}
-All keys are optional. ``operators`` and ``operator_names`` are matched
separately, the same
-way the task instance filters treat them: ``operators`` is the operator class
name, while
-``operator_names`` is the display name shown in the UI (an operator's
-``custom_operator_name``). For a plain operator the two are identical, so
either key works.
-They differ for decorator-based tasks: a ``@task.bash`` task has the display
name
-``@task.bash`` but the private class name ``_BashDecoratedOperator``, so use
-``operator_names`` to target it.
+Keys are **dotted field paths** into the records the page has, not a fixed set
of criteria, so
+anything the REST API returns for an entity is addressable — ``state``,
``operator``, ``pool``,
+``queue``, ``try_number``, and so on. Values are matched for equality, and are
compared as
+strings, so numeric and boolean fields work without quoting rules of their own
+(``"try_number": ["2"]``, ``"is_paused": ["false"]``).
-Criteria combine like Kubernetes label selectors — **OR within a key, AND
across keys**. A
-Dag matching any listed tag satisfies ``dag_tags``, and a view configured with
both
-``dag_tags`` and ``operators`` requires both to match.
+An **unqualified path is rooted at the entity the destination is about** — on
``dag_run``,
+``state`` is the run's state; on ``task_instance``, the task instance's. A
path may instead
+name a related record as its first segment: ``dag``, ``dag_run``, ``task`` or
+``task_instance``. Traversing a list fans out across it, so ``dag.tags.name``
collects every
+tag name and matches if any of them is listed.
-Crucially, the AND applies **only across criteria the current page can
evaluate**. A
-``task_ids`` criterion cannot be judged on a Dag-level page, so it is skipped
there rather
+Paths combine like Kubernetes label selectors — **OR within a path, AND across
paths**. A Dag
+matching any listed tag satisfies ``dag.tags.name``, and a view configured
with both
+``dag.tags.name`` and ``state`` requires both to match.
+
+Crucially, the AND applies **only across paths the current page can
evaluate**. A
+``task_instance.*`` path cannot be judged on a Dag-level page, so it is
skipped there rather
than failing the match. This lets one ``applies_to`` block be shared by a
plugin's Dag- and
-task-level destinations. Which criteria each destination can evaluate:
+task-level destinations. Which records each destination resolves:
.. list-table::
:header-rows: 1
* - Destination
- - ``dag_tags`` / ``dag_ids``
- - ``task_ids`` / ``operators`` / ``operator_names``
- * - ``dag``, ``dag_run``, ``dag_overview``
- - evaluated
- - skipped
- * - ``task``, ``task_overview``, ``task_instance``
- - evaluated
- - evaluated
+ - Unqualified path is rooted at
+ - Records a qualified path can reach
+ * - ``dag``, ``dag_overview``
+ - ``dag``
+ - ``dag``
+ * - ``dag_run``
+ - ``dag_run``
+ - ``dag``, ``dag_run``
+ * - ``task``, ``task_overview``
+ - ``task``
+ - ``dag``, ``task``
+ * - ``task_instance``
+ - ``task_instance``
+ - ``dag``, ``dag_run``, ``task``, ``task_instance``
* - ``nav``, ``base``, ``dashboard``, ``asset``
- - skipped
- - skipped
+ - —
+ - none, so every path is skipped
+
+If none of the configured paths can be evaluated on a given page, the view is
shown. On task
+group pages the task-level records are absent, since a group is not a task.
+
+A path is also skipped when the record exists but has no such field. That
means a **bad path
+widens the scope rather than narrowing it**, so paths are checked against the
API response
+models when plugins load and a path naming no field is logged with a suggested
correction.
+The check stops at a field whose contents the models do not describe — the
dict behind
+``class_ref``, or a Dag Run's ``conf`` — so a path below one of those is still
accepted and
+still widens silently. If a view appears in more places than you expect, check
the API server
+log first, then the path against the REST API response for that entity.
+
+An empty list is different from a missing field: a Dag with no tags has
definitively answered
+``dag.tags.name``, so the view is not shown. A path that stops short of a leaf
is likewise a
+decided answer rather than a skip: ``dag.tags`` resolves to a list of objects,
which have no
+comparable value, so the view is hidden. Address the field you mean to compare
+(``dag.tags.name``).
+
+Targeting operators
+^^^^^^^^^^^^^^^^^^^
+
+``operator_name`` is spelled the same way on a task and on a task instance, so
**one
+unqualified path targets an operator on either page**:
+
+.. code-block:: python
+
+ "applies_to": {"operator_name": ["KubernetesPodOperator"]}
+
+``operator_name`` is the display name shown in the UI (an operator's
+``custom_operator_name``). For a plain operator it is the class name, but the
two differ for
+decorator-based tasks: a ``@task.bash`` task has the display name
``@task.bash`` and the
+private class name ``_BashDecoratedOperator``, so ``operator_name`` is the one
to match on.
+
+If you specifically need the operator *class* name, the two records spell it
differently — a
+task instance has ``operator``, while a task carries it through
``class_ref.class_name``. The
+skip rule is what lets one block cover both, by naming each source:
+
+.. code-block:: python
+
+ "applies_to": {
+ # On a task page the first is skipped and the second decides; on a
task instance
+ # page, the reverse. Prefer `operator_name` unless you need the
private class name.
+ "task_instance.operator": ["KubernetesPodOperator"],
+ "task.class_ref.class_name": ["KubernetesPodOperator"],
Review Comment:
Fixed.
class_ref will only apply to Task level plugins
operator will only apply to Task Instances
operator_name can apply to both but on TIs it will use the
TaskInstanceResponse
--
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]