Spaces:
Sleeping
Sleeping
| import os | |
| import gradio as gr | |
| import json | |
| import logging | |
| from app.app import app as flask_app # Flask ์ฑ ๊ฐ์ ธ์ค๊ธฐ | |
| from flask import json as flask_json | |
| from retrying import retry | |
| # ๋ก๊ฑฐ ์ค์ | |
| logging.basicConfig( | |
| format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', | |
| level=logging.DEBUG # INFO์์ DEBUG๋ก ๋ณ๊ฒฝํ์ฌ ๋ ์์ธํ ๋ก๊ทธ ํ์ธ | |
| ) | |
| logger = logging.getLogger(__name__) | |
| # Flask ํ ์คํธ ํด๋ผ์ด์ธํธ ์ด๊ธฐํ | |
| def init_flask_client(): | |
| """๋ฐฑ๊ทธ๋ผ์ด๋ ์คํ Flask ์๋ฒ์ ์ฐ๊ฒฐํ๋ ํด๋ผ์ด์ธํธ ์ด๊ธฐํ""" | |
| try: | |
| test_client = flask_app.test_client() | |
| logger.info("Flask ํ ์คํธ ํด๋ผ์ด์ธํธ ์ด๊ธฐํ ์ฑ๊ณต") | |
| return test_client | |
| except Exception as e: | |
| logger.error(f"Flask ํ ์คํธ ํด๋ผ์ด์ธํธ ์ด๊ธฐํ ์คํจ: {e}") | |
| raise e | |
| # ์์ค ์ ๋ณด ํฌ๋งทํ ํค๋ฃจํผ ํจ์ | |
| def format_source_info(sources, prefix=""): | |
| """๊ฒ์ ๊ฒฐ๊ณผ ์์ค ์ ๋ณด๋ฅผ ํ์ํ | |
| Args: | |
| sources: ์์ค ์ ๋ณด ๋ฆฌ์คํธ | |
| prefix: ๋ก๊ทธ ๋ฉ์์ง ์ ๋์ฌ (๊ธฐ๋ณธ๊ฐ: "") | |
| Returns: | |
| ํ์ํ๋ ์์ค ์ ๋ณด ๋ฌธ์์ด | |
| """ | |
| source_info = "" | |
| if sources and len(sources) > 0: | |
| logger.debug(f"{prefix}์์ค ์ ๋ณด ํฌ๋งทํ : {len(sources)}๊ฐ ์์ค: {json.dumps(sources, ensure_ascii=False, indent=2)}") | |
| source_list = [] | |
| for src in sources: | |
| source_text = src["source"] | |
| # id ํ๋๊ฐ ์์ผ๋ฉด ํจ๊ป ํ์ | |
| if "id" in src: | |
| logger.debug(f"{prefix}ID ํ๋ ๋ฐ๊ฒฌ: {src['id']}") | |
| source_text += f" (ID: {src['id']})" | |
| source_list.append(source_text) | |
| if source_list: | |
| source_info = "\n\n์ฐธ์กฐ ์์ค:\n" + "\n".join(source_list) | |
| logger.debug(f"{prefix}์ต์ข ์์ค ์ ๋ณด ํ์: {source_info}") | |
| return source_info | |
| # Flask ํ ์คํธ ํด๋ผ์ด์ธํธ ์ด๊ธฐํ | |
| flask_client = init_flask_client() | |
| # Gradio ๋ฒ์ ํ์ธ ๋ฉ์์ง | |
| logger.info(f"Gradio ๋ฒ์ : {gr.__version__}") | |
| # Gradio ์ธํฐํ์ด์ค ์์ฑ | |
| with gr.Blocks(title="RAG ๊ฒ์ ์ฑ๋ด with ์์ฑ์ธ์") as demo: | |
| gr.HTML(""" | |
| <div style="text-align: center; max-width: 800px; margin: 0 auto;"> | |
| <h1>RAG ๊ฒ์ ์ฑ๋ด with ์์ฑ์ธ์</h1> | |
| <p>ํ ์คํธ ๋๋ ์์ฑ์ผ๋ก ์ง๋ฌธ์ ์ ๋ ฅํ์ธ์.</p> | |
| </div> | |
| """) | |
| with gr.Tab("ํ ์คํธ ์ฑ"): | |
| text_input = gr.Textbox(label="์ง๋ฌธ ์ ๋ ฅ", placeholder="์ฌ๊ธฐ์ ์ง๋ฌธ์ ์ ๋ ฅํ์ธ์...") | |
| text_output = gr.Textbox(label="์๋ต", interactive=False) | |
| text_button = gr.Button("์ง๋ฌธ ์ ์ถ") | |
| with gr.Tab("์์ฑ ์ฑ"): | |
| with gr.Row(): | |
| # ๋ น์ UI ๊ฐ์ : ๋ง์ดํฌ๋กํฐ์ผ๋ก ์์ค ์ง์ ๋ฐ ์ํ ํ์ ํ์ฑํ | |
| audio_input = gr.Audio( | |
| label="์์ฑ ์ ๋ ฅ", | |
| type="filepath", | |
| sources=["microphone"], | |
| show_label=True, | |
| waveform_options={"show_controls": True, "normalize": True}, | |
| interactive=True | |
| ) | |
| audio_transcription = gr.Textbox(label="์ธ์๋ ํ ์คํธ", interactive=False) | |
| audio_output = gr.Textbox(label="์๋ต", interactive=False) | |
| gr.Markdown(""" | |
| <div style="text-align: center; margin: 10px 0;"> | |
| <p>๋ น์ ์ ์ง ๋ฒํผ์ ๋๋ฅด๋ฉด ์๋์ผ๋ก ์์ฑ์ด ์ ์ก๋ฉ๋๋ค.</p> | |
| </div> | |
| """) | |
| with gr.Tab("๋ฌธ์ ์ ๋ก๋"): | |
| doc_input = gr.File(label="๋ฌธ์ ์ ๋ก๋", file_types=[".txt", ".md", ".pdf", ".docx", ".csv"]) | |
| doc_output = gr.Textbox(label="์ ๋ก๋ ๊ฒฐ๊ณผ", interactive=False) | |
| doc_button = gr.Button("๋ฌธ์ ์ ๋ก๋") | |
| # ํ ์คํธ ์ฑ ๊ธฐ๋ฅ | |
| def handle_text_chat(query): | |
| if not query: | |
| return "์ง๋ฌธ์ ์ ๋ ฅํ์ธ์." | |
| try: | |
| logger.info("ํ ์คํธ ์ฑ ์์ฒญ: /api/chat") | |
| response = flask_client.post("/api/chat", json={"query": query}) | |
| data = flask_json.loads(response.data) | |
| # ๋๋ฒ๊น ์ ์ํ API ์๋ต ๋ก๊ทธ | |
| logger.info(f"API ์๋ต ๊ตฌ์กฐ: {json.dumps(data, ensure_ascii=False, indent=2)[:500]}...") | |
| if "error" in data: | |
| logger.error(f"ํ ์คํธ ์ฑ ์ค๋ฅ: {data['error']}") | |
| return data["error"] | |
| # ์์ค ์ ๋ณด ์ถ์ถ ๋ฐ ํฌ๋งทํ | |
| source_info = "" | |
| if "sources" in data and data["sources"]: | |
| source_info = format_source_info(data["sources"]) | |
| # ์๋ต๊ณผ ์์ค ์ ๋ณด๋ฅผ ํจ๊ป ๋ฐํ | |
| return data["answer"] + source_info | |
| except Exception as e: | |
| logger.error(f"ํ ์คํธ ์ฑ ์ฒ๋ฆฌ ์คํจ: {str(e)}") | |
| return f"์ฒ๋ฆฌ ์ค ์ค๋ฅ ๋ฐ์: {str(e)}" | |
| # ์์ฑ ์ฑ ๊ธฐ๋ฅ | |
| def handle_voice_chat(audio_file): | |
| if not audio_file: | |
| return "", "์์ฑ์ ์ ๋ก๋ํ์ธ์." | |
| try: | |
| logger.info("์์ฑ ์ฑ ์์ฒญ: /api/voice") | |
| with open(audio_file, "rb") as f: | |
| # Flask ํ ์คํธ ํด๋ผ์ด์ธํธ๋ files ์ง์ ์ง์ ์ ํ๋ฏ๋ก, ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด ์ ๋ฌ | |
| response = flask_client.post( | |
| "/api/voice", | |
| data={"audio": (f, "audio_file")} | |
| ) | |
| data = flask_json.loads(response.data) | |
| # ๋๋ฒ๊น ์ ์ํ API ์๋ต ๋ก๊ทธ | |
| logger.info(f"[์์ฑ์ฑ] API ์๋ต ๊ตฌ์กฐ: {json.dumps(data, ensure_ascii=False, indent=2)[:500]}...") | |
| if "error" in data: | |
| logger.error(f"์์ฑ ์ฑ ์ค๋ฅ: {data['error']}") | |
| return "", data["error"] | |
| # ์์ค ์ ๋ณด ์ถ์ถ ๋ฐ ํฌ๋งทํ | |
| source_info = "" | |
| if "sources" in data and data["sources"]: | |
| source_info = format_source_info(data["sources"], prefix="[์์ฑ์ฑ] ") | |
| # ์ธ์๋ ํ ์คํธ์ ์์ค ์ ๋ณด๊ฐ ํฌํจ๋ ์๋ต ๋ฐํ | |
| return data["transcription"], data["answer"] + source_info | |
| except Exception as e: | |
| logger.error(f"์์ฑ ์ฑ ์ฒ๋ฆฌ ์คํจ: {str(e)}") | |
| return "", f"์ฒ๋ฆฌ ์ค ์ค๋ฅ ๋ฐ์: {str(e)}" | |
| # ๋ฌธ์ ์ ๋ก๋ ๊ธฐ๋ฅ | |
| def handle_doc_upload(doc_file): | |
| if not doc_file: | |
| return "๋ฌธ์๋ฅผ ์ ๋ก๋ํ์ธ์." | |
| try: | |
| logger.info(f"๋ฌธ์ ์ ๋ก๋ ์์ฒญ: /api/upload, ํ์ผ๋ช : {doc_file.name}") | |
| file_extension = os.path.splitext(doc_file.name)[1].lower() | |
| logger.info(f"ํ์ผ ํ์ฅ์: {file_extension}") | |
| with open(doc_file, "rb") as f: | |
| response = flask_client.post( | |
| "/api/upload", | |
| data={"document": (f, doc_file.name)} | |
| ) | |
| data = flask_json.loads(response.data) | |
| if "error" in data: | |
| logger.error(f"๋ฌธ์ ์ ๋ก๋ ์ค๋ฅ: {data['error']}") | |
| return data["error"] | |
| return data["message"] | |
| except Exception as e: | |
| logger.error(f"๋ฌธ์ ์ ๋ก๋ ์ฒ๋ฆฌ ์คํจ: {str(e)}") | |
| return f"์ฒ๋ฆฌ ์ค ์ค๋ฅ ๋ฐ์: {str(e)}" | |
| # ์ด๋ฒคํธ ํธ๋ค๋ฌ ์ฐ๊ฒฐ | |
| text_button.click( | |
| fn=handle_text_chat, | |
| inputs=text_input, | |
| outputs=text_output | |
| ) | |
| # ์์ฑ ์ ๋ ฅ ๊ฐ์ด ๋ณ๊ฒฝ๋ ๋ ์๋์ผ๋ก ์ ์ก | |
| audio_input.change( | |
| fn=handle_voice_chat, | |
| inputs=audio_input, | |
| outputs=[audio_transcription, audio_output] | |
| ) | |
| doc_button.click( | |
| fn=handle_doc_upload, | |
| inputs=doc_input, | |
| outputs=doc_output | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch(server_port=7860) |