This is an automated email from the ASF dual-hosted git repository.
guanmingchiu pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/v3-1-test by this push:
new 7d34579b4c5 [v3-1-test] Alias run_after for XComResponse (#61443)
(#61672)
7d34579b4c5 is described below
commit 7d34579b4c5f1caf99e2a93eb86a2fa8deeab528
Author: Guan-Ming (Wesley) Chiu <[email protected]>
AuthorDate: Mon Feb 9 21:27:42 2026 +0800
[v3-1-test] Alias run_after for XComResponse (#61443) (#61672)
* Alias run_after for XComResponse
* Fix CTL test
* Update to display run_id plus run_after
---------
(cherry picked from commit e8140016f0475054e8b8c91dbb92cd1d06054865)
Signed-off-by: Guan-Ming (Wesley) Chiu
<[email protected]>
---
.../airflow/api_fastapi/core_api/datamodels/xcom.py | 1 +
.../core_api/openapi/v2-rest-api-generated.yaml | 15 +++++++++++++++
.../airflow/ui/openapi-gen/requests/schemas.gen.ts | 21 ++++++++++++++++++---
.../airflow/ui/openapi-gen/requests/types.gen.ts | 3 +++
airflow-core/src/airflow/ui/src/pages/XCom/XCom.tsx | 14 +++++++++++++-
.../api_fastapi/core_api/routes/public/test_xcom.py | 12 ++++++++++++
.../src/airflowctl/api/datamodels/generated.py | 3 +++
7 files changed, 65 insertions(+), 4 deletions(-)
diff --git a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/xcom.py
b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/xcom.py
index 174bfbadf30..9f2bb84ac46 100644
--- a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/xcom.py
+++ b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/xcom.py
@@ -36,6 +36,7 @@ class XComResponse(BaseModel):
run_id: str
dag_display_name: str = Field(validation_alias=AliasPath("dag_run",
"dag_model", "dag_display_name"))
task_display_name: str = Field(validation_alias=AliasPath("task",
"task_display_name"))
+ run_after: datetime = Field(validation_alias=AliasPath("dag_run",
"run_after"))
def _stringify_if_needed(value):
diff --git
a/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml
b/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml
index 38db3d22848..0bd1bf28dc4 100644
---
a/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml
+++
b/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml
@@ -12859,6 +12859,10 @@ components:
task_display_name:
type: string
title: Task Display Name
+ run_after:
+ type: string
+ format: date-time
+ title: Run After
type: object
required:
- key
@@ -12870,6 +12874,7 @@ components:
- run_id
- dag_display_name
- task_display_name
+ - run_after
title: XComResponse
description: Serializer for a xcom item.
XComResponseNative:
@@ -12905,6 +12910,10 @@ components:
task_display_name:
type: string
title: Task Display Name
+ run_after:
+ type: string
+ format: date-time
+ title: Run After
value:
title: Value
type: object
@@ -12918,6 +12927,7 @@ components:
- run_id
- dag_display_name
- task_display_name
+ - run_after
- value
title: XComResponseNative
description: XCom response serializer with native return type.
@@ -12954,6 +12964,10 @@ components:
task_display_name:
type: string
title: Task Display Name
+ run_after:
+ type: string
+ format: date-time
+ title: Run After
value:
anyOf:
- type: string
@@ -12970,6 +12984,7 @@ components:
- run_id
- dag_display_name
- task_display_name
+ - run_after
- value
title: XComResponseString
description: XCom response serializer with string return type.
diff --git a/airflow-core/src/airflow/ui/openapi-gen/requests/schemas.gen.ts
b/airflow-core/src/airflow/ui/openapi-gen/requests/schemas.gen.ts
index 34a549a9070..54c6d40dbfe 100644
--- a/airflow-core/src/airflow/ui/openapi-gen/requests/schemas.gen.ts
+++ b/airflow-core/src/airflow/ui/openapi-gen/requests/schemas.gen.ts
@@ -6429,10 +6429,15 @@ export const $XComResponse = {
task_display_name: {
type: 'string',
title: 'Task Display Name'
+ },
+ run_after: {
+ type: 'string',
+ format: 'date-time',
+ title: 'Run After'
}
},
type: 'object',
- required: ['key', 'timestamp', 'logical_date', 'map_index', 'task_id',
'dag_id', 'run_id', 'dag_display_name', 'task_display_name'],
+ required: ['key', 'timestamp', 'logical_date', 'map_index', 'task_id',
'dag_id', 'run_id', 'dag_display_name', 'task_display_name', 'run_after'],
title: 'XComResponse',
description: 'Serializer for a xcom item.'
} as const;
@@ -6484,12 +6489,17 @@ export const $XComResponseNative = {
type: 'string',
title: 'Task Display Name'
},
+ run_after: {
+ type: 'string',
+ format: 'date-time',
+ title: 'Run After'
+ },
value: {
title: 'Value'
}
},
type: 'object',
- required: ['key', 'timestamp', 'logical_date', 'map_index', 'task_id',
'dag_id', 'run_id', 'dag_display_name', 'task_display_name', 'value'],
+ required: ['key', 'timestamp', 'logical_date', 'map_index', 'task_id',
'dag_id', 'run_id', 'dag_display_name', 'task_display_name', 'run_after',
'value'],
title: 'XComResponseNative',
description: 'XCom response serializer with native return type.'
} as const;
@@ -6541,6 +6551,11 @@ export const $XComResponseString = {
type: 'string',
title: 'Task Display Name'
},
+ run_after: {
+ type: 'string',
+ format: 'date-time',
+ title: 'Run After'
+ },
value: {
anyOf: [
{
@@ -6554,7 +6569,7 @@ export const $XComResponseString = {
}
},
type: 'object',
- required: ['key', 'timestamp', 'logical_date', 'map_index', 'task_id',
'dag_id', 'run_id', 'dag_display_name', 'task_display_name', 'value'],
+ required: ['key', 'timestamp', 'logical_date', 'map_index', 'task_id',
'dag_id', 'run_id', 'dag_display_name', 'task_display_name', 'run_after',
'value'],
title: 'XComResponseString',
description: 'XCom response serializer with string return type.'
} as const;
diff --git a/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts
b/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts
index c5a755153ce..726ed514a2b 100644
--- a/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts
+++ b/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts
@@ -1593,6 +1593,7 @@ export type XComResponse = {
run_id: string;
dag_display_name: string;
task_display_name: string;
+ run_after: string;
};
/**
@@ -1608,6 +1609,7 @@ export type XComResponseNative = {
run_id: string;
dag_display_name: string;
task_display_name: string;
+ run_after: string;
value: unknown;
};
@@ -1624,6 +1626,7 @@ export type XComResponseString = {
run_id: string;
dag_display_name: string;
task_display_name: string;
+ run_after: string;
value: string | null;
};
diff --git a/airflow-core/src/airflow/ui/src/pages/XCom/XCom.tsx
b/airflow-core/src/airflow/ui/src/pages/XCom/XCom.tsx
index e3b9f5c0719..df41c3f2c26 100644
--- a/airflow-core/src/airflow/ui/src/pages/XCom/XCom.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/XCom/XCom.tsx
@@ -70,7 +70,19 @@ const columns = (translate: (key: string) => string, open:
boolean): Array<Colum
</Link>
),
enableSorting: false,
- header: translate("common:runId"),
+ header: translate("common:dagRunId"),
+ },
+ {
+ accessorKey: "run_after",
+ cell: ({ row: { original } }: { row: { original: XComResponse } }) => (
+ <Link asChild color="fg.info" fontWeight="bold">
+ <RouterLink to={`/dags/${original.dag_id}/runs/${original.run_id}`}>
+ <Time datetime={original.run_after} />
+ </RouterLink>
+ </Link>
+ ),
+ enableSorting: false,
+ header: translate("common:dagRun.runAfter"),
},
{
accessorKey: "task_display_name",
diff --git
a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_xcom.py
b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_xcom.py
index 395e45f0a9e..3fef7f3a212 100644
--- a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_xcom.py
+++ b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_xcom.py
@@ -62,6 +62,7 @@ TEST_TASK_DISPLAY_NAME_2 = "test-task-id-2"
logical_date_parsed = timezone.parse(TEST_EXECUTION_DATE)
logical_date_formatted = logical_date_parsed.strftime("%Y-%m-%dT%H:%M:%SZ")
run_after_parsed = timezone.parse(TEST_EXECUTION_DATE)
+run_after_formatted = run_after_parsed.strftime("%Y-%m-%dT%H:%M:%SZ")
run_id = DagRun.generate_run_id(
run_type=DagRunType.MANUAL, logical_date=logical_date_parsed,
run_after=run_after_parsed
)
@@ -134,6 +135,7 @@ class TestGetXComEntry(TestXComEndpoint):
"dag_display_name": TEST_DAG_DISPLAY_NAME,
"logical_date": logical_date_parsed.strftime("%Y-%m-%dT%H:%M:%SZ"),
"run_id": run_id,
+ "run_after": run_after_formatted,
"key": TEST_XCOM_KEY,
"task_id": TEST_TASK_ID,
"task_display_name": TEST_TASK_DISPLAY_NAME,
@@ -231,6 +233,7 @@ class TestGetXComEntries(TestXComEndpoint):
"dag_display_name": TEST_DAG_DISPLAY_NAME,
"logical_date": logical_date_formatted,
"run_id": run_id,
+ "run_after": run_after_formatted,
"key": f"{TEST_XCOM_KEY}-0",
"task_id": TEST_TASK_ID,
"task_display_name": TEST_TASK_DISPLAY_NAME,
@@ -242,6 +245,7 @@ class TestGetXComEntries(TestXComEndpoint):
"dag_display_name": TEST_DAG_DISPLAY_NAME,
"logical_date": logical_date_formatted,
"run_id": run_id,
+ "run_after": run_after_formatted,
"key": f"{TEST_XCOM_KEY}-1",
"task_id": TEST_TASK_ID,
"task_display_name": TEST_TASK_DISPLAY_NAME,
@@ -271,6 +275,7 @@ class TestGetXComEntries(TestXComEndpoint):
"dag_display_name": TEST_DAG_DISPLAY_NAME,
"logical_date": logical_date_formatted,
"run_id": run_id,
+ "run_after": run_after_formatted,
"key": f"{TEST_XCOM_KEY}-0",
"task_id": TEST_TASK_ID,
"task_display_name": TEST_TASK_DISPLAY_NAME,
@@ -282,6 +287,7 @@ class TestGetXComEntries(TestXComEndpoint):
"dag_display_name": TEST_DAG_DISPLAY_NAME,
"logical_date": logical_date_formatted,
"run_id": run_id,
+ "run_after": run_after_formatted,
"key": f"{TEST_XCOM_KEY}-1",
"task_id": TEST_TASK_ID,
"task_display_name": TEST_TASK_DISPLAY_NAME,
@@ -293,6 +299,7 @@ class TestGetXComEntries(TestXComEndpoint):
"dag_display_name": TEST_DAG_DISPLAY_NAME_2,
"logical_date": logical_date_formatted,
"run_id": run_id,
+ "run_after": run_after_formatted,
"key": f"{TEST_XCOM_KEY}-0",
"task_id": TEST_TASK_ID_2,
"task_display_name": TEST_TASK_DISPLAY_NAME_2,
@@ -304,6 +311,7 @@ class TestGetXComEntries(TestXComEndpoint):
"dag_display_name": TEST_DAG_DISPLAY_NAME_2,
"logical_date": logical_date_formatted,
"run_id": run_id,
+ "run_after": run_after_formatted,
"key": f"{TEST_XCOM_KEY}-1",
"task_id": TEST_TASK_ID_2,
"task_display_name": TEST_TASK_DISPLAY_NAME_2,
@@ -334,6 +342,7 @@ class TestGetXComEntries(TestXComEndpoint):
"dag_display_name": TEST_DAG_DISPLAY_NAME,
"logical_date": logical_date_formatted,
"run_id": run_id,
+ "run_after": run_after_formatted,
"key": TEST_XCOM_KEY,
"task_id": TEST_TASK_ID,
"task_display_name": TEST_TASK_DISPLAY_NAME,
@@ -349,6 +358,7 @@ class TestGetXComEntries(TestXComEndpoint):
"dag_display_name": TEST_DAG_DISPLAY_NAME,
"logical_date": logical_date_formatted,
"run_id": run_id,
+ "run_after": run_after_formatted,
"key": TEST_XCOM_KEY,
"task_id": TEST_TASK_ID,
"task_display_name": TEST_TASK_DISPLAY_NAME,
@@ -374,6 +384,7 @@ class TestGetXComEntries(TestXComEndpoint):
"dag_display_name": TEST_DAG_DISPLAY_NAME,
"logical_date": logical_date_formatted,
"run_id": run_id,
+ "run_after": run_after_formatted,
"key": TEST_XCOM_KEY,
"task_id": TEST_TASK_ID,
"task_display_name": TEST_TASK_DISPLAY_NAME,
@@ -385,6 +396,7 @@ class TestGetXComEntries(TestXComEndpoint):
"dag_display_name": TEST_DAG_DISPLAY_NAME,
"logical_date": logical_date_formatted,
"run_id": run_id,
+ "run_after": run_after_formatted,
"key": TEST_XCOM_KEY,
"task_id": TEST_TASK_ID,
"task_display_name": TEST_TASK_DISPLAY_NAME,
diff --git a/airflow-ctl/src/airflowctl/api/datamodels/generated.py
b/airflow-ctl/src/airflowctl/api/datamodels/generated.py
index 65364faa318..c8f11ec0e60 100644
--- a/airflow-ctl/src/airflowctl/api/datamodels/generated.py
+++ b/airflow-ctl/src/airflowctl/api/datamodels/generated.py
@@ -966,6 +966,7 @@ class XComResponse(BaseModel):
run_id: Annotated[str, Field(title="Run Id")]
dag_display_name: Annotated[str, Field(title="Dag Display Name")]
task_display_name: Annotated[str, Field(title="Task Display Name")]
+ run_after: Annotated[datetime, Field(title="Run After")]
class XComResponseNative(BaseModel):
@@ -982,6 +983,7 @@ class XComResponseNative(BaseModel):
run_id: Annotated[str, Field(title="Run Id")]
dag_display_name: Annotated[str, Field(title="Dag Display Name")]
task_display_name: Annotated[str, Field(title="Task Display Name")]
+ run_after: Annotated[datetime, Field(title="Run After")]
value: Annotated[Any, Field(title="Value")]
@@ -999,6 +1001,7 @@ class XComResponseString(BaseModel):
run_id: Annotated[str, Field(title="Run Id")]
dag_display_name: Annotated[str, Field(title="Dag Display Name")]
task_display_name: Annotated[str, Field(title="Task Display Name")]
+ run_after: Annotated[datetime, Field(title="Run After")]
value: Annotated[str | None, Field(title="Value")] = None