This is an automated email from the ASF dual-hosted git repository.

Lee-W pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new 18af65032e3 Render the Language SDK Spec diagrams as Mermaid (#74065)
18af65032e3 is described below

commit 18af65032e35087b4f53b5eb3c3366f63d0c3f0f
Author: Wei Lee <[email protected]>
AuthorDate: Fri Oct 2 22:05:29 2026 +0900

    Render the Language SDK Spec diagrams as Mermaid (#74065)
---
 task-sdk/docs/conf.py           |  1 +
 task-sdk/docs/lang-sdk-spec.rst | 83 +++++++++++++++++++++--------------------
 2 files changed, 44 insertions(+), 40 deletions(-)

diff --git a/task-sdk/docs/conf.py b/task-sdk/docs/conf.py
index 07925d43d25..c53f14b63b1 100644
--- a/task-sdk/docs/conf.py
+++ b/task-sdk/docs/conf.py
@@ -57,6 +57,7 @@ extensions = [
     "sphinx.ext.intersphinx",
     "airflow_intersphinx",
     "exampleinclude",
+    "sphinxcontrib.mermaid",
     "sphinxcontrib.spelling",
 ]
 
diff --git a/task-sdk/docs/lang-sdk-spec.rst b/task-sdk/docs/lang-sdk-spec.rst
index fed3c2d6f15..a260b7a56fc 100644
--- a/task-sdk/docs/lang-sdk-spec.rst
+++ b/task-sdk/docs/lang-sdk-spec.rst
@@ -27,35 +27,33 @@ Spec version: ``1.0``.
 
 There are two authoring features, and they differ in one thing: who owns the 
graph.
 
-.. code-block:: text
-
-     FEATURE 1                                   FEATURE 2
-     Mixed Language Task Handler                 Native Dag
-     Python owns the graph                       the SDK owns the graph
-
-     Python @task.stub                           Dag(spec)
-     declares dag_id, task_id,                          |
-     arguments, and every edge                          v
-           |                                           dag  <-- owns the 
schedule,
-           | binds by dag_id + task_id                  |        the tasks, 
the edges
-           v                                            v
-     fn --> TaskHandler(dagId, taskId, fn)       fn --> dag.Task(fn, options)
-                    |                                           |
-                    v                                           v
-             TaskHandlerRef                                  TaskRef
-                    |                                           |
-                    |                                           |  Inputs(ref) 
     data edge, carries a value
-                    |                                           |  before / 
after   order edge, carries nothing
-                    |                                           v
-                    |                                        TaskRef
-                    |                                           |
-                    +---------------------+---------------------+
-                                          |
-                                          v
-                         bundle.register(Dag | TaskHandler)
-                                          |
-                                          v
-                                   bundle.serve()  <-- the task subprocess 
entrypoint
+.. mermaid::
+
+    flowchart TD
+        subgraph F1["Feature 1 — Mixed Language Task Handler"]
+            direction TB
+            P1["Python @task.stub<br/>declares dag_id, task_id,<br/>arguments, 
and every edge"]
+            H1["fn -&gt; TaskHandler(dagId, taskId, fn)"]
+            H2[TaskHandlerRef]
+            P1 -. "binds by dag_id + task_id" .-> H1
+            H1 --> H2
+        end
+
+        subgraph F2["Feature 2 — Native Dag"]
+            direction TB
+            D1["Dag(spec)"]
+            D2["dag<br/>(owns the schedule, the tasks, the edges)"]
+            D3["fn -&gt; dag.Task(fn, options)"]
+            D4a[TaskRef]
+            D4b[TaskRef]
+            D1 --> D2 --> D3 --> D4a
+            D4a -- "Inputs(ref): data edge<br/>(carries a value)" --> D4b
+            D4a -. "before / after: order edge<br/>(carries nothing)" .-> D4b
+        end
+
+        H2 --> R["bundle.register(Dag | TaskHandler)"]
+        D4b --> R
+        R --> SV["bundle.serve()<br/>the task subprocess entrypoint"]
 
 A ``TaskHandler`` supplies a body for a task Python already declared, so it 
names the
 ``dagId``/``taskId`` pair it binds to and nothing else. A native ``Dag`` owns 
the schedule, the
@@ -148,17 +146,22 @@ Task subprocess lifecycle
 Authoring is only half the contract. Every SDK runs the same sequence inside 
the task
 subprocess, once per task instance:
 
-.. code-block:: text
-
-   1  process start
-   2  receive StartupDetails from the supervisor
-   3  build Context + Client, bind the cancellation signal
-   4  look up the registered fn for (dag_id, task_id)
-   5  bind arguments: TaskFlow data, plus ctx/client where they are injected
-   6  +-- scope holding Context + Client --+
-      |             invoke fn              |   <-- a getter reads this scope
-      +------------------------------------+
-   7  push the return value to XCom, report the terminal state
+.. mermaid::
+
+    sequenceDiagram
+        participant S as Supervisor
+        participant T as Task subprocess
+
+        T->>T: 1. process start
+        S->>T: 2. send StartupDetails
+        T->>T: 3. build Context + Client,<br/>bind the cancellation signal
+        T->>T: 4. look up the registered fn<br/>for (dag_id, task_id)
+        T->>T: 5. bind arguments: TaskFlow data,<br/>plus ctx/client where 
injected
+        rect rgb(230, 230, 250)
+            note right of T: scope holding Context + Client<br/>(a getter 
reads this scope)
+            T->>T: 6. invoke fn
+        end
+        T->>S: 7. push the return value to XCom,<br/>report the terminal state
 
 Steps 2 through 5 and step 7 belong to the SDK; step 6 is the only one that 
runs code a user
 wrote. How ``fn`` reaches ``Context`` and ``Client`` is each SDK's own choice 
— parameters, or

Reply via email to