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

bugraoz 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 a551e03c68e Send `limit` parameter in `execute_list` server requests 
(#63048)
a551e03c68e is described below

commit a551e03c68ec8dee23a42db88ae750f1c670953b
Author: leon.jeon <[email protected]>
AuthorDate: Mon Mar 9 21:22:00 2026 +0000

    Send `limit` parameter in `execute_list` server requests (#63048)
    
    * Send limit parameter in execute_list server requests
    
    execute_list uses a local limit (default 50) for offset arithmetic
    but did not include it in server requests.  The server falls back
    to its own fallback_page_limit which happens to also default to 50,
    so current behavior is correct.  However, if the server config
    differs, offsets diverge and pages overlap.
    
    Include limit in shared_params so pagination is robust regardless
    of server configuration.
    
    Co-Authored-By: claude-flow <[email protected]>
    
    * Update airflow-ctl/tests/airflow_ctl/api/test_operations.py
    
    Co-authored-by: Henry Chen <[email protected]>
    
    ---------
    
    Co-authored-by: claude-flow <[email protected]>
    Co-authored-by: Henry Chen <[email protected]>
---
 airflow-ctl/src/airflowctl/api/operations.py       |  2 +-
 .../tests/airflow_ctl/api/test_operations.py       | 32 ++++++++++++++++++++++
 2 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/airflow-ctl/src/airflowctl/api/operations.py 
b/airflow-ctl/src/airflowctl/api/operations.py
index e4a046ed774..445d490c08d 100644
--- a/airflow-ctl/src/airflowctl/api/operations.py
+++ b/airflow-ctl/src/airflowctl/api/operations.py
@@ -164,7 +164,7 @@ class BaseOperations:
         limit: int = 50,
         params: dict | None = None,
     ) -> T | ServerResponseError:
-        shared_params = {**(params or {})}
+        shared_params = {"limit": limit, **(params or {})}
         self.response = self.client.get(path, params=shared_params)
         first_pass = data_model.model_validate_json(self.response.content)
         total_entries = first_pass.total_entries  # type: ignore[attr-defined]
diff --git a/airflow-ctl/tests/airflow_ctl/api/test_operations.py 
b/airflow-ctl/tests/airflow_ctl/api/test_operations.py
index 65f058d6656..f75a3c9678f 100644
--- a/airflow-ctl/tests/airflow_ctl/api/test_operations.py
+++ b/airflow-ctl/tests/airflow_ctl/api/test_operations.py
@@ -194,6 +194,38 @@ class TestBaseOperations:
 
         assert expected_response == response
 
+    def test_execute_list_sends_limit_to_server(self):
+        """``limit`` must be included in request params so the server returns
+        the expected page size.  Without it the server uses its own default
+        (e.g. 100) which causes duplicate entries when ``limit`` differs."""
+        mock_client = Mock()
+        mock_client.get.return_value = Mock(
+            content=json.dumps({"hellos": [{"name": "hello"}] * 3, 
"total_entries": 3})
+        )
+        base_operation = BaseOperations(client=mock_client)
+
+        base_operation.execute_list(path="hello", 
data_model=HelloCollectionResponse, limit=50)
+
+        call_params = mock_client.get.call_args_list[0]
+        assert call_params.kwargs["params"]["limit"] == 50
+
+    def test_execute_list_sends_limit_on_subsequent_pages(self):
+        """Every paginated request must include ``limit`` so that offset
+        arithmetic stays consistent with the actual page size returned."""
+        mock_client = Mock()
+        mock_client.get.side_effect = [
+            Mock(content=json.dumps({"hellos": [{"name": "a"}, {"name": "b"}], 
"total_entries": 3})),
+            Mock(content=json.dumps({"hellos": [{"name": "c"}], 
"total_entries": 3})),
+        ]
+        base_operation = BaseOperations(client=mock_client)
+
+        response = base_operation.execute_list(path="hello", 
data_model=HelloCollectionResponse, limit=2)
+
+        assert len(response.hellos) == 3
+        # Verify limit is sent on both the first and second request
+        for call in mock_client.get.call_args_list:
+            assert call.kwargs["params"]["limit"] == 2
+
 
 class TestAssetsOperations:
     asset_id: int = 1

Reply via email to