I typically author DAGs as modular, testable pipelines combining Sensors, Operators, and TaskGroups. Example pattern:python
from airflow import DAG
from airflow.operators.empty import EmptyOperator
from airflow.operators.python import PythonOperator
from airflow.providers.amazon.aws.sensors.s3 import S3KeySensor
from airflow.utils.task_group import TaskGroup
from datetime import datetime, timedelta
with DAG('etl_daily', start_date=datetime(2025,1,1), schedule='@daily', catchup=False, default_args={
'retries': 2, 'retry_delay': timedelta(minutes=5), 'sla': timedelta(hours=2)
}) as dag:
start = EmptyOperator(task_id='start')
wait_file = S3KeySensor(task_id='wait_raw', bucket_key='s3://my-bucket/{{ ds }}/file.csv', timeout=3600)
with TaskGroup('transform') as tg:
extract = PythonOperator(task_id='extract', python_callable=extract_fn)
transform = PythonOperator(task_id='transform', python_callable=transform_fn)
load = PythonOperator(task_id='load', python_callable=load_fn)
extract >> transform >> load
end = EmptyOperator(task_id='end')
start >> wait_file >> tg >> end
Key choices and reasoning:- Operators/sensors: use managed provider operators (S3, BigQuery, SparkSubmit) for reliability and monitoring.- Dependencies: explicit >> chaining and TaskGroup for logical grouping and clearer UI.- Retries & SLA: sensible defaults in default_args (2 retries, exponential backoff optional). SLA on critical tasks triggers SLA callbacks for missed windows.- Alerting: integrate with alerting via on_failure_callback and on_retry_callback that send messages to PagerDuty/Slack; use Airflow email backend for lower severity.- Secrets & connections: store creds in Airflow Connections and Variables encrypted by backend (e.g., AWS Secrets Manager or HashiCorp Vault integration). Use connection IDs in operators (aws_conn_id) and avoid hardcoding secrets.- Local testing: validate with unit tests (pytest) for task logic, use Airflow's DagBag to validate DAG parse, run tasks locally with `airflow tasks test <dag> <task> <date>` and docker-compose/dev environment to run end-to-end.- CI/CD: lint DAGs, run unit tests and DagBag validation, and deploy via GitOps; promote to production after automated checks.- Observability: add metrics (task durations, row counts) to DataDog, enable task-level logging and XCom size limits to prevent leaks.This approach balances reliability, security, and developer velocity for production data pipelines.