You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by bb...@apache.org on 2022/04/06 14:48:43 UTC

[airflow] 01/01: set treeData as camelCase in webserver

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

bbovenzi pushed a commit to branch camelCase-tree-data
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit e18b40aa1b9d15d2835efe67ecde90889e02e8c2
Author: Brent Bovenzi <br...@gmail.com>
AuthorDate: Wed Apr 6 09:59:35 2022 -0400

    set treeData as camelCase in webserver
---
 airflow/www/static/js/tree/api/useTreeData.js      |  7 ++--
 airflow/www/static/js/tree/context/autorefresh.jsx | 10 +----
 airflow/www/static/js/tree/treeDataUtils.js        | 15 +-------
 airflow/www/templates/airflow/tree.html            |  3 +-
 airflow/www/utils.py                               | 45 ++++++++++++++--------
 airflow/www/views.py                               | 24 ++++++------
 6 files changed, 48 insertions(+), 56 deletions(-)

diff --git a/airflow/www/static/js/tree/api/useTreeData.js b/airflow/www/static/js/tree/api/useTreeData.js
index 83d638f0e0..663ebae69a 100644
--- a/airflow/www/static/js/tree/api/useTreeData.js
+++ b/airflow/www/static/js/tree/api/useTreeData.js
@@ -23,7 +23,7 @@ import { useQuery } from 'react-query';
 
 import { getMetaValue } from '../../utils';
 import { useAutoRefresh } from '../context/autorefresh';
-import { formatData, areActiveRuns } from '../treeDataUtils';
+import { areActiveRuns } from '../treeDataUtils';
 
 // dagId comes from dag.html
 const dagId = getMetaValue('dag_id');
@@ -37,7 +37,7 @@ const useTreeData = () => {
     dagRuns: [],
     groups: {},
   };
-  const initialData = formatData(treeData, emptyData);
+  const initialData = treeData || emptyData;
   const { isRefreshOn, stopRefresh } = useAutoRefresh();
   return useQuery('treeData', async () => {
     try {
@@ -45,8 +45,7 @@ const useTreeData = () => {
       const base = baseDate ? `&base_date=${baseDate}` : '';
       const resp = await fetch(`${treeDataUrl}?dag_id=${dagId}&num_runs=${numRuns}${root}${base}`);
       if (resp) {
-        let newData = await resp.json();
-        newData = formatData(newData);
+        const newData = await resp.json();
         // turn off auto refresh if there are no active runs
         if (!areActiveRuns(newData.dagRuns)) stopRefresh();
         return newData;
diff --git a/airflow/www/static/js/tree/context/autorefresh.jsx b/airflow/www/static/js/tree/context/autorefresh.jsx
index 77ca7f342f..3d6d68654e 100644
--- a/airflow/www/static/js/tree/context/autorefresh.jsx
+++ b/airflow/www/static/js/tree/context/autorefresh.jsx
@@ -21,7 +21,7 @@
 
 import React, { useContext, useState, useEffect } from 'react';
 import { getMetaValue } from '../../utils';
-import { formatData, areActiveRuns } from '../treeDataUtils';
+import { areActiveRuns } from '../treeDataUtils';
 
 const autoRefreshKey = 'disabledAutoRefresh';
 
@@ -31,13 +31,7 @@ const isRefreshDisabled = JSON.parse(localStorage.getItem(autoRefreshKey));
 const AutoRefreshContext = React.createContext(null);
 
 export const AutoRefreshProvider = ({ children }) => {
-  let dagRuns = [];
-  try {
-    const data = JSON.parse(treeData);
-    if (data.dag_runs) dagRuns = formatData(data.dag_runs);
-  } catch {
-    dagRuns = [];
-  }
+  const dagRuns = (treeData && treeData.dagRuns) || [];
   const [isPaused, setIsPaused] = useState(initialIsPaused);
   const isActive = areActiveRuns(dagRuns);
   const isRefreshAllowed = !(isPaused || isRefreshDisabled);
diff --git a/airflow/www/static/js/tree/treeDataUtils.js b/airflow/www/static/js/tree/treeDataUtils.js
index 95171652b7..89c1621e57 100644
--- a/airflow/www/static/js/tree/treeDataUtils.js
+++ b/airflow/www/static/js/tree/treeDataUtils.js
@@ -17,18 +17,5 @@
  * under the License.
  */
 
-import camelcaseKeys from 'camelcase-keys';
-
+// eslint-disable-next-line import/prefer-default-export
 export const areActiveRuns = (runs = []) => runs.filter((run) => ['queued', 'running', 'scheduled'].includes(run.state)).length > 0;
-
-export const formatData = (data, emptyData) => {
-  if (!data || !Object.keys(data).length) {
-    return emptyData;
-  }
-  let formattedData = data;
-  // Convert to json if needed
-  if (typeof data === 'string') formattedData = JSON.parse(data);
-  // change from pascal to camelcase
-  formattedData = camelcaseKeys(formattedData, { deep: true });
-  return formattedData;
-};
diff --git a/airflow/www/templates/airflow/tree.html b/airflow/www/templates/airflow/tree.html
index 1394cbc61b..4011fff4d5 100644
--- a/airflow/www/templates/airflow/tree.html
+++ b/airflow/www/templates/airflow/tree.html
@@ -78,7 +78,8 @@
 {% block tail_js %}
   {{ super() }}
   <script>
-    const treeData = {{ data|tojson }};
+    // Data is already json, there is no need to convert it
+    const treeData = {{ data }};
     const stateColors = {{ state_color_mapping|tojson }};
     const autoRefreshInterval = {{ auto_refresh_interval }};
   </script>
diff --git a/airflow/www/utils.py b/airflow/www/utils.py
index fc29d62027..21b516c471 100644
--- a/airflow/www/utils.py
+++ b/airflow/www/utils.py
@@ -75,7 +75,7 @@ def get_instance_with_map(task_instance, session):
     return get_mapped_summary(task_instance, mapped_instances)
 
 
-def get_mapped_summary(parent_instance, task_instances):
+def get_mapped_summary(parent_instance, task_instances, camel_case=False):
     priority = [
         TaskInstanceState.FAILED,
         TaskInstanceState.UPSTREAM_FAILED,
@@ -113,6 +113,17 @@ def get_mapped_summary(parent_instance, task_instances):
         if parent_instance.prev_attempted_tries != 0
         else parent_instance.try_number
     )
+    if camel_case:
+        return {
+            'taskId': parent_instance.task_id,
+            'runId': parent_instance.run_id,
+            'state': group_state,
+            'startDate': group_start_date,
+            'endDate': group_end_date,
+            'mappedStates': mapped_states,
+            'tryNumber': try_count,
+        }
+
     return {
         'task_id': parent_instance.task_id,
         'run_id': parent_instance.run_id,
@@ -131,7 +142,9 @@ def encode_ti(
         return None
 
     if is_mapped:
-        return get_mapped_summary(task_instance, task_instances=get_mapped_instances(task_instance, session))
+        return get_mapped_summary(
+            task_instance, task_instances=get_mapped_instances(task_instance, session), camel_case=True
+        )
 
     try_count = (
         task_instance.prev_attempted_tries
@@ -139,14 +152,14 @@ def encode_ti(
         else task_instance.try_number
     )
     return {
-        'task_id': task_instance.task_id,
-        'run_id': task_instance.run_id,
-        'map_index': task_instance.map_index,
+        'taskId': task_instance.task_id,
+        'runId': task_instance.run_id,
+        'mapIndex': task_instance.map_index,
         'state': task_instance.state,
         'duration': task_instance.duration,
-        'start_date': datetime_to_string(task_instance.start_date),
-        'end_date': datetime_to_string(task_instance.end_date),
-        'try_number': try_count,
+        'startDate': datetime_to_string(task_instance.start_date),
+        'endDate': datetime_to_string(task_instance.end_date),
+        'tryNumber': try_count,
     }
 
 
@@ -155,15 +168,15 @@ def encode_dag_run(dag_run: Optional[models.DagRun]) -> Optional[Dict[str, Any]]
         return None
 
     return {
-        'run_id': dag_run.run_id,
-        'start_date': datetime_to_string(dag_run.start_date),
-        'end_date': datetime_to_string(dag_run.end_date),
+        'runId': dag_run.run_id,
+        'startDate': datetime_to_string(dag_run.start_date),
+        'endDate': datetime_to_string(dag_run.end_date),
         'state': dag_run.state,
-        'execution_date': datetime_to_string(dag_run.execution_date),
-        'data_interval_start': datetime_to_string(dag_run.data_interval_start),
-        'data_interval_end': datetime_to_string(dag_run.data_interval_end),
-        'run_type': dag_run.run_type,
-        'last_scheduling_decision': datetime_to_string(dag_run.last_scheduling_decision),
+        'executionDate': datetime_to_string(dag_run.execution_date),
+        'dataIntervalStart': datetime_to_string(dag_run.data_interval_start),
+        'dataIntervalEnd': datetime_to_string(dag_run.data_interval_end),
+        'runType': dag_run.run_type,
+        'lastSchedulingDecision': datetime_to_string(dag_run.last_scheduling_decision),
     }
 
 
diff --git a/airflow/www/views.py b/airflow/www/views.py
index 03cd5e6e02..049d884f10 100644
--- a/airflow/www/views.py
+++ b/airflow/www/views.py
@@ -243,8 +243,8 @@ def task_group_to_tree(task_item_or_group, dag, dag_runs, tis, session):
                 if ti.task_id == task_item_or_group.task_id
             ],
             'label': task_item_or_group.label,
-            'extra_links': task_item_or_group.extra_links,
-            'is_mapped': task_item_or_group.is_mapped,
+            'extraLinks': task_item_or_group.extra_links,
+            'isMapped': task_item_or_group.is_mapped,
         }
 
     # Task Group
@@ -276,12 +276,10 @@ def task_group_to_tree(task_item_or_group, dag, dag_runs, tis, session):
         child_instances = [item for sublist in child_instances for item in sublist]
 
         children_start_dates = [
-            item['start_date'] for item in child_instances if item['run_id'] == dag_run.run_id
+            item['startDate'] for item in child_instances if item['runId'] == dag_run.run_id
         ]
-        children_end_dates = [
-            item['end_date'] for item in child_instances if item['run_id'] == dag_run.run_id
-        ]
-        children_states = [item['state'] for item in child_instances if item['run_id'] == dag_run.run_id]
+        children_end_dates = [item['endDate'] for item in child_instances if item['runId'] == dag_run.run_id]
+        children_states = [item['state'] for item in child_instances if item['runId'] == dag_run.run_id]
 
         group_state = None
         for state in priority:
@@ -296,11 +294,11 @@ def task_group_to_tree(task_item_or_group, dag, dag_runs, tis, session):
         )
 
         return {
-            'task_id': task_group.group_id,
-            'run_id': dag_run.run_id,
+            'taskId': task_group.group_id,
+            'runId': dag_run.run_id,
             'state': group_state,
-            'start_date': group_start_date,
-            'end_date': group_end_date,
+            'startDate': group_start_date,
+            'endDate': group_end_date,
         }
 
     group_summaries = [get_summary(dr, children) for dr in dag_runs]
@@ -2556,7 +2554,7 @@ class Airflow(AirflowBaseView):
 
         data = {
             'groups': task_group_to_tree(dag.task_group, dag, dag_runs, tis, session),
-            'dag_runs': encoded_runs,
+            'dagRuns': encoded_runs,
         }
 
         # avoid spaces to reduce payload size
@@ -3426,7 +3424,7 @@ class Airflow(AirflowBaseView):
             tis = dag.get_task_instances(start_date=min_date, end_date=base_date, session=session)
             data = {
                 'groups': task_group_to_tree(dag.task_group, dag, dag_runs, tis, session),
-                'dag_runs': encoded_runs,
+                'dagRuns': encoded_runs,
             }
 
         # avoid spaces to reduce payload size