Spaces:
Runtime error
Runtime error
youdie006
commited on
Commit
·
ffe95ea
1
Parent(s):
aa58f77
Fix: compatibility issues
Browse files- Dockerfile +22 -15
- main.py +79 -66
- requirements.txt +7 -32
Dockerfile
CHANGED
|
@@ -1,11 +1,11 @@
|
|
| 1 |
-
# Dockerfile
|
| 2 |
|
| 3 |
FROM python:3.10-slim
|
| 4 |
|
| 5 |
# 메타데이터
|
| 6 |
LABEL maintainer="[email protected]"
|
| 7 |
-
LABEL description="SimSimi AI Agent -
|
| 8 |
-
LABEL version="1.0.
|
| 9 |
|
| 10 |
# 시스템 의존성 설치
|
| 11 |
RUN apt-get update && apt-get install -y \
|
|
@@ -27,7 +27,7 @@ ENV PYTHONPATH=/app
|
|
| 27 |
ENV PYTHONDONTWRITEBYTECODE=1
|
| 28 |
ENV PYTHONUNBUFFERED=1
|
| 29 |
|
| 30 |
-
# Python 의존성 설치
|
| 31 |
COPY requirements.txt .
|
| 32 |
RUN pip install --upgrade pip
|
| 33 |
RUN pip install --no-cache-dir -r requirements.txt
|
|
@@ -39,23 +39,30 @@ COPY . .
|
|
| 39 |
RUN mkdir -p /app/data /app/cache /app/logs /app/static
|
| 40 |
RUN chmod -R 777 /app/data /app/cache /app/logs
|
| 41 |
|
| 42 |
-
#
|
| 43 |
-
RUN
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 48 |
|
| 49 |
# 스마트 시작 스크립트 복사
|
| 50 |
COPY start.sh /app/start.sh
|
| 51 |
RUN chmod +x /app/start.sh
|
| 52 |
|
| 53 |
-
# 포트 노출
|
| 54 |
EXPOSE 7860
|
| 55 |
|
| 56 |
-
# 헬스체크
|
| 57 |
-
HEALTHCHECK --interval=
|
| 58 |
-
CMD curl -f http://localhost:7860/api/v1/health || exit 1
|
| 59 |
|
| 60 |
-
#
|
| 61 |
CMD ["/app/start.sh"]
|
|
|
|
| 1 |
+
# Dockerfile - 에러 대비 안전 버전
|
| 2 |
|
| 3 |
FROM python:3.10-slim
|
| 4 |
|
| 5 |
# 메타데이터
|
| 6 |
LABEL maintainer="[email protected]"
|
| 7 |
+
LABEL description="SimSimi AI Agent - Error-Safe Version"
|
| 8 |
+
LABEL version="1.0.1"
|
| 9 |
|
| 10 |
# 시스템 의존성 설치
|
| 11 |
RUN apt-get update && apt-get install -y \
|
|
|
|
| 27 |
ENV PYTHONDONTWRITEBYTECODE=1
|
| 28 |
ENV PYTHONUNBUFFERED=1
|
| 29 |
|
| 30 |
+
# Python 의존성 설치 (호환성 우선)
|
| 31 |
COPY requirements.txt .
|
| 32 |
RUN pip install --upgrade pip
|
| 33 |
RUN pip install --no-cache-dir -r requirements.txt
|
|
|
|
| 39 |
RUN mkdir -p /app/data /app/cache /app/logs /app/static
|
| 40 |
RUN chmod -R 777 /app/data /app/cache /app/logs
|
| 41 |
|
| 42 |
+
# 🛡️ 안전한 데이터 다운로드 (실패해도 계속 진행)
|
| 43 |
+
RUN echo "🔄 데이터 다운로드 시도 중..." && \
|
| 44 |
+
(huggingface-cli download \
|
| 45 |
+
youdie006/simsimi-ai-agent-data \
|
| 46 |
+
--repo-type dataset \
|
| 47 |
+
--local-dir /app/data \
|
| 48 |
+
--local-dir-use-symlinks False || \
|
| 49 |
+
echo "⚠️ 데이터 다운로드 실패 - 데모 모드로 실행") && \
|
| 50 |
+
echo "✅ 초기화 완료"
|
| 51 |
+
|
| 52 |
+
# 기본 HTML 파일 생성 (정적 파일 대비)
|
| 53 |
+
RUN mkdir -p /app/static && \
|
| 54 |
+
echo '<!DOCTYPE html><html><head><title>마음이 AI</title></head><body><h1>💙 마음이 AI</h1><p>초기화 중...</p></body></html>' > /app/static/index.html
|
| 55 |
|
| 56 |
# 스마트 시작 스크립트 복사
|
| 57 |
COPY start.sh /app/start.sh
|
| 58 |
RUN chmod +x /app/start.sh
|
| 59 |
|
| 60 |
+
# 포트 노출
|
| 61 |
EXPOSE 7860
|
| 62 |
|
| 63 |
+
# 🛡️ 더 관대한 헬스체크
|
| 64 |
+
HEALTHCHECK --interval=60s --timeout=30s --start-period=600s --retries=5 \
|
| 65 |
+
CMD curl -f http://localhost:7860/api/v1/health || curl -f http://localhost:7860/ || exit 1
|
| 66 |
|
| 67 |
+
# 스마트 시작
|
| 68 |
CMD ["/app/start.sh"]
|
main.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
# main.py -
|
| 2 |
|
| 3 |
import os
|
| 4 |
import sys
|
|
@@ -109,6 +109,78 @@ app.add_middleware(
|
|
| 109 |
allow_headers=["*"],
|
| 110 |
)
|
| 111 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 112 |
# 정적 파일 서빙 (환경별)
|
| 113 |
if CONFIG["features"]["static_files"]:
|
| 114 |
try:
|
|
@@ -125,7 +197,7 @@ if CONFIG["features"]["static_files"]:
|
|
| 125 |
except Exception as e:
|
| 126 |
print(f"⚠️ 정적 파일 설정 실패: {e}")
|
| 127 |
|
| 128 |
-
# 라우터 등록 (오류 처리
|
| 129 |
try:
|
| 130 |
from src.api import chat, openai, vector
|
| 131 |
|
|
@@ -135,6 +207,11 @@ try:
|
|
| 135 |
print("✅ API 라우터 등록 완료")
|
| 136 |
except ImportError as e:
|
| 137 |
print(f"⚠️ API 라우터 import 실패: {e}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 138 |
add_demo_routes()
|
| 139 |
|
| 140 |
|
|
@@ -197,70 +274,6 @@ if CONFIG["features"]["debug_routes"]:
|
|
| 197 |
except FileNotFoundError:
|
| 198 |
return {"logs": ["로그 파일이 없습니다."]}
|
| 199 |
|
| 200 |
-
|
| 201 |
-
def create_default_html(file_path: str):
|
| 202 |
-
"""기본 HTML 파일 생성"""
|
| 203 |
-
html_content = get_default_html()
|
| 204 |
-
with open(file_path, "w", encoding="utf-8") as f:
|
| 205 |
-
f.write(html_content)
|
| 206 |
-
|
| 207 |
-
|
| 208 |
-
def get_default_html() -> str:
|
| 209 |
-
"""환경별 기본 HTML 반환"""
|
| 210 |
-
env_emoji = {
|
| 211 |
-
"huggingface": "🤗",
|
| 212 |
-
"local_dev": "🏠",
|
| 213 |
-
"production": "🏭",
|
| 214 |
-
"default": "🔧"
|
| 215 |
-
}
|
| 216 |
-
|
| 217 |
-
return f'''
|
| 218 |
-
<!DOCTYPE html>
|
| 219 |
-
<html lang="ko">
|
| 220 |
-
<head>
|
| 221 |
-
<meta charset="UTF-8">
|
| 222 |
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 223 |
-
<title>마음이 AI | {CONFIG['description']}</title>
|
| 224 |
-
<style>
|
| 225 |
-
body {{ font-family: 'Noto Sans KR', sans-serif; background: #f4f7f6; display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; }}
|
| 226 |
-
.container {{ text-align: center; background: white; padding: 40px; border-radius: 20px; box-shadow: 0 8px 32px rgba(0,0,0,0.1); }}
|
| 227 |
-
.title {{ color: #8A2BE2; font-size: 2rem; margin-bottom: 20px; }}
|
| 228 |
-
.env {{ color: #666; font-size: 1rem; margin-bottom: 15px; }}
|
| 229 |
-
.message {{ color: #666; font-size: 1.1rem; margin-bottom: 30px; }}
|
| 230 |
-
.status {{ padding: 10px 20px; background: #e8f5e8; color: #4a5e4a; border-radius: 8px; display: inline-block; }}
|
| 231 |
-
{"" if not CONFIG['debug'] else ".debug { background: #fff3cd; color: #856404; padding: 10px; border-radius: 5px; margin-top: 20px; }"}
|
| 232 |
-
</style>
|
| 233 |
-
</head>
|
| 234 |
-
<body>
|
| 235 |
-
<div class="container">
|
| 236 |
-
<h1 class="title">💙 마음이 AI</h1>
|
| 237 |
-
<div class="env">{env_emoji.get(ENVIRONMENT, "🔧")} {CONFIG['description']}</div>
|
| 238 |
-
<p class="message">청소년 공감 상담 챗봇이 곧 시작됩니다!</p>
|
| 239 |
-
<div class="status">시스템 초기화 중...</div>
|
| 240 |
-
{"" if not CONFIG['debug'] else '<div class="debug">🔧 개발 모드 - 디버그 정보 활성화</div>'}
|
| 241 |
-
<script>
|
| 242 |
-
setTimeout(() => {{
|
| 243 |
-
window.location.reload();
|
| 244 |
-
}}, 5000);
|
| 245 |
-
</script>
|
| 246 |
-
</div>
|
| 247 |
-
</body>
|
| 248 |
-
</html>
|
| 249 |
-
'''
|
| 250 |
-
|
| 251 |
-
|
| 252 |
-
def add_demo_routes():
|
| 253 |
-
"""데모용 라우터 추가"""
|
| 254 |
-
|
| 255 |
-
@app.post("/api/v1/chat/teen-chat")
|
| 256 |
-
async def demo_chat(request: dict):
|
| 257 |
-
return {
|
| 258 |
-
"response": f"안녕! 마음이가 곧 준비될 예정이야. ({ENVIRONMENT} 환경) 💙",
|
| 259 |
-
"status": "demo_mode",
|
| 260 |
-
"environment": ENVIRONMENT
|
| 261 |
-
}
|
| 262 |
-
|
| 263 |
-
|
| 264 |
# 환경별 실행 (스크립트로 직접 실행할 때)
|
| 265 |
if __name__ == "__main__":
|
| 266 |
import uvicorn
|
|
|
|
| 1 |
+
# main.py - 에러 수정 버전
|
| 2 |
|
| 3 |
import os
|
| 4 |
import sys
|
|
|
|
| 109 |
allow_headers=["*"],
|
| 110 |
)
|
| 111 |
|
| 112 |
+
|
| 113 |
+
def create_default_html(file_path: str):
|
| 114 |
+
"""기본 HTML 파일 생성"""
|
| 115 |
+
html_content = get_default_html()
|
| 116 |
+
with open(file_path, "w", encoding="utf-8") as f:
|
| 117 |
+
f.write(html_content)
|
| 118 |
+
|
| 119 |
+
|
| 120 |
+
def get_default_html() -> str:
|
| 121 |
+
"""환경별 기본 HTML 반환"""
|
| 122 |
+
env_emoji = {
|
| 123 |
+
"huggingface": "🤗",
|
| 124 |
+
"local_dev": "🏠",
|
| 125 |
+
"production": "🏭",
|
| 126 |
+
"default": "🔧"
|
| 127 |
+
}
|
| 128 |
+
|
| 129 |
+
return f'''
|
| 130 |
+
<!DOCTYPE html>
|
| 131 |
+
<html lang="ko">
|
| 132 |
+
<head>
|
| 133 |
+
<meta charset="UTF-8">
|
| 134 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 135 |
+
<title>마음이 AI | {CONFIG['description']}</title>
|
| 136 |
+
<style>
|
| 137 |
+
body {{ font-family: 'Noto Sans KR', sans-serif; background: #f4f7f6; display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; }}
|
| 138 |
+
.container {{ text-align: center; background: white; padding: 40px; border-radius: 20px; box-shadow: 0 8px 32px rgba(0,0,0,0.1); }}
|
| 139 |
+
.title {{ color: #8A2BE2; font-size: 2rem; margin-bottom: 20px; }}
|
| 140 |
+
.env {{ color: #666; font-size: 1rem; margin-bottom: 15px; }}
|
| 141 |
+
.message {{ color: #666; font-size: 1.1rem; margin-bottom: 30px; }}
|
| 142 |
+
.status {{ padding: 10px 20px; background: #e8f5e8; color: #4a5e4a; border-radius: 8px; display: inline-block; }}
|
| 143 |
+
{"" if not CONFIG['debug'] else ".debug { background: #fff3cd; color: #856404; padding: 10px; border-radius: 5px; margin-top: 20px; }"}
|
| 144 |
+
</style>
|
| 145 |
+
</head>
|
| 146 |
+
<body>
|
| 147 |
+
<div class="container">
|
| 148 |
+
<h1 class="title">💙 마음이 AI</h1>
|
| 149 |
+
<div class="env">{env_emoji.get(ENVIRONMENT, "🔧")} {CONFIG['description']}</div>
|
| 150 |
+
<p class="message">청소년 공감 상담 챗봇이 곧 시작됩니다!</p>
|
| 151 |
+
<div class="status">시스템 초기화 중...</div>
|
| 152 |
+
{"" if not CONFIG['debug'] else '<div class="debug">🔧 개발 모드 - 디버그 정보 활성화</div>'}
|
| 153 |
+
<script>
|
| 154 |
+
setTimeout(() => {{
|
| 155 |
+
window.location.reload();
|
| 156 |
+
}}, 5000);
|
| 157 |
+
</script>
|
| 158 |
+
</div>
|
| 159 |
+
</body>
|
| 160 |
+
</html>
|
| 161 |
+
'''
|
| 162 |
+
|
| 163 |
+
|
| 164 |
+
def add_demo_routes():
|
| 165 |
+
"""데모용 라우터 추가 (함수 정의)"""
|
| 166 |
+
|
| 167 |
+
@app.post("/api/v1/chat/teen-chat")
|
| 168 |
+
async def demo_chat(request: dict):
|
| 169 |
+
return {
|
| 170 |
+
"response": f"안녕! 마음이가 곧 준비될 예정이야. ({ENVIRONMENT} 환경) 💙",
|
| 171 |
+
"status": "demo_mode",
|
| 172 |
+
"environment": ENVIRONMENT
|
| 173 |
+
}
|
| 174 |
+
|
| 175 |
+
@app.post("/api/v1/chat/teen-chat-enhanced")
|
| 176 |
+
async def demo_chat_enhanced(request: dict):
|
| 177 |
+
return {
|
| 178 |
+
"response": f"마음이가 준비 중이야! 조금만 기다려줘. ({ENVIRONMENT} 환경) 💙",
|
| 179 |
+
"status": "demo_mode",
|
| 180 |
+
"environment": ENVIRONMENT
|
| 181 |
+
}
|
| 182 |
+
|
| 183 |
+
|
| 184 |
# 정적 파일 서빙 (환경별)
|
| 185 |
if CONFIG["features"]["static_files"]:
|
| 186 |
try:
|
|
|
|
| 197 |
except Exception as e:
|
| 198 |
print(f"⚠️ 정적 파일 설정 실패: {e}")
|
| 199 |
|
| 200 |
+
# 라우터 등록 (오류 처리 강화)
|
| 201 |
try:
|
| 202 |
from src.api import chat, openai, vector
|
| 203 |
|
|
|
|
| 207 |
print("✅ API 라우터 등록 완료")
|
| 208 |
except ImportError as e:
|
| 209 |
print(f"⚠️ API 라우터 import 실패: {e}")
|
| 210 |
+
print("🔄 데모 모드로 실행합니다.")
|
| 211 |
+
add_demo_routes()
|
| 212 |
+
except Exception as e:
|
| 213 |
+
print(f"⚠️ API 라우터 등록 중 예상치 못한 오류: {e}")
|
| 214 |
+
print("🔄 데모 모드로 실행합니다.")
|
| 215 |
add_demo_routes()
|
| 216 |
|
| 217 |
|
|
|
|
| 274 |
except FileNotFoundError:
|
| 275 |
return {"logs": ["로그 파일이 없습니다."]}
|
| 276 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 277 |
# 환경별 실행 (스크립트로 직접 실행할 때)
|
| 278 |
if __name__ == "__main__":
|
| 279 |
import uvicorn
|
requirements.txt
CHANGED
|
@@ -5,15 +5,15 @@ fastapi==0.104.1
|
|
| 5 |
uvicorn[standard]==0.24.0
|
| 6 |
|
| 7 |
# ===========================================
|
| 8 |
-
# 🤖 AI/ML 라이브러리
|
| 9 |
# ===========================================
|
| 10 |
openai==1.3.8
|
|
|
|
|
|
|
|
|
|
| 11 |
sentence-transformers==2.2.2
|
| 12 |
-
torch==2.0.1
|
| 13 |
transformers==4.30.0
|
| 14 |
-
|
| 15 |
-
# 🔧 HuggingFace Hub (호환성 버전 고정)
|
| 16 |
-
huggingface_hub>=0.20.0 # cached_download 지원 마지막 안정 버전
|
| 17 |
|
| 18 |
# ===========================================
|
| 19 |
# 🗄️ Vector Database
|
|
@@ -36,41 +36,16 @@ pandas==2.0.3
|
|
| 36 |
konlpy==0.6.0
|
| 37 |
|
| 38 |
# ===========================================
|
| 39 |
-
# 📊 AI Hub 데이터 처리
|
| 40 |
# ===========================================
|
| 41 |
-
# JSON 스트리밍 처리
|
| 42 |
ijson==3.2.3
|
| 43 |
-
|
| 44 |
-
# 데이터 분석 및 통계
|
| 45 |
scipy==1.11.4
|
| 46 |
scikit-learn==1.3.2
|
| 47 |
-
|
| 48 |
-
# 텍스트 전처리 및 정규식
|
| 49 |
regex==2023.10.3
|
| 50 |
-
|
| 51 |
-
# 날짜/시간 처리
|
| 52 |
python-dateutil==2.8.2
|
| 53 |
|
| 54 |
-
# ===========================================
|
| 55 |
-
# 🔧 개발 및 테스팅 (Docker에서 제외 가능)
|
| 56 |
-
# ===========================================
|
| 57 |
-
# 주석 처리하여 빌드 시간 단축
|
| 58 |
-
# pytest==7.4.3
|
| 59 |
-
# pytest-asyncio==0.21.1
|
| 60 |
-
|
| 61 |
-
# 성능 모니터링 (프로덕션에서만 필요시)
|
| 62 |
-
# psutil==5.9.6
|
| 63 |
-
|
| 64 |
# ===========================================
|
| 65 |
# 🐳 Docker 최적화
|
| 66 |
# ===========================================
|
| 67 |
-
# Gunicorn (프로덕션 배포용)
|
| 68 |
gunicorn==22.0.0
|
| 69 |
-
|
| 70 |
-
# ===========================================
|
| 71 |
-
# 📝 추가 유틸리티
|
| 72 |
-
# ===========================================
|
| 73 |
-
# 환경 변수 관리
|
| 74 |
-
python-decouple==3.8
|
| 75 |
-
|
| 76 |
-
# 참고: uuid, time은 Python 표준 라이브러리 사용
|
|
|
|
| 5 |
uvicorn[standard]==0.24.0
|
| 6 |
|
| 7 |
# ===========================================
|
| 8 |
+
# 🤖 AI/ML 라이브러리 (호환성 수정)
|
| 9 |
# ===========================================
|
| 10 |
openai==1.3.8
|
| 11 |
+
|
| 12 |
+
# 🔧 HuggingFace 라이브러리들 (호환성 고정)
|
| 13 |
+
huggingface_hub==0.17.3 # cached_download 지원 마지막 버전
|
| 14 |
sentence-transformers==2.2.2
|
|
|
|
| 15 |
transformers==4.30.0
|
| 16 |
+
torch==2.0.1
|
|
|
|
|
|
|
| 17 |
|
| 18 |
# ===========================================
|
| 19 |
# 🗄️ Vector Database
|
|
|
|
| 36 |
konlpy==0.6.0
|
| 37 |
|
| 38 |
# ===========================================
|
| 39 |
+
# 📊 AI Hub 데이터 처리
|
| 40 |
# ===========================================
|
|
|
|
| 41 |
ijson==3.2.3
|
|
|
|
|
|
|
| 42 |
scipy==1.11.4
|
| 43 |
scikit-learn==1.3.2
|
|
|
|
|
|
|
| 44 |
regex==2023.10.3
|
|
|
|
|
|
|
| 45 |
python-dateutil==2.8.2
|
| 46 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 47 |
# ===========================================
|
| 48 |
# 🐳 Docker 최적화
|
| 49 |
# ===========================================
|
|
|
|
| 50 |
gunicorn==22.0.0
|
| 51 |
+
python-decouple==3.8
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|