fix: tolerate gateways without image profiles
This commit is contained in:
@@ -16,6 +16,7 @@ import subprocess
|
|||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import tomllib
|
import tomllib
|
||||||
|
import urllib.error
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
import urllib.request
|
import urllib.request
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -23,7 +24,7 @@ from typing import Any
|
|||||||
|
|
||||||
|
|
||||||
APP_NAME = "codex-retry-gateway-tui"
|
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_ADMIN_PATH = "/__codex_retry_gateway"
|
||||||
DEFAULT_GATEWAY_URL = "http://127.0.0.1:4610/__codex_retry_gateway"
|
DEFAULT_GATEWAY_URL = "http://127.0.0.1:4610/__codex_retry_gateway"
|
||||||
DEFAULT_API_URL = DEFAULT_GATEWAY_URL
|
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
|
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():
|
if not str(url or "").strip():
|
||||||
return {}, ""
|
return {}, ""
|
||||||
try:
|
try:
|
||||||
return fetch_payload(url, timeout, access_key), ""
|
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:
|
except Exception as exc:
|
||||||
return {}, str(exc)
|
return {}, str(exc)
|
||||||
|
|
||||||
@@ -2030,12 +2041,12 @@ def fetch_dashboard_snapshot(
|
|||||||
"image_profiles": build_api_url(gateway_root, "/api/image-profiles"),
|
"image_profiles": build_api_url(gateway_root, "/api/image-profiles"),
|
||||||
}
|
}
|
||||||
|
|
||||||
def fetch_optional(url: str) -> tuple[dict[str, Any], str]:
|
def fetch_optional(url: str, *, allow_not_found: bool = False) -> tuple[dict[str, Any], str]:
|
||||||
return fetch_optional_payload(url, timeout, access_key)
|
return fetch_optional_payload(url, timeout, access_key, allow_not_found=allow_not_found)
|
||||||
|
|
||||||
with ThreadPoolExecutor(max_workers=5) as pool:
|
with ThreadPoolExecutor(max_workers=5) as pool:
|
||||||
futures = {
|
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()
|
for name, url in endpoints.items()
|
||||||
}
|
}
|
||||||
status_payload, status_error = futures["status"].result()
|
status_payload, status_error = futures["status"].result()
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "codex-retry-gateway-tui"
|
name = "codex-retry-gateway-tui"
|
||||||
version = "0.1.8"
|
version = "0.1.9"
|
||||||
description = "Terminal UI for codex-retry-gateway monitoring and control"
|
description = "Terminal UI for codex-retry-gateway monitoring and control"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.11"
|
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_updated_elapsed(row), "1.0s")
|
||||||
self.assertEqual(mod.request_chunk_progress(row), "7 / 4.1KB")
|
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:
|
def test_request_usage_summary_shows_cached_ratio(self) -> None:
|
||||||
mod = load_module()
|
mod = load_module()
|
||||||
row = {
|
row = {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ requires-python = ">=3.11"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "codex-retry-gateway-tui"
|
name = "codex-retry-gateway-tui"
|
||||||
version = "0.1.8"
|
version = "0.1.9"
|
||||||
source = { editable = "." }
|
source = { editable = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "textual" },
|
{ name = "textual" },
|
||||||
|
|||||||
Reference in New Issue
Block a user