Spaces:
Sleeping
Sleeping
File size: 7,090 Bytes
38a637f bbdde00 38a637f bbdde00 9014715 bbdde00 38a637f bbdde00 38a637f 3790afa 38a637f 3790afa 38a637f 3790afa fe17826 9014715 bbdde00 38a637f bbdde00 9014715 bbdde00 38a637f bbdde00 fe17826 38a637f 3790afa 38a637f 3790afa 9014715 3790afa 38a637f 3790afa fe17826 38a637f bbdde00 3790afa 38a637f 3790afa 38a637f fe17826 38a637f fe17826 38a637f fe17826 38a637f 3790afa 38a637f 3790afa 9014715 ae11c94 3790afa bbdde00 38a637f bbdde00 3790afa bbdde00 38a637f bbdde00 3790afa 38a637f 3790afa bbdde00 38a637f bbdde00 3790afa 38a637f 3790afa 38a637f 9014715 ae11c94 38a637f 3790afa 38a637f 9014715 38a637f 9014715 38a637f 9014715 38a637f 9014715 ae11c94 38a637f 3790afa 38a637f 3790afa 38a637f 3790afa 38a637f 3790afa 38a637f 9014715 38a637f 9014715 3790afa 38a637f 3790afa 207d39c 38a637f 207d39c 38a637f 207d39c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# Loading required libraries
import gradio as gr # Gradio: A library for building web interfaces
import requests # requests: A library for sending HTTP requests.
from openai import OpenAI # OpenAI: Clients compatible with the Upstage Solar API
# ------------------------------
# π Defining a document parsing function
# ------------------------------
def parse_document(file, api_key):
"""
Function to convert uploaded PDF document to HTML (using Upstage Document Parse API)
"""
url = "https://api.upstage.ai/v1/document-ai/document-parse" # API request URL
headers = {'Authorization': f'Bearer {api_key}'} # Authentication header settingsμ
files = {"document": open(file.name, "rb")} # read file
data = {
"base64_encoding": "['table']", # Table data is encoded in base64
"model": "document-parse" # Specify usage model
}
response = requests.post(url, headers=headers, files=files, data=data) # POST request
result = response.json() # Parsing response results
html_text = result.get("content", {}).get("html", "") # HTML Extraction
return html_text
# ------------------------------
# π¬ Defining a document-based Q&A function
# ------------------------------
def chat_with_document(history, html_text, user_question, api_key):
"""
Solar LLM functions to answer user questions based on document content
"""
if not html_text.strip():
return history, history, "β οΈ Please convert the document first." # Guidance if there is no document
# OpenAI client initialization (Upstage Solar LLM)
client = OpenAI(
api_key=api_key,
base_url="https://api.upstage.ai/v1"
)
# Reset previous conversation history
history = history or []
# System prompt: Request a response based on the contents of the HTML document
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}
"""
# Message composition (System β User/bot conversation β Current question)
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})
# Solar LLM Call
try:
response = client.chat.completions.create(
model="solar-pro", # Model name to use
messages=messages, # Deliver the entire message
temperature=0, # Minimize creativity
max_tokens=1024 # maximum response length
)
bot_reply = response.choices[0].message.content # Extract response message
except Exception as e:
bot_reply = f"β οΈ An error occurred: {str(e)}" # Error handling
# Return after updating conversation history
history.append((user_question, bot_reply))
return history, history, ""
# ------------------------------
# π HTML View Toggle Function
# ------------------------------
def toggle_html_view(current_html, is_visible):
"""
Function to toggle the HTML view/hide state
"""
return (
gr.update(value=current_html, visible=not is_visible), # Hide/Show Text Box
gr.update(value=current_html, visible=is_visible), # HTML rendering opposite behavior
not is_visible # state inversion
)
# ------------------------------
# π¦ Gradio UI configuration
# ------------------------------
with gr.Blocks() as demo:
# Show title and description
gr.Markdown("# π Financial Statement Analysis Chatbot")
gr.Markdown("1. Convert PDF documents to HTML using the Document Parse API.\n"
"2. Answer document-based questions with Solar LLM.")
# π API Key input window (entered directly by the user)
api_key_input = gr.Textbox(label="π Upstage API Key", type="password", placeholder="Paste your API key here")
# π File Upload + Document Conversion Button
with gr.Row():
file_input = gr.File(label="π Upload financial statements")
parse_btn = gr.Button("Document HTML conversion")
# π HTML output area (text + HTML toggle view)
html_output = gr.Textbox(label="π document content", lines=10, visible=True, elem_id="scrollable-html")
html_display = gr.HTML(visible=False, elem_id="scrollable-html-display")
toggle_html_btn = gr.Button("π Switch HTML views")
html_visible_state = gr.State(False) # Save view state
# Click the Convert Document button β Generate HTML
parse_btn.click(
fn=parse_document,
inputs=[file_input, api_key_input],
outputs=html_output
)
# When clicking the HTML view switch button β Execute the toggle action
toggle_html_btn.click(
fn=toggle_html_view,
inputs=[html_output, html_visible_state],
outputs=[html_output, html_display, html_visible_state]
)
# π¬ Chatbot Interface
chatbot = gr.Chatbot(label="π¬ Document-based Q&A", height=400)
user_question = gr.Textbox(label="β Please enter your question", lines=2)
answer_btn = gr.Button("Generate Answer")
chat_state = gr.State([]) # Save conversation state
# π‘ Example Question Button Configuration
with gr.Row():
gr.Markdown("π‘example questions:")
ex1 = gr.Button("Which company's financial statements are these?")
ex2 = gr.Button("What was the total net sales for the third quarter?")
# Click the example question button β Run question + answer
for btn, question in [(ex1, "Which company's financial statements are these?"), (ex2, "What was the total net sales for the first quarter?")]:
btn.click(
fn=lambda q=question: q, # Pass question text
inputs=[],
outputs=user_question
).then(
fn=chat_with_document,
inputs=[chat_state, html_output, user_question, api_key_input],
outputs=[chatbot, chat_state, user_question],
show_progress=True
)
# Submit a User Question β Solar LLM Answers
answer_btn.click(
fn=chat_with_document,
inputs=[chat_state, html_output, user_question, api_key_input],
outputs=[chatbot, chat_state, user_question],
show_progress=True
)
# ------------------------------
# π¨ Styling a scrollable HTML box
# ------------------------------
demo.css = """
#scrollable-html, #scrollable-html-display {
max-height: 400px;
overflow: auto;
border: 1px solid #ccc;
padding: 10px;
}
"""
# π run app
if __name__ == "__main__":
demo.launch() |