This is an automated email from the ASF dual-hosted git repository.
ephraimanierobi 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 7b85d4e6bd include limit and offset in request body schema for List
task instances (batch) endpoint (#42870)
7b85d4e6bd is described below
commit 7b85d4e6bdc5a9f80cd8ccf1d65c248623b5e1d4
Author: Kalyan R <[email protected]>
AuthorDate: Mon Oct 28 18:09:22 2024 +0530
include limit and offset in request body schema for List task instances
(batch) endpoint (#42870)
* add offset and limit
* add offset and limit
* add offset and limit
* add tests
* add test for default offset and limit
* fix
* Update airflow/api_connexion/endpoints/task_instance_endpoint.py
Co-authored-by: Ephraim Anierobi <[email protected]>
* Update tests/api_connexion/endpoints/test_task_instance_endpoint.py
Co-authored-by: Ephraim Anierobi <[email protected]>
* fix test
---------
Co-authored-by: Ephraim Anierobi <[email protected]>
---
.../endpoints/task_instance_endpoint.py | 1 +
airflow/api_connexion/openapi/v1.yaml | 9 ++++
airflow/www/static/js/types/api-generated.ts | 7 +++
.../endpoints/test_task_instance_endpoint.py | 50 ++++++++++++++++++++++
4 files changed, 67 insertions(+)
diff --git a/airflow/api_connexion/endpoints/task_instance_endpoint.py
b/airflow/api_connexion/endpoints/task_instance_endpoint.py
index 0e98173f68..2c32bad9f3 100644
--- a/airflow/api_connexion/endpoints/task_instance_endpoint.py
+++ b/airflow/api_connexion/endpoints/task_instance_endpoint.py
@@ -425,6 +425,7 @@ def get_task_instances_batch(session: Session =
NEW_SESSION) -> APIResponse:
except _UnsupportedOrderBy as e:
raise BadRequest(detail=f"Ordering with {e.order_by!r} is not
supported")
+ ti_query = ti_query.offset(data["page_offset"]).limit(data["page_limit"])
task_instances = session.scalars(ti_query)
return task_instance_collection_schema.dump(
diff --git a/airflow/api_connexion/openapi/v1.yaml
b/airflow/api_connexion/openapi/v1.yaml
index 62d4226407..252d4cd6ed 100644
--- a/airflow/api_connexion/openapi/v1.yaml
+++ b/airflow/api_connexion/openapi/v1.yaml
@@ -5038,6 +5038,15 @@ components:
ListTaskInstanceForm:
type: object
properties:
+ page_offset:
+ type: integer
+ minimum: 0
+ description: The number of items to skip before starting to collect
the result set.
+ page_limit:
+ type: integer
+ minimum: 1
+ default: 100
+ description: The numbers of items to return.
dag_ids:
type: array
items:
diff --git a/airflow/www/static/js/types/api-generated.ts
b/airflow/www/static/js/types/api-generated.ts
index 930c6834d7..e5c3434ae9 100644
--- a/airflow/www/static/js/types/api-generated.ts
+++ b/airflow/www/static/js/types/api-generated.ts
@@ -2256,6 +2256,13 @@ export interface components {
end_date_lte?: string;
};
ListTaskInstanceForm: {
+ /** @description The number of items to skip before starting to collect
the result set. */
+ page_offset?: number;
+ /**
+ * @description The numbers of items to return.
+ * @default 100
+ */
+ page_limit?: number;
/**
* @description Return objects with specific DAG IDs.
* The value can be repeated to retrieve multiple matching values (OR
condition).
diff --git a/tests/api_connexion/endpoints/test_task_instance_endpoint.py
b/tests/api_connexion/endpoints/test_task_instance_endpoint.py
index 1051aa21e0..d8b9078bbe 100644
--- a/tests/api_connexion/endpoints/test_task_instance_endpoint.py
+++ b/tests/api_connexion/endpoints/test_task_instance_endpoint.py
@@ -1032,6 +1032,56 @@ class
TestGetTaskInstancesBatch(TestTaskInstanceEndpoint):
assert response.status_code == 400
assert expected in response.json["detail"]
+ def test_should_respond_200_for_pagination(self, session):
+ dag_id = "example_python_operator"
+
+ self.create_task_instances(
+ session,
+ task_instances=[
+ {"start_date": DEFAULT_DATETIME_1 + dt.timedelta(minutes=(i +
1))} for i in range(10)
+ ],
+ dag_id=dag_id,
+ )
+
+ # First 5 items
+ response_batch1 = self.client.post(
+ "/api/v1/dags/~/dagRuns/~/taskInstances/list",
+ environ_overrides={"REMOTE_USER": "test"},
+ json={"page_limit": 5, "page_offset": 0},
+ )
+ assert response_batch1.status_code == 200, response_batch1.json
+ num_entries_batch1 = len(response_batch1.json["task_instances"])
+ assert num_entries_batch1 == 5
+ assert len(response_batch1.json["task_instances"]) == 5
+
+ # 5 items after that
+ response_batch2 = self.client.post(
+ "/api/v1/dags/~/dagRuns/~/taskInstances/list",
+ environ_overrides={"REMOTE_USER": "test"},
+ json={"page_limit": 5, "page_offset": 5},
+ )
+ assert response_batch2.status_code == 200, response_batch2.json
+ num_entries_batch2 = len(response_batch2.json["task_instances"])
+ assert num_entries_batch2 > 0
+ assert len(response_batch2.json["task_instances"]) > 0
+
+ # Match
+ ti_count = 9
+ assert response_batch1.json["total_entries"] ==
response_batch2.json["total_entries"] == ti_count
+ assert (num_entries_batch1 + num_entries_batch2) == ti_count
+ assert response_batch1 != response_batch2
+
+ # default limit and offset
+ response_batch3 = self.client.post(
+ "/api/v1/dags/~/dagRuns/~/taskInstances/list",
+ environ_overrides={"REMOTE_USER": "test"},
+ json={},
+ )
+
+ num_entries_batch3 = len(response_batch3.json["task_instances"])
+ assert num_entries_batch3 == ti_count
+ assert len(response_batch3.json["task_instances"]) == ti_count
+
class TestPostClearTaskInstances(TestTaskInstanceEndpoint):
@pytest.mark.parametrize(