Spaces:
Sleeping
Sleeping
""" | |
RAG κ²μ μ±λ΄ μΉ μ ν리μΌμ΄μ - μ₯μΉ κ΄λ¦¬ API λΌμ°νΈ μ μ (API κ²½λ‘ μμ λ¨) | |
""" | |
import logging | |
import requests | |
from flask import request, jsonify | |
# λ‘κ±° κ°μ Έμ€κΈ° | |
logger = logging.getLogger(__name__) | |
def register_device_routes(app, login_required, DEVICE_SERVER_URL): | |
"""Flask μ ν리μΌμ΄μ μ μ₯μΉ κ΄λ¦¬ κ΄λ ¨ λΌμ°νΈ λ±λ‘""" | |
# μ¬μ©μ μ§μ μ₯μΉ μλ² URL λ³μ | |
custom_device_url = None | |
# URL μ€μ ν¨μ | |
def get_device_url(): | |
# μ¬μ©μ μ§μ URLμ΄ μμΌλ©΄ μ¬μ©, μμΌλ©΄ νκ²½λ³μ κ° μ¬μ© | |
return custom_device_url or DEVICE_SERVER_URL | |
def connect_device_server(): | |
"""μ¬μ©μ μ§μ μ₯μΉ μλ² URL μ°κ²° API""" | |
nonlocal custom_device_url # μμ μ€μ½νμ λ³μ μ°Έμ‘° | |
try: | |
# μμ²μμ URL κ°μ Έμ€κΈ° | |
request_data = request.get_json() | |
if not request_data or 'url' not in request_data: | |
logger.error("URLμ΄ μ 곡λμ§ μμμ΅λλ€.") | |
return jsonify({ | |
"success": False, | |
"error": "URLμ΄ μ 곡λμ§ μμμ΅λλ€." | |
}), 400 # Bad Request | |
new_url = request_data['url'].strip() | |
if not new_url: | |
logger.error("URLμ΄ λΉμ΄ μμ΅λλ€.") | |
return jsonify({ | |
"success": False, | |
"error": "URLμ΄ λΉμ΄ μμ΅λλ€." | |
}), 400 # Bad Request | |
# URL μ€μ | |
logger.info(f"μ¬μ©μ μ§μ μ₯μΉ μλ² URL μ€μ : {new_url}") | |
custom_device_url = new_url | |
# μ€μ λ URLλ‘ μν νμΈ μλ | |
try: | |
api_path = "/api/status" | |
logger.info(f"μ₯μΉ μλ² μν νμΈ μμ²: {custom_device_url}{api_path}") | |
response = requests.get(f"{custom_device_url}{api_path}", timeout=5) | |
if response.status_code == 200: | |
try: | |
data = response.json() | |
logger.info(f"μ¬μ©μ μ§μ μ₯μΉ μλ² μ°κ²° μ±κ³΅. μλ΅ λ°μ΄ν°: {data}") | |
return jsonify({ | |
"success": True, | |
"message": "μ₯μΉ μλ² μ°κ²°μ μ±κ³΅νμ΅λλ€.", | |
"server_status": data.get("status", "μ μ") | |
}) | |
except requests.exceptions.JSONDecodeError: | |
logger.error("μ₯μΉ μλ² μλ΅ JSON νμ± μ€ν¨") | |
return jsonify({ | |
"success": False, | |
"error": "μ₯μΉ μλ²λ‘λΆν° μ ν¨νμ§ μμ JSON μλ΅μ λ°μμ΅λλ€." | |
}), 502 # Bad Gateway | |
else: | |
error_message = f"μ₯μΉ μλ² μλ΅ μ€λ₯: {response.status_code}" | |
try: | |
error_detail = response.json().get("error", response.text) | |
error_message += f" - {error_detail}" | |
except Exception: | |
error_message += f" - {response.text}" | |
logger.warning(error_message) | |
custom_device_url = None # μ°κ²° μ€ν¨ μ URL μ΄κΈ°ν | |
return jsonify({ | |
"success": False, | |
"error": error_message | |
}), 502 # Bad Gateway | |
except requests.exceptions.Timeout: | |
logger.error(f"μ₯μΉ μλ² μ°κ²° νμμμ ({custom_device_url})") | |
custom_device_url = None # μ°κ²° μ€ν¨ μ URL μ΄κΈ°ν | |
return jsonify({ | |
"success": False, | |
"error": "μ₯μΉ μλ² μ°κ²° νμμμ. μλ² μλ΅μ΄ λ무 λ립λλ€." | |
}), 504 # Gateway Timeout | |
except requests.exceptions.ConnectionError: | |
logger.error(f"μ₯μΉ κ΄λ¦¬ μλ² μ°κ²° μ€ν¨ ({custom_device_url})") | |
custom_device_url = None # μ°κ²° μ€ν¨ μ URL μ΄κΈ°ν | |
return jsonify({ | |
"success": False, | |
"error": "μ₯μΉ κ΄λ¦¬ μλ²μ μ°κ²°ν μ μμ΅λλ€. μλ²κ° μ€ν μ€μΈμ§, URLμ΄ μ ννμ§ νμΈν΄μ£ΌμΈμ." | |
}), 502 # Bad Gateway | |
except Exception as e: | |
logger.error(f"μ₯μΉ μλ² μ°κ²° μ€ μμμΉ λͺ»ν μ€λ₯ λ°μ: {e}", exc_info=True) | |
custom_device_url = None # μ°κ²° μ€ν¨ μ URL μ΄κΈ°ν | |
return jsonify({ | |
"success": False, | |
"error": f"μ₯μΉ μλ² μ°κ²° μ€ μ€λ₯ λ°μ: {str(e)}" | |
}), 500 # Internal Server Error | |
except Exception as e: | |
logger.error(f"/api/device/connect μ²λ¦¬ μ€ λ΄λΆ μλ² μ€λ₯: {e}", exc_info=True) | |
return jsonify({ | |
"success": False, | |
"error": f"λ΄λΆ μλ² μ€λ₯ λ°μ: {str(e)}" | |
}), 500 # Internal Server Error | |
def device_status(): | |
"""μ₯μΉ κ΄λ¦¬ μλ²μ μνλ₯Ό νμΈνλ API μλν¬μΈνΈ""" | |
try: | |
# requests λΌμ΄λΈλ¬λ¦¬λ ν¨μ λ΄μμ μν¬νΈν νμ μμ (μλ¨ μν¬νΈ μ¬μ©) | |
# json, jsonifyλ Flaskμμ μ΄λ―Έ μν¬νΈλ¨ (μλ¨ μν¬νΈ μ¬μ©) | |
# μ°κ²° νμμμ μ€μ | |
timeout = 5 # 5μ΄λ‘ νμμμ μ€μ | |
try: | |
# μ₯μΉ μλ² μν νμΈ - κ²½λ‘: /api/status | |
current_device_url = get_device_url() | |
api_path = "/api/status" | |
logger.info(f"μ₯μΉ μλ² μν νμΈ μμ²: {current_device_url}{api_path}") | |
response = requests.get(f"{current_device_url}{api_path}", timeout=timeout) | |
# μλ΅ μν μ½λ λ° λ΄μ© λ‘κΉ (λλ²κΉ κ°ν) | |
logger.debug(f"μ₯μΉ μλ² μλ΅ μν μ½λ: {response.status_code}") | |
try: | |
logger.debug(f"μ₯μΉ μλ² μλ΅ λ΄μ©: {response.text[:200]}...") # λ무 κΈΈλ©΄ μλΌμ λ‘κΉ | |
except Exception: | |
logger.debug("μ₯μΉ μλ² μλ΅ λ΄μ© λ‘κΉ μ€ν¨ (ν μ€νΈ νμ μλ?)") | |
if response.status_code == 200: | |
# μ±κ³΅ μ μλ΅ λ°μ΄ν° ꡬ쑰 νμΈ λ° λ‘κΉ | |
try: | |
data = response.json() | |
logger.info(f"μ₯μΉ μλ² μν νμΈ μ±κ³΅. μλ΅ λ°μ΄ν°: {data}") | |
return jsonify({"success": True, "status": "connected", "data": data}) | |
except requests.exceptions.JSONDecodeError: | |
logger.error("μ₯μΉ μλ² μλ΅ JSON νμ± μ€ν¨") | |
return jsonify({ | |
"success": False, | |
"error": "μ₯μΉ μλ²λ‘λΆν° μ ν¨νμ§ μμ JSON μλ΅μ λ°μμ΅λλ€." | |
}), 502 # Bad Gateway (μ μ€νΈλ¦Ό μλ² μ€λ₯) | |
else: | |
# μ€ν¨ μ μ€λ₯ λ©μμ§ ν¬ν¨ λ‘κΉ | |
error_message = f"μ₯μΉ μλ² μλ΅ μ€λ₯: {response.status_code}" | |
try: | |
# μλ²μμ μ€λ₯ λ©μμ§λ₯Ό jsonμΌλ‘ 보λ΄λ κ²½μ° ν¬ν¨ | |
error_detail = response.json().get("error", response.text) | |
error_message += f" - {error_detail}" | |
except Exception: | |
error_message += f" - {response.text}" # JSON νμ± μ€ν¨ μ μλ³Έ ν μ€νΈ | |
logger.warning(error_message) # κ²½κ³ λ λ²¨λ‘ λ‘κΉ | |
return jsonify({ | |
"success": False, | |
"error": error_message | |
}), 502 # Bad Gateway | |
except requests.exceptions.Timeout: | |
logger.error(f"μ₯μΉ μλ² μ°κ²° νμμμ ({DEVICE_SERVER_URL})") | |
return jsonify({ | |
"success": False, | |
"error": "μ₯μΉ μλ² μ°κ²° νμμμ. μλ² μλ΅μ΄ λ무 λ립λλ€." | |
}), 504 # Gateway Timeout | |
except requests.exceptions.ConnectionError: | |
current_device_url = get_device_url() | |
logger.error(f"μ₯μΉ κ΄λ¦¬ μλ² μ°κ²° μ€ν¨ ({current_device_url})") | |
return jsonify({ | |
"success": False, | |
"error": "μ₯μΉ κ΄λ¦¬ μλ²μ μ°κ²°ν μ μμ΅λλ€. μλ²κ° μ€ν μ€μΈμ§, URLμ΄ μ ννμ§ νμΈν΄μ£ΌμΈμ." | |
}), 502 # Bad Gateway (μ°κ²° μ€ν¨λ μ μ€νΈλ¦Ό λ¬Έμ λ‘ κ°μ£Ό) | |
except Exception as e: | |
logger.error(f"μ₯μΉ μλ² μ°κ²° μ€ μμμΉ λͺ»ν μ€λ₯ λ°μ: {e}", exc_info=True) # μμΈ μ€ν νΈλ μ΄μ€ λ‘κΉ | |
return jsonify({ | |
"success": False, | |
"error": f"μ₯μΉ μλ² μ°κ²° μ€ μ€λ₯ λ°μ: {str(e)}" | |
}), 500 # Internal Server Error (Flask μ± λ΄λΆ λλ requests λΌμ΄λΈλ¬λ¦¬ λ¬Έμ κ°λ₯μ±) | |
except Exception as e: | |
# μ΄ try-except λΈλ‘μ /api/device/status λΌμ°νΈ μ체μ λ΄λΆ μ€λ₯ μ²λ¦¬ | |
logger.error(f"/api/device/status μ²λ¦¬ μ€ λ΄λΆ μλ² μ€λ₯: {e}", exc_info=True) | |
return jsonify({ | |
"success": False, | |
"error": f"λ΄λΆ μλ² μ€λ₯ λ°μ: {str(e)}" | |
}), 500 # Internal Server Error | |
def device_list(): | |
"""μ₯μΉ λͺ©λ‘ μ‘°ν API""" | |
logger.info("μ₯μΉ λͺ©λ‘ μ‘°ν μμ²") | |
try: | |
current_device_url = get_device_url() | |
api_path = "/api/devices" | |
logger.info(f"μ₯μΉ λͺ©λ‘ μ‘°ν μμ²: {current_device_url}{api_path}") | |
response = requests.get(f"{current_device_url}{api_path}", timeout=5) | |
logger.debug(f"μ₯μΉ λͺ©λ‘ μλ΅ μν μ½λ: {response.status_code}") | |
if response.status_code == 200: | |
try: | |
data = response.json() | |
devices = data.get("devices", []) | |
logger.info(f"μ₯μΉ λͺ©λ‘ μ‘°ν μ±κ³΅: {len(devices)}κ° μ₯μΉ") | |
return jsonify({ | |
"success": True, | |
"devices": devices | |
}) | |
except requests.exceptions.JSONDecodeError: | |
logger.error("μ₯μΉ λͺ©λ‘ μλ΅ JSON νμ± μ€ν¨") | |
return jsonify({"success": False, "error": "μ₯μΉ μλ²λ‘λΆν° μ ν¨νμ§ μμ JSON μλ΅"}), 502 | |
else: | |
error_message = f"μ₯μΉ λͺ©λ‘ μ‘°ν μ€ν¨: {response.status_code}" | |
try: error_message += f" - {response.json().get('error', response.text)}" | |
except Exception: error_message += f" - {response.text}" | |
logger.warning(error_message) | |
return jsonify({ | |
"success": False, | |
"error": error_message | |
}), 502 | |
except requests.exceptions.Timeout: | |
logger.error("μ₯μΉ λͺ©λ‘ μ‘°ν μκ° μ΄κ³Ό") | |
return jsonify({ | |
"success": False, | |
"error": "μ₯μΉ λͺ©λ‘ μ‘°ν μκ°μ΄ μ΄κ³Όλμμ΅λλ€." | |
}), 504 | |
except requests.exceptions.ConnectionError: | |
logger.error("μ₯μΉ κ΄λ¦¬ μλ² μ°κ²° μ€ν¨") | |
return jsonify({ | |
"success": False, | |
"error": "μ₯μΉ κ΄λ¦¬ μλ²μ μ°κ²°ν μ μμ΅λλ€. μλ²κ° μ€ν μ€μΈμ§ νμΈν΄μ£ΌμΈμ." | |
}), 503 # Service Unavailable | |
except Exception as e: | |
logger.error(f"μ₯μΉ λͺ©λ‘ μ‘°ν μ€ μ€λ₯ λ°μ: {e}", exc_info=True) | |
return jsonify({ | |
"success": False, | |
"error": f"μ₯μΉ λͺ©λ‘ μ‘°ν μ€ μ€λ₯ λ°μ: {str(e)}" | |
}), 500 | |
def device_programs(): | |
"""μ€ν κ°λ₯ν νλ‘κ·Έλ¨ λͺ©λ‘ μ‘°ν API""" | |
logger.info("νλ‘κ·Έλ¨ λͺ©λ‘ μ‘°ν μμ²") | |
try: | |
current_device_url = get_device_url() | |
api_path = "/api/programs" | |
logger.info(f"νλ‘κ·Έλ¨ λͺ©λ‘ μ‘°ν μμ²: {current_device_url}{api_path}") | |
response = requests.get(f"{current_device_url}{api_path}", timeout=5) | |
logger.debug(f"νλ‘κ·Έλ¨ λͺ©λ‘ μλ΅ μν μ½λ: {response.status_code}") | |
if response.status_code == 200: | |
try: | |
data = response.json() | |
programs = data.get("programs", []) | |
logger.info(f"νλ‘κ·Έλ¨ λͺ©λ‘ μ‘°ν μ±κ³΅: {len(programs)}κ° νλ‘κ·Έλ¨") | |
return jsonify({ | |
"success": True, | |
"programs": programs | |
}) | |
except requests.exceptions.JSONDecodeError: | |
logger.error("νλ‘κ·Έλ¨ λͺ©λ‘ μλ΅ JSON νμ± μ€ν¨") | |
return jsonify({"success": False, "error": "μ₯μΉ μλ²λ‘λΆν° μ ν¨νμ§ μμ JSON μλ΅"}), 502 | |
else: | |
error_message = f"νλ‘κ·Έλ¨ λͺ©λ‘ μ‘°ν μ€ν¨: {response.status_code}" | |
try: error_message += f" - {response.json().get('error', response.text)}" | |
except Exception: error_message += f" - {response.text}" | |
logger.warning(error_message) | |
return jsonify({ | |
"success": False, | |
"error": error_message | |
}), 502 | |
except requests.exceptions.Timeout: | |
logger.error("νλ‘κ·Έλ¨ λͺ©λ‘ μ‘°ν μκ° μ΄κ³Ό") | |
return jsonify({ | |
"success": False, | |
"error": "νλ‘κ·Έλ¨ λͺ©λ‘ μ‘°ν μκ°μ΄ μ΄κ³Όλμμ΅λλ€." | |
}), 504 | |
except requests.exceptions.ConnectionError: | |
logger.error("μ₯μΉ κ΄λ¦¬ μλ² μ°κ²° μ€ν¨") | |
return jsonify({ | |
"success": False, | |
"error": "μ₯μΉ κ΄λ¦¬ μλ²μ μ°κ²°ν μ μμ΅λλ€. μλ²κ° μ€ν μ€μΈμ§ νμΈν΄μ£ΌμΈμ." | |
}), 503 | |
except Exception as e: | |
logger.error(f"νλ‘κ·Έλ¨ λͺ©λ‘ μ‘°ν μ€ μ€λ₯ λ°μ: {e}", exc_info=True) | |
return jsonify({ | |
"success": False, | |
"error": f"νλ‘κ·Έλ¨ λͺ©λ‘ μ‘°ν μ€ μ€λ₯ λ°μ: {str(e)}" | |
}), 500 | |
def execute_program(program_id): | |
"""νλ‘κ·Έλ¨ μ€ν API""" | |
logger.info(f"νλ‘κ·Έλ¨ μ€ν μμ²: {program_id}") | |
try: | |
current_device_url = get_device_url() | |
api_path = f"/api/programs/{program_id}/execute" | |
logger.info(f"νλ‘κ·Έλ¨ μ€ν μμ²: {current_device_url}{api_path}") | |
response = requests.post( | |
f"{current_device_url}{api_path}", | |
json={}, # νμμ μ¬κΈ°μ νλΌλ―Έν° μΆκ° κ°λ₯ | |
timeout=10 # νλ‘κ·Έλ¨ μ€νμλ λ κΈ΄ μκ° λΆμ¬ | |
) | |
logger.debug(f"νλ‘κ·Έλ¨ μ€ν μλ΅ μν μ½λ: {response.status_code}") | |
if response.status_code == 200: | |
try: | |
data = response.json() | |
success = data.get("success", False) | |
message = data.get("message", "") | |
logger.info(f"νλ‘κ·Έλ¨ μ€ν μλ΅: {success}, {message}") | |
return jsonify(data) # μλ² μλ΅ κ·Έλλ‘ λ°ν | |
except requests.exceptions.JSONDecodeError: | |
logger.error("νλ‘κ·Έλ¨ μ€ν μλ΅ JSON νμ± μ€ν¨") | |
# μ±κ³΅(200)νμ§λ§ μλ΅μ΄ λΉμ μμ μΈ κ²½μ° | |
return jsonify({ | |
"success": False, # νμ± μ€ν¨νμΌλ―λ‘ Falseλ‘ κ°μ£Ό | |
"error": "νλ‘κ·Έλ¨ μ€ν μλ²λ‘λΆν° μ ν¨νμ§ μμ JSON μλ΅" | |
}), 502 | |
else: | |
error_message = f"νλ‘κ·Έλ¨ μ€ν μμ² μ€ν¨: {response.status_code}" | |
try: error_message += f" - {response.json().get('error', response.text)}" | |
except Exception: error_message += f" - {response.text}" | |
logger.warning(error_message) | |
return jsonify({ | |
"success": False, | |
"error": error_message | |
}), 502 # λλ response.status_code λ₯Ό κ·Έλλ‘ λ°ννλ κ²λ κ³ λ € | |
except requests.exceptions.Timeout: | |
logger.error("νλ‘κ·Έλ¨ μ€ν μμ² μκ° μ΄κ³Ό") | |
return jsonify({ | |
"success": False, | |
"error": "νλ‘κ·Έλ¨ μ€ν μμ² μκ°μ΄ μ΄κ³Όλμμ΅λλ€." | |
}), 504 | |
except requests.exceptions.ConnectionError: | |
logger.error("μ₯μΉ κ΄λ¦¬ μλ² μ°κ²° μ€ν¨") | |
return jsonify({ | |
"success": False, | |
"error": "μ₯μΉ κ΄λ¦¬ μλ²μ μ°κ²°ν μ μμ΅λλ€. μλ²κ° μ€ν μ€μΈμ§ νμΈν΄μ£ΌμΈμ." | |
}), 503 | |
except Exception as e: | |
logger.error(f"νλ‘κ·Έλ¨ μ€ν μ€ μ€λ₯ λ°μ: {e}", exc_info=True) | |
return jsonify({ | |
"success": False, | |
"error": f"νλ‘κ·Έλ¨ μ€ν μ€ μ€λ₯ λ°μ: {str(e)}" | |
}), 500 |