ai-station/.venv/lib/python3.12/site-packages/traceloop/sdk/client/http.py

131 lines
4.7 KiB
Python
Raw Normal View History

from typing import Any, Dict, Optional
import requests
from colorama import Fore
class HTTPClient:
base_url: str
api_key: str
version: str
def __init__(self, base_url: str, api_key: str, version: str):
self.base_url = base_url.rstrip("/")
self.api_key = api_key
self.version = version
def _headers(self) -> Dict[str, str]:
return {
"Authorization": f"Bearer {self.api_key}",
"X-Traceloop-SDK-Version": self.version,
}
def post(self, path: str, data: Dict[str, Any]) -> Any:
"""
Make a POST request to the API
"""
try:
response = requests.post(
f"{self.base_url}/v2/{path.lstrip('/')}",
json=data,
headers=self._headers(),
)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
error_msg = self._format_error_message(path, e)
print(Fore.RED + error_msg + Fore.RESET)
return None
def get(self, path: str, params: Optional[Dict[str, Any]] = None) -> Any:
"""
Make a GET request to the API
"""
try:
response = requests.get(
f"{self.base_url}/v2/{path.lstrip('/')}",
params=params,
headers=self._headers(),
)
response.raise_for_status()
content_type = response.headers.get("content-type", "").lower()
if "text/csv" in content_type or "application/x-ndjson" in content_type:
return response.text
else:
return response.json()
except requests.exceptions.RequestException as e:
error_msg = self._format_error_message(path, e)
print(Fore.RED + error_msg + Fore.RESET)
return None
def delete(self, path: str) -> bool:
"""
Make a DELETE request to the API
"""
try:
response = requests.delete(
f"{self.base_url}/v2/{path.lstrip('/')}", headers=self._headers()
)
response.raise_for_status()
return response.status_code == 204 or response.status_code == 200
except requests.exceptions.RequestException as e:
error_msg = self._format_error_message(path, e)
print(Fore.RED + error_msg + Fore.RESET)
return False
def put(self, path: str, data: Dict[str, Any]) -> Any:
"""
Make a PUT request to the API
"""
try:
response = requests.put(
f"{self.base_url}/v2/{path.lstrip('/')}",
json=data,
headers=self._headers(),
)
response.raise_for_status()
if response.content:
return response.json()
else:
return {}
except requests.exceptions.RequestException as e:
error_msg = self._format_error_message(path, e)
print(Fore.RED + error_msg + Fore.RESET)
return None
def _format_error_message(self, path: str, exception: requests.exceptions.RequestException) -> str:
"""
Format a detailed error message including server response if available
"""
error_parts = [f"Error making request to {path}: {str(exception)}"]
# Try to extract error details from response
if hasattr(exception, 'response') and exception.response is not None:
response = exception.response
# Try to parse JSON error from response
try:
error_data = response.json()
if isinstance(error_data, dict):
# Check common error fields
if 'error' in error_data:
error_parts.append(f"Server error: {error_data['error']}")
elif 'message' in error_data:
error_parts.append(f"Server message: {error_data['message']}")
elif 'msg' in error_data:
error_parts.append(f"Server message: {error_data['msg']}")
else:
# Include the entire JSON if no standard field found
error_parts.append(f"Server response: {error_data}")
except (ValueError, AttributeError):
# Not JSON, try to get text
try:
error_text = response.text
if error_text and len(error_text) < 500: # Only include short error messages
error_parts.append(f"Server response: {error_text}")
except Exception:
pass
return "\n".join(error_parts)