mirror of
https://github.com/encounter/adk-python.git
synced 2026-07-09 18:19:28 -07:00
chore: Add ADK logger in RestApiTool
Fixes: https://github.com/google/adk-python/issues/3780 Co-authored-by: Xuan Yang <xygoogle@google.com> PiperOrigin-RevId: 862897383
This commit is contained in:
committed by
Copybara-Service
parent
ecce7e54a6
commit
288c2c448d
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import logging
|
||||||
import ssl
|
import ssl
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from typing import Callable
|
from typing import Callable
|
||||||
@@ -48,6 +49,8 @@ from .openapi_spec_parser import ParsedOperation
|
|||||||
from .operation_parser import OperationParser
|
from .operation_parser import OperationParser
|
||||||
from .tool_auth_handler import ToolAuthHandler
|
from .tool_auth_handler import ToolAuthHandler
|
||||||
|
|
||||||
|
logger = logging.getLogger("google_adk." + __name__)
|
||||||
|
|
||||||
|
|
||||||
def snake_to_lower_camel(snake_case_string: str):
|
def snake_to_lower_camel(snake_case_string: str):
|
||||||
"""Converts a snake_case string to a lower_camel_case string.
|
"""Converts a snake_case string to a lower_camel_case string.
|
||||||
@@ -158,6 +161,7 @@ class RestApiTool(BaseTool):
|
|||||||
self._default_headers: Dict[str, str] = {}
|
self._default_headers: Dict[str, str] = {}
|
||||||
self._ssl_verify = ssl_verify
|
self._ssl_verify = ssl_verify
|
||||||
self._header_provider = header_provider
|
self._header_provider = header_provider
|
||||||
|
self._logger = logger
|
||||||
if should_parse_operation:
|
if should_parse_operation:
|
||||||
self._operation_parser = OperationParser(self.operation)
|
self._operation_parser = OperationParser(self.operation)
|
||||||
|
|
||||||
@@ -493,14 +497,40 @@ class RestApiTool(BaseTool):
|
|||||||
if provider_headers:
|
if provider_headers:
|
||||||
request_params.setdefault("headers", {}).update(provider_headers)
|
request_params.setdefault("headers", {}).update(provider_headers)
|
||||||
|
|
||||||
|
# Log the API request
|
||||||
|
self._logger.debug(
|
||||||
|
"API Request: %s %s",
|
||||||
|
request_params.get("method", "").upper(),
|
||||||
|
request_params.get("url", ""),
|
||||||
|
)
|
||||||
|
self._logger.debug("API Request params: %s", request_params.get("params"))
|
||||||
|
if "json" in request_params:
|
||||||
|
self._logger.debug("API Request body: %s", request_params.get("json"))
|
||||||
|
|
||||||
response = requests.request(**request_params)
|
response = requests.request(**request_params)
|
||||||
|
|
||||||
|
# Log the API response
|
||||||
|
self._logger.debug(
|
||||||
|
"API Response: %s %s - Status: %d",
|
||||||
|
request_params.get("method", "").upper(),
|
||||||
|
request_params.get("url", ""),
|
||||||
|
response.status_code,
|
||||||
|
)
|
||||||
|
|
||||||
# Parse API response
|
# Parse API response
|
||||||
try:
|
try:
|
||||||
response.raise_for_status() # Raise HTTPError for bad responses
|
response.raise_for_status() # Raise HTTPError for bad responses
|
||||||
return response.json() # Try to decode JSON
|
result = response.json() # Try to decode JSON
|
||||||
|
self._logger.debug("API Response body: %s", result)
|
||||||
|
return result
|
||||||
except requests.exceptions.HTTPError:
|
except requests.exceptions.HTTPError:
|
||||||
error_details = response.content.decode("utf-8")
|
error_details = response.content.decode("utf-8")
|
||||||
|
self._logger.warning(
|
||||||
|
"API call failed for tool %s: Status %d - %s",
|
||||||
|
self.name,
|
||||||
|
response.status_code,
|
||||||
|
error_details,
|
||||||
|
)
|
||||||
return {
|
return {
|
||||||
"error": (
|
"error": (
|
||||||
f"Tool {self.name} execution failed. Analyze this execution error"
|
f"Tool {self.name} execution failed. Analyze this execution error"
|
||||||
@@ -510,6 +540,7 @@ class RestApiTool(BaseTool):
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
except ValueError:
|
except ValueError:
|
||||||
|
self._logger.debug("API Response (non-JSON): %s", response.text)
|
||||||
return {"text": response.text} # Return text if not JSON
|
return {"text": response.text} # Return text if not JSON
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
|||||||
@@ -1048,10 +1048,9 @@ class TestRestApiTool:
|
|||||||
if expected_verify_in_call == "USE_SSL_FIXTURE":
|
if expected_verify_in_call == "USE_SSL_FIXTURE":
|
||||||
expected_verify_in_call = mock_ssl_context
|
expected_verify_in_call = mock_ssl_context
|
||||||
|
|
||||||
mock_response = mock.create_autospec(
|
mock_response = mock.create_autospec(requests.Response, instance=True)
|
||||||
requests.Response, instance=True, spec_set=True
|
|
||||||
)
|
|
||||||
mock_response.json.return_value = {"result": "success"}
|
mock_response.json.return_value = {"result": "success"}
|
||||||
|
mock_response.configure_mock(status_code=200)
|
||||||
|
|
||||||
tool = RestApiTool(
|
tool = RestApiTool(
|
||||||
name="test_tool",
|
name="test_tool",
|
||||||
@@ -1084,10 +1083,9 @@ class TestRestApiTool:
|
|||||||
sample_auth_credential,
|
sample_auth_credential,
|
||||||
):
|
):
|
||||||
"""Test that configure_verify updates the verify setting."""
|
"""Test that configure_verify updates the verify setting."""
|
||||||
mock_response = mock.create_autospec(
|
mock_response = mock.create_autospec(requests.Response, instance=True)
|
||||||
requests.Response, instance=True, spec_set=True
|
|
||||||
)
|
|
||||||
mock_response.json.return_value = {"result": "success"}
|
mock_response.json.return_value = {"result": "success"}
|
||||||
|
mock_response.configure_mock(status_code=200)
|
||||||
|
|
||||||
tool = RestApiTool(
|
tool = RestApiTool(
|
||||||
name="test_tool",
|
name="test_tool",
|
||||||
@@ -1153,10 +1151,9 @@ class TestRestApiTool:
|
|||||||
sample_auth_credential,
|
sample_auth_credential,
|
||||||
):
|
):
|
||||||
"""Test that header_provider adds headers to the request."""
|
"""Test that header_provider adds headers to the request."""
|
||||||
mock_response = mock.create_autospec(
|
mock_response = mock.create_autospec(requests.Response, instance=True)
|
||||||
requests.Response, instance=True, spec_set=True
|
|
||||||
)
|
|
||||||
mock_response.json.return_value = {"result": "success"}
|
mock_response.json.return_value = {"result": "success"}
|
||||||
|
mock_response.configure_mock(status_code=200)
|
||||||
|
|
||||||
def my_header_provider(context):
|
def my_header_provider(context):
|
||||||
return {"X-Custom-Header": "custom-value", "X-Request-ID": "12345"}
|
return {"X-Custom-Header": "custom-value", "X-Request-ID": "12345"}
|
||||||
@@ -1192,10 +1189,9 @@ class TestRestApiTool:
|
|||||||
sample_auth_credential,
|
sample_auth_credential,
|
||||||
):
|
):
|
||||||
"""Test that header_provider receives the tool_context."""
|
"""Test that header_provider receives the tool_context."""
|
||||||
mock_response = mock.create_autospec(
|
mock_response = mock.create_autospec(requests.Response, instance=True)
|
||||||
requests.Response, instance=True, spec_set=True
|
|
||||||
)
|
|
||||||
mock_response.json.return_value = {"result": "success"}
|
mock_response.json.return_value = {"result": "success"}
|
||||||
|
mock_response.configure_mock(status_code=200)
|
||||||
|
|
||||||
received_context = []
|
received_context = []
|
||||||
|
|
||||||
@@ -1232,10 +1228,9 @@ class TestRestApiTool:
|
|||||||
sample_auth_credential,
|
sample_auth_credential,
|
||||||
):
|
):
|
||||||
"""Test that call works without header_provider."""
|
"""Test that call works without header_provider."""
|
||||||
mock_response = mock.create_autospec(
|
mock_response = mock.create_autospec(requests.Response, instance=True)
|
||||||
requests.Response, instance=True, spec_set=True
|
|
||||||
)
|
|
||||||
mock_response.json.return_value = {"result": "success"}
|
mock_response.json.return_value = {"result": "success"}
|
||||||
|
mock_response.configure_mock(status_code=200)
|
||||||
|
|
||||||
tool = RestApiTool(
|
tool = RestApiTool(
|
||||||
name="test_tool",
|
name="test_tool",
|
||||||
|
|||||||
Reference in New Issue
Block a user