Files
airflow/ts-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
..
…
…

Airflow TypeScript SDK

Write Apache Airflow Dags in TypeScript, and run them on Node.js.

Status: 1.0.0-beta2 · API may change · Node 22+ · ESM-only

Installation

npm install @apache-airflow/ts-sdk@1.0.0-beta2
npm install --save-dev esbuild

Quick start

Declare a Dag in src/main.ts:

import { Bundle, Dag } from "@apache-airflow/ts-sdk";

const dag = new Dag("ts_hello", { schedule: "@daily", queue: "typescript" });

const extract = dag.task("extract", async (): Promise<number> => 42);
const report = dag.task("report", async ({ rows }: { rows: number }) => {
  console.log(`extracted ${rows} rows`);
});

report({ rows: extract() });

await new Bundle(dag).serve();

Build it into a single file:

npx airflow-ts-pack src/main.ts --outdir dist

Put dist/bundle.min.mjs in a Dag bundle, such as the default dags-folder bundle, and send the typescript queue to the Node.js coordinator in airflow.cfg:

[sdk]
coordinators = {"ts": {"classpath": "airflow.sdk.coordinators.node.NodeCoordinator"}}
queue_to_coordinator = {"typescript": "ts"}

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

Learn more

The TypeScript SDK guide covers:

Topic Guide section
Task inputs, options, order-only dependencies, task groups, branching, triggering another Dag Declaring a Dag in TypeScript
approval and hitl tasks that wait for a person Human-in-the-loop tasks
getContext(), getClient() and the TaskClient Writing tasks
Building a bundle with airflow-ts-pack Building a bundle
Where to deploy a bundle, and the NodeCoordinator options Deploying
What a Dag declared in TypeScript cannot do yet Limitations

See example/ for a working project.

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. Do not edit the table by hand. Update the manifest and run the update-ts-sdk-readme-matrix prek hook.

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 triggerDagRun with skipWhenAlreadyExists only
state: deferred MAY ✓ 3.4.0 1.0.0 triggerDagRun with deferrable only
state: up_for_reschedule MAY ✗ – – runtime does not emit RescheduleTask yet
state: awaiting_input MAY ✓ 3.4.0 1.0.0 approval() / hitl() in a Dag definition
state: removed MAY ✓ 3.4.0 1.0.0
Task runtime
capability: task-logging MUST ✓ 3.4.0 1.0.0 structured records over the log socket
capability: xcom-read-write MUST ✓ 3.4.0 1.0.0 getXCom / setXCom
capability: connection-read MUST ✓ 3.4.0 1.0.0 getConnection
capability: variable-read-write MUST ✓ 3.4.0 1.0.0 getVariable / setVariable / deleteVariable
capability: self-contained-bundle MUST ✓ 3.4.0 1.0.0 Airflow metadata embedded in the bundle
capability: retry-policy MAY ✗ – – no task-facing retry-policy API yet
capability: task-state-store MAY ✓ 3.4.0 1.0.0 taskStateStore.get / set / delete / clear
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 new 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 label(task, text)
capability: taskflow-dependencies MUST † ✓ 3.4.0 1.0.0
capability: task-group MAY † ✓ 3.4.0 1.0.0 dag.taskGroup
capability: task-loops MAY † ✗ – –
capability: if-else-branching SHOULD † ✓ 3.4.0 1.0.0 dag.if
capability: switch-case-branching SHOULD † ✓ 3.4.0 1.0.0 dag.switch
capability: trigger-dag-run MAY † ✓ 3.4.0 1.0.0 triggerDagRun
capability: dynamic-dag-generation MAY † ✓ 3.4.0 1.0.0
capability: human-in-the-loop MAY † ✓ 3.4.0 1.0.0 approval() / hitl()
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.