Spaces:
Sleeping
Sleeping
import gradio as gr | |
import requests | |
import os | |
from openai import OpenAI | |
UPSTAGE_API_KEY = os.getenv("UPSTAGE_API_KEY") | |
def parse_document(file): | |
url = "https://api.upstage.ai/v1/document-ai/document-parse" | |
headers = {'Authorization': f'Bearer {UPSTAGE_API_KEY}'} | |
files = {"document": open(file.name, "rb")} | |
data = { | |
"base64_encoding": "['table']", | |
"model": "document-parse" | |
} | |
response = requests.post(url, headers=headers, files=files, data=data) | |
result = response.json() | |
html_text = result.get("content", {}).get("html", "") | |
return html_text | |
def chat_with_document(history, html_text, user_question): | |
if not html_text.strip(): | |
return history, history, "โ ๏ธ ๋จผ์ ๋ฌธ์๋ฅผ ๋ณํํด์ฃผ์ธ์." | |
client = OpenAI( | |
api_key=UPSTAGE_API_KEY, | |
base_url="https://api.upstage.ai/v1" | |
) | |
history = history or [] | |
system_prompt = f"""The following is a financial statement document extracted in HTML format. | |
Please answer user questions accurately and concisely in Korean, based on the text within HTML tags. | |
Document: | |
{html_text} | |
""" | |
messages = [{"role": "system", "content": system_prompt}] | |
for user, bot in history: | |
messages.append({"role": "user", "content": user}) | |
messages.append({"role": "assistant", "content": bot}) | |
messages.append({"role": "user", "content": user_question}) | |
try: | |
response = client.chat.completions.create( | |
model="solar-pro", | |
messages=messages, | |
temperature=0, | |
max_tokens=1024 | |
) | |
bot_reply = response.choices[0].message.content | |
except Exception as e: | |
bot_reply = f"โ ๏ธ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค: {str(e)}" | |
history.append((user_question, bot_reply)) | |
return history, history, "" | |
def toggle_html_view(current_html, is_visible): | |
return ( | |
gr.update(value=current_html, visible=not is_visible), | |
gr.update(value=current_html, visible=is_visible), | |
not is_visible | |
) | |
with gr.Blocks() as demo: | |
gr.Markdown("# ๐ ์ฌ๋ฌด์ ํ ๋ถ์ ์ฑ๋ด") | |
gr.Markdown("1. Document Parse API๋ก PDF ๋ฌธ์๋ฅผ HTML๋ก ๋ณํํฉ๋๋ค.\n" | |
"2. Solar LLM์ ํตํด ๋ฌธ์ ๊ธฐ๋ฐ ์ง๋ฌธ์ ๋ต๋ณํฉ๋๋ค.") | |
gr.Markdown("์์ ํ์ผ์ Files ๋ฒํผ์ ํด๋ฆญํ๋ฉด ํ์ธ ๋ฐ ๋ค์ด๋ก๋ ๊ฐ๋ฅํฉ๋๋ค.") | |
with gr.Row(): | |
file_input = gr.File(label="๐ ์ฌ๋ฌด์ ํ ์ ๋ก๋") | |
parse_btn = gr.Button("๋ฌธ์ HTML ๋ณํ") | |
html_output = gr.Textbox(label="๐ ๋ฌธ์ ๋ด์ฉ", lines=10, visible=True, elem_id="scrollable-html") | |
html_display = gr.HTML(visible=False, elem_id="scrollable-html-display") | |
toggle_html_btn = gr.Button("๐ HTML ๋ณด๊ธฐ ์ ํ") | |
html_visible_state = gr.State(False) | |
parse_btn.click(fn=parse_document, inputs=file_input, outputs=html_output) | |
toggle_html_btn.click( | |
fn=toggle_html_view, | |
inputs=[html_output, html_visible_state], | |
outputs=[html_output, html_display, html_visible_state] | |
) | |
chatbot = gr.Chatbot(label="๐ฌ ๋ฌธ์ ๊ธฐ๋ฐ Q&A", height=400) | |
user_question = gr.Textbox(label="โ ์ง๋ฌธ์ ์ ๋ ฅํ์ธ์", lines=2) | |
answer_btn = gr.Button("๋ต๋ณ ์์ฑ") | |
chat_state = gr.State([]) | |
with gr.Row(): | |
gr.Markdown("๐ก ์์ ์ง๋ฌธ:") | |
ex1 = gr.Button("์ด๋ค ๊ธฐ์ ์ ์ฌ๋ฌด์ ํ์ธ๊ฐ์?") | |
ex2 = gr.Button("Q3 ๋ถ๊ธฐ์ ์ด ๋งค์ถ์ก์ ์ผ๋ง์ธ๊ฐ์?") | |
# ์์ ์ง๋ฌธ โ ์ง๋ฌธ ์ ๋ ฅ + ์๋ ์๋ต | |
ex1.click( | |
fn=lambda: "์ด๋ค ๊ธฐ์ ์ ์ฌ๋ฌด์ ํ์ธ๊ฐ์?", | |
inputs=[], | |
outputs=user_question | |
).then( | |
fn=chat_with_document, | |
inputs=[chat_state, html_output, user_question], | |
outputs=[chatbot, chat_state, user_question], | |
show_progress=True | |
) | |
ex2.click( | |
fn=lambda: "Q3 ๋ถ๊ธฐ์ ์ด ๋งค์ถ์ก์ ์ผ๋ง์ธ๊ฐ์?", | |
inputs=[], | |
outputs=user_question | |
).then( | |
fn=chat_with_document, | |
inputs=[chat_state, html_output, user_question], | |
outputs=[chatbot, chat_state, user_question], | |
show_progress=True | |
) | |
answer_btn.click( | |
fn=chat_with_document, | |
inputs=[chat_state, html_output, user_question], | |
outputs=[chatbot, chat_state, user_question], | |
show_progress=True | |
) | |
demo.css = """ | |
#scrollable-html, #scrollable-html-display { | |
max-height: 400px; | |
overflow: auto; | |
border: 1px solid #AEB3FA; /* Primary 30 */ | |
padding: 16px; | |
background-color: #F4F4FF; /* Primary 10 */ | |
border-radius: 12px; | |
font-family: 'Arial', sans-serif; | |
color: #2F22A4; /* Primary 60 */ | |
box-shadow: 0 2px 6px rgba(128, 92, 251, 0.1); /* Ups Purple */ | |
} | |
""" | |
demo.launch() | |