Files
airflow/go-sdk
ChickenBenny f942cca74d Send the Python task's execution_timeout to the supervisor (#75387)
* Send the Python task's execution_timeout to the supervisor

* Load the stub task only inside the is_stub branch of ti_run

Only a task a language SDK runs needs its definition from the serialized Dag, so keeping every use of it under that branch makes it clear a Python task never loads one.

* Let a stub task ask for no execution_timeout

A language SDK runtime has to tell a task that sets no timeout, which gets the worker's default, from one that asks for none. Sending zero for the latter needs a negative timeout to stay negative, so the supervisor, not the server, turns it into the grace period alone.

* Drop the note on where the default execution_timeout is read

* Set the run context's execution_timeout only in the coordinator

* Address review nits on execution_timeout docs and schema description

* Reword execution_timeout comment for runtimes that send SetExecutionTimeout

* Address review nits on ti_run stub task lookup
2026-11-03 10:07:50 +08:00
..
2026-08-20 21:19:24 +08:00
2026-08-20 21:19:24 +08:00

Airflow Go SDK

Write Apache Airflow Dags and tasks in Go.

Requires Go 1.25 or later.

Installation

go get github.com/apache/airflow/go-sdk/airflow
go get -tool github.com/apache/airflow/go-sdk/cmd/airflow-go-pack

Quick start

Declare a Dag in main.go:

package main

import (
    "log"

    "github.com/apache/airflow/go-sdk/airflow"
)

func extract(airflow.Context) (int, error) {
    return 42, nil
}

func report(actx airflow.Context, rows int) error {
    actx.Logger().InfoContext(actx, "extracted rows", "rows", rows)
    return nil
}

func main() {
    dag := airflow.Dag("go_hello", airflow.DagSpec{Schedule: "@daily", Queue: "golang"})

    extracted := dag.Task(extract)
    dag.Task(report, airflow.Inputs(extracted))

    bundle := airflow.Bundle()
    bundle.Register(dag)
    if err := bundle.Serve(); err != nil {
        log.Fatal(err)
    }
}

Build it into a bundle, a single executable:

go tool airflow-go-pack --output dist/go_hello .

Put dist/go_hello in a Dag bundle, such as the default dags-folder bundle, and send the golang queue to the Go coordinator in airflow.cfg:

[sdk]
coordinators = {"go": {"classpath": "airflow.sdk.coordinators.executable.ExecutableCoordinator"}}
queue_to_coordinator = {"golang": "go"}

Airflow reads the bundle like any other Dag file: go_hello shows up in the UI, runs on its schedule, and report receives the value extract returned.

Learn more

The Go SDK guide covers:

Topic Guide section
Task inputs, options, order-only dependencies, task groups, branching, triggering another Dag Declaring a Dag in Go
The airflow.Context, the sdk.Client and the task state store Writing tasks
Building a bundle with airflow-go-pack, and cross-platform builds Building a bundle
Where to deploy a bundle, and the ExecutableCoordinator options Deploying
What a Dag declared in Go cannot do yet Limitations

See example/ for working projects.

Compatibility matrix

Which Airflow TaskInstance states and capabilities this SDK supports. This table is generated from capabilities.yaml; the conformance dimensions are defined in the Language SDK conformance spec. The minimum version applies to the current SDK source, while "Since" records when each capability first became available and can therefore be earlier than the current minimum. Do not edit the table by hand — edit capabilities.yaml and let the update-go-sdk-readme-matrix prek hook regenerate it.

Min. Airflow version: 3.5.0 · supervisor schema: 2027-02-28

Dimension Tier Supported Since (Airflow) Since (SDK) Notes
TaskInstance states
state: success MUST ✓ 3.4.0 1.0.0
state: failed MUST ✓ 3.4.0 1.0.0
state: up_for_retry MUST ✓ 3.4.0 1.0.0 RetryTask
state: skipped SHOULD ✓ 3.4.0 1.0.0 airflow.TriggerDagRun with SkipWhenAlreadyExists only
state: deferred MAY ✓ 3.4.0 1.0.0 airflow.TriggerDagRun with Deferrable only; resumes in the Go runtime
state: up_for_reschedule MAY ✗ – – runtime does not emit RescheduleTask yet
state: awaiting_input MAY ✗ – – runtime does not emit AwaitInputTask yet
state: removed MAY ✓ 3.4.0 1.0.0
Task runtime
capability: task-logging MUST ✓ 3.4.0 1.0.0 slog records streamed over the logs socket
capability: xcom-read-write MUST ✓ 3.4.0 1.0.0 PushXCom / GetXCom
capability: connection-read MUST ✓ 3.4.0 1.0.0 GetConnection
capability: variable-read-write MUST ✓ 3.4.0 1.0.0
capability: self-contained-bundle MUST ✓ 3.4.0 1.0.0 AFBNDL01 native binary via airflow-go-pack
capability: retry-policy MAY ✗ – – no task-facing retry-policy API yet
capability: task-state-store MAY ✓ 3.4.0 1.0.0
capability: asset-state-store MAY ✗ – – no task-facing asset state-store API yet
capability: asset-event-emit MAY ✗ – – runtime does not emit asset events yet
capability: asset-event-read MAY ✗ – – no task-facing asset-event API yet
capability: object-store MAY ✗ – – no object-storage API yet
capability: listeners MAY ✗ – – no hook into the Python listener API, so a task emits no OpenLineage facets of its own
Dag definition
capability: dag-definition-authoring SHOULD ✓ 3.4.0 1.0.0 airflow.Dag
capability: dag-args MUST † ✓ 3.4.0 1.0.0
capability: task-args MUST † ✓ 3.4.0 1.0.0
capability: dag-params MUST † ✗ – –
capability: dag-callbacks MAY † ✗ – –
capability: explicit-dependencies MUST † ✓ 3.4.0 1.0.0 Before / After
capability: edge-labels MAY † ✓ 3.4.0 1.0.0 airflow.Label(text).On(task)
capability: taskflow-dependencies MUST † ✓ 3.4.0 1.0.0
capability: task-group MAY † ✓ 3.4.0 1.0.0 DagRef.TaskGroup
capability: task-loops MAY † ✗ – –
capability: if-else-branching SHOULD † ✓ 3.4.0 1.0.0 DagRef.If
capability: switch-case-branching SHOULD † ✓ 3.4.0 1.0.0 DagRef.Switch
capability: trigger-dag-run MAY † ✓ 3.4.0 1.0.0 airflow.TriggerDagRun
capability: dynamic-dag-generation MAY † ✓ 3.4.0 1.0.0
capability: human-in-the-loop MAY † ✗ – –
capability: dag-test SHOULD † ✗ – –
capability: asset-definition MAY † ✗ – –
capability: asset-scheduling MAY † ✗ – –
capability: mapped-tasks MAY † ✗ – –
capability: asset-inlets-outlets MAY † ✗ – –
capability: task-callbacks MAY † ✗ – – no SDK-defined task callbacks
Python Dag with stub TaskHandler
capability: mixed-lang-stub-target MUST ✓ 3.4.0 1.0.0 @task.stub
capability: taskflow-binding MUST ✓ 3.4.0 1.0.0 mapped stubs excluded
capability: mapped-tasks MAY ✗ – – Airflow does not bind arguments to mapped stubs yet
capability: asset-inlets-outlets MAY ✗ – – runtime does not report task outlets yet
capability: task-callbacks MAY ✗ – – a Python-declared task callback does not run for a stub task

Marks: ✓ supported · ✗ not supported · n/a not applicable. A tier marked † applies only when dag-definition-authoring is supported.