86 lines
3.6 KiB
Python
86 lines
3.6 KiB
Python
import requests
|
|
import json
|
|
import time
|
|
|
|
class ApiHookClient:
|
|
def __init__(self, base_url="http://127.0.0.1:8999", max_retries=3, retry_delay=1):
|
|
self.base_url = base_url
|
|
self.max_retries = max_retries
|
|
self.retry_delay = retry_delay
|
|
|
|
def wait_for_server(self, timeout=10):
|
|
"""
|
|
Polls the /status endpoint until the server is ready or timeout is reached.
|
|
"""
|
|
start_time = time.time()
|
|
while time.time() - start_time < timeout:
|
|
try:
|
|
if self.get_status().get('status') == 'ok':
|
|
return True
|
|
except (requests.exceptions.ConnectionError, requests.exceptions.Timeout):
|
|
time.sleep(0.5)
|
|
return False
|
|
|
|
def _make_request(self, method, endpoint, data=None):
|
|
url = f"{self.base_url}{endpoint}"
|
|
headers = {'Content-Type': 'application/json'}
|
|
|
|
last_exception = None
|
|
for attempt in range(self.max_retries + 1):
|
|
try:
|
|
if method == 'GET':
|
|
response = requests.get(url, timeout=2)
|
|
elif method == 'POST':
|
|
response = requests.post(url, json=data, headers=headers, timeout=2)
|
|
else:
|
|
raise ValueError(f"Unsupported HTTP method: {method}")
|
|
|
|
response.raise_for_status() # Raise HTTPError for bad responses (4xx or 5xx)
|
|
return response.json()
|
|
except (requests.exceptions.Timeout, requests.exceptions.ConnectionError) as e:
|
|
last_exception = e
|
|
if attempt < self.max_retries:
|
|
time.sleep(self.retry_delay)
|
|
continue
|
|
else:
|
|
if isinstance(e, requests.exceptions.Timeout):
|
|
raise requests.exceptions.Timeout(f"Request to {endpoint} timed out after {self.max_retries} retries.") from e
|
|
else:
|
|
raise requests.exceptions.ConnectionError(f"Could not connect to API hook server at {self.base_url} after {self.max_retries} retries.") from e
|
|
except requests.exceptions.HTTPError as e:
|
|
raise requests.exceptions.HTTPError(f"HTTP error {e.response.status_code} for {endpoint}: {e.response.text}") from e
|
|
except json.JSONDecodeError as e:
|
|
raise ValueError(f"Failed to decode JSON from response for {endpoint}: {response.text}") from e
|
|
|
|
if last_exception:
|
|
raise last_exception
|
|
|
|
def get_status(self):
|
|
"""Checks the health of the hook server."""
|
|
url = f"{self.base_url}/status"
|
|
try:
|
|
response = requests.get(url, timeout=1)
|
|
response.raise_for_status()
|
|
return response.json()
|
|
except Exception:
|
|
raise requests.exceptions.ConnectionError(f"Could not reach /status at {self.base_url}")
|
|
|
|
def get_project(self):
|
|
return self._make_request('GET', '/api/project')
|
|
|
|
def post_project(self, project_data):
|
|
return self._make_request('POST', '/api/project', data={'project': project_data})
|
|
|
|
def get_session(self):
|
|
return self._make_request('GET', '/api/session')
|
|
|
|
def get_performance(self):
|
|
"""Retrieves UI performance metrics."""
|
|
return self._make_request('GET', '/api/performance')
|
|
|
|
def post_session(self, session_entries):
|
|
return self._make_request('POST', '/api/session', data={'session': {'entries': session_entries}})
|
|
|
|
def post_gui(self, gui_data):
|
|
return self._make_request('POST', '/api/gui', data=gui_data)
|