Skip to main content

Dagwick

Dagwick: grade your Airflow DAGs from A to F, right inside the Airflow UI

Setup

1. Install it where Airflow runs:

pip install dagwick

Using Docker? Add dagwick to your Airflow image's requirements.txt.

2. Restart the Airflow api-server.

3. Open Airflow. You now have:

  • a Dagwick tab on every DAG page, and
  • a Dagwick page in the sidebar that grades all your DAGs.

That's it. There is nothing to configure.

What you get

  • A score and a grade for every DAG. 20 checks in 7 categories: reliability, observability, ownership, scheduling, structure, performance and security. Each check that doesn't pass tells you how to fix it. See what it checks.
  • Checks that read your DAG file without running it: Variable.get at parse time, deprecated Airflow imports, hard-coded secrets (the value is never shown), and sensors that hold a worker slot while they wait.
  • Run health next to the score: success rate, retries, typical run time and its trend over the last 30 days. It never changes the score.
  • Score history: the score of each of the last 20 versions of a DAG, and which checks started or stopped passing at each step.
  • A fleet page that grades all the DAGs you can see and shows the most common issues.
  • dagwick check and a pre-commit hook to grade DAG files before they are merged. See Check DAGs before they are merged.
  • Break a check on purpose, with a reason. Some DAGs need catchup=True or no retries. See Acknowledge a check on purpose.

Experimental and off by default: the lantern can dress up for holidays like Newroz, Eid, Christmas and Halloween (seasonal moods).

The Dagwick tab on a DAG

The Dagwick fleet page

Acknowledge a check on purpose

Some DAGs break a check for a good reason: an ingest DAG uses catchup=True to backfill the days it missed during an outage, or a task that inserts without de-duplicating must never retry. Tell Dagwick with a comment in the DAG file:

# dagwick: ack <check> -- <reason>

For example:

DAG(
    "daily_ingest",
    catchup=True,  # dagwick: ack catchup -- backfills one file per missed day
    default_args={"retries": 0},  # dagwick: ack retries -- inserts are not idempotent
)

After Airflow parses the file again, the check is shown greyed out with your reason, and it no longer counts toward the score. It is never hidden, and the fleet page counts it as "acknowledged". To score the check again, delete the comment.

  • Put the comment anywhere in the file. It applies to every DAG in that file.
  • One comment can name several checks: # dagwick: ack retries, catchup -- <reason>.
  • The reason after -- is required. Without it the comment is ignored.
  • Dagwick reads the comment from the DAG's source code; it never runs the file.

Checks you can acknowledge (use the id in the comment):

Check Id The reason must say
Tasks retry on failure retries why the DAG breaks it on purpose
Retries are visible retry_alerts why the DAG breaks it on purpose
Has a schedule schedule why the DAG breaks it on purpose
No surprise backfills catchup why the DAG breaks it on purpose
Bounded parallel runs max_active_runs why the DAG breaks it on purpose
Split into steps decomposition why the DAG breaks it on purpose
Someone hears about failures failure_alerts where failures are alerted instead, e.g. a central listener or a Grafana rule
Stops after repeated failures auto_pause what stops the DAG when it keeps failing, e.g. on-call pausing it by hand
Sensors free their worker slot sensor_slots why the sensor must keep its worker slot, e.g. it needs sub-minute reaction

Every other check (owner, docs, tags, timeouts, naming, file name, imports, parse time, Variable.get and secrets) can't be acknowledged: each one protects something every DAG needs. A comment for one of them is ignored, and the Dagwick tab says so. Run ./dev/run.sh from a clone of this repository to see a demo DAG (demo_acknowledged_ingest) with every case.

Check DAGs before they are merged

dagwick check grades DAG files with the same checks as the UI and can fail a pull request below a chosen grade:

dagwick check dags/ --min-grade C     # exit 1 if any DAG is below C
dagwick check dags/my_dag.py --json   # machine-readable report

It needs Airflow installed next to it, and it imports the DAG files, so their top-level code runs, the same as in Airflow's DAG processor. Use it on a developer machine or in CI. The Airflow plugin itself never runs DAG code.

Exit codes: 0 all good, 1 a DAG is below --min-grade, 2 a file failed to load.

pre-commit

- repo: https://github.com/ardalan-jalal/dagwick
  rev: v0.2.0
  hooks:
    - id: dagwick
      args: [--min-grade, C]   # default: D

The hook uses language: system, so run pre-commit from an environment where Airflow and Dagwick are installed.

Requirements

  • Apache Airflow 3.1 or newer
  • Python 3.10 – 3.15

Dagwick has no dependencies of its own, so installing it never changes your other packages. It is read-only and only shows each user the DAGs they can already see.

Remove

pip uninstall dagwick

Then restart the api-server.

More

Metadata

Release files for dagwick 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dagwick 0.2.0
File Size Uploaded Provenance Actions
dagwick-0.2.0.tar.gz 110.7 kB With provenance Details for dagwick-0.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for dagwick 0.2.0
File Interpreter ABI Platform Actions
dagwick-0.2.0-py3-none-any.whl Python 3 none any Details for dagwick-0.2.0-py3-none-any.whl

Total release size: 165.8 kB

Release files / dagwick-0.2.0.tar.gz

Download URL dagwick-0.2.0.tar.gz
Size 110.7 kB
Tags Source
SHA-256 checksum
How to use checksums
081358820ba82fc2dd70ce7c3a0ec11a6639aeae0a86f5f616a518bb1ce461cd
BLAKE2b-256 checksum
How to use checksums
b3762e30d37bec931c3e4e9561484de79e788bf4944357baae94411c750aa47c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 9, 2026.

Transparency log

Release files / dagwick-0.2.0-py3-none-any.whl

Download URL dagwick-0.2.0-py3-none-any.whl
Size 55.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
48e145af84206de1d9c9e5459373d5fcd57192616e88914a3c0120ccdc2eb05b
BLAKE2b-256 checksum
How to use checksums
46dc220c93dc79782754803e802b403adbb74543c92f9a36688c2b4d76bad187
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 9, 2026.

Transparency log

Security for dagwick 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for dagwick-0.2.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 9, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page