def graph(self): session = settings.Session() dag_id = request.args.get('dag_id') arrange = request.args.get('arrange', "LR") dag = dagbag.dags[dag_id] nodes = [] edges = [] for task in dag.tasks: nodes.append({ 'id': task.task_id, 'value': { 'label': task.task_id } }) def get_upstream(task): for t in task.upstream_list: edge = { 'u': t.task_id, 'v': task.task_id, } if edge not in edges: edges.append(edge) get_upstream(t) for t in dag.roots: get_upstream(t) dttm = request.args.get('execution_date') if dttm: dttm = dateutil.parser.parse(dttm) else: dttm = dag.latest_execution_date or datetime.now().date() form = GraphForm(data={'execution_date': dttm, 'arrange': arrange}) task_instances = { ti.task_id: utils.alchemy_to_dict(ti) for ti in dag.get_task_instances(session, dttm, dttm) } tasks = {t.task_id: utils.alchemy_to_dict(t) for t in dag.tasks} session.commit() session.close() return self.render( 'airflow/graph.html', dag=dag, form=form, execution_date=dttm.isoformat(), arrange=arrange, task_instances=json.dumps(task_instances, indent=2), tasks=json.dumps(tasks, indent=2), nodes=json.dumps(nodes, indent=2), edges=json.dumps(edges, indent=2), )
def graph(self): session = settings.Session() dag_id = request.args.get('dag_id') arrange = request.args.get('arrange', "LR") dag = dagbag.dags[dag_id] nodes = [] edges = [] for task in dag.tasks: nodes.append({ 'id': task.task_id, 'value': {'label': task.task_id} }) def get_upstream(task): for t in task.upstream_list: edge = { 'u': t.task_id, 'v': task.task_id, } if edge not in edges: edges.append(edge) get_upstream(t) for t in dag.roots: get_upstream(t) dttm = request.args.get('execution_date') if dttm: dttm = dateutil.parser.parse(dttm) else: dttm = dag.latest_execution_date or datetime.now().date() form = GraphForm(data={'execution_date': dttm, 'arrange': arrange}) task_instances = { ti.task_id: utils.alchemy_to_dict(ti) for ti in dag.get_task_instances(session, dttm, dttm) } tasks = { t.task_id: utils.alchemy_to_dict(t) for t in dag.tasks } session.commit() session.close() return self.render( 'airflow/graph.html', dag=dag, form=form, execution_date=dttm.isoformat(), arrange=arrange, task_instances=json.dumps(task_instances, indent=2), tasks=json.dumps(tasks, indent=2), nodes=json.dumps(nodes, indent=2), edges=json.dumps(edges, indent=2),)
def recurse_nodes(task): children = [recurse_nodes(t) for t in task.upstream_list] # D3 tree uses children vs _children to define what is # expanded or not. The following block makes it such that # repeated nodes are collapsed by default. children_key = 'children' if task.task_id not in expanded: expanded.append(task.task_id) elif children: children_key = "_children" return { 'name': task.task_id, 'instances': [ utils.alchemy_to_dict( task_instances.get((task.task_id, d))) or { 'execution_date': d.isoformat(), 'task_id': task.task_id } for d in dates], children_key: children, 'num_dep': len(task.upstream_list), 'operator': task.task_type, 'retries': task.retries, 'owner': task.owner, 'start_date': task.start_date, 'end_date': task.end_date, 'depends_on_past': task.depends_on_past, }
def recurse_nodes(task): children = [recurse_nodes(t) for t in task.upstream_list] # D3 tree uses children vs _children to define what is # expanded or not. The following block makes it such that # repeated nodes are collapsed by default. children_key = 'children' if task.task_id not in expanded: expanded.append(task.task_id) elif children: children_key = "_children" return { 'name': task.task_id, 'instances': [ utils.alchemy_to_dict(task_instances.get( (task.task_id, d))) or { 'execution_date': d.isoformat(), 'task_id': task.task_id } for d in dates ], children_key: children, 'num_dep': len(task.upstream_list), 'operator': task.task_type, 'retries': task.retries, 'owner': task.owner, 'start_date': task.start_date, 'end_date': task.end_date, 'depends_on_past': task.depends_on_past, }