Spaces:
Sleeping
Sleeping
Update app_hf.py
Browse files
app_hf.py
CHANGED
|
@@ -1,14 +1,9 @@
|
|
| 1 |
-
#
|
| 2 |
|
| 3 |
import warnings
|
| 4 |
import os
|
| 5 |
from dotenv import load_dotenv
|
| 6 |
-
from fastapi import FastAPI
|
| 7 |
-
from fastapi.middleware.cors import CORSMiddleware
|
| 8 |
-
from fastapi.responses import RedirectResponse
|
| 9 |
import gradio as gr
|
| 10 |
-
import uvicorn
|
| 11 |
-
from typing import Optional, List
|
| 12 |
|
| 13 |
# .env 파일에서 환경 변수 로드
|
| 14 |
load_dotenv()
|
|
@@ -18,7 +13,7 @@ from prediction import single_prediction
|
|
| 18 |
from chatbot import process_chatbot_query_with_llm
|
| 19 |
from ui import create_ui
|
| 20 |
|
| 21 |
-
# --- API 유틸리티 함수 가져오기 ---
|
| 22 |
from api_utils import (
|
| 23 |
api_get_tide_level,
|
| 24 |
api_get_tide_series,
|
|
@@ -31,55 +26,7 @@ from api_utils import (
|
|
| 31 |
# --- 경고 무시 ---
|
| 32 |
warnings.filterwarnings('ignore')
|
| 33 |
|
| 34 |
-
#
|
| 35 |
-
app = FastAPI(
|
| 36 |
-
title="조위 예측 API",
|
| 37 |
-
description="TimeXer 모델 기반 조위 예측 시스템",
|
| 38 |
-
version="1.0.0",
|
| 39 |
-
)
|
| 40 |
-
|
| 41 |
-
# CORS 설정
|
| 42 |
-
app.add_middleware(
|
| 43 |
-
CORSMiddleware,
|
| 44 |
-
allow_origins=["*"],
|
| 45 |
-
allow_credentials=True,
|
| 46 |
-
allow_methods=["*"],
|
| 47 |
-
allow_headers=["*"],
|
| 48 |
-
)
|
| 49 |
-
|
| 50 |
-
# === 2. API 엔드포인트들 ===
|
| 51 |
-
@app.get("/api/health", tags=["Status"])
|
| 52 |
-
def health():
|
| 53 |
-
"""시스템 상태 확인"""
|
| 54 |
-
return api_health_check()
|
| 55 |
-
|
| 56 |
-
@app.get("/api/tide_level", tags=["Predictions"])
|
| 57 |
-
def get_tide_level(station_id: str, target_time: Optional[str] = None):
|
| 58 |
-
"""특정 시간의 조위 정보 조회"""
|
| 59 |
-
return api_get_tide_level(station_id, target_time)
|
| 60 |
-
|
| 61 |
-
@app.get("/api/tide_series", tags=["Predictions"])
|
| 62 |
-
def get_tide_series(station_id: str, start_time: Optional[str] = None,
|
| 63 |
-
end_time: Optional[str] = None, interval_minutes: int = 60):
|
| 64 |
-
"""시계열 조위 데이터 조회"""
|
| 65 |
-
return api_get_tide_series(station_id, start_time, end_time, interval_minutes)
|
| 66 |
-
|
| 67 |
-
@app.get("/api/extremes", tags=["Predictions"])
|
| 68 |
-
def get_extremes(station_id: str, date: Optional[str] = None, include_secondary: bool = False):
|
| 69 |
-
"""만조/간조 정보 조회"""
|
| 70 |
-
return api_get_extremes_info(station_id, date, include_secondary)
|
| 71 |
-
|
| 72 |
-
@app.get("/api/alert", tags=["Predictions"])
|
| 73 |
-
def check_alert(station_id: str, hours: int = 24, warning_level: float = 700, danger_level: float = 750):
|
| 74 |
-
"""위험 수위 알림 확인"""
|
| 75 |
-
return api_check_tide_alert(station_id, hours, warning_level, danger_level)
|
| 76 |
-
|
| 77 |
-
@app.get("/api/compare", tags=["Predictions"])
|
| 78 |
-
def compare_stations(station_ids: List[str], target_time: Optional[str] = None):
|
| 79 |
-
"""여러 관측소 조위 비교"""
|
| 80 |
-
return api_compare_stations(station_ids, target_time)
|
| 81 |
-
|
| 82 |
-
# === 3. Gradio UI 생성 ===
|
| 83 |
api_handlers = {
|
| 84 |
"health": api_health_check,
|
| 85 |
"tide_level": api_get_tide_level,
|
|
@@ -89,8 +36,13 @@ api_handlers = {
|
|
| 89 |
"compare": api_compare_stations
|
| 90 |
}
|
| 91 |
|
| 92 |
-
|
|
|
|
|
|
|
| 93 |
|
|
|
|
|
|
|
|
|
|
| 94 |
demo = create_ui(
|
| 95 |
prediction_handler=single_prediction,
|
| 96 |
chatbot_handler=process_chatbot_query_with_llm,
|
|
@@ -99,86 +51,18 @@ demo = create_ui(
|
|
| 99 |
|
| 100 |
print("✅ Gradio UI 생성 완료")
|
| 101 |
|
| 102 |
-
#
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
print("🔗 FastAPI + Gradio 통합 모드")
|
| 107 |
-
|
| 108 |
-
# 환경별 Gradio 마운트
|
| 109 |
-
if is_hf_spaces:
|
| 110 |
-
# HF Spaces: 단계적 초기화로 충돌 방지
|
| 111 |
-
print("🔧 HF Spaces 캐시 정리 중...")
|
| 112 |
-
|
| 113 |
-
# 임시 Gradio 실행으로 정적 파일 생성 보장
|
| 114 |
-
try:
|
| 115 |
-
import tempfile
|
| 116 |
-
import time
|
| 117 |
-
temp_interface = gr.Interface(
|
| 118 |
-
fn=lambda x: "cache warming",
|
| 119 |
-
inputs="text",
|
| 120 |
-
outputs="text"
|
| 121 |
-
)
|
| 122 |
-
# 빠른 실행 후 종료로 캐시 워밍업
|
| 123 |
-
temp_interface.launch(
|
| 124 |
-
server_name="127.0.0.1",
|
| 125 |
-
server_port=7861, # 다른 포트 사용
|
| 126 |
-
prevent_thread_lock=True,
|
| 127 |
-
show_error=False,
|
| 128 |
-
quiet=True,
|
| 129 |
-
inbrowser=False
|
| 130 |
-
)
|
| 131 |
-
time.sleep(1) # 1초 대기
|
| 132 |
-
temp_interface.close()
|
| 133 |
-
print("✅ Gradio 캐시 워밍업 완료")
|
| 134 |
-
except Exception as e:
|
| 135 |
-
print(f"⚠️ 캐시 워밍업 실패 (무시): {e}")
|
| 136 |
-
|
| 137 |
-
# 실제 마운트
|
| 138 |
-
app = gr.mount_gradio_app(app, demo, path="/")
|
| 139 |
-
print("✅ HF Spaces: Gradio를 루트(/) 경로에 마운트")
|
| 140 |
-
else:
|
| 141 |
-
# 로컬: /ui 경로에 Gradio 마운트
|
| 142 |
-
app = gr.mount_gradio_app(app, demo, path="/ui")
|
| 143 |
-
print("✅ 로컬: Gradio를 /ui 경로에 마운트")
|
| 144 |
-
|
| 145 |
-
# 로컬에서만 루트 리디렉션
|
| 146 |
-
@app.get("/")
|
| 147 |
-
def redirect_to_ui():
|
| 148 |
-
return RedirectResponse(url="/ui", status_code=302)
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
# HF Spaces를 위한 app export (이 변수가 자동으로 감지됨)
|
| 152 |
-
# HF Spaces에서는 이 app 객체를 직접 사용합니다
|
| 153 |
-
|
| 154 |
-
if is_hf_spaces:
|
| 155 |
-
print("🤗 HF Spaces 환경 - FastAPI + Gradio 외부 노출")
|
| 156 |
-
print("🔗 UI: https://your-space-name.hf.space/ui")
|
| 157 |
-
print("📋 API: https://your-space-name.hf.space/docs")
|
| 158 |
-
|
| 159 |
-
# HF Spaces에서 실행
|
| 160 |
-
if __name__ == "__main__":
|
| 161 |
-
# HF Spaces는 uvicorn을 직접 사용하지 않고 app 객체를 export
|
| 162 |
-
# 하지만 테스트를 위해 여기서도 uvicorn 실행
|
| 163 |
-
uvicorn.run(
|
| 164 |
-
app,
|
| 165 |
-
host="0.0.0.0",
|
| 166 |
-
port=7860
|
| 167 |
-
)
|
| 168 |
-
|
| 169 |
-
else:
|
| 170 |
-
# 로컬 환경
|
| 171 |
-
print("💻 로컬 환경 - FastAPI + Gradio 통합")
|
| 172 |
|
| 173 |
-
|
| 174 |
-
|
| 175 |
-
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
reload=True
|
| 184 |
-
)
|
|
|
|
| 1 |
+
# app_hf_spaces.py - HF Spaces 전용 (Gradio Only)
|
| 2 |
|
| 3 |
import warnings
|
| 4 |
import os
|
| 5 |
from dotenv import load_dotenv
|
|
|
|
|
|
|
|
|
|
| 6 |
import gradio as gr
|
|
|
|
|
|
|
| 7 |
|
| 8 |
# .env 파일에서 환경 변수 로드
|
| 9 |
load_dotenv()
|
|
|
|
| 13 |
from chatbot import process_chatbot_query_with_llm
|
| 14 |
from ui import create_ui
|
| 15 |
|
| 16 |
+
# --- API 유틸리티 함수 가져오기 (UI 내부에서만 사용) ---
|
| 17 |
from api_utils import (
|
| 18 |
api_get_tide_level,
|
| 19 |
api_get_tide_series,
|
|
|
|
| 26 |
# --- 경고 무시 ---
|
| 27 |
warnings.filterwarnings('ignore')
|
| 28 |
|
| 29 |
+
# --- API 핸들러 준비 (UI 내부에서만 사용) ---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
api_handlers = {
|
| 31 |
"health": api_health_check,
|
| 32 |
"tide_level": api_get_tide_level,
|
|
|
|
| 36 |
"compare": api_compare_stations
|
| 37 |
}
|
| 38 |
|
| 39 |
+
# --- HF Spaces 최적화 설정 ---
|
| 40 |
+
os.environ["GRADIO_ANALYTICS_ENABLED"] = "false"
|
| 41 |
+
os.environ["GRADIO_THEME_CACHE"] = "false"
|
| 42 |
|
| 43 |
+
print("🌊 조위 예측 시스템 초기화 중 (HF Spaces 전용)...")
|
| 44 |
+
|
| 45 |
+
# --- Gradio UI 생성 ---
|
| 46 |
demo = create_ui(
|
| 47 |
prediction_handler=single_prediction,
|
| 48 |
chatbot_handler=process_chatbot_query_with_llm,
|
|
|
|
| 51 |
|
| 52 |
print("✅ Gradio UI 생성 완료")
|
| 53 |
|
| 54 |
+
# --- HF Spaces용 실행 ---
|
| 55 |
+
if __name__ == "__main__":
|
| 56 |
+
print("🤗 HF Spaces 조위 예측 시스템 시작")
|
| 57 |
+
print("🔗 https://your-space-name.hf.space")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
|
| 59 |
+
demo.launch(
|
| 60 |
+
server_name="0.0.0.0",
|
| 61 |
+
server_port=7860,
|
| 62 |
+
share=False,
|
| 63 |
+
show_error=True,
|
| 64 |
+
show_api=True,
|
| 65 |
+
# HF Spaces 최적화 설정
|
| 66 |
+
enable_queue=True,
|
| 67 |
+
max_threads=40
|
| 68 |
+
)
|
|
|
|
|
|