/
pa1ch
/
FitAssistant
Обзор
Документация
Войти
/
pa1ch
/
FitAssistant
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
app/services/http.py
50 строк
3 KB
Pavel Chugaev
fix(ai): Gemini через прокси — прокидываем http_client и щедрый таймаут
14 июл 2026, 00:56
14 июл 2026, 00:56
1e90792
Код
Авторство
О чём код?
"""Исходящее проксирование HTTP-вызовов к заблокированным напрямую сервисам. Когда задан ``PROXY_URL``, вызовы к Anthropic/OpenAI/Groq идут через прокси — это нужно в сети, где их API заблокированы напрямую (например, хостинг в РФ). Бот использует свой собственный прокси-клиент для Bot API (см. ``app/bot/utils.py``); ``app/services/oidc.py`` переиспользует ``normalize_proxy_url`` для Telegram OIDC (``oauth.telegram.org`` тоже заблокирован без прокси). Подключение к БД не проксируется никогда. """ from __future__ import annotations import httpx from app.config import settings def normalize_proxy_url(url: str) -> str: """Привести URL прокси к виду с удалённым разрешением DNS. ``socks5://`` разрешает имена локально, а ``socks5h://`` — на стороне прокси. Второе надёжнее, когда локальный DNS может быть подменён/заблокирован, поэтому схему апгрейдим автоматически. """ url = url.strip() if url.startswith("socks5://"): return "socks5h://" + url[len("socks5://") :] return url # Щедрый таймаут для ИИ/STT-вызовов через прокси: генерация ответа LLM и # распознавание речи идут долго. Совпадает с дефолтом pydantic-ai (600с); реальный # лимит на запрос задаёт прикладной слой. Без явного таймаута httpx поставил бы 5с # — и, в частности, Gemini отваливался бы по read timeout (pydantic-ai для google # берёт таймаут прямо из переданного клиента). _AI_HTTP_TIMEOUT = httpx.Timeout(600.0, connect=15.0) def proxied_async_client() -> httpx.AsyncClient | None: """httpx-клиент через ``PROXY_URL`` либо ``None`` для прямого соединения. Передаётся в ИИ-SDK как ``http_client=...``. ``None`` означает «прокси не задан» — тогда SDK создаёт свой клиент по умолчанию, и поведение полностью совпадает с прежним (например, в локальной разработке). """ if not settings.proxy_url.strip(): return None return httpx.AsyncClient( proxy=normalize_proxy_url(settings.proxy_url), timeout=_AI_HTTP_TIMEOUT )