wanda222's picture
Update app.py
c1a7cd0 verified
raw
history blame
4.83 kB
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()