Добавлены все базовые файлы для запуска проекта
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
"""The two HTTP contracts exposed by the supplied n8n workflows."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import httpx
|
||||
|
||||
from config import Settings, require_webhook_url
|
||||
|
||||
|
||||
class WebhookError(RuntimeError):
|
||||
"""An n8n request failed or returned an unusable response."""
|
||||
|
||||
|
||||
class N8NClient:
|
||||
def __init__(
|
||||
self,
|
||||
settings: Settings,
|
||||
transport: httpx.AsyncBaseTransport | None = None,
|
||||
) -> None:
|
||||
self.settings = settings
|
||||
self._transport = transport
|
||||
|
||||
async def ask(self, message: str, collection_name: str, session_id: str) -> str:
|
||||
message = message.strip()
|
||||
collection_name = collection_name.strip()
|
||||
if not message or not collection_name or not session_id:
|
||||
raise ValueError("Укажите вопрос и коллекцию.")
|
||||
|
||||
url = require_webhook_url(self.settings.chat_webhook_url, "вопросов")
|
||||
try:
|
||||
async with httpx.AsyncClient(
|
||||
transport=self._transport,
|
||||
timeout=self.settings.chat_timeout_seconds,
|
||||
) as client:
|
||||
response = await client.post(
|
||||
url,
|
||||
json={
|
||||
"message": message,
|
||||
"collection_name": collection_name,
|
||||
"session_id": session_id,
|
||||
},
|
||||
)
|
||||
response.raise_for_status()
|
||||
except httpx.TimeoutException as exc:
|
||||
raise WebhookError("Время ожидания ответа истекло. Попробуйте ещё раз.") from exc
|
||||
except httpx.HTTPStatusError as exc:
|
||||
raise WebhookError(
|
||||
f"Webhook вопросов вернул HTTP {exc.response.status_code}."
|
||||
) from exc
|
||||
except httpx.RequestError as exc:
|
||||
raise WebhookError("Не удалось связаться с webhook вопросов.") from exc
|
||||
|
||||
answer = response.text.strip()
|
||||
if not answer:
|
||||
raise WebhookError("Webhook вопросов вернул пустой ответ.")
|
||||
return answer
|
||||
|
||||
async def upload(self, filename: str, contents: bytes, collection_name: str) -> None:
|
||||
collection_name = collection_name.strip()
|
||||
if not collection_name:
|
||||
raise ValueError("Укажите коллекцию.")
|
||||
if not filename.lower().endswith(".md"):
|
||||
raise ValueError("Можно загружать только файлы .md.")
|
||||
if not contents:
|
||||
raise ValueError("Выбранный файл пуст.")
|
||||
if len(contents) > self.settings.max_file_bytes:
|
||||
raise ValueError("Размер файла превышает допустимый предел.")
|
||||
|
||||
url = require_webhook_url(self.settings.upload_webhook_url, "загрузки")
|
||||
try:
|
||||
async with httpx.AsyncClient(
|
||||
transport=self._transport,
|
||||
timeout=self.settings.upload_timeout_seconds,
|
||||
) as client:
|
||||
response = await client.post(
|
||||
url,
|
||||
data={"collection_name": collection_name},
|
||||
files={"file": (filename, contents, "text/markdown")},
|
||||
)
|
||||
response.raise_for_status()
|
||||
except httpx.TimeoutException as exc:
|
||||
raise WebhookError("Время ожидания загрузки истекло. Проверьте n8n перед повтором.") from exc
|
||||
except httpx.HTTPStatusError as exc:
|
||||
raise WebhookError(
|
||||
f"Webhook загрузки вернул HTTP {exc.response.status_code}."
|
||||
) from exc
|
||||
except httpx.RequestError as exc:
|
||||
raise WebhookError("Не удалось связаться с webhook загрузки.") from exc
|
||||
Reference in New Issue
Block a user