Add /split route — Open WebUI iframe + 참고자료 polling layout
Browse files
app.py
CHANGED
|
@@ -92,17 +92,13 @@ def _attach_kpaa_routes() -> None:
|
|
| 92 |
"""Mount KPAA OpenAI-compatible /v1 routes onto demo's FastAPI.
|
| 93 |
|
| 94 |
Called AFTER demo.launch() — demo.app is the live Gradio FastAPI by then.
|
| 95 |
-
We use include_router for clean route attachment.
|
| 96 |
"""
|
| 97 |
from kpaa.server import create_app
|
| 98 |
kpaa_app = create_app()
|
| 99 |
|
| 100 |
-
# FastAPI's `include_router` re-registers each route on the parent. Simpler:
|
| 101 |
-
# iterate kpaa_app.routes and append to demo.app.routes.
|
| 102 |
n_added = 0
|
| 103 |
skipped = 0
|
| 104 |
for route in kpaa_app.routes:
|
| 105 |
-
# Skip routes that would conflict with Gradio (e.g., '/').
|
| 106 |
path = getattr(route, "path", None)
|
| 107 |
if path in ("/", None):
|
| 108 |
skipped += 1
|
|
@@ -112,6 +108,32 @@ def _attach_kpaa_routes() -> None:
|
|
| 112 |
print(f"[kpaa-backend] attached {n_added} KPAA routes (skipped {skipped})", flush=True)
|
| 113 |
|
| 114 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 115 |
if __name__ == "__main__":
|
| 116 |
# Launch Gradio in a non-blocking way so we can patch demo.app afterwards.
|
| 117 |
demo.queue()
|
|
@@ -123,9 +145,10 @@ if __name__ == "__main__":
|
|
| 123 |
prevent_thread_lock=True,
|
| 124 |
)
|
| 125 |
|
| 126 |
-
# demo.app is now a live Starlette/FastAPI app — attach KPAA routes.
|
| 127 |
_attach_kpaa_routes()
|
| 128 |
-
|
|
|
|
| 129 |
|
| 130 |
# Block forever (Gradio runs on background thread).
|
| 131 |
while True:
|
|
|
|
| 92 |
"""Mount KPAA OpenAI-compatible /v1 routes onto demo's FastAPI.
|
| 93 |
|
| 94 |
Called AFTER demo.launch() — demo.app is the live Gradio FastAPI by then.
|
|
|
|
| 95 |
"""
|
| 96 |
from kpaa.server import create_app
|
| 97 |
kpaa_app = create_app()
|
| 98 |
|
|
|
|
|
|
|
| 99 |
n_added = 0
|
| 100 |
skipped = 0
|
| 101 |
for route in kpaa_app.routes:
|
|
|
|
| 102 |
path = getattr(route, "path", None)
|
| 103 |
if path in ("/", None):
|
| 104 |
skipped += 1
|
|
|
|
| 108 |
print(f"[kpaa-backend] attached {n_added} KPAA routes (skipped {skipped})", flush=True)
|
| 109 |
|
| 110 |
|
| 111 |
+
def _attach_split_view() -> None:
|
| 112 |
+
"""`/split` endpoint — Open WebUI iframe + 참고자료 polling 분할 레이아웃.
|
| 113 |
+
|
| 114 |
+
KPAA local 의 _SPLIT_HTML 을 그대로 재사용하되 iframe src 만 UI Space URL 로
|
| 115 |
+
교체. /api/last-references polling 은 같은 origin (backend Space) 에서 받음.
|
| 116 |
+
"""
|
| 117 |
+
from fastapi.responses import HTMLResponse
|
| 118 |
+
|
| 119 |
+
from kpaa.server import _SPLIT_HTML
|
| 120 |
+
|
| 121 |
+
# Local 은 localhost:8080 (Open WebUI), HF 에서는 UI Space URL.
|
| 122 |
+
UI_SPACE_URL = "https://scvcoder-korean-privacy-ai-assistant.hf.space"
|
| 123 |
+
hf_html = _SPLIT_HTML.replace(
|
| 124 |
+
'src="http://localhost:8080/"',
|
| 125 |
+
f'src="{UI_SPACE_URL}"',
|
| 126 |
+
)
|
| 127 |
+
|
| 128 |
+
@demo.app.get("/split", response_class=HTMLResponse)
|
| 129 |
+
async def split_view() -> str:
|
| 130 |
+
return hf_html
|
| 131 |
+
|
| 132 |
+
# 사용자 편의: 루트 접속 시 /split 으로 리다이렉트할까 했지만 Gradio 가
|
| 133 |
+
# / 를 점유하므로 /split 으로 직접 접속하도록 안내.
|
| 134 |
+
print(f"[kpaa-backend] /split route added (UI iframe -> {UI_SPACE_URL})", flush=True)
|
| 135 |
+
|
| 136 |
+
|
| 137 |
if __name__ == "__main__":
|
| 138 |
# Launch Gradio in a non-blocking way so we can patch demo.app afterwards.
|
| 139 |
demo.queue()
|
|
|
|
| 145 |
prevent_thread_lock=True,
|
| 146 |
)
|
| 147 |
|
| 148 |
+
# demo.app is now a live Starlette/FastAPI app — attach KPAA routes + split view.
|
| 149 |
_attach_kpaa_routes()
|
| 150 |
+
_attach_split_view()
|
| 151 |
+
print("[kpaa-backend] ready: Gradio at /, /v1/... API, /split (Open WebUI + 참고자료)", flush=True)
|
| 152 |
|
| 153 |
# Block forever (Gradio runs on background thread).
|
| 154 |
while True:
|