Go deep on how a DAG is actually written: the TaskFlow API against classic operators, PythonOperator vs BashOperator, real branching dependencies, and a real retry Airflow's own scheduler observes and recovers from.
Welcome to Authoring DAGs, Module 3 of Orchestrating Data Pipelines with Airflow. Module 2 proved the mechanics work: write a DAG, drop it in the folder, watch the scheduler pick it up and run it. This module goes deep on the writing half of that sentence — the real choices you make every time you author a DAG, and what each one actually changes about how Airflow runs your code.
You’ll start by writing the exact same small computation two different ways — once with the TaskFlow API’s @dag/@task decorators, once with classic PythonOperator instantiation and explicit >> — and prove, with a real file diff, that they produce identical output. From there you’ll add BashOperator to the toolbox alongside PythonOperator, wire a DAG whose dependencies genuinely branch and reconverge (not just a straight line), and demonstrate all four ways Airflow lets you write a dependency: >>, <<, set_upstream, set_downstream. Then you’ll make a task fail on purpose and watch Airflow’s own retry logic catch it, and use a real airflow dags backfill run to see catchup and backfill stop being abstract words and start being real, dated DAG runs. The guided project closes the module by combining a real branch and a real retry into one DAG, verified through both a screenshot and the CLI.
Every DAG in this module is a real file, saved to the same .airflow-local/dags/ folder Module 2 used, triggered against the same live Airflow 2.10.4 stack, and verified with real command output — nothing here is a diagram of what would happen.
Start with Lesson 1, and watch the same real result come out of two very differently-written DAGs.
Complete all 5 lessons to finish the Authoring DAGs module.