Spaces:
Sleeping
Sleeping
| 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 | |
| ] | |
| def home(): | |
| return {"status": "running", "strategy": "failover_models"} | |
| def new_chat(): | |
| new_id = str(uuid.uuid4())[:8] | |
| chat_sessions[new_id] = [] | |
| return {"session_id": new_id, "message": "Новый чат создан."} | |
| 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 | |
| } |