Senior Data Engineer
benchflow-ai/skillsbench
World-class data engineering skill for building scalable data pipelines, ETL/ELT systems, real-time streaming, and data infrastructure.
Authors Apache Airflow DAGs declaratively from dag-factory YAML configs.
$ npx skills add astronomer/agents --skill dag-factory -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install astronomer/agents dag-factory --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/astronomer/agents.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/dag-factory .claude/skills/dag-factory && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "dag-factory" agent skill from https://github.com/astronomer/agents/tree/main/skills/dag-factory into .claude/skills/dag-factory/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "dag-factory", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/astronomer/agents/tree/main/skills/dag-factoryType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add astronomer/agents --skill dag-factory -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install astronomer/agents dag-factory --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/astronomer/agents.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/dag-factory .agents/skills/dag-factory && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "dag-factory" agent skill from https://github.com/astronomer/agents/tree/main/skills/dag-factory into .agents/skills/dag-factory/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "dag-factory", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add astronomer/agents --skill dag-factory -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install astronomer/agents dag-factory --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/astronomer/agents.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/dag-factory .cursor/skills/dag-factory && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "dag-factory" agent skill from https://github.com/astronomer/agents/tree/main/skills/dag-factory into .cursor/skills/dag-factory/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "dag-factory", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/astronomer/agents.git --path skills/dag-factory--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add astronomer/agents --skill dag-factory -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install astronomer/agents dag-factory --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/astronomer/agents.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/dag-factory .gemini/skills/dag-factory && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "dag-factory" agent skill from https://github.com/astronomer/agents/tree/main/skills/dag-factory into .gemini/skills/dag-factory/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "dag-factory", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install astronomer/agents dag-factoryInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add astronomer/agents --skill dag-factory -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/astronomer/agents.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/dag-factory .github/skills/dag-factory && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "dag-factory" agent skill from https://github.com/astronomer/agents/tree/main/skills/dag-factory into .github/skills/dag-factory/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "dag-factory", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add astronomer/agents --skill dag-factory -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install astronomer/agents dag-factory --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/astronomer/agents.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/dag-factory .opencode/skills/dag-factory && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "dag-factory" agent skill from https://github.com/astronomer/agents/tree/main/skills/dag-factory into .opencode/skills/dag-factory/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "dag-factory", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
dag-factoryAuthors Apache Airflow DAGs declaratively from dag-factory YAML configs.
Dag Factory is an agent skill from astronomer/agents. Authors Apache Airflow DAGs declaratively from dag-factory YAML configs. Use when building DAGs declaratively from YAML via dag-factory; creating/editing dag-factory templates/YAML configs,reating/editing dag-factory YAML configs, defaults, dynamic tasks, datasets, or callbacks; or validating dag-factory configurations; upgrading or re-pinning dag-factory.
Its SKILL.md is about 4.3k tokens, which your agent loads only when the skill is triggered. The skill folder holds 2 other files (for example `reference/migration.md`).
It sits in Data & Analytics, covering Data pipelines and ETL. It works with Apache Airflow and Python. The repository describes itself as: AI agent tooling for data engineering workflows. The licence is Apache-2.0.
6 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit 486ee63. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
pipairflowFrom the folder's file list and the shell code blocks in SKILL.md.
Links to these hosts (documentation or services it may open):
astronomer.github.iogithub.compypi.orgFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Dag Factory loads about 4.3k tokens when it runs. Until then it costs about 93 tokens; SKILL.md has 1,363 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from astronomer/agents at commit 486ee63, republished under its Apache-2.0 licence (© astronomer). 1,363 words, ~4,320 tokens.
.claude/skills/dag-factory/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.You are helping a user build Apache Airflow DAGs declaratively with dag-factory, a library that turns YAML configuration files into Airflow DAGs. Execute steps in order and prefer the simplest configuration that meets the user's needs.
Package:
dag-factoryon PyPI Repo: https://github.com/astronomer/dag-factory Docs: https://astronomer.github.io/dag-factory/latest/ Targets: dag-factory v1.0+ only. For pre-1.0 projects, see reference/migration.md before applying any guidance from this skill. Requires: Python 3.10+, Airflow 2.4+ (Airflow 3 supported)
Confirm with the user:
| User Request | Action |
|---|---|
| "Create a YAML DAG" / "Convert this Python DAG to YAML" | Go to Defining a DAG in YAML |
| "Set up dag-factory in my project" | Go to Project Setup |
| "Share defaults across DAGs" / "Set start_date once" | Go to Defaults |
| "Use a custom operator" / "Use KPO / Slack / Snowflake" | Go to Custom & Provider Operators |
| "Dynamic / mapped tasks" / "expand / partial" | Go to Dynamic Task Mapping |
| "Schedule on dataset" / "Outlets and inlets" | Go to Datasets |
| "Add a callback" / "Slack on failure" | Go to Callbacks |
| "Use a timetable" / "datetime in YAML" / "timedelta in YAML" | Go to Custom Python Objects (__type__) |
| "Lint my YAML" / "Validate" | Go to Validation Commands |
| "Convert Airflow 2 YAML to Airflow 3" | Go to Validation Commands (dagfactory convert) |
| "Migrate from dag-factory <1.0" | See reference/migration.md |
| dag-factory errors / troubleshooting | Go to Troubleshooting |
Add to requirements.txt:
dag-factory>=1.0.0dag-factory does not install Airflow providers automatically. Install any provider packages your YAML references (e.g., apache-airflow-providers-slack, apache-airflow-providers-cncf-kubernetes).
Create dags/load_dags.py so Airflow's DAG processor will pick it up:
import os
from pathlib import Path
from dagfactory import load_yaml_dags
CONFIG_ROOT_DIR = Path(os.getenv("CONFIG_ROOT_DIR", "/usr/local/airflow/dags/"))
# Option A: load every *.yml / *.yaml under a folder
load_yaml_dags(globals_dict=globals(), dags_folder=str(CONFIG_ROOT_DIR))
# Option B: load a single file
# load_yaml_dags(globals_dict=globals(), config_filepath=str(CONFIG_ROOT_DIR / "my_dag.yml"))
# Option C: load from an in-Python dict
# load_yaml_dags(globals_dict=globals(), config_dict={...})globals_dict=globals() is required so generated DAG objects are registered into the module namespace where Airflow can discover them.
dagfactory --versionEach top-level YAML key (other than default) defines a DAG. The key becomes the dag_id. Use the list format for tasks and task_groups — it is the recommended format since v1.0.0.
# dags/example_dag_factory.yml
default:
default_args:
start_date: 2024-11-11
basic_example_dag:
default_args:
owner: "custom_owner"
description: "this is an example dag"
schedule: "0 3 * * *"
catchup: false
task_groups:
- group_name: "example_task_group"
tooltip: "this is an example task group"
dependencies: [task_1]
tasks:
- task_id: "task_1"
operator: airflow.operators.bash.BashOperator
bash_command: "echo 1"
- task_id: "task_2"
operator: airflow.operators.bash.BashOperator
bash_command: "echo 2"
dependencies: [task_1]
- task_id: "task_3"
operator: airflow.operators.bash.BashOperator
bash_command: "echo 3"
dependencies: [task_1]
task_group_name: "example_task_group"| Field | Where | Purpose |
|---|---|---|
default | top-level | Shared DAG-level args applied to every DAG in this file |
default_args | DAG or default block | Standard Airflow default_args (owner, retries, start_date, ...) |
schedule | DAG | Cron expression, preset (@daily), Dataset list, or __type__ timetable |
catchup / description / tags | DAG | Standard Airflow DAG kwargs |
tasks | DAG | List of task dicts; each requires task_id and operator |
operator | task | Full import path to operator class (e.g. airflow.operators.bash.BashOperator) |
dependencies | task / task_group | List of upstream task_ids or group_names |
task_groups | DAG | List of group dicts; each requires group_name |
task_group_name | task | Assigns a task to a task group |
Tasks do not need to be ordered by dependency in the YAML — dag-factory resolves the DAG topology.
Pre-1.0 dictionary format (where tasks is a dict keyed by task_id) still works for backward compatibility, but prefer the list format for new code.
There are four ways to set defaults, in precedence order (highest first):
default_args / DAG-level keys inside an individual DAGdefault: block in the same YAML filedefaults_config_dict= argument to load_yaml_dagsdefaults.yml (or defaults.yaml) file via defaults_config_path= (or auto-detected next to the DAG YAML)Note: loader argument names and several other field names changed in v1.0.0. See reference/migration.md if you're working on an older project.
default Block in the Same FilePowerful for templating multiple DAGs from one file:
default:
default_args:
owner: "data-team"
start_date: 2025-01-01
retries: 2
catchup: false
schedule: "@daily"
dag_one:
description: "first DAG"
tasks:
- task_id: t1
operator: airflow.operators.bash.BashOperator
bash_command: "echo one"
dag_two:
description: "second DAG"
tasks:
- task_id: t1
operator: airflow.operators.bash.BashOperator
bash_command: "echo two"defaults.yml FilePlace a defaults.yml next to the DAG YAML, or point defaults_config_path at a parent directory. dag-factory merges all defaults.yml files walking up the directory tree, with the file closest to the DAG YAML winning. DAG-level args (e.g. schedule, catchup) go at the root of defaults.yml; per-task defaults go under default_args.
# defaults.yml
schedule: 0 1 * * *
catchup: false
default_args:
start_date: '2024-12-31'
owner: data-teamReference any operator by its full Python import path. dag-factory passes all other task keys as kwargs to that operator.
tasks:
- task_id: begin
operator: airflow.providers.standard.operators.empty.EmptyOperator
- task_id: make_bread
operator: customized.operators.breakfast_operators.MakeBreadOperator
bread_type: 'Sourdough'The operator's package must be installed and importable. For Airflow 3, prefer airflow.providers.standard.operators.* over the legacy airflow.operators.* paths — the dagfactory convert CLI rewrites these automatically.
Specify the operator path and pass kwargs directly. As of v1.0, dag-factory no longer does legacy type casting — use __type__ for nested k8s objects.
tasks:
- task_id: hello-world-pod
operator: airflow.providers.cncf.kubernetes.operators.pod.KubernetesPodOperator
image: "python:3.12-slim"
cmds: ["python", "-c"]
arguments: ["print('hi')"]
name: example-pod
namespace: default
container_resources:
__type__: kubernetes.client.models.V1ResourceRequirements
limits: {cpu: "1", memory: "1024Mi"}
requests: {cpu: "0.5", memory: "512Mi"}Use expand and partial keys on a task to map dynamically. dag-factory has two distinct ways to reference an upstream task's output:
task_id.output — XCom-style reference, used inside expand op_args / op_kwargs (and the equivalent kwargs of other operators).+task_id — bare value reference, used when the value sits directly under expand (e.g. expand: {number: +numbers_list}) or as a TaskFlow decorator argument.Don't mix them: +request won't resolve inside op_args, and request.output won't resolve as a bare expand value.
dynamic_task_map:
default_args:
start_date: 2025-01-01
schedule: "0 3 * * *"
tasks:
- task_id: request
operator: airflow.providers.standard.operators.python.PythonOperator
python_callable_name: make_list
python_callable_file: $CONFIG_ROOT_DIR/expand_tasks.py
- task_id: process
operator: airflow.providers.standard.operators.python.PythonOperator
python_callable_name: consume_value
python_callable_file: $CONFIG_ROOT_DIR/expand_tasks.py
partial:
op_kwargs:
fixed_param: "test"
expand:
op_args: request.output # XCom-style — used inside op_args / op_kwargs
dependencies: [request]Bare-value form (TaskFlow decorator tasks, or any non-op_args mapping):
tasks:
- task_id: numbers_list
decorator: airflow.sdk.definitions.decorators.task
python_callable: sample.build_numbers_list
- task_id: double_number
decorator: airflow.sdk.definitions.decorators.task
python_callable: sample.double
expand:
number: +numbers_list # + resolves to upstream task `numbers_list`'s XComArgFor named map indices (Airflow 2.9+), set map_index_template: "{{ task.custom_mapping_key }}" and have the callable assign context["custom_mapping_key"].
Tested patterns: simple mapping, task-generated mapping, repeated mapping, partial, multiple-parameter mapping, map_index_template.
Unsupported / untested: mapping over task groups, zipping, transforming expanding data.
Use inlets / outlets on tasks to declare dataset producers, and a list of dataset URIs as schedule to consume them.
producer_dag:
default_args:
start_date: '2024-01-01'
schedule: "0 5 * * *"
catchup: false
tasks:
- task_id: task_1
operator: airflow.operators.bash.BashOperator
bash_command: "echo 1"
outlets: ['s3://bucket_example/raw/dataset1.json']
consumer_dag:
default_args:
start_date: '2024-01-01'
schedule: ['s3://bucket_example/raw/dataset1.json']
catchup: false
tasks:
- task_id: task_1
operator: airflow.operators.bash.BashOperator
bash_command: "echo 'consumer'"Nesting the logical operators __and__ / __or__ under datasets key.
schedule:
datasets:
__or__:
- __and__:
- s3://bucket-cjmm/raw/dataset_custom_1
- s3://bucket-cjmm/raw/dataset_custom_2
- s3://bucket-cjmm/raw/dataset_custom_3Three styles, all valid at the DAG, TaskGroup, or Task level (or under default_args):
- task_id: task_1
operator: airflow.operators.bash.BashOperator
bash_command: "echo task_1"
on_failure_callback: include.custom_callbacks.output_standard_messageWith kwargs:
- task_id: task_2
operator: airflow.operators.bash.BashOperator
bash_command: "echo task_2"
on_success_callback:
callback: include.custom_callbacks.output_custom_message
param1: "Task status"
param2: "Successful!"- task_id: task_3
operator: airflow.operators.bash.BashOperator
bash_command: "echo task_3"
on_retry_callback_name: output_standard_message
on_retry_callback_file: /usr/local/airflow/include/custom_callbacks.py- task_id: task_4
operator: airflow.operators.bash.BashOperator
bash_command: "echo task_4"
on_failure_callback:
callback: airflow.providers.slack.notifications.slack.send_slack_notification
slack_conn_id: slack_conn_id
text: ":red_circle: Task Failed."
channel: "#channel"The provider package must be installed.
__type__)For anything that isn't a simple scalar — datetime, timedelta, Asset, timetables, k8s objects — use the generalized object syntax:
start_date:
__type__: datetime.datetime
year: 2025
month: 1
day: 1
execution_timeout:
__type__: datetime.timedelta
hours: 1
schedule:
__type__: airflow.timetables.trigger.CronTriggerTimetable
cron: "0 1 * * 3"
timezone: UTC__type__ is the full import path to the class__args__ is a list of positional arguments__type__: builtins.list with an items: keyDon't use these YAML keys for your own data — dag-factory reserves them: __type__, __args__, __join__, __and__, __or__. The key items is also reserved when used inside a __type__: builtins.list block — don't add a custom field named items to a typed list construction.
After installing, the dagfactory CLI is on PATH:
| Command | When to Use |
|---|---|
dagfactory --version | Confirm install / version |
dagfactory lint <path> | Validate YAML syntax for a file or directory |
dagfactory lint <path> --verbose | Show a per-file table of results |
dagfactory convert <path> | Show diffs to migrate Airflow 2 → 3 import paths |
dagfactory convert <path> --override | Apply the conversions in place |
# 1. Lint YAML
dagfactory lint dags/
# 2. Have Airflow parse to catch operator/import errors
# (Astro CLI users)
astro dev parsedagfactory lint only checks YAML syntax — operator import errors and missing kwargs surface at Airflow parse time.
ModuleNotFoundErrorCause: Provider package not installed, or wrong import path.
Fix: Install the provider (pip install apache-airflow-providers-...) and verify the path. For Airflow 3, run dagfactory convert to update legacy airflow.operators.* paths to airflow.providers.standard.operators.*.
Cause: Loader file missing or globals_dict=globals() not passed.
Fix: Ensure a Python file in dags/ calls load_yaml_dags(globals_dict=globals(), ...). Check astro dev parse (or airflow dags list-import-errors) for parse errors.
Cause: A scalar string is being passed where a Python object is expected (e.g. start_date: "2025-01-01" for a field that needs datetime).
Fix: Use __type__: datetime.datetime (or datetime.timedelta etc.) per Custom Python Objects.
Cause: Airflow <2.9, dag-factory <0.22, or using legacy !and/!or keys.
Fix: Upgrade and rename to __and__ / __or__.
defaults.yml not merging as expectedCause: defaults_config_path not pointing at a parent directory of the DAG YAML.
Fix: Set defaults_config_path to the highest ancestor folder you want included; dag-factory walks the tree from DAG file → ancestor and merges in that order, with files closer to the DAG winning.
Before finishing, verify with the user:
dagfactory lint dags/ passesdags/ and calls load_yaml_dags(globals_dict=globals(), ...)requirements.txtaf CLI validation. Use when YAML can't express what you need.© astronomer, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 1 other file in skills/dag-factory of astronomer/agents.
Open the folder on GitHubat commit 486ee63
Dag Factory next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Dag Factory this skillastronomer/agents | 451 | — | ~4.3k | Automated safety check: Pass | Apache-2.0 | |
| Senior Data Engineerbenchflow-ai/skillsbench | 1.8k | — | ~5.9k | Automated safety check: Pass | MIT | |
| Airflow DAG Patternswshobson/agents | 40k | 9 repos | ~784 | Automated safety check: Pass | MIT | |
| Version Bumpergodatadriven/whirl | 205 | — | ~1.2k | Automated safety check: Pass | Apache-2.0 | |
| Senior Data Engineeralirezarezvani/claude-skills | 28k | 3 repos | ~1.4k | Automated safety check: Pass | MIT | |
| Senior Data Engineerdavila7/claude-code-templates | 33k | 1 repos | ~1.4k | Automated safety check: Pass | MIT |
benchflow-ai/skillsbench
World-class data engineering skill for building scalable data pipelines, ETL/ELT systems, real-time streaming, and data infrastructure.
wshobson/agents
Patterns for writing production-ready Apache Airflow DAGs: task dependencies, custom operators and sensors, local testing, and rules for what to avoid.
godatadriven/whirl
Bump the Airflow or Python version across all project files.
alirezarezvani/claude-skills
Data engineering skill for building scalable data pipelines, ETL/ELT systems, and data infrastructure.
davila7/claude-code-templates
World-class data engineering skill for building scalable data pipelines, ETL/ELT systems, and data infrastructure.
ancoleman/ai-design-components
Transform raw data into analytical assets using ETL/ELT patterns, SQL (dbt), Python (pandas/polars/PySpark), and orchestration (Airflow).
astronomer/agents
Queries the data warehouse with SQL and answers business questions about data.
astronomer/agents
Queries, manages, and troubleshoots Apache Airflow using the af CLI.
astronomer/agents
Guide for migrating Dagster projects to Apache Airflow 3 on Astro.
astronomer/agents
Workflow and best practices for writing Apache Airflow DAGs.
astronomer/agents
Deploys Airflow DAGs and projects. An agent skill from astronomer/agents.
astronomer/agents
Builds human-in-the-loop (HITL) Airflow workflows - approval gates, form input, and human-driven branching.
Works with
Categories
Authors Apache Airflow DAGs declaratively from dag-factory YAML configs. Dag Factory is an agent skill from astronomer/agents. Authors Apache Airflow DAGs declaratively from dag-factory YAML configs.
Dag Factory fits situations like: building DAGs declaratively from YAML via dag-factory; creating/editing dag-factory templates/YAML configs; reating/editing dag-factory YAML configs; validating dag-factory configurations.
Run `npx skills add astronomer/agents --skill dag-factory -a claude-code`. Or copy the skill folder (skills/dag-factory in astronomer/agents) into .claude/skills/dag-factory in your project. Claude Code loads it when a task matches its description.
Run `npx skills add astronomer/agents --skill dag-factory -a codex`. Or copy the skill folder (skills/dag-factory in astronomer/agents) into .agents/skills/dag-factory in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add astronomer/agents --skill dag-factory -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/dag-factory, .gemini/skills/dag-factory, .github/skills/dag-factory and .opencode/skills/dag-factory in your project.
Going by SKILL.md and its folder, Dag Factory needs the command-line tools its instructions call (pip and airflow). Our summary lists: Python 3.
SKILL.md names 3 domains. As links in the text: astronomer.github.io, github.com and pypi.org. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Dag Factory is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 4.3k tokens (SKILL.md is roughly 17k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Dag Factory: Senior Data Engineer (benchflow-ai/skillsbench, 1.8k stars), Airflow DAG Patterns (wshobson/agents, 40k stars), Version Bumper (godatadriven/whirl, 205 stars) and Senior Data Engineer (alirezarezvani/claude-skills, 28k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
astronomer (a GitHub organization) maintains it in astronomer/agents, which has 451 GitHub stars. The repository holds 34 skills in this directory. The repository was last updated on October 7, 2026.
Source: astronomer/agents on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.