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

vincbeck 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 a9a78f6e8f6 Remove unused batch methods from auth manager (#52883)
a9a78f6e8f6 is described below

commit a9a78f6e8f694829bcac4b3a42ace0dbbf537f18
Author: Vincent <[email protected]>
AuthorDate: Mon Jul 7 12:23:19 2025 -0400

    Remove unused batch methods from auth manager (#52883)
---
 .../docs/core-concepts/auth-manager/index.rst      |  3 -
 .../api_fastapi/auth/managers/base_auth_manager.py | 66 ---------------
 .../api_fastapi/auth/managers/models/batch_apis.py | 24 ------
 .../auth/managers/test_base_auth_manager.py        | 64 ---------------
 .../amazon/aws/auth_manager/aws_auth_manager.py    | 55 -------------
 .../aws/auth_manager/test_aws_auth_manager.py      | 93 ----------------------
 .../fab/src/airflow/providers/fab/www/auth.py      | 53 +++++-------
 providers/fab/tests/unit/fab/www/test_auth.py      |  6 +-
 providers/fab/www-hash.txt                         |  2 +-
 9 files changed, 22 insertions(+), 344 deletions(-)

diff --git a/airflow-core/docs/core-concepts/auth-manager/index.rst 
b/airflow-core/docs/core-concepts/auth-manager/index.rst
index a1959da497f..b0c99abf4bf 100644
--- a/airflow-core/docs/core-concepts/auth-manager/index.rst
+++ b/airflow-core/docs/core-concepts/auth-manager/index.rst
@@ -176,10 +176,7 @@ Optional methods recommended to override for optimization
 
 The following methods aren't required to override to have a functional Airflow 
auth manager. However, it is recommended to override these to make your auth 
manager faster (and potentially less costly):
 
-* ``batch_is_authorized_connection``: Batch version of 
``is_authorized_connection``. If not overridden, it will call 
``is_authorized_connection`` for every single item.
 * ``batch_is_authorized_dag``: Batch version of ``is_authorized_dag``. If not 
overridden, it will call ``is_authorized_dag`` for every single item.
-* ``batch_is_authorized_pool``: Batch version of ``is_authorized_pool``. If 
not overridden, it will call ``is_authorized_pool`` for every single item.
-* ``batch_is_authorized_variable``: Batch version of 
``is_authorized_variable``. If not overridden, it will call 
``is_authorized_variable`` for every single item.
 * ``get_authorized_dag_ids``: Return the list of DAG IDs the user has access 
to.  If not overridden, it will call ``is_authorized_dag`` for every single DAG 
available in the environment.
 
 CLI
diff --git 
a/airflow-core/src/airflow/api_fastapi/auth/managers/base_auth_manager.py 
b/airflow-core/src/airflow/api_fastapi/auth/managers/base_auth_manager.py
index cd766652e2d..108e4a12893 100644
--- a/airflow-core/src/airflow/api_fastapi/auth/managers/base_auth_manager.py
+++ b/airflow-core/src/airflow/api_fastapi/auth/managers/base_auth_manager.py
@@ -47,10 +47,7 @@ if TYPE_CHECKING:
     from sqlalchemy.orm import Session
 
     from airflow.api_fastapi.auth.managers.models.batch_apis import (
-        IsAuthorizedConnectionRequest,
         IsAuthorizedDagRequest,
-        IsAuthorizedPoolRequest,
-        IsAuthorizedVariableRequest,
     )
     from airflow.api_fastapi.auth.managers.models.resource_details import (
         AccessView,
@@ -307,27 +304,6 @@ class BaseAuthManager(Generic[T], LoggingMixin, 
metaclass=ABCMeta):
         :param user: the user
         """
 
-    def batch_is_authorized_connection(
-        self,
-        requests: Sequence[IsAuthorizedConnectionRequest],
-        *,
-        user: T,
-    ) -> bool:
-        """
-        Batch version of ``is_authorized_connection``.
-
-        By default, calls individually the ``is_authorized_connection`` API on 
each item in the list of
-        requests, which can lead to some poor performance. It is recommended 
to override this method in the auth
-        manager implementation to provide a more efficient implementation.
-
-        :param requests: a list of requests containing the parameters for 
``is_authorized_connection``
-        :param user: the user to performing the action
-        """
-        return all(
-            self.is_authorized_connection(method=request["method"], 
details=request.get("details"), user=user)
-            for request in requests
-        )
-
     def batch_is_authorized_dag(
         self,
         requests: Sequence[IsAuthorizedDagRequest],
@@ -354,48 +330,6 @@ class BaseAuthManager(Generic[T], LoggingMixin, 
metaclass=ABCMeta):
             for request in requests
         )
 
-    def batch_is_authorized_pool(
-        self,
-        requests: Sequence[IsAuthorizedPoolRequest],
-        *,
-        user: T,
-    ) -> bool:
-        """
-        Batch version of ``is_authorized_pool``.
-
-        By default, calls individually the ``is_authorized_pool`` API on each 
item in the list of
-        requests. Can lead to some poor performance. It is recommended to 
override this method in the auth
-        manager implementation to provide a more efficient implementation.
-
-        :param requests: a list of requests containing the parameters for 
``is_authorized_pool``
-        :param user: the user to performing the action
-        """
-        return all(
-            self.is_authorized_pool(method=request["method"], 
details=request.get("details"), user=user)
-            for request in requests
-        )
-
-    def batch_is_authorized_variable(
-        self,
-        requests: Sequence[IsAuthorizedVariableRequest],
-        *,
-        user: T,
-    ) -> bool:
-        """
-        Batch version of ``is_authorized_variable``.
-
-        By default, calls individually the ``is_authorized_variable`` API on 
each item in the list of
-        requests. Can lead to some poor performance. It is recommended to 
override this method in the auth
-        manager implementation to provide a more efficient implementation.
-
-        :param requests: a list of requests containing the parameters for 
``is_authorized_variable``
-        :param user: the user to performing the action
-        """
-        return all(
-            self.is_authorized_variable(method=request["method"], 
details=request.get("details"), user=user)
-            for request in requests
-        )
-
     @provide_session
     def get_authorized_dag_ids(
         self,
diff --git 
a/airflow-core/src/airflow/api_fastapi/auth/managers/models/batch_apis.py 
b/airflow-core/src/airflow/api_fastapi/auth/managers/models/batch_apis.py
index 2fe11b659af..5acdd3edee5 100644
--- a/airflow-core/src/airflow/api_fastapi/auth/managers/models/batch_apis.py
+++ b/airflow-core/src/airflow/api_fastapi/auth/managers/models/batch_apis.py
@@ -22,38 +22,14 @@ from typing import TYPE_CHECKING, TypedDict
 if TYPE_CHECKING:
     from airflow.api_fastapi.auth.managers.base_auth_manager import 
ResourceMethod
     from airflow.api_fastapi.auth.managers.models.resource_details import (
-        ConnectionDetails,
         DagAccessEntity,
         DagDetails,
-        PoolDetails,
-        VariableDetails,
     )
 
 
-class IsAuthorizedConnectionRequest(TypedDict, total=False):
-    """Represent the parameters of ``is_authorized_connection`` API in the 
auth manager."""
-
-    method: ResourceMethod
-    details: ConnectionDetails | None
-
-
 class IsAuthorizedDagRequest(TypedDict, total=False):
     """Represent the parameters of ``is_authorized_dag`` API in the auth 
manager."""
 
     method: ResourceMethod
     access_entity: DagAccessEntity | None
     details: DagDetails | None
-
-
-class IsAuthorizedPoolRequest(TypedDict, total=False):
-    """Represent the parameters of ``is_authorized_pool`` API in the auth 
manager."""
-
-    method: ResourceMethod
-    details: PoolDetails | None
-
-
-class IsAuthorizedVariableRequest(TypedDict, total=False):
-    """Represent the parameters of ``is_authorized_variable`` API in the auth 
manager."""
-
-    method: ResourceMethod
-    details: VariableDetails | None
diff --git 
a/airflow-core/tests/unit/api_fastapi/auth/managers/test_base_auth_manager.py 
b/airflow-core/tests/unit/api_fastapi/auth/managers/test_base_auth_manager.py
index aad69253ef2..a0fc0ab0343 100644
--- 
a/airflow-core/tests/unit/api_fastapi/auth/managers/test_base_auth_manager.py
+++ 
b/airflow-core/tests/unit/api_fastapi/auth/managers/test_base_auth_manager.py
@@ -261,70 +261,6 @@ class TestBaseAuthManager:
         )
         assert result == expected
 
-    @pytest.mark.parametrize(
-        "return_values, expected",
-        [
-            ([False, False], False),
-            ([True, False], False),
-            ([True, True], True),
-        ],
-    )
-    @patch.object(EmptyAuthManager, "is_authorized_connection")
-    def test_batch_is_authorized_connection(
-        self, mock_is_authorized_connection, auth_manager, return_values, 
expected
-    ):
-        mock_is_authorized_connection.side_effect = return_values
-        result = auth_manager.batch_is_authorized_connection(
-            [
-                {"method": "GET", "details": 
ConnectionDetails(conn_id="conn1")},
-                {"method": "GET", "details": 
ConnectionDetails(conn_id="conn2")},
-            ],
-            user=Mock(),
-        )
-        assert result == expected
-
-    @pytest.mark.parametrize(
-        "return_values, expected",
-        [
-            ([False, False], False),
-            ([True, False], False),
-            ([True, True], True),
-        ],
-    )
-    @patch.object(EmptyAuthManager, "is_authorized_pool")
-    def test_batch_is_authorized_pool(self, mock_is_authorized_pool, 
auth_manager, return_values, expected):
-        mock_is_authorized_pool.side_effect = return_values
-        result = auth_manager.batch_is_authorized_pool(
-            [
-                {"method": "GET", "details": PoolDetails(name="pool1")},
-                {"method": "GET", "details": PoolDetails(name="pool2")},
-            ],
-            user=Mock(),
-        )
-        assert result == expected
-
-    @pytest.mark.parametrize(
-        "return_values, expected",
-        [
-            ([False, False], False),
-            ([True, False], False),
-            ([True, True], True),
-        ],
-    )
-    @patch.object(EmptyAuthManager, "is_authorized_variable")
-    def test_batch_is_authorized_variable(
-        self, mock_is_authorized_variable, auth_manager, return_values, 
expected
-    ):
-        mock_is_authorized_variable.side_effect = return_values
-        result = auth_manager.batch_is_authorized_variable(
-            [
-                {"method": "GET", "details": VariableDetails(key="var1")},
-                {"method": "GET", "details": VariableDetails(key="var2")},
-            ],
-            user=Mock(),
-        )
-        assert result == expected
-
     @pytest.mark.parametrize(
         "access_per_dag, dag_ids, expected",
         [
diff --git 
a/providers/amazon/src/airflow/providers/amazon/aws/auth_manager/aws_auth_manager.py
 
b/providers/amazon/src/airflow/providers/amazon/aws/auth_manager/aws_auth_manager.py
index d427f210e11..387d968ec15 100644
--- 
a/providers/amazon/src/airflow/providers/amazon/aws/auth_manager/aws_auth_manager.py
+++ 
b/providers/amazon/src/airflow/providers/amazon/aws/auth_manager/aws_auth_manager.py
@@ -44,10 +44,7 @@ from airflow.providers.amazon.version_compat import 
AIRFLOW_V_3_0_PLUS
 if TYPE_CHECKING:
     from airflow.api_fastapi.auth.managers.base_auth_manager import 
ResourceMethod
     from airflow.api_fastapi.auth.managers.models.batch_apis import (
-        IsAuthorizedConnectionRequest,
         IsAuthorizedDagRequest,
-        IsAuthorizedPoolRequest,
-        IsAuthorizedVariableRequest,
     )
     from airflow.api_fastapi.auth.managers.models.resource_details import (
         AccessView,
@@ -247,24 +244,6 @@ class AwsAuthManager(BaseAuthManager[AwsAuthManagerUser]):
 
         return [menu_item for menu_item in menu_items if 
_has_access_to_menu_item(requests[menu_item.value])]
 
-    def batch_is_authorized_connection(
-        self,
-        requests: Sequence[IsAuthorizedConnectionRequest],
-        *,
-        user: AwsAuthManagerUser,
-    ) -> bool:
-        facade_requests: Sequence[IsAuthorizedRequest] = [
-            {
-                "method": request["method"],
-                "entity_type": AvpEntities.CONNECTION,
-                "entity_id": cast("ConnectionDetails", 
request["details"]).conn_id
-                if request.get("details")
-                else None,
-            }
-            for request in requests
-        ]
-        return self.avp_facade.batch_is_authorized(requests=facade_requests, 
user=user)
-
     def batch_is_authorized_dag(
         self,
         requests: Sequence[IsAuthorizedDagRequest],
@@ -288,40 +267,6 @@ class AwsAuthManager(BaseAuthManager[AwsAuthManagerUser]):
         ]
         return self.avp_facade.batch_is_authorized(requests=facade_requests, 
user=user)
 
-    def batch_is_authorized_pool(
-        self,
-        requests: Sequence[IsAuthorizedPoolRequest],
-        *,
-        user: AwsAuthManagerUser,
-    ) -> bool:
-        facade_requests: Sequence[IsAuthorizedRequest] = [
-            {
-                "method": request["method"],
-                "entity_type": AvpEntities.POOL,
-                "entity_id": cast("PoolDetails", request["details"]).name if 
request.get("details") else None,
-            }
-            for request in requests
-        ]
-        return self.avp_facade.batch_is_authorized(requests=facade_requests, 
user=user)
-
-    def batch_is_authorized_variable(
-        self,
-        requests: Sequence[IsAuthorizedVariableRequest],
-        *,
-        user: AwsAuthManagerUser,
-    ) -> bool:
-        facade_requests: Sequence[IsAuthorizedRequest] = [
-            {
-                "method": request["method"],
-                "entity_type": AvpEntities.VARIABLE,
-                "entity_id": cast("VariableDetails", request["details"]).key
-                if request.get("details")
-                else None,
-            }
-            for request in requests
-        ]
-        return self.avp_facade.batch_is_authorized(requests=facade_requests, 
user=user)
-
     def filter_authorized_dag_ids(
         self,
         *,
diff --git 
a/providers/amazon/tests/unit/amazon/aws/auth_manager/test_aws_auth_manager.py 
b/providers/amazon/tests/unit/amazon/aws/auth_manager/test_aws_auth_manager.py
index 055e50ac9a0..eab473ea9a5 100644
--- 
a/providers/amazon/tests/unit/amazon/aws/auth_manager/test_aws_auth_manager.py
+++ 
b/providers/amazon/tests/unit/amazon/aws/auth_manager/test_aws_auth_manager.py
@@ -368,37 +368,6 @@ class TestAwsAuthManager:
         )
         assert result
 
-    @patch.object(AwsAuthManager, "avp_facade")
-    def test_batch_is_authorized_connection(
-        self,
-        mock_avp_facade,
-        auth_manager,
-    ):
-        batch_is_authorized = Mock(return_value=True)
-        mock_avp_facade.batch_is_authorized = batch_is_authorized
-
-        result = auth_manager.batch_is_authorized_connection(
-            requests=[{"method": "GET"}, {"method": "GET", "details": 
ConnectionDetails(conn_id="conn_id")}],
-            user=mock,
-        )
-
-        batch_is_authorized.assert_called_once_with(
-            requests=[
-                {
-                    "method": "GET",
-                    "entity_type": AvpEntities.CONNECTION,
-                    "entity_id": None,
-                },
-                {
-                    "method": "GET",
-                    "entity_type": AvpEntities.CONNECTION,
-                    "entity_id": "conn_id",
-                },
-            ],
-            user=ANY,
-        )
-        assert result
-
     def test_filter_authorized_menu_items(self, auth_manager):
         batch_is_authorized_output = [
             {
@@ -541,68 +510,6 @@ class TestAwsAuthManager:
         )
         assert result
 
-    @patch.object(AwsAuthManager, "avp_facade")
-    def test_batch_is_authorized_pool(
-        self,
-        mock_avp_facade,
-        auth_manager,
-    ):
-        batch_is_authorized = Mock(return_value=True)
-        mock_avp_facade.batch_is_authorized = batch_is_authorized
-
-        result = auth_manager.batch_is_authorized_pool(
-            requests=[{"method": "GET"}, {"method": "GET", "details": 
PoolDetails(name="pool1")}],
-            user=mock,
-        )
-
-        batch_is_authorized.assert_called_once_with(
-            requests=[
-                {
-                    "method": "GET",
-                    "entity_type": AvpEntities.POOL,
-                    "entity_id": None,
-                },
-                {
-                    "method": "GET",
-                    "entity_type": AvpEntities.POOL,
-                    "entity_id": "pool1",
-                },
-            ],
-            user=ANY,
-        )
-        assert result
-
-    @patch.object(AwsAuthManager, "avp_facade")
-    def test_batch_is_authorized_variable(
-        self,
-        mock_avp_facade,
-        auth_manager,
-    ):
-        batch_is_authorized = Mock(return_value=True)
-        mock_avp_facade.batch_is_authorized = batch_is_authorized
-
-        result = auth_manager.batch_is_authorized_variable(
-            requests=[{"method": "GET"}, {"method": "GET", "details": 
VariableDetails(key="var1")}],
-            user=mock,
-        )
-
-        batch_is_authorized.assert_called_once_with(
-            requests=[
-                {
-                    "method": "GET",
-                    "entity_type": AvpEntities.VARIABLE,
-                    "entity_id": None,
-                },
-                {
-                    "method": "GET",
-                    "entity_type": AvpEntities.VARIABLE,
-                    "entity_id": "var1",
-                },
-            ],
-            user=ANY,
-        )
-        assert result
-
     @pytest.mark.parametrize(
         "method, user, expected_result",
         [
diff --git a/providers/fab/src/airflow/providers/fab/www/auth.py 
b/providers/fab/src/airflow/providers/fab/www/auth.py
index 5cd35e4600d..e25f77c8758 100644
--- a/providers/fab/src/airflow/providers/fab/www/auth.py
+++ b/providers/fab/src/airflow/providers/fab/www/auth.py
@@ -46,10 +46,7 @@ from airflow.utils.net import get_hostname
 if TYPE_CHECKING:
     from airflow.api_fastapi.auth.managers.base_auth_manager import 
ResourceMethod
     from airflow.api_fastapi.auth.managers.models.batch_apis import (
-        IsAuthorizedConnectionRequest,
         IsAuthorizedDagRequest,
-        IsAuthorizedPoolRequest,
-        IsAuthorizedVariableRequest,
     )
     from airflow.models import DagRun, Pool, TaskInstance, Variable
     from airflow.models.connection import Connection
@@ -170,15 +167,13 @@ def has_access_connection(method: ResourceMethod) -> 
Callable[[T], T]:
         @wraps(func)
         def decorated(*args, **kwargs):
             connections: set[Connection] = set(args[1])
-            requests: Sequence[IsAuthorizedConnectionRequest] = [
-                {
-                    "method": method,
-                    "details": ConnectionDetails(conn_id=connection.conn_id),
-                }
+            is_authorized = all(
+                get_auth_manager().is_authorized_connection(
+                    method=method,
+                    details=ConnectionDetails(conn_id=connection.conn_id),
+                    user=get_auth_manager().get_user(),
+                )
                 for connection in connections
-            ]
-            is_authorized = get_auth_manager().batch_is_authorized_connection(
-                requests, user=get_auth_manager().get_user()
             )
             return _has_access(
                 is_authorized=is_authorized,
@@ -284,15 +279,11 @@ def has_access_pool(method: ResourceMethod) -> 
Callable[[T], T]:
         @wraps(func)
         def decorated(*args, **kwargs):
             pools: set[Pool] = set(args[1])
-            requests: Sequence[IsAuthorizedPoolRequest] = [
-                {
-                    "method": method,
-                    "details": PoolDetails(name=pool.pool),
-                }
+            is_authorized = all(
+                get_auth_manager().is_authorized_pool(
+                    method=method, details=PoolDetails(name=pool.pool), 
user=get_auth_manager().get_user()
+                )
                 for pool in pools
-            ]
-            is_authorized = get_auth_manager().batch_is_authorized_pool(
-                requests, user=get_auth_manager().get_user()
             )
             return _has_access(
                 is_authorized=is_authorized,
@@ -310,23 +301,15 @@ def has_access_variable(method: ResourceMethod) -> 
Callable[[T], T]:
     def has_access_decorator(func: T):
         @wraps(func)
         def decorated(*args, **kwargs):
-            if len(args) == 1:
-                # No items provided
-                is_authorized = get_auth_manager().is_authorized_variable(
-                    method=method, user=get_auth_manager().get_user()
-                )
-            else:
-                variables: set[Variable] = set(args[1])
-                requests: Sequence[IsAuthorizedVariableRequest] = [
-                    {
-                        "method": method,
-                        "details": VariableDetails(key=variable.key),
-                    }
-                    for variable in variables
-                ]
-                is_authorized = 
get_auth_manager().batch_is_authorized_variable(
-                    requests, user=get_auth_manager().get_user()
+            variables: set[Variable] = set(args[1])
+            is_authorized = all(
+                get_auth_manager().is_authorized_variable(
+                    method=method,
+                    details=VariableDetails(key=variable.key),
+                    user=get_auth_manager().get_user(),
                 )
+                for variable in variables
+            )
             return _has_access(
                 is_authorized=is_authorized,
                 func=func,
diff --git a/providers/fab/tests/unit/fab/www/test_auth.py 
b/providers/fab/tests/unit/fab/www/test_auth.py
index dfa7df6e4c4..b20ee27bd34 100644
--- a/providers/fab/tests/unit/fab/www/test_auth.py
+++ b/providers/fab/tests/unit/fab/www/test_auth.py
@@ -135,11 +135,11 @@ def get_variable():
     [
         (
             "has_access_connection",
-            "batch_is_authorized_connection",
+            "is_authorized_connection",
             "get_connection",
         ),
-        ("has_access_pool", "batch_is_authorized_pool", "get_pool"),
-        ("has_access_variable", "batch_is_authorized_variable", 
"get_variable"),
+        ("has_access_pool", "is_authorized_pool", "get_pool"),
+        ("has_access_variable", "is_authorized_variable", "get_variable"),
     ],
 )
 class TestHasAccessWithDetails:
diff --git a/providers/fab/www-hash.txt b/providers/fab/www-hash.txt
index 9ac61b6cd01..e84aa2d163c 100644
--- a/providers/fab/www-hash.txt
+++ b/providers/fab/www-hash.txt
@@ -1 +1 @@
-bba05295e6d4ef8f0bfe766b77cef4d90d62e86f3a2162de32d6e94979b236c7
+06230f1bd1b77ee1be84feaaa61b26d7dcdb2f4665ec619e459b7d8b383f3ca0

Reply via email to