You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by as...@apache.org on 2022/04/07 12:28:11 UTC

[airflow] branch main updated: Don't show irrelevant/duplicated/"internal" Task attrs in UI (#22812)

This is an automated email from the ASF dual-hosted git repository.

ash 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 b639e1b8e4 Don't show irrelevant/duplicated/"internal" Task attrs in UI (#22812)
b639e1b8e4 is described below

commit b639e1b8e44d80828b309e1297d35a19c4b2b31e
Author: Ash Berlin-Taylor <as...@apache.org>
AuthorDate: Thu Apr 7 13:27:58 2022 +0100

    Don't show irrelevant/duplicated/"internal" Task attrs in UI (#22812)
    
    For example, showing `Log Logger <airflow.models.mappedoperator.MappedOperator (INFO)>` isn't useful.
---
 airflow/models/abstractoperator.py | 35 ++++++++++++++++++++++++++++++++++-
 airflow/models/mappedoperator.py   |  7 +++++++
 airflow/www/views.py               | 15 ++++++++++++---
 3 files changed, 53 insertions(+), 4 deletions(-)

diff --git a/airflow/models/abstractoperator.py b/airflow/models/abstractoperator.py
index 5ee57c5e31..ee4aa48416 100644
--- a/airflow/models/abstractoperator.py
+++ b/airflow/models/abstractoperator.py
@@ -18,7 +18,21 @@
 
 import datetime
 import inspect
-from typing import TYPE_CHECKING, Any, Callable, Collection, Dict, Iterable, List, Optional, Set, Type, Union
+from typing import (
+    TYPE_CHECKING,
+    Any,
+    Callable,
+    ClassVar,
+    Collection,
+    Dict,
+    FrozenSet,
+    Iterable,
+    List,
+    Optional,
+    Set,
+    Type,
+    Union,
+)
 
 from sqlalchemy.orm import Session
 
@@ -83,6 +97,25 @@ class AbstractOperator(LoggingMixin, DAGNode):
     owner: str
     task_id: str
 
+    HIDE_ATTRS_FROM_UI: ClassVar[FrozenSet[str]] = frozenset(
+        (
+            'log',
+            'dag',  # We show dag_id, don't need to show this too
+            'node_id',  # Duplicates task_id
+            'task_group',  # Doesn't have a useful repr, no point showing in UI
+            'inherits_from_dummy_operator',  # impl detail
+            # For compatibility with TG, for operators these are just the current task, no point showing
+            'roots',
+            'leaves',
+            # These lists are already shown via *_task_ids
+            'upstream_list',
+            'downstream_list',
+            # Not useful, implementation detail, already shown elsewhere
+            'global_operator_extra_link_dict',
+            'operator_extra_link_dict',
+        )
+    )
+
     def get_dag(self) -> "Optional[DAG]":
         raise NotImplementedError()
 
diff --git a/airflow/models/mappedoperator.py b/airflow/models/mappedoperator.py
index e1df72b50b..27d6bf8518 100644
--- a/airflow/models/mappedoperator.py
+++ b/airflow/models/mappedoperator.py
@@ -278,6 +278,13 @@ class MappedOperator(AbstractOperator):
     is_mapped: ClassVar[bool] = True
     subdag: None = None  # Since we don't support SubDagOperator, this is always None.
 
+    HIDE_ATTRS_FROM_UI: ClassVar[FrozenSet[str]] = AbstractOperator.HIDE_ATTRS_FROM_UI | frozenset(
+        (
+            'parse_time_mapped_ti_count',
+            'operator_class',
+        )
+    )
+
     def __repr__(self):
         return f"<Mapped({self._task_type}): {self.task_id}>"
 
diff --git a/airflow/www/views.py b/airflow/www/views.py
index 03cd5e6e02..edc2de32c6 100644
--- a/airflow/www/views.py
+++ b/airflow/www/views.py
@@ -1614,12 +1614,21 @@ class Airflow(AirflowBaseView):
             ti_attrs = sorted((name, attr) for name, attr in all_ti_attrs if not callable(attr))
 
         attr_renderers = wwwutils.get_attr_renderer()
+
+        attrs_to_skip = getattr(task, 'HIDE_ATTRS_FROM_UI', set())
+
+        def include_task_attrs(attr_name):
+            return not (
+                attr_name == 'HIDE_ATTRS_FROM_UI'
+                or attr_name.startswith("_")
+                or attr_name in attr_renderers
+                or attr_name in attrs_to_skip
+            )
+
         task_attrs = [
             (attr_name, attr)
             for attr_name, attr in (
-                (attr_name, getattr(task, attr_name))
-                for attr_name in dir(task)
-                if not attr_name.startswith("_") and attr_name not in attr_renderers
+                (attr_name, getattr(task, attr_name)) for attr_name in filter(include_task_attrs, dir(task))
             )
             if not callable(attr)
         ]