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) |