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/03/11 14:53:57 UTC

[airflow] branch main updated: Update links to new Grid/Graph view instead of relying on redirects (#22167)

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 961225f  Update links to new Grid/Graph view instead of relying on redirects (#22167)
961225f is described below

commit 961225f3ad7ece97b0214927e28c1e63ec6eb54b
Author: Ash Berlin-Taylor <as...@apache.org>
AuthorDate: Fri Mar 11 14:53:07 2022 +0000

    Update links to new Grid/Graph view instead of relying on redirects (#22167)
    
    Recently we changed the URL strucutre for Graph and Grid (nee Tree)
    views, but there were still a few places that used the old names (which
    still work thanks to the redirects we have in place.)
    
    This changes the front end to use the new URLs directly.
    
    A few of the places the URL is generated/tweaked via JS, so we needed a
    pass a "fake" dag_id -- `$dag_id` to the `url_for()` helper (otherwise
    it would blow up) and then replace it directly in the string from JS.
---
 UPDATING.md                                        |  4 ++++
 airflow/config_templates/config.yml                |  8 ++++----
 airflow/config_templates/default_airflow.cfg       |  8 ++++----
 airflow/configuration.py                           |  1 +
 airflow/models/dag.py                              | 13 ++++++++++---
 airflow/www/static/js/calendar.js                  | 11 ++++-------
 airflow/www/static/js/dag.js                       |  7 ++++++-
 airflow/www/static/js/dags.js                      |  5 ++---
 airflow/www/templates/airflow/calendar.html        |  3 +--
 airflow/www/templates/airflow/dag.html             |  2 +-
 airflow/www/templates/airflow/dags.html            |  2 +-
 tests/api_connexion/endpoints/test_dag_endpoint.py | 10 +++++-----
 tests/sensors/test_external_task_sensor.py         |  2 +-
 13 files changed, 44 insertions(+), 32 deletions(-)

diff --git a/UPDATING.md b/UPDATING.md
index 474f7bc..cda775f 100644
--- a/UPDATING.md
+++ b/UPDATING.md
@@ -222,6 +222,10 @@ When a `ReadyToRescheduleDep` is run, it now checks whether the `reschedule` att
 
 To support operator-mapping (AIP 42), the `deps` attribute on operator class must be a set at the class level. This means that if a custom operator implements this as an instance-level variable, it will not be able to be used for operator-mapping. This does not affect existing code, but we highly recommend you to restructure the operator's dep logic in order to support the new feature.
 
+### The `tree` default view setting has been renamed to `grid`
+
+If you set the `dag_default_view` config option or the `default_view` argument to `DAG()` to `tree` you will need to update your deployment. The old name will continue to work but will issue warnings.
+
 ## Airflow 2.2.4
 
 ### Smart sensors deprecated
diff --git a/airflow/config_templates/config.yml b/airflow/config_templates/config.yml
index c6448d2..d43e1fb 100644
--- a/airflow/config_templates/config.yml
+++ b/airflow/config_templates/config.yml
@@ -1155,11 +1155,11 @@
       default: "True"
     - name: dag_default_view
       description: |
-        Default DAG view. Valid values are: ``tree``, ``graph``, ``duration``, ``gantt``, ``landing_times``
+        Default DAG view. Valid values are: ``grid``, ``graph``, ``duration``, ``gantt``, ``landing_times``
       version_added: ~
       type: string
       example: ~
-      default: "tree"
+      default: "grid"
     - name: dag_orientation
       description: |
         Default DAG orientation. Valid values are:
@@ -1351,7 +1351,7 @@
       default: "False"
     - name: auto_refresh_interval
       description: |
-        How frequently, in seconds, the DAG data will auto-refresh in graph or tree view
+        How frequently, in seconds, the DAG data will auto-refresh in graph or grid view
         when auto-refresh is turned on
       version_added: 2.2.0
       type: integer
@@ -1372,7 +1372,7 @@
       version_added: 2.3.0
       type: string
       example: ~
-      default: "gantt,landing_times,tries,duration,calendar,graph,tree,tree_data"
+      default: "gantt,landing_times,tries,duration,calendar,graph,grid,tree,tree_data"
     - name: audit_view_included_events
       description: |
         Comma separated string of view events to include in dag audit view.
diff --git a/airflow/config_templates/default_airflow.cfg b/airflow/config_templates/default_airflow.cfg
index 1477e07..c8d34bb 100644
--- a/airflow/config_templates/default_airflow.cfg
+++ b/airflow/config_templates/default_airflow.cfg
@@ -592,8 +592,8 @@ expose_hostname = True
 # Expose stacktrace in the web server
 expose_stacktrace = True
 
-# Default DAG view. Valid values are: ``tree``, ``graph``, ``duration``, ``gantt``, ``landing_times``
-dag_default_view = tree
+# Default DAG view. Valid values are: ``grid``, ``graph``, ``duration``, ``gantt``, ``landing_times``
+dag_default_view = grid
 
 # Default DAG orientation. Valid values are:
 # ``LR`` (Left->Right), ``TB`` (Top->Bottom), ``RL`` (Right->Left), ``BT`` (Bottom->Top)
@@ -680,7 +680,7 @@ session_lifetime_minutes = 43200
 # Whether the custom page title for the DAGs overview page contains any Markup language
 instance_name_has_markup = False
 
-# How frequently, in seconds, the DAG data will auto-refresh in graph or tree view
+# How frequently, in seconds, the DAG data will auto-refresh in graph or grid view
 # when auto-refresh is turned on
 auto_refresh_interval = 3
 
@@ -690,7 +690,7 @@ warn_deployment_exposure = True
 # Comma separated string of view events to exclude from dag audit view.
 # All other events will be added minus the ones passed here.
 # The audit logs in the db will not be affected by this parameter.
-audit_view_excluded_events = gantt,landing_times,tries,duration,calendar,graph,tree,tree_data
+audit_view_excluded_events = gantt,landing_times,tries,duration,calendar,graph,grid,tree,tree_data
 
 # Comma separated string of view events to include in dag audit view.
 # If passed, only these events will populate the dag audit view.
diff --git a/airflow/configuration.py b/airflow/configuration.py
index 03a1e7a..95233d0 100644
--- a/airflow/configuration.py
+++ b/airflow/configuration.py
@@ -196,6 +196,7 @@ class AirflowConfigParser(ConfigParser):
         },
         'webserver': {
             'navbar_color': (re.compile(r'\A#007A87\Z', re.IGNORECASE), '#fff', '2.1'),
+            'dag_default_view': (re.compile(r'^tree$'), 'grid', '3.0'),
         },
         'email': {
             'email_backend': (
diff --git a/airflow/models/dag.py b/airflow/models/dag.py
index 86a93f4..b6ede6f 100644
--- a/airflow/models/dag.py
+++ b/airflow/models/dag.py
@@ -96,7 +96,7 @@ if TYPE_CHECKING:
 
 log = logging.getLogger(__name__)
 
-DEFAULT_VIEW_PRESETS = ['tree', 'graph', 'duration', 'gantt', 'landing_times']
+DEFAULT_VIEW_PRESETS = ['grid', 'graph', 'duration', 'gantt', 'landing_times']
 ORIENTATION_PRESETS = ['LR', 'TB', 'RL', 'BT']
 
 
@@ -245,8 +245,8 @@ class DAG(LoggingMixin):
         timeouts. See :ref:`sla_miss_callback<concepts:sla_miss_callback>` for
         more information about the function signature and parameters that are
         passed to the callback.
-    :param default_view: Specify DAG default view (tree, graph, duration,
-                                                   gantt, landing_times), default tree
+    :param default_view: Specify DAG default view (grid, graph, duration,
+                                                   gantt, landing_times), default grid
     :param orientation: Specify DAG orientation in graph view (LR, TB, RL, BT), default LR
     :param catchup: Perform scheduler catchup (or only run latest)? Defaults to True
     :param on_failure_callback: A function to be called when a DagRun of this dag fails.
@@ -436,6 +436,13 @@ class DAG(LoggingMixin):
         self.sla_miss_callback = sla_miss_callback
         if default_view in DEFAULT_VIEW_PRESETS:
             self._default_view: str = default_view
+        elif default_view == 'tree':
+            warnings.warn(
+                "`default_view` of 'tree' has been renamed to 'grid' -- please update your DAG",
+                DeprecationWarning,
+                stacklevel=2,
+            )
+            self._default_view = 'grid'
         else:
             raise AirflowException(
                 f'Invalid values of dag.default_view: only support '
diff --git a/airflow/www/static/js/calendar.js b/airflow/www/static/js/calendar.js
index 81c6b23..6f15a65 100644
--- a/airflow/www/static/js/calendar.js
+++ b/airflow/www/static/js/calendar.js
@@ -20,13 +20,10 @@
 /* global calendarData, statesColors, document, window, $, d3, moment */
 import { getMetaValue } from './utils';
 
-const dagId = getMetaValue('dag_id');
-const treeUrl = getMetaValue('tree_url');
+const gridUrl = getMetaValue('grid_url');
 
-function getTreeViewURL(d) {
-  return `${treeUrl
-  }?dag_id=${encodeURIComponent(dagId)
-  }&base_date=${encodeURIComponent(d.toISOString())}`;
+function getGridViewURL(d) {
+  return `${gridUrl}?base_date=${encodeURIComponent(d.toISOString())}`;
 }
 
 // date helpers
@@ -283,7 +280,7 @@ document.addEventListener('DOMContentLoaded', () => {
         return d3.interpolateHsl(statesColors.success, statesColors.failed)(ratioFailures);
       })
       .on('click', (data) => {
-        window.location.href = getTreeViewURL(
+        window.location.href = getGridViewURL(
           // add 1 day and subtract 1 ms to not show any run from the next day.
           toMoment(data.year, data.month, data.day).add(1, 'day').subtract(1, 'ms'),
         );
diff --git a/airflow/www/static/js/dag.js b/airflow/www/static/js/dag.js
index 7f44a86..ae7f6e4 100644
--- a/airflow/www/static/js/dag.js
+++ b/airflow/www/static/js/dag.js
@@ -61,7 +61,12 @@ const buttons = Array.from(document.querySelectorAll('a[id^="btn_"][data-base-ur
 }, {});
 
 function updateButtonUrl(elm, params) {
-  elm.setAttribute('href', `${elm.dataset.baseUrl}?${$.param(params)}`);
+  let url = elm.dataset.baseUrl;
+  if (params.dag_id && elm.dataset.baseUrl.indexOf(dagId) !== -1) {
+    url = url.replace(dagId, params.dag_id);
+    delete params.dag_id;
+  }
+  elm.setAttribute('href', `${url}?${$.param(params)}`);
 }
 
 function updateModalUrls() {
diff --git a/airflow/www/static/js/dags.js b/airflow/www/static/js/dags.js
index 268487e..3ada349 100644
--- a/airflow/www/static/js/dags.js
+++ b/airflow/www/static/js/dags.js
@@ -36,7 +36,7 @@ const csrfToken = getMetaValue('csrf_token');
 const lastDagRunsUrl = getMetaValue('last_dag_runs_url');
 const dagStatsUrl = getMetaValue('dag_stats_url');
 const taskStatsUrl = getMetaValue('task_stats_url');
-const treeUrl = getMetaValue('tree_url');
+const gridUrl = getMetaValue('grid_url');
 
 $('#tags_filter').select2({
   placeholder: 'Filter DAGs by tag',
@@ -122,8 +122,7 @@ $('.typeahead').typeahead({
     const dagId = value.trim();
     if (dagId) {
       const query = new URLSearchParams(window.location.search);
-      query.set('dag_id', dagId);
-      window.location = `${treeUrl}?${query}`;
+      window.location = `${gridUrl.replace('__DAG_ID__', dagId)}?${query}`;
     }
   },
 });
diff --git a/airflow/www/templates/airflow/calendar.html b/airflow/www/templates/airflow/calendar.html
index 4caf2d9..05aa425 100644
--- a/airflow/www/templates/airflow/calendar.html
+++ b/airflow/www/templates/airflow/calendar.html
@@ -22,8 +22,7 @@
 
 {% block head_css %}
   {{ super() }}
-  <meta name="dag_id" content="{{ dag.dag_id }}">
-  <meta name="tree_url" content="{{ url_for('Airflow.tree') }}">
+  <meta name="grid_url" content="{{ url_for('Airflow.grid', dag_id=dag.dag_id) }}">
   <link rel="stylesheet" type="text/css" href="{{ url_for_asset('calendar.css') }}">
 {% endblock %}
 
diff --git a/airflow/www/templates/airflow/dag.html b/airflow/www/templates/airflow/dag.html
index 19c07ed..9b20ba9 100644
--- a/airflow/www/templates/airflow/dag.html
+++ b/airflow/www/templates/airflow/dag.html
@@ -185,7 +185,7 @@
         </div>
         <div class="modal-body">
           <div id="div_btn_subdag">
-            <a id="btn_subdag" class="btn btn-primary" data-base-url="{{ url_for('Airflow.legacy_' + dag.default_view) }}">
+            <a id="btn_subdag" class="btn btn-primary" data-base-url="{{ url_for('Airflow.' + dag.default_view, dag_id=dag.dag_id) }}">
               Zoom into Sub DAG
             </a>
             <hr>
diff --git a/airflow/www/templates/airflow/dags.html b/airflow/www/templates/airflow/dags.html
index c6e8ae7..f062a57 100644
--- a/airflow/www/templates/airflow/dags.html
+++ b/airflow/www/templates/airflow/dags.html
@@ -39,7 +39,7 @@
   <meta name="last_dag_runs_url" content="{{ url_for('Airflow.last_dagruns') }}">
   <meta name="dag_stats_url" content="{{ url_for('Airflow.dag_stats') }}">
   <meta name="task_stats_url" content="{{ url_for('Airflow.task_stats') }}">
-  <meta name="tree_url" content="{{ url_for('Airflow.tree') }}">
+  <meta name="grid_url" content="{{ url_for('Airflow.grid', dag_id='__DAG_ID__') }}">
 {% endblock %}
 
 {% block head_css %}
diff --git a/tests/api_connexion/endpoints/test_dag_endpoint.py b/tests/api_connexion/endpoints/test_dag_endpoint.py
index eac26bc..7f9addd 100644
--- a/tests/api_connexion/endpoints/test_dag_endpoint.py
+++ b/tests/api_connexion/endpoints/test_dag_endpoint.py
@@ -227,7 +227,7 @@ class TestGetDagDetails(TestDagEndpoint):
             "max_active_tasks": 16,
             "dag_id": "test_dag",
             "dag_run_timeout": None,
-            "default_view": "tree",
+            "default_view": "grid",
             "description": None,
             "doc_md": "details",
             "fileloc": __file__,
@@ -268,7 +268,7 @@ class TestGetDagDetails(TestDagEndpoint):
             "max_active_tasks": 16,
             "dag_id": "test_dag2",
             "dag_run_timeout": None,
-            "default_view": "tree",
+            "default_view": "grid",
             "description": None,
             "doc_md": None,
             "fileloc": __file__,
@@ -302,7 +302,7 @@ class TestGetDagDetails(TestDagEndpoint):
             "max_active_tasks": 16,
             "dag_id": "test_dag3",
             "dag_run_timeout": None,
-            "default_view": "tree",
+            "default_view": "grid",
             "description": None,
             "doc_md": None,
             "fileloc": __file__,
@@ -340,7 +340,7 @@ class TestGetDagDetails(TestDagEndpoint):
             "max_active_tasks": 16,
             "dag_id": "test_dag",
             "dag_run_timeout": None,
-            "default_view": "tree",
+            "default_view": "grid",
             "description": None,
             "doc_md": "details",
             "fileloc": __file__,
@@ -387,7 +387,7 @@ class TestGetDagDetails(TestDagEndpoint):
             'max_active_tasks': 16,
             'dag_id': 'test_dag',
             'dag_run_timeout': None,
-            'default_view': 'tree',
+            'default_view': 'grid',
             'description': None,
             'doc_md': 'details',
             'fileloc': __file__,
diff --git a/tests/sensors/test_external_task_sensor.py b/tests/sensors/test_external_task_sensor.py
index 6e7222e..f30172e 100644
--- a/tests/sensors/test_external_task_sensor.py
+++ b/tests/sensors/test_external_task_sensor.py
@@ -427,7 +427,7 @@ def test_external_task_sensor_templated(dag_maker, app):
     with app.app_context():
         url = instance.task.get_extra_links(instance, "External DAG")
 
-        assert f"tree?dag_id=dag_{DEFAULT_DATE.date()}" in url
+        assert f"/dags/dag_{DEFAULT_DATE.date()}/grid" in url
 
 
 class TestExternalTaskMarker(unittest.TestCase):