From 59048308e49aa7fa9f492a24e1f0749dddc32027 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Sun, 14 Jun 2026 07:27:16 +0400 Subject: [PATCH] =?UTF-8?q?fix(llm):=20httpx=20=D1=81=20HTTP/2=20=D0=B2?= =?UTF-8?q?=D0=BC=D0=B5=D1=81=D1=82=D0=BE=20requests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit api.aillm.ru за ddos-guard — требует HTTP/2. requests (HTTP/1.1) не работал. httpx[http2] — поддержка HTTP/2, работает с ddos-guard. --- requirements.txt | 1 + site/llm_client.py | 20 ++++++++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/requirements.txt b/requirements.txt index dbe9f25..1c1ec7c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,3 +5,4 @@ requests psycopg2-binary python-dotenv pdfplumber +httpx[http2] diff --git a/site/llm_client.py b/site/llm_client.py index 9db5a7a..4f9aed5 100644 --- a/site/llm_client.py +++ b/site/llm_client.py @@ -4,13 +4,15 @@ llm_client.py — Тонкий HTTP-клиент к LLM API. Только отправить промпт → получить ответ. Никакой бизнес-логики. Бизнес-логика (промпты, парсинг ответа) → extractor.py. -Использует: +Использует httpx (HTTP/2) — api.aillm.ru за ddos-guard, требует HTTP/2. + +Переменные окружения: LLM_API_URL — URL API (по умолчанию https://api.aillm.ru/v1/chat/completions) LLM_API_KEY — ключ авторизации """ import os -import requests +import httpx # ── Конфигурация ──────────────────────────────────────────────── @@ -55,9 +57,11 @@ def ask(prompt: str, model: str = None, max_tokens: int = 8000) -> dict: } try: - resp = requests.post(api_url, json=payload, headers=headers, timeout=120) - resp.raise_for_status() - data = resp.json() + # httpx с HTTP/2 — обязательно для ddos-guard + with httpx.Client(http2=True, timeout=120) as client: + resp = client.post(api_url, json=payload, headers=headers) + resp.raise_for_status() + data = resp.json() # OpenAI-совместимый формат ответа choice = data.get("choices", [{}])[0] @@ -70,11 +74,11 @@ def ask(prompt: str, model: str = None, max_tokens: int = 8000) -> dict: "usage": data.get("usage", {}), } - except requests.exceptions.Timeout: + except httpx.TimeoutException: return {"error": "LLM timeout (120s)"} - except requests.exceptions.HTTPError as e: + except httpx.HTTPStatusError as e: return {"error": f"LLM HTTP {e.response.status_code}: {e.response.text[:500]}"} - except requests.exceptions.RequestException as e: + except httpx.RequestError as e: return {"error": f"LLM request failed: {e}"} except Exception as e: return {"error": f"LLM unexpected: {e}"}