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

jscheffl 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 a9764afd3fc Docs: add doc_md and task docstrings to measurement 
correction example Dags (#66707)
a9764afd3fc is described below

commit a9764afd3fce151f94bf9a29f59e5c494adc2dc2
Author: André Ahlert <[email protected]>
AuthorDate: Mon May 11 17:22:10 2026 -0300

    Docs: add doc_md and task docstrings to measurement correction example Dags 
(#66707)
    
    Follow-up to #66257 addressing review feedback from @jscheffl:
    
    - Expand module docstrings on both example Dags with storyline, scope and
      no-external-dependencies notes.
    - Add a Dag-level doc_md so the storyline shows up in the UI Dag details
      page.
    - Add task-level docstrings explaining what each step does and how it
      would map to a production pipeline.
    - Reference both example Dags from the Example Dag Review Checklist as
      canonical templates for new tutorial-style examples.
    
    Signed-off-by: André Ahlert <[email protected]>
---
 .../28_example_dag_review_checklist.rst            | 17 +++++
 .../example_measurement_correction_decorator.py    | 77 ++++++++++++++++++----
 .../example_measurement_correction_operator.py     | 63 ++++++++++++++++--
 3 files changed, 137 insertions(+), 20 deletions(-)

diff --git a/contributing-docs/28_example_dag_review_checklist.rst 
b/contributing-docs/28_example_dag_review_checklist.rst
index 9647b62d266..b32b6aabf7b 100644
--- a/contributing-docs/28_example_dag_review_checklist.rst
+++ b/contributing-docs/28_example_dag_review_checklist.rst
@@ -94,3 +94,20 @@ Provider examples have slightly different expectations:
 - [ ] Provider dependencies are clearly documented in the docstring.
 - [ ] Example is not auto-loaded unless intended.
 - [ ] Example naming follows provider naming conventions.
+
+Reference Examples
+------------------
+
+The following example Dags are kept aligned with this checklist and are good
+templates for new tutorial-style examples. Both implement the same
+"measurement correction" storyline so the TaskFlow and ``PythonOperator``
+styles can be compared side by side:
+
+- `example_measurement_correction_decorator.py
+  
<https://github.com/apache/airflow/blob/main/providers/standard/src/airflow/providers/standard/example_dags/example_measurement_correction_decorator.py>`_
 — TaskFlow version.
+- `example_measurement_correction_operator.py
+  
<https://github.com/apache/airflow/blob/main/providers/standard/src/airflow/providers/standard/example_dags/example_measurement_correction_operator.py>`_
 — classic ``PythonOperator`` version.
+
+When introducing a new tutorial-style example, prefer copying the shape of
+these two files (module docstring, ``doc_md``, per-task docstrings, no
+external dependencies) rather than starting from scratch.
diff --git 
a/providers/standard/src/airflow/providers/standard/example_dags/example_measurement_correction_decorator.py
 
b/providers/standard/src/airflow/providers/standard/example_dags/example_measurement_correction_decorator.py
index a7a5f177ac0..b41f49ba676 100644
--- 
a/providers/standard/src/airflow/providers/standard/example_dags/example_measurement_correction_decorator.py
+++ 
b/providers/standard/src/airflow/providers/standard/example_dags/example_measurement_correction_decorator.py
@@ -14,8 +14,23 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+"""
+Tutorial example Dag: measurement correction storyline (TaskFlow).
 
-"""Example Dag demonstrating a simple measurement correction workflow"""
+This Dag is part of the "Examples Refurbish" storyline and is meant to be a
+short, didactic walkthrough of a typical scientific or industrial data
+pipeline. It demonstrates the TaskFlow API on a self-contained workflow that:
+
+1. reads a raw measurement,
+2. validates it,
+3. applies a correction factor,
+4. stores the corrected result.
+
+The Dag has no external dependencies (no connections, no datasets, no hooks),
+so it parses and runs out of the box. Pair it with
+``example_measurement_correction_operator.py`` to compare TaskFlow and the
+classic ``PythonOperator`` style on the exact same storyline.
+"""
 
 from __future__ import annotations
 
@@ -23,6 +38,27 @@ import pendulum
 
 from airflow.sdk import dag, task
 
+DAG_DOC_MD = """
+### Measurement correction (TaskFlow)
+
+Tutorial Dag showing a minimal "read, validate, correct, store" measurement
+pipeline implemented with the TaskFlow API.
+
+**Storyline**
+
+1. `read_measurement` produces a raw value coming from a fictional sensor.
+2. `validate_measurement` rejects negative values.
+3. `apply_correction` multiplies the value by a calibration factor.
+4. `store_result` logs the corrected value (the real Dag would persist it).
+
+**When to use this example**
+
+- Learning the TaskFlow API on a single, linear pipeline.
+- As a reference shape for new "tutorial" example Dags following the
+  [example Dag review checklist](
+  
https://github.com/apache/airflow/blob/main/contributing-docs/28_example_dag_review_checklist.rst).
+"""
+
 
 # [START example_measurement_correction_decorator]
 @dag(
@@ -31,37 +67,52 @@ from airflow.sdk import dag, task
     schedule=None,
     catchup=False,
     tags=["example"],
+    doc_md=DAG_DOC_MD,
 )
 def measurement_correction_decorator():
-    """
-    A tutorial Dag showing how to:
-    1. Read a raw measurement
-    2. Validate the measurement
-    3. Apply a correction factor
-    4. Log the corrected result
-    """
-
-    # Task 1: Read a raw measurement
+    """Tutorial Dag: read, validate, correct, and store a measurement."""
+
     @task
     def read_measurement() -> int:
+        """Return the raw measurement coming from the source system.
+
+        In a real pipeline this would fetch the value from a sensor, an
+        external API, or an upstream dataset. For the tutorial it returns a
+        constant so the Dag is fully self-contained.
+        """
         return 100
 
-    # Task 2: Validate the measurement
     @task
     def validate_measurement(value: int) -> int:
+        """Reject obviously invalid measurements.
+
+        Raises ``ValueError`` when ``value`` is negative, so the failure is
+        visible as a failed task in the UI instead of silently corrupting
+        downstream data.
+        """
         if value < 0:
             raise ValueError("Measurement must be positive")
         return value
 
-    # Task 3: Apply a correction factor
     @task
     def apply_correction(value: int) -> float:
+        """Apply the calibration factor to a validated measurement.
+
+        The factor (``1.1``) is hard-coded here for brevity; a real pipeline
+        would read it from a Variable, a Connection extra, or a config file.
+        """
         correction_factor = 1.1
         return value * correction_factor
 
-    # Task 4: Log the final corrected result
     @task
     def store_result(value: float) -> None:
+        """Persist the corrected measurement.
+
+        The tutorial implementation logs the value via ``print`` so the
+        result is visible in the task logs. A production Dag would write it
+        to a database, an object store, or publish it to a downstream
+        system.
+        """
         print(f"Corrected measurement: {value}")
 
     raw_value = read_measurement()
diff --git 
a/providers/standard/src/airflow/providers/standard/example_dags/example_measurement_correction_operator.py
 
b/providers/standard/src/airflow/providers/standard/example_dags/example_measurement_correction_operator.py
index 0bcbf8154ba..43e7faa29d6 100644
--- 
a/providers/standard/src/airflow/providers/standard/example_dags/example_measurement_correction_operator.py
+++ 
b/providers/standard/src/airflow/providers/standard/example_dags/example_measurement_correction_operator.py
@@ -15,8 +15,16 @@
 # specific language governing permissions and limitations
 # under the License.
 """
-Example Dag demonstrating a simple measurement correction workflow
-using operator PythonOperator tasks.
+Tutorial example Dag: measurement correction storyline (PythonOperator).
+
+Classic, ``PythonOperator`` based counterpart of
+``example_measurement_correction_decorator.py``. It runs the same
+"read, validate, correct, store" pipeline so that learners can compare the
+TaskFlow API and the operator-based style on identical business logic.
+
+The Dag has no external dependencies (no connections, no datasets, no hooks),
+so it parses and runs out of the box and is suitable as a tutorial or as a
+documentation snippet.
 """
 
 from __future__ import annotations
@@ -26,28 +34,69 @@ import pendulum
 from airflow.providers.standard.operators.python import PythonOperator
 from airflow.sdk import DAG
 
+DAG_DOC_MD = """
+### Measurement correction (PythonOperator)
+
+Tutorial Dag showing a minimal "read, validate, correct, store" measurement
+pipeline implemented with classic ``PythonOperator`` tasks and XCom for
+inter-task communication.
+
+**Storyline**
+
+1. `read_measurement` returns a raw value.
+2. `validate_measurement` pulls it from XCom and rejects negative values.
+3. `apply_correction` multiplies it by a calibration factor.
+4. `store_result` logs the corrected value.
+
+**When to use this example**
+
+- Comparing the TaskFlow API with the classic operator style on the same
+  storyline (see ``example_measurement_correction_decorator.py``).
+- As a reference shape for new "tutorial" example Dags following the
+  [example Dag review checklist](
+  
https://github.com/apache/airflow/blob/main/contributing-docs/28_example_dag_review_checklist.rst).
+"""
+
 
-# Task 1: Return a raw measurement value
 def read_measurement(**context):
+    """Return the raw measurement value pushed to XCom.
+
+    The returned value becomes the task's XCom payload so the downstream
+    tasks can pull it with ``ti.xcom_pull``.
+    """
     return 100
 
 
-# Task 2: Validate the measurement value
 def validate_measurement(**context):
+    """Validate the upstream measurement pulled from XCom.
+
+    Raises ``ValueError`` when the value is negative so the failure is
+    visible as a failed task in the UI instead of silently corrupting
+    downstream data.
+    """
     value = context["ti"].xcom_pull(task_ids="read_measurement")
     if value < 0:
         raise ValueError("Measurement must be positive")
     return value
 
 
-# Task 3: Apply correction factor
 def apply_correction(**context):
+    """Apply the calibration factor to a validated measurement.
+
+    The factor (``1.1``) is hard-coded for brevity; a production pipeline
+    would source it from a Variable, a Connection extra, or a config file.
+    """
     value = context["ti"].xcom_pull(task_ids="validate_measurement")
     return value * 1.1
 
 
-# Task 4: Log the corrected result
 def store_result(**context):
+    """Persist the corrected measurement.
+
+    The tutorial implementation logs the value via ``print`` so the result
+    is visible in the task logs. A production Dag would write it to a
+    database, an object store, or publish it to a downstream system.
+    """
     value = context["ti"].xcom_pull(task_ids="apply_correction")
     print(f"Corrected measurement: {value}")
 
@@ -59,6 +108,7 @@ with DAG(
     schedule=None,
     catchup=False,
     tags=["example"],
+    doc_md=DAG_DOC_MD,
 ) as dag:
     read = PythonOperator(
         task_id="read_measurement",
@@ -80,6 +130,5 @@ with DAG(
         python_callable=store_result,
     )
 
-    # Define execution order
     read >> validate >> correct >> store
 # [END example_measurement_correction_operator]

Reply via email to