Use httpx for Telegram onboarding worker calls

This commit is contained in:
Shannon Sands 2026-06-06 08:30:51 +10:00 committed by Teknium
parent e3b8b6d32c
commit ba29010902
2 changed files with 71 additions and 17 deletions

View file

@ -3385,6 +3385,7 @@ def _write_platform_enabled(platform_id: str, enabled: bool) -> None:
_TELEGRAM_ONBOARDING_DEFAULT_URL = "https://setup.hermes-agent.nousresearch.com"
_TELEGRAM_ONBOARDING_USER_AGENT = f"HermesDashboard/{__version__}"
_TELEGRAM_USER_ID_RE = re.compile(r"^\d+$")
@ -3457,27 +3458,32 @@ def _telegram_onboarding_request_sync(
body: dict[str, Any] | None = None,
bearer_token: str | None = None,
) -> dict[str, Any]:
data = None
headers = {"Accept": "application/json"}
import httpx
headers = {
"Accept": "application/json",
"User-Agent": _TELEGRAM_ONBOARDING_USER_AGENT,
}
request_kwargs: dict[str, Any] = {}
if body is not None:
data = json.dumps(body).encode("utf-8")
headers["Content-Type"] = "application/json"
request_kwargs["json"] = body
if bearer_token:
headers["Authorization"] = f"Bearer {bearer_token}"
request = urllib.request.Request(
f"{_telegram_onboarding_base_url()}{path}",
data=data,
headers=headers,
method=method,
)
url = f"{_telegram_onboarding_base_url()}{path}"
try:
with urllib.request.urlopen(request, timeout=10) as response:
payload = response.read()
except urllib.error.HTTPError as exc:
payload = exc.read()
with httpx.Client(timeout=httpx.Timeout(10.0)) as client:
response = client.request(
method,
url,
headers=headers,
**request_kwargs,
)
response.raise_for_status()
except httpx.HTTPStatusError as exc:
try:
parsed = json.loads(payload.decode("utf-8"))
parsed = exc.response.json()
except Exception:
parsed = {}
error = str(parsed.get("error") or parsed.get("status") or "")
@ -3485,18 +3491,18 @@ def _telegram_onboarding_request_sync(
error,
"Telegram setup service returned an error.",
)
status_code = 404 if exc.code == 404 else 502
status_code = 404 if exc.response.status_code == 404 else 502
if error in {"expired", "claimed"}:
status_code = 410
raise HTTPException(status_code=status_code, detail=detail) from exc
except Exception as exc:
except httpx.RequestError as exc:
raise HTTPException(
status_code=502,
detail="Telegram setup service is unavailable. Try again shortly.",
) from exc
try:
parsed = json.loads(payload.decode("utf-8"))
parsed = response.json()
except Exception as exc:
raise HTTPException(
status_code=502,

View file

@ -1134,6 +1134,54 @@ class TestWebServerEndpoints:
assert data["state"] == "not_configured"
assert "DISCORD_BOT_TOKEN" in data["message"]
def test_telegram_onboarding_worker_request_uses_httpx(self, monkeypatch):
import httpx
import hermes_cli.web_server as ws
calls = {}
def fail_urlopen(*_args, **_kwargs):
raise AssertionError("Telegram onboarding should not use urllib")
class FakeHttpxClient:
def __init__(self, *args, **kwargs):
calls["client_kwargs"] = kwargs
def __enter__(self):
return self
def __exit__(self, *_exc_info):
return False
def request(self, method, url, **kwargs):
calls["request"] = (method, url, kwargs)
return httpx.Response(
201,
json={"ok": True},
request=httpx.Request(method, url),
)
monkeypatch.setenv("TELEGRAM_ONBOARDING_URL", "https://worker.example")
monkeypatch.setattr(ws.urllib.request, "urlopen", fail_urlopen)
monkeypatch.setattr(httpx, "Client", FakeHttpxClient)
payload = ws._telegram_onboarding_request_sync(
"POST",
"/v1/telegram/pairings",
body={"bot_name": "Hermes Agent"},
bearer_token="poll-secret",
)
assert payload == {"ok": True}
method, url, kwargs = calls["request"]
assert method == "POST"
assert url == "https://worker.example/v1/telegram/pairings"
assert kwargs["json"] == {"bot_name": "Hermes Agent"}
assert kwargs["headers"]["Accept"] == "application/json"
assert kwargs["headers"]["Authorization"] == "Bearer poll-secret"
assert kwargs["headers"]["Content-Type"] == "application/json"
assert kwargs["headers"]["User-Agent"].startswith("HermesDashboard/")
def test_telegram_onboarding_start_strips_poll_token(self, monkeypatch):
import hermes_cli.web_server as ws