fix: tolerate gateways without image profiles
This commit is contained in:
@@ -16,6 +16,7 @@ import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import tomllib
|
||||
import urllib.error
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
from pathlib import Path
|
||||
@@ -23,7 +24,7 @@ from typing import Any
|
||||
|
||||
|
||||
APP_NAME = "codex-retry-gateway-tui"
|
||||
FALLBACK_VERSION = "0.1.8"
|
||||
FALLBACK_VERSION = "0.1.9"
|
||||
DEFAULT_GATEWAY_ADMIN_PATH = "/__codex_retry_gateway"
|
||||
DEFAULT_GATEWAY_URL = "http://127.0.0.1:4610/__codex_retry_gateway"
|
||||
DEFAULT_API_URL = DEFAULT_GATEWAY_URL
|
||||
@@ -1150,11 +1151,21 @@ def fetch_payload(api_url: str, timeout: int, access_key: str = "") -> dict[str,
|
||||
return data
|
||||
|
||||
|
||||
def fetch_optional_payload(url: str, timeout: int, access_key: str = "") -> tuple[dict[str, Any], str]:
|
||||
def fetch_optional_payload(
|
||||
url: str,
|
||||
timeout: int,
|
||||
access_key: str = "",
|
||||
*,
|
||||
allow_not_found: bool = False,
|
||||
) -> tuple[dict[str, Any], str]:
|
||||
if not str(url or "").strip():
|
||||
return {}, ""
|
||||
try:
|
||||
return fetch_payload(url, timeout, access_key), ""
|
||||
except urllib.error.HTTPError as exc:
|
||||
if allow_not_found and exc.code == 404:
|
||||
return {}, ""
|
||||
return {}, str(exc)
|
||||
except Exception as exc:
|
||||
return {}, str(exc)
|
||||
|
||||
@@ -2030,12 +2041,12 @@ def fetch_dashboard_snapshot(
|
||||
"image_profiles": build_api_url(gateway_root, "/api/image-profiles"),
|
||||
}
|
||||
|
||||
def fetch_optional(url: str) -> tuple[dict[str, Any], str]:
|
||||
return fetch_optional_payload(url, timeout, access_key)
|
||||
def fetch_optional(url: str, *, allow_not_found: bool = False) -> tuple[dict[str, Any], str]:
|
||||
return fetch_optional_payload(url, timeout, access_key, allow_not_found=allow_not_found)
|
||||
|
||||
with ThreadPoolExecutor(max_workers=5) as pool:
|
||||
futures = {
|
||||
name: pool.submit(fetch_optional, url)
|
||||
name: pool.submit(fetch_optional, url, allow_not_found=name == "image_profiles")
|
||||
for name, url in endpoints.items()
|
||||
}
|
||||
status_payload, status_error = futures["status"].result()
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "codex-retry-gateway-tui"
|
||||
version = "0.1.8"
|
||||
version = "0.1.9"
|
||||
description = "Terminal UI for codex-retry-gateway monitoring and control"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.11"
|
||||
|
||||
@@ -121,6 +121,24 @@ class CodexRetryGatewayTUITests(unittest.TestCase):
|
||||
self.assertEqual(mod.request_updated_elapsed(row), "1.0s")
|
||||
self.assertEqual(mod.request_chunk_progress(row), "7 / 4.1KB")
|
||||
|
||||
def test_optional_image_profiles_endpoint_can_be_absent_on_older_gateway(self) -> None:
|
||||
mod = load_module()
|
||||
missing_endpoint = mod.urllib.error.HTTPError(
|
||||
"http://127.0.0.1:4610/__codex_retry_gateway/api/image-profiles",
|
||||
404,
|
||||
"Not Found",
|
||||
{},
|
||||
None,
|
||||
)
|
||||
with mock.patch.object(mod, "fetch_payload", side_effect=missing_endpoint):
|
||||
payload, error = mod.fetch_optional_payload(
|
||||
"http://127.0.0.1:4610/__codex_retry_gateway/api/image-profiles",
|
||||
5,
|
||||
allow_not_found=True,
|
||||
)
|
||||
self.assertEqual(payload, {})
|
||||
self.assertEqual(error, "")
|
||||
|
||||
def test_request_usage_summary_shows_cached_ratio(self) -> None:
|
||||
mod = load_module()
|
||||
row = {
|
||||
|
||||
Reference in New Issue
Block a user