scvcoder commited on
Commit
cce074d
·
verified ·
1 Parent(s): 2c4f582

Hide demo inside main() to avoid HF auto-launch port conflict

Browse files
Files changed (1) hide show
  1. app.py +34 -45
app.py CHANGED
@@ -2,9 +2,8 @@
2
 
3
  This Space is the inference backend. It exposes:
4
  - POST /v1/chat/completions (OpenAI-compatible, streaming)
5
- - GET /v1/models
6
- - GET /healthz / /info
7
- - GET /gradio (minimal status page; Gradio SDK detection)
8
 
9
  UI (Open WebUI) is hosted at a separate Space which points its
10
  OPENAI_API_BASE_URL to this Space's /v1.
@@ -23,10 +22,6 @@ sys.path.insert(0, str(Path(__file__).resolve().parent / "src"))
23
 
24
 
25
  # ─── monkey-patch: gradio_client `/api_info` schema bug ────────────────────
26
- # Gradio 5.x 의 gradio_client.utils 는 JSON Schema 의 `additionalProperties: True`
27
- # (bool, 합법적 형식) 를 dict 로만 가정해서 TypeError 를 낸다. 이 백엔드는
28
- # Gradio UI 자체를 사용자에게 노출하지 않지만 Gradio 가 mount 되어 있어
29
- # /api_info 가 호출될 가능성이 있으므로 안전 패치.
30
  import gradio_client.utils as _gc_utils # noqa: E402
31
 
32
  _orig_get_type = _gc_utils.get_type
@@ -50,10 +45,7 @@ _gc_utils._json_schema_to_python_type = _safe_jstpt
50
  # ──────────────────────────────────────────────────────────────────────────
51
 
52
 
53
- # ─── HF Spaces ZeroGPU startup canary ─────────────────────────────────────
54
- # ZeroGPU 는 startup 시점에 module-level `@spaces.GPU` 함수가 적어도 하나 검출되어야
55
- # GPU 스케줄을 잡는다. 실제 GPU 작업은 ZeroGPUBackend.stream_chat 안에서 동적으로
56
- # 데코레이트되지만 startup 스캔에서 안 보이므로 sentinel 추가.
57
  try:
58
  import spaces # type: ignore[import-not-found]
59
 
@@ -65,48 +57,45 @@ except ImportError:
65
  # ──────────────────────────────────────────────────────────────────────────
66
 
67
 
68
- import gradio as gr # noqa: E402
69
-
70
- from kpaa.server import create_app # noqa: E402
71
-
72
-
73
- # Build the FastAPI app from KPAA's existing OpenAI-compatible server.
74
- fastapi_app = create_app()
75
-
76
-
77
- # Build a minimal Gradio status page so HF Spaces 에 "Gradio app" 으로 인식되고,
78
- # 사용자가 backend URL 에 접속해도 친절한 안내 페이지가 나오도록 함.
79
- with gr.Blocks(title="KPAA Backend", theme=gr.themes.Soft()) as demo:
80
- gr.Markdown(
81
- """
82
- # 🧠 KPAA Backend — 개인정보보호법 RAG 추론 서버
83
 
84
- 한국 개인정보보호법 RAG 백엔드. **OpenAI 호환 API**.
85
- UI 는 별도 Space (`scvcoder/korean-privacy-ai-assistant`) 의 Open WebUI 가 제공합니다.
86
 
87
- ## API Endpoints
88
 
89
- - **POST** `/v1/chat/completions` — OpenAI 호환 chat (스트리밍 지원)
90
- - **GET** `/v1/models` — 모델 목록 (`kpaa-privacy-ko`)
91
- - **GET** `/healthz` — health check
92
- - **GET** `/info`상세 정보 / Swagger UI 링크
93
 
94
- ## 외부 연동
95
- Open WebUI 등에 OpenAI provider 등록:
96
- - **URL** `https://scvcoder-kpaa-backend.hf.space/v1`
97
- - **Key** any (인증 없음)
98
- - **Model** `kpaa-privacy-ko`
99
- """
100
- )
101
 
102
- # Mount the Gradio Blocks at /gradio. The FastAPI routes (/v1/..., /healthz, ...)
103
- # remain at the root.
104
- final_app = gr.mount_gradio_app(fastapi_app, demo, path="/gradio")
105
 
 
 
 
 
106
 
107
- def main() -> None:
108
- import uvicorn
 
 
 
 
 
109
 
 
110
  port = int(os.environ.get("PORT", "7860"))
111
  uvicorn.run(final_app, host="0.0.0.0", port=port)
112
 
 
2
 
3
  This Space is the inference backend. It exposes:
4
  - POST /v1/chat/completions (OpenAI-compatible, streaming)
5
+ - GET /v1/models / /healthz / /info
6
+ - GET /gradio (minimal status page)
 
7
 
8
  UI (Open WebUI) is hosted at a separate Space which points its
9
  OPENAI_API_BASE_URL to this Space's /v1.
 
22
 
23
 
24
  # ─── monkey-patch: gradio_client `/api_info` schema bug ────────────────────
 
 
 
 
25
  import gradio_client.utils as _gc_utils # noqa: E402
26
 
27
  _orig_get_type = _gc_utils.get_type
 
45
  # ──────────────────────────────────────────────────────────────────────────
46
 
47
 
48
+ # ─── HF Spaces ZeroGPU startup canary (module-level required) ─────────────
 
 
 
49
  try:
50
  import spaces # type: ignore[import-not-found]
51
 
 
57
  # ──────────────────────────────────────────────────────────────────────────
58
 
59
 
60
+ def main() -> None:
61
+ """Build app and run uvicorn.
62
+
63
+ Gradio Blocks (`demo`) is built INSIDE this function — not at module level —
64
+ so HF Spaces' Gradio SDK auto-launcher cannot detect it and call
65
+ `demo.launch()` separately (which would bind a second port and conflict
66
+ with our uvicorn on 7860).
67
+ """
68
+ import gradio as gr
69
+ import uvicorn
 
 
 
 
 
70
 
71
+ from kpaa.server import create_app
 
72
 
73
+ fastapi_app = create_app()
74
 
75
+ with gr.Blocks(title="KPAA Backend", theme=gr.themes.Soft()) as demo:
76
+ gr.Markdown(
77
+ """
78
+ # 🧠 KPAA Backend 개인정보보호법 RAG 추론 서버
79
 
80
+ 한국 개인정보보호법 RAG 백엔드. **OpenAI 호환 API**.
81
+ UI 별도 Space (`scvcoder/korean-privacy-ai-assistant`) Open WebUI 가 제공합니다.
 
 
 
 
 
82
 
83
+ ## API Endpoints
 
 
84
 
85
+ - **POST** `/v1/chat/completions` — OpenAI 호환 chat (스트리밍 지원)
86
+ - **GET** `/v1/models` — 모델 목록 (`kpaa-privacy-ko`)
87
+ - **GET** `/healthz` — health check
88
+ - **GET** `/info` — 상세 정보 / Swagger UI
89
 
90
+ ## 외부 연동
91
+ Open WebUI 등에 OpenAI provider 로 등록:
92
+ - **URL** `https://scvcoder-kpaa-backend.hf.space/v1`
93
+ - **Key** any (인증 없음)
94
+ - **Model** `kpaa-privacy-ko`
95
+ """
96
+ )
97
 
98
+ final_app = gr.mount_gradio_app(fastapi_app, demo, path="/gradio")
99
  port = int(os.environ.get("PORT", "7860"))
100
  uvicorn.run(final_app, host="0.0.0.0", port=port)
101