Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions src/google/adk/tools/apihub_tool/clients/apihub_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
from google.oauth2 import service_account
import requests

# Default timeout in seconds for HTTP requests.
_REQUEST_TIMEOUT_SECONDS = 30


class BaseAPIHubClient(ABC):
"""Base class for API Hub clients."""
Expand Down Expand Up @@ -133,7 +136,9 @@ def list_apis(self, project: str, location: str) -> List[Dict[str, Any]]:
"accept": "application/json, text/plain, */*",
"Authorization": f"Bearer {self._get_access_token()}",
}
response = requests.get(url, headers=headers)
response = requests.get(
url, headers=headers, timeout=_REQUEST_TIMEOUT_SECONDS
)
response.raise_for_status()
apis = response.json().get("apis", [])
return apis
Expand All @@ -153,7 +158,9 @@ def get_api(self, api_resource_name: str) -> Dict[str, Any]:
"accept": "application/json, text/plain, */*",
"Authorization": f"Bearer {self._get_access_token()}",
}
response = requests.get(url, headers=headers)
response = requests.get(
url, headers=headers, timeout=_REQUEST_TIMEOUT_SECONDS
)
response.raise_for_status()
apis = response.json()
return apis
Expand All @@ -173,7 +180,9 @@ def get_api_version(self, api_version_name: str) -> Dict[str, Any]:
"accept": "application/json, text/plain, */*",
"Authorization": f"Bearer {self._get_access_token()}",
}
response = requests.get(url, headers=headers)
response = requests.get(
url, headers=headers, timeout=_REQUEST_TIMEOUT_SECONDS
)
response.raise_for_status()
return response.json()

Expand All @@ -192,7 +201,9 @@ def _fetch_spec(self, api_spec_resource_name: str) -> str:
"accept": "application/json, text/plain, */*",
"Authorization": f"Bearer {self._get_access_token()}",
}
response = requests.get(url, headers=headers)
response = requests.get(
url, headers=headers, timeout=_REQUEST_TIMEOUT_SECONDS
)
response.raise_for_status()
content_base64 = response.json().get("contents", "")
if content_base64:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
"integrations.mtls.googleapis.com"
)

# Default timeout in seconds for HTTP requests.
_REQUEST_TIMEOUT_SECONDS = 30


class ConnectionsClient:
"""Utility class for interacting with Google Cloud Connectors API."""
Expand Down Expand Up @@ -886,7 +889,9 @@ def _execute_api_call(self, url):
"Authorization": f"Bearer {self._get_access_token()}",
}

response = requests.get(url, headers=headers)
response = requests.get(
url, headers=headers, timeout=_REQUEST_TIMEOUT_SECONDS
)
response.raise_for_status()
return response

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
"{location}-integrations.mtls.googleapis.com"
)

# Default timeout in seconds for HTTP requests.
_REQUEST_TIMEOUT_SECONDS = 30


class IntegrationClient:
"""A client for interacting with Google Cloud Application Integration.
Expand Down Expand Up @@ -118,7 +121,9 @@ def get_openapi_spec_for_integration(self):
],
"fileFormat": "JSON",
}
response = requests.post(url, headers=headers, json=data)
response = requests.post(
url, headers=headers, json=data, timeout=_REQUEST_TIMEOUT_SECONDS
)
response.raise_for_status()
spec = response.json().get("openApiSpec", {})
return json.loads(spec)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import base64
import json
from unittest.mock import ANY
from unittest.mock import MagicMock
from unittest.mock import patch

Expand Down Expand Up @@ -74,6 +75,7 @@ def test_list_apis(self, mock_get, client):
"accept": "application/json, text/plain, */*",
"Authorization": "Bearer mocked_token",
},
timeout=ANY,
)

@patch("requests.get")
Expand Down Expand Up @@ -105,6 +107,7 @@ def test_get_api(self, mock_get, client):
"accept": "application/json, text/plain, */*",
"Authorization": "Bearer mocked_token",
},
timeout=ANY,
)

@patch("requests.get")
Expand All @@ -127,6 +130,7 @@ def test_get_api_version(self, mock_get, client):
"accept": "application/json, text/plain, */*",
"Authorization": "Bearer mocked_token",
},
timeout=ANY,
)

@patch("requests.get")
Expand All @@ -151,6 +155,7 @@ def test_get_spec_content(self, mock_get, client):
"accept": "application/json, text/plain, */*",
"Authorization": "Bearer mocked_token",
},
timeout=ANY,
)

@patch("requests.get")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ def test_execute_api_call_success(
"Content-Type": "application/json",
"Authorization": f"Bearer {mock_credentials.token}",
},
timeout=mock.ANY,
)

def test_execute_api_call_credential_error(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ def test_get_openapi_spec_for_integration_success(
}],
"fileFormat": "JSON",
},
timeout=mock.ANY,
)

def test_get_openapi_spec_for_integration_success_mtls(
Expand Down Expand Up @@ -218,6 +219,7 @@ def test_get_openapi_spec_for_integration_success_mtls(
}],
"fileFormat": "JSON",
},
timeout=mock.ANY,
)

def test_get_openapi_spec_for_integration_credential_error(
Expand Down