From 3e8a603697e9b793b6db290bb4f158218c7192db Mon Sep 17 00:00:00 2001 From: Nana Oppong Ampofo Date: Tue, 28 Apr 2026 16:56:52 -0500 Subject: [PATCH] Support HTTP Basic auth for OpenAPI tools --- .../tools/openapi_tool/auth/auth_helpers.py | 19 +++++++++++++++---- .../openapi_tool/auth/test_auth_helper.py | 13 ++++++++----- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/google/adk/tools/openapi_tool/auth/auth_helpers.py b/src/google/adk/tools/openapi_tool/auth/auth_helpers.py index e8eba69a94..3f2cd3e7b7 100644 --- a/src/google/adk/tools/openapi_tool/auth/auth_helpers.py +++ b/src/google/adk/tools/openapi_tool/auth/auth_helpers.py @@ -14,6 +14,7 @@ from __future__ import annotations +import base64 from typing import Any from typing import Dict from typing import List @@ -391,12 +392,22 @@ def credential_to_param( and auth_credential.http and auth_credential.http.credentials and ( - auth_credential.http.credentials.username - or auth_credential.http.credentials.password + auth_credential.http.credentials.username is not None + or auth_credential.http.credentials.password is not None ) ): - # Basic Auth is explicitly NOT supported - raise NotImplementedError("Basic Authentication is not supported.") + username = auth_credential.http.credentials.username or "" + password = auth_credential.http.credentials.password or "" + encoded = base64.b64encode(f"{username}:{password}".encode()).decode() + param = ApiParameter( + original_name="Authorization", + param_location="header", + param_schema=Schema(type="string"), + description=auth_scheme.description or "Basic auth", + py_name=INTERNAL_AUTH_PREFIX + "Authorization", + ) + kwargs = {param.py_name: f"Basic {encoded}"} + return param, kwargs else: raise ValueError("Invalid HTTP auth credentials") diff --git a/tests/unittests/tools/openapi_tool/auth/test_auth_helper.py b/tests/unittests/tools/openapi_tool/auth/test_auth_helper.py index 3f5e8f07b5..68637ac1ee 100644 --- a/tests/unittests/tools/openapi_tool/auth/test_auth_helper.py +++ b/tests/unittests/tools/openapi_tool/auth/test_auth_helper.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import base64 from unittest.mock import patch from fastapi.openapi.models import APIKey @@ -411,7 +412,7 @@ def test_credential_to_param_http_bearer(): assert kwargs == {INTERNAL_AUTH_PREFIX + "Authorization": "Bearer test_token"} -def test_credential_to_param_http_basic_not_supported(): +def test_credential_to_param_http_basic(): auth_scheme = HTTPBase(scheme="basic") auth_credential = AuthCredential( auth_type=AuthCredentialTypes.HTTP, @@ -421,10 +422,12 @@ def test_credential_to_param_http_basic_not_supported(): ), ) - with pytest.raises( - NotImplementedError, match="Basic Authentication is not supported." - ): - credential_to_param(auth_scheme, auth_credential) + param, kwargs = credential_to_param(auth_scheme, auth_credential) + + expected = base64.b64encode(b"user:password").decode() + assert param.original_name == "Authorization" + assert param.param_location == "header" + assert kwargs == {INTERNAL_AUTH_PREFIX + "Authorization": f"Basic {expected}"} def test_credential_to_param_http_invalid_credentials_no_http():