Skip to content
Back to skills

Authoring Airflow Dags

ASecurity

Write production-grade Apache Airflow DAGs using the TaskFlow API — idempotent tasks, correct scheduling and catchup, retries/SLAs, connections/variables, and avoiding top-level code. Use when creating or reviewing Airflow DAGs, scheduling pipelines, wiring task dependencies, configuring retries/backfills, or fixing non-idempotent tasks.

  • 15 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 1, 2026
ai-agentspythongodebuggingrefactoringapidatabase

Works with

  • api

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned September 1, 2026

npx -y skills add Unknown-333/awesome-data-engineering-skills --skill authoring-airflow-dags --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Authoring Airflow Dags?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Authoring Airflow Dags
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/unknown-333-authoring-airflow-dags/badge)](https://www.skillsdirectory.com/skills/unknown-333-authoring-airflow-dags)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: authoring-airflow-dags
description: Write production-grade Apache Airflow DAGs using the TaskFlow API — idempotent tasks, correct scheduling and catchup, retries/SLAs, connections/variables, and avoiding top-level code. Use when creating or reviewing Airflow DAGs, scheduling pipelines, wiring task dependencies, configuring retries/backfills, or fixing non-idempotent tasks.
---

# Authoring Airflow DAGs

## When to use

- Creating or refactoring Airflow DAGs and tasks.
- Configuring schedules, catchup/backfill, retries, and SLAs.
- Passing data between tasks (XCom) or using connections/variables.
- Do NOT use for diagnosing a broken running DAG (use
  `debugging-airflow-pipelines`).

## Workflow

```
- [ ] Make each task idempotent and parameterized by the data interval
- [ ] Keep expensive/import-heavy code inside tasks, not at module top level
- [ ] Set schedule + catchup deliberately
- [ ] Configure retries, retry_delay, and SLAs
- [ ] Wire dependencies via TaskFlow return values or >> operators
```

1. **Idempotent tasks** — a task for the `2026-01-15` interval must produce the
   same result whether it runs once or is re-run. Use the data interval, not
   `datetime.now()`.
2. **No heavy top-level code** — the scheduler parses every DAG file frequently;
   database calls, API calls, or big imports at module level slow scheduling and
   can break parsing. Put them inside tasks.
3. **Schedule + catchup on purpose** — `catchup=True` backfills every missed
   interval from `start_date`; default to `False` unless you want that.
4. **Retries and SLAs** — transient failures are normal; set `retries` and
   `retry_delay`; use SLAs/alerts for lateness.

## Patterns

**TaskFlow DAG, idempotent and cleanly wired:**

```python
from airflow.decorators import dag, task
import pendulum

@dag(
    schedule="@daily",
    start_date=pendulum.datetime(2026, 1, 1, tz="UTC"),
    catchup=False,
    default_args={"retries": 3, "retry_delay": pendulum.duration(minutes=5)},
    tags=["orders"],
)
def orders_pipeline():

    @task
    def extract(data_interval_start=None):
        # Use the interval, not now(), so re-runs are deterministic.
        return fetch_orders(day=data_interval_start.date())

    @task
    def load(rows):
        # Delete-insert the partition -> idempotent on retry.
        overwrite_partition("fct_orders", rows)

    load(extract())

orders_pipeline()
```

**Pass small data via XCom (return values); pass large data via storage** — write
to S3/GCS/warehouse and pass the path/key, never megabytes through XCom.

**Use connections/variables** for secrets and config (`BaseHook.get_connection`,
`Variable.get`), never hard-coded credentials.

## Common pitfalls

- **Top-level API/DB calls or heavy imports** — slow the scheduler and can fail
  DAG parsing across the whole deployment.
- **`datetime.now()` inside tasks** — breaks idempotency and backfills; use
  `data_interval_start`/`_end`.
- **`catchup=True` unintentionally** — floods the cluster with historical runs on
  first deploy.
- **Large payloads through XCom** — bloats the metadata DB; pass references.
- **Dynamic `start_date`** (e.g. `days_ago`) — makes schedules nondeterministic;
  use a fixed timestamp.
- **One monster task** — split extract/transform/load so retries are granular.

## References

- [Scheduling, catchup, and backfill reference](references/SCHEDULING.md)

Files in this skill

  • SKILL.md3.3 KB
  • references/SCHEDULING.md1.4 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…