Model / app.py
nicolaydef's picture
Update app.py
cbc15c2 verified
import os
import requests
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List, Dict, Optional
import uuid
app = FastAPI(title="Gemini Multi-Model Proxy")
# Хранилище сессий (в памяти)
chat_sessions: Dict[str, List[dict]] = {}
class UserRequest(BaseModel):
message: str
session_id: Optional[str] = None
# Берем ключ из Secret Variables на Hugging Face
API_KEY = os.getenv("GEMINI_API_KEY")
# СПИСОК МОДЕЛЕЙ ДЛЯ ПЕРЕБОРА (от лучшей к худшей)
MODELS_TO_TRY = [
"gemini-2.0-flash-exp", # New 2.0 (Free tier available)
"gemini-1.5-flash", # Current stable fast
"gemini-1.5-flash-latest", # Alias for latest flash
"gemini-1.5-flash-001", # Fixed version
"gemini-1.5-pro", # Pro version
"gemini-pro" # Legacy 1.0
]
@app.get("/")
def home():
return {"status": "running", "strategy": "failover_models"}
@app.post("/newchat")
def new_chat():
new_id = str(uuid.uuid4())[:8]
chat_sessions[new_id] = []
return {"session_id": new_id, "message": "Новый чат создан."}
@app.post("/chat")
def chat(req: UserRequest):
if not API_KEY:
raise HTTPException(status_code=500, detail="GEMINI_API_KEY не установлен")
sid = req.session_id
if not sid or sid not in chat_sessions:
sid = str(uuid.uuid4())[:8]
chat_sessions[sid] = []
# 1. Сохраняем сообщение юзера
user_msg_obj = {"role": "user", "parts": [{"text": req.message}]}
chat_sessions[sid].append(user_msg_obj)
# 2. Пытаемся отправить запрос, перебирая модели
last_error = ""
success = False
ai_text = ""
used_model = ""
payload = {"contents": chat_sessions[sid]}
headers = {"Content-Type": "application/json"}
for model_name in MODELS_TO_TRY:
url = f"https://generativelanguage.googleapis.com/v1beta/models/{model_name}:generateContent?key={API_KEY}"
try:
print(f"Trying model: {model_name}...") # Лог в консоль HF
response = requests.post(url, json=payload, headers=headers, timeout=30)
# Если 404 (модель не найдена) или 5xx (ошибка сервера) -> идем к следующей
if response.status_code != 200:
error_detail = response.text
print(f"Failed {model_name}: {response.status_code} - {error_detail}")
last_error = f"{response.status_code} on {model_name}"
continue # Пробуем следующую модель
# Если 200 OK
data = response.json()
try:
ai_text = data["candidates"][0]["content"]["parts"][0]["text"]
used_model = model_name
success = True
break # Выходим из цикла, успех!
except (KeyError, IndexError):
# Бывает, если сработал фильтр безопасности
ai_text = "[Gemini заблокировал ответ (Safety Filter)]"
success = True
break
except requests.exceptions.RequestException as e:
print(f"Connection error on {model_name}: {e}")
last_error = str(e)
continue
# 3. Обработка результата
if not success:
# Если перепробовали все модели и ничего не вышло
chat_sessions[sid].pop() # Удаляем вопрос юзера, чтобы не портить историю
raise HTTPException(status_code=502, detail=f"Все модели недоступны. Last error: {last_error}")
# 4. Сохраняем ответ (и дописываем, какая модель ответила, для дебага можно убрать)
# ai_text += f"\n\n_(model: {used_model})_"
ai_msg_obj = {"role": "model", "parts": [{"text": ai_text}]}
chat_sessions[sid].append(ai_msg_obj)
return {
"response": ai_text,
"session_id": sid,
"model_used": used_model
}