-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgigachat_api.py
More file actions
171 lines (143 loc) · 5.98 KB
/
gigachat_api.py
File metadata and controls
171 lines (143 loc) · 5.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# работа с GigaChat API
import requests
import time
import uuid
import urllib3
from app.config import (
GIGACHAT_API_KEY,
GIGACHAT_API_URL,
GIGACHAT_TOKEN_URL,
GIGACHAT_SCOPE,
GIGACHAT_MODEL,
GIGACHAT_VERIFY_SSL
)
from app.history import get_history, add_assistant_message
# Отключаем предупреждения о небезопасных SSL запросах, если проверка отключена
if not GIGACHAT_VERIFY_SSL:
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
# Кэш для Access token
_access_token = None
_token_expires_at = 0
TOKEN_LIFETIME = 30 * 60 # 30 минут в секундах
def get_access_token() -> str:
"""
Получает Access token для авторизации запросов к GigaChat API.
Токен кэшируется и обновляется при необходимости (действует 30 минут).
Returns:
Access token
"""
global _access_token, _token_expires_at
# Проверяем наличие необходимых данных
if not GIGACHAT_API_KEY:
raise Exception("GIGACHAT_API_KEY не установлен. Проверьте файл .env")
if not GIGACHAT_SCOPE:
raise Exception("GIGACHAT_SCOPE не установлен. Проверьте файл .env")
# Проверяем, не истек ли токен (оставляем запас в 1 минуту)
current_time = time.time()
if _access_token and current_time < (_token_expires_at - 60):
return _access_token
# Получаем новый токен
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json',
'RqUID': str(uuid.uuid4()),
'Authorization': f'Basic {GIGACHAT_API_KEY}'
}
payload = {
'scope': GIGACHAT_SCOPE
}
try:
response = requests.post(
GIGACHAT_TOKEN_URL,
headers=headers,
data=payload,
timeout=30,
verify=GIGACHAT_VERIFY_SSL
)
# Детальная обработка ошибок
if response.status_code == 401:
error_detail = ""
try:
error_data = response.json()
error_detail = f" Детали: {error_data}"
except:
error_detail = f" Ответ сервера: {response.text[:200]}"
raise Exception(
f"Ошибка авторизации (401). Проверьте правильность GIGACHAT_API_KEY и GIGACHAT_SCOPE.{error_detail}"
)
response.raise_for_status()
data = response.json()
_access_token = data.get('access_token')
if not _access_token:
raise ValueError("Access token не найден в ответе API")
# Сохраняем время истечения токена
_token_expires_at = current_time + TOKEN_LIFETIME
return _access_token
except requests.exceptions.HTTPError as e:
error_detail = ""
if hasattr(e.response, 'text'):
try:
error_data = e.response.json()
error_detail = f" Детали: {error_data}"
except:
error_detail = f" Ответ сервера: {e.response.text[:200]}"
raise Exception(f"HTTP ошибка при получении Access token: {str(e)}{error_detail}")
except requests.exceptions.RequestException as e:
raise Exception(f"Ошибка при получении Access token: {str(e)}")
except KeyError as e:
raise Exception(f"Ошибка при обработке ответа API токена: {str(e)}")
except Exception as e:
raise Exception(f"Неожиданная ошибка при получении токена: {str(e)}")
def send_message_to_gigachat() -> str:
"""
Отправляет историю диалога в GigaChat API и возвращает ответ.
Использует всю историю диалога для контекста.
Returns:
Ответ от GigaChat
"""
# Получаем историю диалога
messages = get_history()
# Получаем Access token
try:
access_token = get_access_token()
except Exception as e:
return f"Ошибка авторизации: {str(e)}"
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': f'Bearer {access_token}'
}
payload = {
"model": GIGACHAT_MODEL,
"messages": messages,
"n": 1,
"stream": False,
"max_tokens": 512,
"temperature": 0.1,
"repetition_penalty": 1,
"update_interval": 0
}
try:
response = requests.post(
GIGACHAT_API_URL,
headers=headers,
json=payload,
timeout=30,
verify=GIGACHAT_VERIFY_SSL
)
response.raise_for_status()
data = response.json()
# Извлекаем ответ из структуры ответа API
if "choices" in data and len(data["choices"]) > 0:
response_text = data["choices"][0]["message"]["content"]
# Добавляем ответ ассистента в историю
add_assistant_message(response_text)
return response_text
else:
return "Ошибка: не удалось получить ответ от API"
except requests.exceptions.RequestException as e:
return f"Ошибка при обращении к API: {str(e)}"
except KeyError as e:
return f"Ошибка при обработке ответа API: {str(e)}"
except Exception as e:
return f"Неожиданная ошибка: {str(e)}"