Изменения:

-добавлены нетворки в докер композ
-исправлен рутинг (баг пайчарма)
-запросы к ии агентам не проходят из-за ссл сертификата (пробовали отключить, но пока не выходит, нужно доделать)
This commit is contained in:
2025-12-19 00:57:13 +03:00
parent 24f4ce118f
commit a649fb1192
16 changed files with 433 additions and 62 deletions

View File

@@ -1,11 +1,17 @@
import os
import aiohttp
import ssl
import base64
import uuid
import time
from urllib.parse import urlencode
from typing import Optional, List, Dict, Any
from dotenv import load_dotenv
from app.core.config import settings
load_dotenv()
class GigaChatService:
def __init__(self):
@@ -19,8 +25,19 @@ class GigaChatService:
if time.time() < (self.token_expires_at - 60):
return self.access_token
credentials = f"{settings.GIGACHAT_CLIENT_ID}:{settings.GIGACHAT_CLIENT_SECRET}"
encoded_credentials = base64.b64encode(credentials.encode()).decode()
# Проверяем наличие credentials
client_id = os.getenv("GIGACHAT_CLIENT_ID")
client_secret = os.getenv("GIGACHAT_CLIENT_SECRET")
if not client_id or not client_secret:
raise Exception(
"GigaChat credentials not configured. "
"Please set GIGACHAT_CLIENT_ID and GIGACHAT_CLIENT_SECRET in .env file"
)
# Формируем credentials и кодируем в Base64 с явным указанием UTF-8
credentials = f"{client_id}:{client_secret}".strip().encode('utf-8') # Обрезаем лишние символы
encoded_credentials = base64.b64encode(credentials).decode('utf-8')
headers = {
"Authorization": f"Basic {encoded_credentials}",
@@ -29,31 +46,61 @@ class GigaChatService:
"RqUID": str(uuid.uuid4())
}
data = {"scope": "GIGACHAT_API_PERS"}
# Правильно кодируем данные формы (как в рабочем примере)
form_data = {
"grant_type": "client_credentials",
"scope": "GIGACHAT_API_PERS"
}
# Создаем SSL контекст без проверки сертификата (только для разработки!)
ssl_context = ssl.create_default_context()
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_NONE
connector = aiohttp.TCPConnector(ssl=ssl_context)
# Отключаем проверку SSL (только для разработки!)
# Используем ssl=False для полного отключения проверки сертификата
connector = aiohttp.TCPConnector(ssl=False)
async with aiohttp.ClientSession(connector=connector) as session:
async with session.post(
settings.GIGACHAT_AUTH_URL,
os.getenv("GIGACHAT_BASE_URL"),
headers=headers,
data=data
data=form_data
) as response:
if response.status != 200:
raise Exception(f"Failed to get token: {response.status}")
# Получаем детали ошибки из ответа
try:
error_body = await response.text()
# Пытаемся распарсить как JSON, если не получается - возвращаем текст
try:
error_json = await response.json()
error_detail = error_json.get("error_description") or error_json.get("error") or str(error_json)
except:
error_detail = error_body
except:
error_detail = "No error details available"
raise Exception(
f"Failed to get token: HTTP {response.status}. "
f"Error details: {error_detail}. "
f"Check your GIGACHAT_CLIENT_ID and GIGACHAT_CLIENT_SECRET_2 in .env file"
)
result = await response.json()
self.access_token = result.get("access_token")
expires_in = result.get("expires_at", 1800)
# expires_at может быть timestamp или количество секунд
if expires_in > 1000000000: # Это timestamp
self.token_expires_at = expires_in
else: # Это количество секунд
if not self.access_token:
raise Exception(f"Token not found in response: {result}")
# Обрабатываем время истечения токена (может быть expires_at или expires_in)
expires_at = result.get("expires_at")
expires_in = result.get("expires_in")
if expires_at:
# expires_at может быть timestamp или количество секунд
if expires_at > 1000000000: # Это timestamp
self.token_expires_at = expires_at
else: # Это количество секунд
self.token_expires_at = time.time() + expires_at
elif expires_in:
# expires_in - это всегда количество секунд до истечения
self.token_expires_at = time.time() + expires_in
else:
# По умолчанию 30 минут (1800 секунд)
self.token_expires_at = time.time() + 1800
return self.access_token
@@ -65,7 +112,7 @@ class GigaChatService:
) -> Dict[str, Any]:
"""Отправить сообщение в GigaChat"""
token = await self._get_token()
model = model or settings.GIGACHAT_MODEL_CHAT
model = model or settings.GIGACHAT_MODEL_CHAT or "GigaChat"
messages = context or []
messages.append({"role": "user", "content": message})
@@ -82,12 +129,9 @@ class GigaChatService:
"max_tokens": 2000
}
# Создаем SSL контекст без проверки сертификата (только для разработки!)
ssl_context = ssl.create_default_context()
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_NONE
connector = aiohttp.TCPConnector(ssl=ssl_context)
# Отключаем проверку SSL (только для разработки!)
# Используем ssl=False для полного отключения проверки сертификата
connector = aiohttp.TCPConnector(ssl=False)
async with aiohttp.ClientSession(connector=connector) as session:
async with session.post(
f"{settings.GIGACHAT_BASE_URL}/chat/completions",