Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -5,7 +5,7 @@ from pydantic import BaseModel
|
|
| 5 |
from typing import List, Dict, Optional
|
| 6 |
import uuid
|
| 7 |
|
| 8 |
-
app = FastAPI(title="Gemini
|
| 9 |
|
| 10 |
# Хранилище сессий (в памяти)
|
| 11 |
chat_sessions: Dict[str, List[dict]] = {}
|
|
@@ -16,11 +16,20 @@ class UserRequest(BaseModel):
|
|
| 16 |
|
| 17 |
# Берем ключ из Secret Variables на Hugging Face
|
| 18 |
API_KEY = os.getenv("GEMINI_API_KEY")
|
| 19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
|
| 21 |
@app.get("/")
|
| 22 |
def home():
|
| 23 |
-
return {"status": "running", "
|
| 24 |
|
| 25 |
@app.post("/newchat")
|
| 26 |
def new_chat():
|
|
@@ -28,57 +37,75 @@ def new_chat():
|
|
| 28 |
chat_sessions[new_id] = []
|
| 29 |
return {"session_id": new_id, "message": "Новый чат создан."}
|
| 30 |
|
| 31 |
-
@app.get("/chats")
|
| 32 |
-
def list_chats():
|
| 33 |
-
return {"active_sessions": list(chat_sessions.keys())}
|
| 34 |
-
|
| 35 |
@app.post("/chat")
|
| 36 |
def chat(req: UserRequest):
|
| 37 |
if not API_KEY:
|
| 38 |
-
raise HTTPException(status_code=500, detail="GEMINI_API_KEY не установлен
|
| 39 |
|
| 40 |
sid = req.session_id
|
| 41 |
if not sid or sid not in chat_sessions:
|
| 42 |
sid = str(uuid.uuid4())[:8]
|
| 43 |
chat_sessions[sid] = []
|
| 44 |
|
| 45 |
-
#
|
| 46 |
user_msg_obj = {"role": "user", "parts": [{"text": req.message}]}
|
| 47 |
chat_sessions[sid].append(user_msg_obj)
|
| 48 |
|
| 49 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
payload = {"contents": chat_sessions[sid]}
|
| 51 |
headers = {"Content-Type": "application/json"}
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
f"{GEMINI_URL}?key={API_KEY}",
|
| 56 |
-
json=payload,
|
| 57 |
-
headers=headers,
|
| 58 |
-
timeout=30
|
| 59 |
-
)
|
| 60 |
-
response.raise_for_status()
|
| 61 |
-
data = response.json()
|
| 62 |
|
| 63 |
-
# Парсим ответ
|
| 64 |
try:
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
from typing import List, Dict, Optional
|
| 6 |
import uuid
|
| 7 |
|
| 8 |
+
app = FastAPI(title="Gemini Multi-Model Proxy")
|
| 9 |
|
| 10 |
# Хранилище сессий (в памяти)
|
| 11 |
chat_sessions: Dict[str, List[dict]] = {}
|
|
|
|
| 16 |
|
| 17 |
# Берем ключ из Secret Variables на Hugging Face
|
| 18 |
API_KEY = os.getenv("GEMINI_API_KEY")
|
| 19 |
+
|
| 20 |
+
# СПИСОК МОДЕЛЕЙ ДЛЯ ПЕРЕБОРА (от лучшей к худшей)
|
| 21 |
+
MODELS_TO_TRY = [
|
| 22 |
+
"gemini-2.0-flash-exp", # New 2.0 (Free tier available)
|
| 23 |
+
"gemini-1.5-flash", # Current stable fast
|
| 24 |
+
"gemini-1.5-flash-latest", # Alias for latest flash
|
| 25 |
+
"gemini-1.5-flash-001", # Fixed version
|
| 26 |
+
"gemini-1.5-pro", # Pro version
|
| 27 |
+
"gemini-pro" # Legacy 1.0
|
| 28 |
+
]
|
| 29 |
|
| 30 |
@app.get("/")
|
| 31 |
def home():
|
| 32 |
+
return {"status": "running", "strategy": "failover_models"}
|
| 33 |
|
| 34 |
@app.post("/newchat")
|
| 35 |
def new_chat():
|
|
|
|
| 37 |
chat_sessions[new_id] = []
|
| 38 |
return {"session_id": new_id, "message": "Новый чат создан."}
|
| 39 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
@app.post("/chat")
|
| 41 |
def chat(req: UserRequest):
|
| 42 |
if not API_KEY:
|
| 43 |
+
raise HTTPException(status_code=500, detail="GEMINI_API_KEY не установлен")
|
| 44 |
|
| 45 |
sid = req.session_id
|
| 46 |
if not sid or sid not in chat_sessions:
|
| 47 |
sid = str(uuid.uuid4())[:8]
|
| 48 |
chat_sessions[sid] = []
|
| 49 |
|
| 50 |
+
# 1. Сохраняем сообщение юзера
|
| 51 |
user_msg_obj = {"role": "user", "parts": [{"text": req.message}]}
|
| 52 |
chat_sessions[sid].append(user_msg_obj)
|
| 53 |
|
| 54 |
+
# 2. Пытаемся отправить запрос, перебирая модели
|
| 55 |
+
last_error = ""
|
| 56 |
+
success = False
|
| 57 |
+
ai_text = ""
|
| 58 |
+
used_model = ""
|
| 59 |
+
|
| 60 |
payload = {"contents": chat_sessions[sid]}
|
| 61 |
headers = {"Content-Type": "application/json"}
|
| 62 |
+
|
| 63 |
+
for model_name in MODELS_TO_TRY:
|
| 64 |
+
url = f"https://generativelanguage.googleapis.com/v1beta/models/{model_name}:generateContent?key={API_KEY}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 65 |
|
|
|
|
| 66 |
try:
|
| 67 |
+
print(f"Trying model: {model_name}...") # Лог в консоль HF
|
| 68 |
+
response = requests.post(url, json=payload, headers=headers, timeout=30)
|
| 69 |
+
|
| 70 |
+
# Если 404 (модель не найдена) или 5xx (ошибка сервера) -> идем к следующей
|
| 71 |
+
if response.status_code != 200:
|
| 72 |
+
error_detail = response.text
|
| 73 |
+
print(f"Failed {model_name}: {response.status_code} - {error_detail}")
|
| 74 |
+
last_error = f"{response.status_code} on {model_name}"
|
| 75 |
+
continue # Пробуем следующую модель
|
| 76 |
+
|
| 77 |
+
# Если 200 OK
|
| 78 |
+
data = response.json()
|
| 79 |
+
try:
|
| 80 |
+
ai_text = data["candidates"][0]["content"]["parts"][0]["text"]
|
| 81 |
+
used_model = model_name
|
| 82 |
+
success = True
|
| 83 |
+
break # Выходим из цикла, успех!
|
| 84 |
+
except (KeyError, IndexError):
|
| 85 |
+
# Бывает, если сработал фильтр безопасности
|
| 86 |
+
ai_text = "[Gemini заблокировал ответ (Safety Filter)]"
|
| 87 |
+
success = True
|
| 88 |
+
break
|
| 89 |
+
|
| 90 |
+
except requests.exceptions.RequestException as e:
|
| 91 |
+
print(f"Connection error on {model_name}: {e}")
|
| 92 |
+
last_error = str(e)
|
| 93 |
+
continue
|
| 94 |
+
|
| 95 |
+
# 3. Обработка результата
|
| 96 |
+
if not success:
|
| 97 |
+
# Если перепробовали все модели и ничего не вышло
|
| 98 |
+
chat_sessions[sid].pop() # Удаляем вопрос юзера, чтобы не портить историю
|
| 99 |
+
raise HTTPException(status_code=502, detail=f"Все модели недоступны. Last error: {last_error}")
|
| 100 |
+
|
| 101 |
+
# 4. Сохраняем ответ (и дописываем, какая модель ответила, для дебага можно убрать)
|
| 102 |
+
# ai_text += f"\n\n_(model: {used_model})_"
|
| 103 |
+
|
| 104 |
+
ai_msg_obj = {"role": "model", "parts": [{"text": ai_text}]}
|
| 105 |
+
chat_sessions[sid].append(ai_msg_obj)
|
| 106 |
+
|
| 107 |
+
return {
|
| 108 |
+
"response": ai_text,
|
| 109 |
+
"session_id": sid,
|
| 110 |
+
"model_used": used_model
|
| 111 |
+
}
|