airflow-adapter
Airflow adapter pattern for v2/v3 API compatibility. Use when working with adapters, version detection, or adding new API methods that need to work across…
The language-neutral foundation for Airflow language SDKs — implement task logic in a non-Python language while the DAG stays in Python. Use when the user wants to run an Airflow task in another language (Java, Kotlin, Go, or other JVM/native languages), asks how the Python
$ npx -y skills add astronomer/agents --skill authoring-language-sdk-tasks --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/authoring-language-sdk-tasksContext preview
The summary Claude sees to decide when to auto-load this skill.
The language-neutral foundation for Airflow language SDKs — implement task logic in a non-Python language while the DAG stays in Python. Use when the user wants to run an Airflow task in another language (Java, Kotlin, Go, or other JVM/native languages), asks how the Python
name: authoring-language-sdk-tasks description: The language-neutral foundation for Airflow language SDKs — implement task logic in a non-Python language while the DAG stays in Python. Use when the user wants to run an Airflow task in another language (Java, Kotlin, Go, or other JVM/native languages), asks how the Python `@task.stub` pairs with native task code, how task/DAG IDs must match across the two sides, how data passes via XCom as JSON, or which language SDKs exist. This skill owns the shared Python-stub pattern and conceptual model; for a specific language's native API, build, and runtime, use that language's skill (e.g. authoring-java-sdk-tasks, authoring-go-sdk-tasks).
Airflow language SDKs let you implement task logic in a language other than Python while the DAG and its scheduling stay in Python. This skill describes the parts that are identical across every language SDK. Each language has its own companion skill for the native API, build tooling, and runtime — see [Per-language skills](#per-language-skills).
> **Experimental.** The language SDKs are in preview. APIs and artifact coordinates may change.
---
A DAG is authored in Python as usual. Tasks that should run in another language are declared as **stubs** routed to a dedicated queue. At runtime, Airflow hands a stub task to a **coordinator** that launches a short-lived **native subprocess** for that one task instance, runs your compiled/native code, and shuts the subprocess down.
Consequences that hold for every language SDK:
---
Every task has two halves that must agree:
1. A **Python stub** in a normal DAG file — no logic; it declares the task, its queue, the dependency graph, and retry policy. 2. A **native implementation** (Java, Go, etc.) whose IDs match the Python side and where the work happens.
The example below uses the Go SDK to be concrete, but the Python side is **identical for every language SDK**. The queue name (`"golang"` here) is an arbitrary label you choose — it just has to match a key in `queue_to_coordinator` (see **configuring-airflow-language-sdks**). Pick whatever name fits the SDK you're routing to.
from datetime import timedelta
from airflow.sdk import dag, task
@dag
def sales_pipeline():
@task.stub(queue="golang") # queue selects the coordinator (see configuring-airflow-language-sdks)
def extract(): ...
@task.stub(queue="golang")
def transform(extracted): ... # arg only declares the dependency
@task.stub(queue="golang", retries=1, retry_delay=timedelta(seconds=5))
def load(transformed): ...
@task() # an ordinary Python task can sit downstream
def report(loaded):
print(f"done: {loaded}")
report(load(transform(extract())))
sales_pipeline()Rules that apply regardless of language:
---
XCom values are stored as JSON in Airflow's metadata database, so the boundary between Python and any native language is JSON. The Python/JSON side is the same for every SDK:
| Python type | JSON | |-------------|------| | `int` | number (integer) | | `float` | number (decimal) | | `str` | string | | `bool` | boolean | | `None` | null | | `list` | array | | `dict` | object |
Each language SDK maps these JSON types onto its own native types (e.g. a JSON integer becomes a Java `Long`). The native-type mapping lives in that language's skill. The key portability rule: a value pushed by one task is read by another **as JSON**, so the consuming side must expect a type compatible with what was stored.
---
This skill deliberately stops at the shared concepts. The following differ per language and are documented in each language's companion skills:
The Airflow-side wiring (which coordinator runs which queue) is shared in structure but has per-coordinator options; it lives in **configuring-airflow-language-sdks**.
---
AI agent tooling for data engineering workflows. Includes an MCP server for Airflow, a CLI tool (af) for interacting with Airflow from your terminal, and skills that extend AI coding agents with specialized capabilities for working with Airflow and data
Airflow adapter pattern for v2/v3 API compatibility. Use when working with adapters, version detection, or adding new API methods that need to work across…
Builds human-in-the-loop (HITL) Airflow workflows - approval gates, form input, and human-driven branching. Use when a DAG needs a human in the loop - an…
Builds Airflow 3.1+ plugins that embed FastAPI apps, custom UI pages, React components, middleware, macros, and operator links directly into the Airflow UI.…
Persists task and asset state across retries and DAG runs using Airflow 3.3's AIP-103 key/value stores (`task_state_store`, `asset_state_store`) and the…
Queries, manages, and troubleshoots Apache Airflow using the `af` CLI. Use when working with anything related to Airflow - a DAG, a DAG run, a task log, an…
Queries the data warehouse with SQL and answers business questions about data. Use when answering anything that needs warehouse data - counts, metrics, trends,…