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

shubhamraj 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 e3af5c47e10 Add readable dags checks for the dependencies endpoint 
(#62046) (#62586)
e3af5c47e10 is described below

commit e3af5c47e103a7bd8b6f49d056e38a6d02807484
Author: Shubham Raj <[email protected]>
AuthorDate: Sat Feb 28 10:53:04 2026 +0530

    Add readable dags checks for the dependencies endpoint (#62046) (#62586)
    
    (cherry picked from commit 9d7b2a1c19ef4adce9e9aadd1f7a036794f4483e)
---
 .../api_fastapi/core_api/routes/ui/dependencies.py | 14 +++++++---
 .../core_api/routes/ui/test_dependencies.py        | 31 +++++++++++++++++++---
 2 files changed, 39 insertions(+), 6 deletions(-)

diff --git 
a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dependencies.py 
b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dependencies.py
index 8a0d8bbacd1..ce2ff1ccdf6 100644
--- a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dependencies.py
+++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dependencies.py
@@ -25,7 +25,7 @@ from airflow.api_fastapi.common.db.common import SessionDep
 from airflow.api_fastapi.common.router import AirflowRouter
 from airflow.api_fastapi.core_api.datamodels.ui.common import BaseGraphResponse
 from airflow.api_fastapi.core_api.openapi.exceptions import 
create_openapi_http_exception_doc
-from airflow.api_fastapi.core_api.security import requires_access_dag
+from airflow.api_fastapi.core_api.security import ReadableDagsFilterDep, 
requires_access_dag
 from airflow.api_fastapi.core_api.services.ui.dependencies import 
extract_single_connected_component
 from airflow.models.serialized_dag import SerializedDagModel
 
@@ -41,12 +41,20 @@ dependencies_router = AirflowRouter(tags=["Dependencies"])
     ),
     dependencies=[Depends(requires_access_dag("GET", 
DagAccessEntity.DEPENDENCIES))],
 )
-def get_dependencies(session: SessionDep, node_id: str | None = None) -> 
BaseGraphResponse:
+def get_dependencies(
+    session: SessionDep,
+    readable_dags_filter: ReadableDagsFilterDep,
+    node_id: str | None = None,
+) -> BaseGraphResponse:
     """Dependencies graph."""
     nodes_dict: dict[str, dict] = {}
     edge_tuples: set[tuple[str, str]] = set()
 
-    for dag, dependencies in 
sorted(SerializedDagModel.get_dag_dependencies().items()):
+    dag_dependencies = SerializedDagModel.get_dag_dependencies()
+    readable_dag_ids = readable_dags_filter.value
+    for dag, dependencies in sorted(dag_dependencies.items()):
+        if readable_dag_ids is not None and dag not in readable_dag_ids:
+            continue
         dag_node_id = f"dag:{dag}"
         if dag_node_id not in nodes_dict:
             for dep in dependencies:
diff --git 
a/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_dependencies.py 
b/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_dependencies.py
index c18ffe92d4a..fbc427f1382 100644
--- 
a/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_dependencies.py
+++ 
b/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_dependencies.py
@@ -16,6 +16,8 @@
 # under the License.
 from __future__ import annotations
 
+from unittest import mock
+
 import pendulum
 import pytest
 from sqlalchemy import select
@@ -204,7 +206,7 @@ def expected_secondary_component_response(asset2_id):
 class TestGetDependencies:
     @pytest.mark.usefixtures("make_primary_connected_component")
     def test_should_response_200(self, test_client, 
expected_primary_component_response):
-        with assert_queries_count(5):
+        with assert_queries_count(6):
             response = test_client.get("/dependencies")
         assert response.status_code == 200
 
@@ -240,7 +242,7 @@ class TestGetDependencies:
     @pytest.mark.usefixtures("make_primary_connected_component", 
"make_secondary_connected_component")
     def test_with_node_id_filter(self, test_client, node_id, 
expected_response_fixture, request):
         expected_response = request.getfixturevalue(expected_response_fixture)
-        with assert_queries_count(5):
+        with assert_queries_count(6):
             response = test_client.get("/dependencies", params={"node_id": 
node_id})
         assert response.status_code == 200
 
@@ -258,7 +260,7 @@ class TestGetDependencies:
             (asset1_id, expected_primary_component_response),
             (asset2_id, expected_secondary_component_response),
         ):
-            with assert_queries_count(5):
+            with assert_queries_count(6):
                 response = test_client.get("/dependencies", params={"node_id": 
f"asset:{asset_id}"})
             assert response.status_code == 200
 
@@ -272,3 +274,26 @@ class TestGetDependencies:
         assert response.json() == {
             "detail": "Unique connected component not found, got [] for 
connected components of node missing_node_id, expected only 1 connected 
component.",
         }
+
+    @mock.patch(
+        
"airflow.api_fastapi.auth.managers.base_auth_manager.BaseAuthManager.get_authorized_dag_ids",
+        return_value={"upstream", "downstream"},
+    )
+    @pytest.mark.usefixtures("make_primary_connected_component", 
"make_secondary_connected_component")
+    def test_scheduling_dependencies_respects_readable_dags_filter(self, _, 
test_client):
+        response = test_client.get("/dependencies")
+        assert response.status_code == 200
+
+        result = response.json()
+        dag_node_ids = {node["id"] for node in result["nodes"] if node["type"] 
== "dag"}
+        expected_present = ["dag:upstream", "dag:downstream"]
+        expected_absent = [
+            "dag:other_dag",
+            "dag:external_trigger_dag_id",
+            "dag:upstream_secondary",
+            "dag:downstream_secondary",
+        ]
+        for node_id in expected_present:
+            assert node_id in dag_node_ids
+        for node_id in expected_absent:
+            assert node_id not in dag_node_ids

Reply via email to