IAMTFRMZA commited on
Commit
d3205b2
·
verified ·
1 Parent(s): 6aa98b4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +71 -78
app.py CHANGED
@@ -1,92 +1,85 @@
1
- import gradio as gr
2
- import openai
3
  import os
4
  import json
 
 
 
5
 
6
- # === Load Secrets ===
7
- openai.api_key = os.environ.get("OPENAI_API_KEY")
8
- ASSISTANT_ID = os.environ.get("ASSISTANT_ID")
9
- VECTOR_STORE_ID = "vs_68199dddd40c8191973e8a6d1b136cd3"
10
-
11
- # === Chat Function ===
12
- def search_drawings(user_query):
13
- try:
14
- thread = openai.beta.threads.create()
15
- openai.beta.threads.messages.create(
16
- thread_id=thread.id,
17
- role="user",
18
- content=user_query
19
- )
20
 
21
- run = openai.beta.threads.runs.create(
22
- thread_id=thread.id,
23
- assistant_id=ASSISTANT_ID,
24
- tool_choice="auto",
25
- vector_store_ids=[VECTOR_STORE_ID]
26
- )
27
-
28
- # Wait for completion
29
- while True:
30
- run_status = openai.beta.threads.runs.retrieve(thread_id=thread.id, run_id=run.id)
31
- if run_status.status in ["completed", "failed", "cancelled"]:
32
- break
33
-
34
- if run_status.status != "completed":
35
- return gr.update(visible=True), f"❌ Assistant failed: {run_status.status}", []
36
 
37
- messages = openai.beta.threads.messages.list(thread_id=thread.id)
38
- for m in reversed(messages.data):
39
- if m.role == "assistant":
40
- raw = m.content[0].text.value
41
- try:
42
- result = json.loads(raw)
43
- cards = []
44
- for entry in result.get("drawings", []):
45
- img_tag = f'<img src="{entry["image_url"]}" style="width:100%; border-radius:12px"/>'
46
- page_caption = f"{entry['drawing_number']} – Page {entry['page_number']}"
47
- summary = f"<b>Summary:</b> {entry['summary']}"
48
 
49
- with gr.Column(scale=1):
50
- cards.append(gr.HTML(f"""
51
- <div style='background:#1a1a1a; border:1px solid #333; border-radius:14px; padding:16px; height:100%'>
52
- {img_tag}<br>
53
- <p style='margin-top:8px; font-weight:bold;'>{page_caption}</p>
54
- <p style='font-size:14px'>{summary}</p>
55
- </div>
56
- """))
57
- return gr.update(visible=False), "", cards
58
- except Exception as e:
59
- return gr.update(visible=True), "⚠️ Could not parse assistant response as JSON.", []
60
- return gr.update(visible=True), "⚠️ No assistant response found.", []
61
 
62
- except Exception as e:
63
- return gr.update(visible=True), f" Error: {str(e)}", []
 
 
 
64
 
65
- # === UI ===
66
- title = "\U0001F5A9 Forrestdale Technical Drawing Assistant"
67
- description = "Ask for plans by discipline, components or tags (e.g. \"Show all architectural plans\")"
68
 
69
- def ui():
70
- with gr.Blocks(theme=gr.themes.Monochrome()) as demo:
71
- gr.Markdown(f"""
72
- <h1 style='font-size:32px'>{title}</h1>
73
- <p style='color:#aaa; font-size:16px'>{description}</p>
74
- """)
75
 
76
- with gr.Row():
77
- query_input = gr.Textbox(placeholder="e.g. Show all electrical plans", scale=4)
78
- submit_btn = gr.Button("Search", variant="primary", scale=1)
 
 
79
 
80
- error_box = gr.Markdown("", visible=False)
81
- result_gallery = gr.Group([])
 
 
82
 
83
- submit_btn.click(
84
- fn=search_drawings,
85
- inputs=[query_input],
86
- outputs=[error_box, error_box, result_gallery]
87
- )
 
 
 
 
88
 
89
- return demo
 
 
 
 
 
 
 
 
 
 
 
90
 
91
- app = ui()
92
- app.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
 
2
  import os
3
  import json
4
+ import time
5
+ import requests
6
+ from openai import OpenAI
7
 
8
+ # ------------------ App Configuration ------------------
9
+ st.set_page_config(page_title="Forrestdale Drawing Assistant", layout="wide")
10
+ st.title("📐 Forrestdale Technical Drawing Assistant")
 
 
 
 
 
 
 
 
 
 
 
11
 
12
+ # ------------------ Load API Key and Assistant ID ------------------
13
+ OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY")
14
+ ASSISTANT_ID = os.environ.get("ASSISTANT_ID")
 
 
 
 
 
 
 
 
 
 
 
 
15
 
16
+ if not OPENAI_API_KEY or not ASSISTANT_ID:
17
+ st.error("❌ Missing secrets. Please set OPENAI_API_KEY and ASSISTANT_ID in secrets.")
18
+ st.stop()
 
 
 
 
 
 
 
 
19
 
20
+ client = OpenAI(api_key=OPENAI_API_KEY)
 
 
 
 
 
 
 
 
 
 
 
21
 
22
+ # ------------------ Session State Init ------------------
23
+ if "thread_id" not in st.session_state:
24
+ st.session_state.thread_id = None
25
+ if "results" not in st.session_state:
26
+ st.session_state.results = []
27
 
28
+ # ------------------ Query Bar ------------------
29
+ prompt = st.text_input("Ask about plans, drawings or components", placeholder="e.g. Show me all electrical plans")
 
30
 
31
+ if prompt:
32
+ if st.session_state.thread_id is None:
33
+ thread = client.beta.threads.create()
34
+ st.session_state.thread_id = thread.id
 
 
35
 
36
+ client.beta.threads.messages.create(
37
+ thread_id=st.session_state.thread_id,
38
+ role="user",
39
+ content=prompt
40
+ )
41
 
42
+ run = client.beta.threads.runs.create(
43
+ thread_id=st.session_state.thread_id,
44
+ assistant_id=ASSISTANT_ID
45
+ )
46
 
47
+ with st.spinner("Thinking..."):
48
+ while True:
49
+ run_status = client.beta.threads.runs.retrieve(
50
+ thread_id=st.session_state.thread_id,
51
+ run_id=run.id
52
+ )
53
+ if run_status.status in ("completed", "failed", "cancelled"):
54
+ break
55
+ time.sleep(1)
56
 
57
+ if run_status.status == "completed":
58
+ messages = client.beta.threads.messages.list(thread_id=st.session_state.thread_id)
59
+ for message in reversed(messages.data):
60
+ if message.role == "assistant":
61
+ try:
62
+ json_data = json.loads(message.content[0].text.value)
63
+ st.session_state.results = json_data["results"]
64
+ except Exception as e:
65
+ st.error("⚠️ Could not parse assistant response as JSON.")
66
+ break
67
+ else:
68
+ st.error(f"⚠️ Assistant failed: {run_status.status}")
69
 
70
+ # ------------------ Display Results as Cards ------------------
71
+ if st.session_state.results:
72
+ cols = st.columns(4)
73
+ for i, result in enumerate(st.session_state.results):
74
+ with cols[i % 4]:
75
+ st.markdown("""
76
+ <div style='border:1px solid #444; padding:10px; border-radius:10px; background:#111;'>
77
+ <h5 style='color:#fdd;'>📁 {drawing_number}</h5>
78
+ <b>Summary:</b> {summary}<br>
79
+ <img src="{image_url}" style="width:100%; margin-top:10px; border-radius:6px;">
80
+ </div>
81
+ """.format(
82
+ drawing_number=result.get("drawing_number", "Untitled"),
83
+ summary=result.get("summary", "No summary available."),
84
+ image_url=result.get("image_url", "")
85
+ ), unsafe_allow_html=True)