Spaces:
Sleeping
Sleeping
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,140 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import requests
|
3 |
+
import os
|
4 |
+
from openai import OpenAI
|
5 |
+
|
6 |
+
UPSTAGE_API_KEY = os.getenv("UPSTAGE_API_KEY")
|
7 |
+
|
8 |
+
def parse_document(filename):
|
9 |
+
"""Parses a PDF document using the Upstage Document Parse API and returns the extracted HTML."""
|
10 |
+
|
11 |
+
# Define the API endpoint
|
12 |
+
url = "https://api.upstage.ai/v1/document-ai/document-parse"
|
13 |
+
|
14 |
+
# Set the authorization header with your API key
|
15 |
+
headers = {'Authorization': f'Bearer {UPSTAGE_API_KEY}'}
|
16 |
+
|
17 |
+
# Open the PDF file in binary mode and attach it to the request
|
18 |
+
files = {"document": open(filename, "rb")}
|
19 |
+
|
20 |
+
# Define additional request parameters
|
21 |
+
data = {
|
22 |
+
"base64_encoding": "['table']", # Request base64 encoding of table elements
|
23 |
+
"model": "document-parse" # Specify the model to use
|
24 |
+
}
|
25 |
+
# Send the POST request to the API
|
26 |
+
response = requests.post(url, headers=headers, files=files, data=data)
|
27 |
+
|
28 |
+
# Parse the JSON response
|
29 |
+
result = response.json()
|
30 |
+
|
31 |
+
# For debugging: print the entire API response
|
32 |
+
# print(response.json())
|
33 |
+
|
34 |
+
# Extract the HTML content from the response
|
35 |
+
html_text = result.get("content", {}).get("html", "")
|
36 |
+
|
37 |
+
return html_text
|
38 |
+
|
39 |
+
def chat_with_document(history, html_text, user_question):
|
40 |
+
"""Handles multi-turn Q&A based on the parsed HTML document using Upstage Solar Pro LLM."""
|
41 |
+
|
42 |
+
# Initialize the OpenAI client for Solar LLM
|
43 |
+
client = OpenAI(
|
44 |
+
api_key=UPSTAGE_API_KEY,
|
45 |
+
base_url="https://api.upstage.ai/v1"
|
46 |
+
)
|
47 |
+
|
48 |
+
# If this is the first turn, initialize an empty history
|
49 |
+
history = history or []
|
50 |
+
|
51 |
+
# Construct a system prompt with instructions and the HTML content
|
52 |
+
system_prompt = f"""The following is a financial statement document extracted in HTML format.
|
53 |
+
Please answer user questions accurately and concisely in Korean, based on the text within HTML tags.
|
54 |
+
|
55 |
+
Document:
|
56 |
+
{html_text}
|
57 |
+
"""
|
58 |
+
|
59 |
+
# Build the conversation history for the chat model
|
60 |
+
messages = [{"role": "system", "content": system_prompt}]
|
61 |
+
for user, bot in history:
|
62 |
+
messages.append({"role": "user", "content": user})
|
63 |
+
messages.append({"role": "assistant", "content": bot})
|
64 |
+
|
65 |
+
# Add the current user question
|
66 |
+
messages.append({"role": "user", "content": user_question})
|
67 |
+
|
68 |
+
# Call the Solar LLM to generate a response
|
69 |
+
response = client.chat.completions.create(
|
70 |
+
model="solar-pro",
|
71 |
+
messages=messages,
|
72 |
+
temperature=0,
|
73 |
+
max_tokens=1024
|
74 |
+
)
|
75 |
+
|
76 |
+
# Extract the assistant's reply
|
77 |
+
bot_reply = response.choices[0].message.content
|
78 |
+
|
79 |
+
# Update the chat history
|
80 |
+
history.append((user_question, bot_reply))
|
81 |
+
|
82 |
+
# Return updated chatbot display, state, and clear the input
|
83 |
+
return history, history, ""
|
84 |
+
|
85 |
+
|
86 |
+
def set_example_question(example_text):
|
87 |
+
return example_text
|
88 |
+
|
89 |
+
def toggle_html_view(current_html, is_visible):
|
90 |
+
return (
|
91 |
+
gr.update(value=current_html, visible=not is_visible), # html_output toggle
|
92 |
+
gr.update(value=current_html, visible=is_visible), # html_display ๋ฐ๋๋ก toggle
|
93 |
+
not is_visible
|
94 |
+
)
|
95 |
+
|
96 |
+
|
97 |
+
# Gradio UI
|
98 |
+
with gr.Blocks() as demo:
|
99 |
+
gr.Markdown("# ๐ ์ฌ๋ฌด์ ํ ๋ถ์ ์ฑ๋ด")
|
100 |
+
gr.Markdown("1. Document Parse API๋ก PDF ๋ฌธ์๋ฅผ HTML๋ก ๋ณํํฉ๋๋ค.\n"
|
101 |
+
"2. Solar LLM์ ํตํด ๋ฌธ์ ๊ธฐ๋ฐ ์ง๋ฌธ์ ๋ต๋ณํฉ๋๋ค.")
|
102 |
+
|
103 |
+
with gr.Row():
|
104 |
+
file_input = gr.File(label="๐ ์ฌ๋ฌด์ ํ ์
๋ก๋")
|
105 |
+
parse_btn = gr.Button("๋ฌธ์ HTML ๋ณํ")
|
106 |
+
|
107 |
+
html_output = gr.Textbox(label="๐ ๋ฌธ์ ๋ด์ฉ", lines=10, visible=True)
|
108 |
+
html_display = gr.HTML(visible=False)
|
109 |
+
toggle_html_btn = gr.Button("๐ HTML ๋ณด๊ธฐ ์ ํ")
|
110 |
+
html_visible_state = gr.State(False)
|
111 |
+
|
112 |
+
parse_btn.click(fn=parse_document, inputs=file_input, outputs=html_output)
|
113 |
+
toggle_html_btn.click(
|
114 |
+
fn=toggle_html_view,
|
115 |
+
inputs=[html_output, html_visible_state],
|
116 |
+
outputs=[html_output, html_display, html_visible_state]
|
117 |
+
)
|
118 |
+
|
119 |
+
chatbot = gr.Chatbot(label="๐ฌ ๋ฌธ์ ๊ธฐ๋ฐ Q&A", height=400)
|
120 |
+
user_question = gr.Textbox(label="โ ์ง๋ฌธ์ ์
๋ ฅํ์ธ์", lines=2)
|
121 |
+
answer_btn = gr.Button("๋ต๋ณ ์์ฑ")
|
122 |
+
|
123 |
+
chat_state = gr.State([])
|
124 |
+
|
125 |
+
with gr.Row():
|
126 |
+
gr.Markdown("๐ก ์์ ์ง๋ฌธ:")
|
127 |
+
ex1 = gr.Button("์ด๋ค ๊ธฐ์
์ ์ฌ๋ฌด์ ํ์ธ๊ฐ์?")
|
128 |
+
ex2 = gr.Button("Q3 ๋ถ๊ธฐ์ ์ด ๋งค์ถ์ก์ ์ผ๋ง์ธ๊ฐ์?")
|
129 |
+
|
130 |
+
ex1.click(set_example_question, inputs=[], outputs=user_question)
|
131 |
+
ex2.click(set_example_question, inputs=[], outputs=user_question)
|
132 |
+
|
133 |
+
answer_btn.click(
|
134 |
+
fn=chat_with_document,
|
135 |
+
inputs=[chat_state, html_output, user_question],
|
136 |
+
outputs=[chatbot, chat_state, user_question],
|
137 |
+
show_progress=True
|
138 |
+
)
|
139 |
+
|
140 |
+
demo.launch()
|