jeongsoo's picture
init
6575706
# --- Flask 라우트 μ •μ˜ ---
@app.route('/login', methods=['GET', 'POST'])
def login():
error = None
next_url = request.args.get('next')
logger.info(f"-------------- 둜그인 νŽ˜μ΄μ§€ 접속 (Next: {next_url}) --------------")
logger.info(f"Method: {request.method}")
if request.method == 'POST':
logger.info("둜그인 μ‹œλ„ λ°›μŒ")
username = request.form.get('username', '')
password = request.form.get('password', '')
logger.info(f"μž…λ ₯된 μ‚¬μš©μžλͺ…: {username}")
logger.info(f"λΉ„λ°€λ²ˆν˜Έ μž…λ ₯ μ—¬λΆ€: {len(password) > 0}")
# ν™˜κ²½ λ³€μˆ˜ λ˜λŠ” κΈ°λ³Έκ°’κ³Ό 비ꡐ
valid_username = ADMIN_USERNAME
valid_password = ADMIN_PASSWORD
logger.info(f"κ²€μ¦μš© μ‚¬μš©μžλͺ…: {valid_username}")
logger.info(f"κ²€μ¦μš© λΉ„λ°€λ²ˆν˜Έ 쑴재 μ—¬λΆ€: {valid_password is not None and len(valid_password) > 0}")
if username == valid_username and password == valid_password:
logger.info(f"둜그인 성곡: {username}")
# μ„Έμ…˜ μ„€μ • μ „ ν˜„μž¬ μ„Έμ…˜ μƒνƒœ λ‘œκΉ…
logger.debug(f"μ„Έμ…˜ μ„€μ • μ „: {session}")
# μ„Έμ…˜μ— 둜그인 정보 μ €μž₯
session.permanent = True
session['logged_in'] = True
session['username'] = username
session.modified = True
logger.info(f"μ„Έμ…˜ μ„€μ • ν›„: {session}")
logger.info("μ„Έμ…˜ μ„€μ • μ™„λ£Œ, λ¦¬λ””λ ‰μ…˜ μ‹œλ„")
# 둜그인 성곡 ν›„ λ¦¬λ””λ ‰μ…˜
redirect_to = next_url or url_for('index')
logger.info(f"λ¦¬λ””λ ‰μ…˜ λŒ€μƒ: {redirect_to}")
response = redirect(redirect_to)
return response
else:
logger.warning("둜그인 μ‹€νŒ¨: 아이디 λ˜λŠ” λΉ„λ°€λ²ˆν˜Έ 뢈일치")
if username != valid_username: logger.warning("μ‚¬μš©μžλͺ… 뢈일치")
if password != valid_password: logger.warning("λΉ„λ°€λ²ˆν˜Έ 뢈일치")
error = '아이디 λ˜λŠ” λΉ„λ°€λ²ˆν˜Έκ°€ μ˜¬λ°”λ₯΄μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.'
else:
logger.info("둜그인 νŽ˜μ΄μ§€ GET μš”μ²­")
if 'logged_in' in session:
logger.info("이미 둜그인된 μ‚¬μš©μž, 메인 νŽ˜μ΄μ§€λ‘œ λ¦¬λ””λ ‰μ…˜")
return redirect(url_for('index'))
logger.info("---------- 둜그인 νŽ˜μ΄μ§€ λ Œλ”λ§ ----------")
return render_template('login.html', error=error, next=next_url)
@app.route('/logout')
def logout():
logger.info("-------------- λ‘œκ·Έμ•„μ›ƒ μš”μ²­ --------------")
logger.info(f"λ‘œκ·Έμ•„μ›ƒ μ „ μ„Έμ…˜ μƒνƒœ: {session}")
if 'logged_in' in session:
username = session.get('username', 'unknown')
logger.info(f"μ‚¬μš©μž {username} λ‘œκ·Έμ•„μ›ƒ 처리 μ‹œμž‘")
session.pop('logged_in', None)
session.pop('username', None)
session.modified = True
logger.info(f"μ„Έμ…˜ 정보 μ‚­μ œ μ™„λ£Œ. ν˜„μž¬ μ„Έμ…˜: {session}")
else:
logger.warning("λ‘œκ·ΈμΈλ˜μ§€ μ•Šμ€ μƒνƒœμ—μ„œ λ‘œκ·Έμ•„μ›ƒ μ‹œλ„")
logger.info("둜그인 νŽ˜μ΄μ§€λ‘œ λ¦¬λ””λ ‰μ…˜")
response = redirect(url_for('login'))
return response
@app.route('/')
@login_required
def index():
"""메인 νŽ˜μ΄μ§€"""
global app_ready
# μ•± μ€€λΉ„ μƒνƒœ 확인 - 30초 이상 μ§€λ‚¬μœΌλ©΄ κ°•μ œλ‘œ ready μƒνƒœλ‘œ λ³€κ²½
current_time = datetime.now()
start_time = datetime.fromtimestamp(os.path.getmtime(__file__))
time_diff = (current_time - start_time).total_seconds()
if not app_ready and time_diff > 30:
logger.warning(f"앱이 30초 이상 μ΄ˆκΈ°ν™” 쀑 μƒνƒœμž…λ‹ˆλ‹€. κ°•μ œλ‘œ ready μƒνƒœλ‘œ λ³€κ²½ν•©λ‹ˆλ‹€.")
app_ready = True
if not app_ready:
logger.info("앱이 아직 μ€€λΉ„λ˜μ§€ μ•Šμ•„ λ‘œλ”© νŽ˜μ΄μ§€ ν‘œμ‹œ")
return render_template('loading.html'), 503 # μ„œλΉ„μŠ€ μ€€λΉ„ μ•ˆλ¨ μƒνƒœ μ½”λ“œ
logger.info("메인 νŽ˜μ΄μ§€ μš”μ²­")
return render_template('index.html')
@app.route('/api/status')
@login_required
def app_status():
"""μ•± μ΄ˆκΈ°ν™” μƒνƒœ 확인 API"""
logger.info(f"μ•± μƒνƒœ 확인 μš”μ²­: {'Ready' if app_ready else 'Not Ready'}")
return jsonify({"ready": app_ready})
@app.route('/api/llm', methods=['GET', 'POST'])
@login_required
def llm_api():
"""μ‚¬μš© κ°€λŠ₯ν•œ LLM λͺ©λ‘ 및 선택 API"""
global llm_interface
if not app_ready:
return jsonify({"error": "앱이 아직 μ΄ˆκΈ°ν™” μ€‘μž…λ‹ˆλ‹€. μž μ‹œ ν›„ λ‹€μ‹œ μ‹œλ„ν•΄μ£Όμ„Έμš”."}), 503
if request.method == 'GET':
logger.info("LLM λͺ©λ‘ μš”μ²­")
try:
current_details = llm_interface.get_current_llm_details() if hasattr(llm_interface, 'get_current_llm_details') else {"id": "unknown", "name": "Unknown"}
supported_llms_dict = llm_interface.SUPPORTED_LLMS if hasattr(llm_interface, 'SUPPORTED_LLMS') else {}
supported_list = [{
"name": name, "id": id, "current": id == current_details.get("id")
} for name, id in supported_llms_dict.items()]
return jsonify({
"supported_llms": supported_list,
"current_llm": current_details
})
except Exception as e:
logger.error(f"LLM 정보 쑰회 였λ₯˜: {e}")
return jsonify({"error": "LLM 정보 쑰회 쀑 였λ₯˜ λ°œμƒ"}), 500
elif request.method == 'POST':
data = request.get_json()
if not data or 'llm_id' not in data:
return jsonify({"error": "LLM IDκ°€ μ œκ³΅λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€."}), 400
llm_id = data['llm_id']
logger.info(f"LLM λ³€κ²½ μš”μ²­: {llm_id}")
try:
if not hasattr(llm_interface, 'set_llm') or not hasattr(llm_interface, 'llm_clients'):
raise NotImplementedError("LLM μΈν„°νŽ˜μ΄μŠ€μ— ν•„μš”ν•œ λ©”μ†Œλ“œ/속성 μ—†μŒ")
if llm_id not in llm_interface.llm_clients:
return jsonify({"error": f"μ§€μ›λ˜μ§€ μ•ŠλŠ” LLM ID: {llm_id}"}), 400
success = llm_interface.set_llm(llm_id)
if success:
new_details = llm_interface.get_current_llm_details()
logger.info(f"LLM이 '{new_details.get('name', llm_id)}'둜 λ³€κ²½λ˜μ—ˆμŠ΅λ‹ˆλ‹€.")
return jsonify({
"success": True,
"message": f"LLM이 '{new_details.get('name', llm_id)}'둜 λ³€κ²½λ˜μ—ˆμŠ΅λ‹ˆλ‹€.",
"current_llm": new_details
})
else:
logger.error(f"LLM λ³€κ²½ μ‹€νŒ¨ (ID: {llm_id})")
return jsonify({"error": "LLM λ³€κ²½ 쀑 λ‚΄λΆ€ 였λ₯˜ λ°œμƒ"}), 500
except Exception as e:
logger.error(f"LLM λ³€κ²½ 처리 쀑 였λ₯˜: {e}", exc_info=True)
return jsonify({"error": f"LLM λ³€κ²½ 쀑 였λ₯˜ λ°œμƒ: {str(e)}"}), 500