Spaces:
Sleeping
Sleeping
File size: 4,608 Bytes
5f84cf1 7f857aa e2f3a86 5f84cf1 61b054f 7f857aa 5f84cf1 7f857aa b35f69a 7f857aa 5f84cf1 7f857aa 5f84cf1 7f857aa e2f3a86 7f857aa b35f69a 54f10bf 7f857aa 54f10bf 7f857aa 67639c3 dd32f04 7f857aa 5f84cf1 7f857aa e2f3a86 7f857aa 3fe9d85 61b054f 7f857aa 3fe9d85 7f857aa a5cb03d 7f857aa a5cb03d 7f857aa a5cb03d 7f857aa 3fe9d85 7f857aa e2f3a86 7f857aa 79f5a3d 7f857aa 3fe9d85 7f857aa 8eabd7e 7f857aa 8eabd7e 7f857aa 8eabd7e 7f857aa 8eabd7e 3fe9d85 a5cb03d | 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 | import os
import json
import gradio as gr
from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import JSONResponse, RedirectResponse
from gradio_client import Client
# ==================== Конфигурация ====================
PRIVATE_SPACE_URL = os.getenv("PRIVATE_SPACE_URL")
PRIVATE_TOKEN = os.getenv("PRIVATE_TOKEN")
PUBLIC_ENDPOINT = os.getenv("PUBLIC_ENDPOINT")
PRIVATE_ENDPOINT = os.getenv("PRIVATE_ENDPOINT")
# ==================== Инициализация Клиента ====================
client = None
def init_client():
"""Ленивая или повторная инициализация клиента"""
global client
if not PRIVATE_SPACE_URL or not PRIVATE_TOKEN:
print("⚠️ Config missing: PRIVATE_SPACE_URL or TOKEN not set.")
return None
print("🔄 Initializing upstream connection...")
try:
# Клиент создается
new_client = Client(PRIVATE_SPACE_URL, token=PRIVATE_TOKEN, verbose=False)
print("✅ Upstream connection established.")
return new_client
except Exception as e:
# Логируем только факт ошибки, не печатаем само исключение, так как оно может содержать URL
print(PRIVATE_SPACE_URL)
print("❌ Connection failed.")
print(e)
return None
# Пробуем соединиться при старте
client = init_client()
# ==================== FastAPI (Прокси) ====================
fastapi_app = FastAPI(title="Secure Proxy")
@fastapi_app.get("/")
async def root_redirect():
return RedirectResponse(url="/ui")
@fastapi_app.get("/health")
async def health_check():
# Не показываем детали, просто жив сервис или нет
return {"status": "ok" if client else "connecting"}
@fastapi_app.post(f"/{PUBLIC_ENDPOINT}")
async def proxy_webhook(request: Request):
global client
# Если клиент отвалился или не был создан, пробуем пересоздать
if not client:
client = init_client()
if not client:
raise HTTPException(status_code=503, detail="Upstream unavailable")
try:
# 1. Получаем JSON (без логирования содержимого)
payload = await request.json()
# 2. Конвертируем в строку для Gradio
payload_str = json.dumps(payload, ensure_ascii=False)
# 3. Вызываем приватный API
# Используем api_name, это безопаснее при изменениях кода.
result = client.predict(payload_str, api_name=f"/{PRIVATE_ENDPOINT}")
# 4. Возвращаем успех, не показывая ответ приватного сервера (если там есть данные)
# Если нужно вернуть ID для отладки Яндекс.Форм, можно вернуть минимальный JSON
return JSONResponse(
content={
"status": "forwarded",
"timestamp": os.urandom(4).hex(), # Просто уникальный маркер
}
)
except Exception:
# В случае ошибки не возвращаем её текст клиенту, чтобы не светить внутренности
print("❌ Error during forwarding.")
raise HTTPException(status_code=500, detail="Internal forwarding error")
# ==================== Безопасный Gradio UI ====================
def create_secure_ui():
with gr.Blocks(title="System Status") as demo:
gr.Markdown("## 🛡️ Gateway Status")
# Индикатор статуса без деталей
status_indicator = gr.Textbox(
label="Service State", value="Checking...", interactive=False
)
btn = gr.Button("Refresh Status")
def check_safe():
if client:
return "✅ Online / Connected to Upstream"
else:
return "⚠️ Offline / Reconnecting..."
# При загрузке и нажатии проверяем статус
demo.load(check_safe, outputs=status_indicator)
btn.click(check_safe, outputs=status_indicator)
return demo
app = gr.mount_gradio_app(fastapi_app, create_secure_ui(), path="/ui")
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=7860)
|