bypass proxies for schedule API

This commit is contained in:
Server 2026-08-30 12:16:56 +00:00
parent 889eede593
commit bfbb8920e2

View file

@ -10,7 +10,7 @@ import time
from typing import Any
from urllib.error import HTTPError, URLError
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.request import ProxyHandler, Request, build_opener
from zoneinfo import ZoneInfo
import config
@ -30,9 +30,11 @@ MOSCOW = ZoneInfo("Europe/Moscow")
_CACHE_TTL = 300.0
_REQUEST_TIMEOUT = 10.0
_FAILURE_RETRY_DELAY = 30.0
_REQUEST_ATTEMPTS = 2
_cache: dict[str, tuple[float, list[dict[str, Any]]]] = {}
_failures: dict[str, tuple[float, str]] = {}
_cache_lock = threading.RLock()
_direct_opener = build_opener(ProxyHandler({}))
class ScheduleAPIError(RuntimeError):
@ -55,19 +57,32 @@ def _load_result(path: str) -> list[dict[str, Any]]:
return cached[1]
raise ScheduleAPIError(failure[1])
request = Request(_api_url(path), headers={"Accept": "application/json"})
try:
with urlopen(request, timeout=_REQUEST_TIMEOUT) as response:
payload = json.load(response)
except (HTTPError, URLError, TimeoutError, OSError, ValueError) as error:
message = f"Не удалось получить {path}: {error}"
url = _api_url(path)
request = Request(url, headers={"Accept": "application/json"})
error: Exception | None = None
payload: Any = None
for _ in range(_REQUEST_ATTEMPTS):
try:
with _direct_opener.open(request, timeout=_REQUEST_TIMEOUT) as response:
payload = json.load(response)
error = None
break
except (HTTPError, URLError, TimeoutError, OSError, ValueError) as attempt_error:
error = attempt_error
if error is not None:
message = f"Не удалось получить {url}: {error}"
with _cache_lock:
_failures[path] = (now + _FAILURE_RETRY_DELAY, message)
if cached:
return cached[1]
raise ScheduleAPIError(message) from error
if payload.get("ok") is not True or not isinstance(payload.get("result"), list):
if (
not isinstance(payload, dict)
or payload.get("ok") is not True
or not isinstance(payload.get("result"), list)
):
if cached:
return cached[1]
raise ScheduleAPIError(f"Сервер вернул некорректный ответ для {path}")