Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
@@ -12,107 +12,170 @@ from gradio_client import Client
|
|
12 |
KEY_FILE = "openai_api_key.txt"
|
13 |
MODEL = "gpt-4o-2024-05-13"
|
14 |
|
15 |
-
# Load stored API key
|
16 |
-
DEFAULT_KEY = ""
|
17 |
-
if os.path.exists(KEY_FILE):
|
18 |
-
with open(KEY_FILE, 'r') as f:
|
19 |
-
DEFAULT_KEY = f.read().strip()
|
20 |
-
|
21 |
# 🔧 Helpers
|
22 |
-
|
23 |
-
|
|
|
|
|
24 |
f.write(key.strip())
|
25 |
return "🔑 Key saved!"
|
26 |
|
27 |
-
|
28 |
-
|
|
|
|
|
29 |
if input_key and input_key.strip():
|
30 |
save_api_key(input_key)
|
31 |
return input_key.strip()
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
raise gr.Error("❗ OpenAI API key required.")
|
39 |
|
40 |
-
|
41 |
def apply_filters(files, filters):
|
42 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
for f in files:
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
if
|
52 |
-
|
53 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
|
55 |
def generate_table(selected, api_key):
|
|
|
|
|
|
|
56 |
key = get_api_key(api_key)
|
57 |
openai.api_key = key
|
58 |
-
|
|
|
59 |
md = "| ✅ | Type | Filename |\n|---|------|----------|\n"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
for path, typ in selected:
|
61 |
-
emoji = '🖼️' if typ=='image' else '🎤' if typ=='audio' else '🎥' if typ=='video' else '📄'
|
62 |
name = os.path.basename(path)
|
63 |
-
md += f"| ✅ | {
|
|
|
64 |
return md
|
65 |
|
66 |
-
|
67 |
def chat_handler(api_key, message, history):
|
|
|
|
|
|
|
68 |
key = get_api_key(api_key)
|
69 |
openai.api_key = key
|
|
|
70 |
messages = []
|
71 |
-
for
|
72 |
-
messages.append({"role": "user",
|
73 |
-
messages.append({"role": "assistant","content":
|
|
|
74 |
messages.append({"role": "user", "content": message})
|
75 |
resp = openai.ChatCompletion.create(model=MODEL, messages=messages)
|
|
|
76 |
answer = resp.choices[0].message.content
|
77 |
history.append((message, answer))
|
78 |
return history
|
79 |
|
80 |
-
# 🎞️ Example: Video Summarizer (placeholder)
|
81 |
-
# def summarize_video(api_key, file_path, prompt):
|
82 |
-
# ... implementation ...
|
83 |
|
84 |
# 🔑 UI Definition
|
85 |
with gr.Blocks(title="🔬🧠 ScienceBrain.Gradio") as demo:
|
86 |
gr.Markdown("# 🔬🧠 ScienceBrain Gradio")
|
87 |
|
88 |
with gr.Row():
|
89 |
-
api_input = gr.Textbox(
|
|
|
|
|
|
|
|
|
90 |
save_btn = gr.Button("💾 Save Key")
|
91 |
status_txt = gr.Textbox(interactive=False)
|
|
|
92 |
save_btn.click(save_api_key, inputs=api_input, outputs=status_txt)
|
93 |
|
|
|
94 |
gr.Markdown("## 📋 Media Gallery & Filters")
|
95 |
upload = gr.File(file_count="multiple", label="Upload files (images, audio, videos, PDFs)")
|
96 |
-
gallery = gr.Gallery(label="Filtered Gallery"
|
97 |
filter_opts = ["🖼️ Images", "🎤 Audio", "🎥 Video", "📄 PDF"]
|
98 |
filters = gr.CheckboxGroup(filter_opts, value=filter_opts, label="🔍 Filter Types")
|
99 |
select_btn = gr.Button("⚙️ Apply Filters")
|
100 |
selected = gr.Variable()
|
101 |
-
select_btn.click(apply_filters, inputs=[upload, filters], outputs=[gallery, selected])
|
102 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
103 |
gr.Markdown("## ✅ Include in Discussion")
|
104 |
-
disc = gr.CheckboxGroup(label="Select items", choices=[])
|
105 |
-
gallery.select(
|
|
|
|
|
|
|
|
|
106 |
|
|
|
107 |
gr.Markdown("## 📝 Summary Table")
|
108 |
table_md = gr.Markdown()
|
109 |
table_btn = gr.Button("Generate Table")
|
110 |
-
table_btn.click(
|
|
|
|
|
|
|
|
|
111 |
|
|
|
112 |
with gr.Tab("💬 Chat"):
|
113 |
chatbot = gr.Chatbot()
|
114 |
msg_in = gr.Textbox(placeholder="Type your message...")
|
115 |
-
msg_in.submit(
|
|
|
|
|
|
|
|
|
116 |
|
117 |
if __name__ == "__main__":
|
118 |
-
demo.launch()
|
|
|
12 |
KEY_FILE = "openai_api_key.txt"
|
13 |
MODEL = "gpt-4o-2024-05-13"
|
14 |
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
# 🔧 Helpers
|
16 |
+
|
17 |
+
def save_api_key(key: str) -> str:
|
18 |
+
"""Save a new OpenAI API key to disk."""
|
19 |
+
with open(KEY_FILE, "w") as f:
|
20 |
f.write(key.strip())
|
21 |
return "🔑 Key saved!"
|
22 |
|
23 |
+
|
24 |
+
def get_api_key(input_key: str) -> str:
|
25 |
+
"""Determine which OpenAI key to use: input > saved > env."""
|
26 |
+
# 1️⃣ User-provided
|
27 |
if input_key and input_key.strip():
|
28 |
save_api_key(input_key)
|
29 |
return input_key.strip()
|
30 |
+
|
31 |
+
# 2️⃣ Previously saved
|
32 |
+
if os.path.exists(KEY_FILE):
|
33 |
+
with open(KEY_FILE) as f:
|
34 |
+
return f.read().strip()
|
35 |
+
|
36 |
+
# 3️⃣ Environment variable
|
37 |
+
env_key = os.getenv("OPENAI_KEY", "")
|
38 |
+
if env_key:
|
39 |
+
save_api_key(env_key)
|
40 |
+
return env_key
|
41 |
+
|
42 |
+
# ❗ None found
|
43 |
raise gr.Error("❗ OpenAI API key required.")
|
44 |
|
45 |
+
|
46 |
def apply_filters(files, filters):
|
47 |
+
"""
|
48 |
+
Filter uploaded files by extension and user-selected filters.
|
49 |
+
Returns a list for the Gallery display and a list of (path, type) for tracking.
|
50 |
+
"""
|
51 |
+
gallery_items = []
|
52 |
+
tracking = []
|
53 |
+
|
54 |
+
if not files:
|
55 |
+
return gallery_items, tracking
|
56 |
+
|
57 |
for f in files:
|
58 |
+
# file may be a tempfile object or filepath string
|
59 |
+
path = getattr(f, "name", f)
|
60 |
+
ext = os.path.splitext(path)[1].lower()
|
61 |
+
|
62 |
+
if ext in ['.png', '.jpg', '.jpeg'] and '🖼️ Images' in filters:
|
63 |
+
gallery_items.append(f)
|
64 |
+
tracking.append((path, 'image'))
|
65 |
+
if ext in ['.wav', '.mp3'] and '🎤 Audio' in filters:
|
66 |
+
gallery_items.append(f)
|
67 |
+
tracking.append((path, 'audio'))
|
68 |
+
if ext in ['.mp4', '.webm'] and '🎥 Video' in filters:
|
69 |
+
gallery_items.append(f)
|
70 |
+
tracking.append((path, 'video'))
|
71 |
+
if ext == '.pdf' and '📄 PDF' in filters:
|
72 |
+
gallery_items.append(f)
|
73 |
+
tracking.append((path, 'pdf'))
|
74 |
+
|
75 |
+
return gallery_items, tracking
|
76 |
+
|
77 |
|
78 |
def generate_table(selected, api_key):
|
79 |
+
"""
|
80 |
+
Build a Markdown table of selected items with type icons.
|
81 |
+
"""
|
82 |
key = get_api_key(api_key)
|
83 |
openai.api_key = key
|
84 |
+
|
85 |
+
# Header
|
86 |
md = "| ✅ | Type | Filename |\n|---|------|----------|\n"
|
87 |
+
emoji_map = {
|
88 |
+
'image': '🖼️',
|
89 |
+
'audio': '🎤',
|
90 |
+
'video': '🎥',
|
91 |
+
'pdf': '📄'
|
92 |
+
}
|
93 |
+
|
94 |
for path, typ in selected:
|
|
|
95 |
name = os.path.basename(path)
|
96 |
+
md += f"| ✅ | {emoji_map.get(typ, '')} {typ.capitalize()} | {name} |\n"
|
97 |
+
|
98 |
return md
|
99 |
|
100 |
+
|
101 |
def chat_handler(api_key, message, history):
|
102 |
+
"""
|
103 |
+
Send a user message + chat history to OpenAI and append the response.
|
104 |
+
"""
|
105 |
key = get_api_key(api_key)
|
106 |
openai.api_key = key
|
107 |
+
|
108 |
messages = []
|
109 |
+
for user_msg, bot_msg in history:
|
110 |
+
messages.append({"role": "user", "content": user_msg})
|
111 |
+
messages.append({"role": "assistant", "content": bot_msg})
|
112 |
+
|
113 |
messages.append({"role": "user", "content": message})
|
114 |
resp = openai.ChatCompletion.create(model=MODEL, messages=messages)
|
115 |
+
|
116 |
answer = resp.choices[0].message.content
|
117 |
history.append((message, answer))
|
118 |
return history
|
119 |
|
|
|
|
|
|
|
120 |
|
121 |
# 🔑 UI Definition
|
122 |
with gr.Blocks(title="🔬🧠 ScienceBrain.Gradio") as demo:
|
123 |
gr.Markdown("# 🔬🧠 ScienceBrain Gradio")
|
124 |
|
125 |
with gr.Row():
|
126 |
+
api_input = gr.Textbox(
|
127 |
+
label="��� OpenAI Key",
|
128 |
+
type="password",
|
129 |
+
value=os.getenv("OPENAI_KEY", "")
|
130 |
+
)
|
131 |
save_btn = gr.Button("💾 Save Key")
|
132 |
status_txt = gr.Textbox(interactive=False)
|
133 |
+
|
134 |
save_btn.click(save_api_key, inputs=api_input, outputs=status_txt)
|
135 |
|
136 |
+
# 📋 Media Gallery & Filters
|
137 |
gr.Markdown("## 📋 Media Gallery & Filters")
|
138 |
upload = gr.File(file_count="multiple", label="Upload files (images, audio, videos, PDFs)")
|
139 |
+
gallery = gr.Gallery(label="Filtered Gallery", columns=4)
|
140 |
filter_opts = ["🖼️ Images", "🎤 Audio", "🎥 Video", "📄 PDF"]
|
141 |
filters = gr.CheckboxGroup(filter_opts, value=filter_opts, label="🔍 Filter Types")
|
142 |
select_btn = gr.Button("⚙️ Apply Filters")
|
143 |
selected = gr.Variable()
|
|
|
144 |
|
145 |
+
select_btn.click(
|
146 |
+
apply_filters,
|
147 |
+
inputs=[upload, filters],
|
148 |
+
outputs=[gallery, selected]
|
149 |
+
)
|
150 |
+
|
151 |
+
# ✅ Include in Discussion
|
152 |
gr.Markdown("## ✅ Include in Discussion")
|
153 |
+
disc = gr.CheckboxGroup(label="Select items", choices=[])
|
154 |
+
gallery.select(
|
155 |
+
lambda x: [x],
|
156 |
+
inputs=[gallery],
|
157 |
+
outputs=[disc]
|
158 |
+
)
|
159 |
|
160 |
+
# 📝 Summary Table
|
161 |
gr.Markdown("## 📝 Summary Table")
|
162 |
table_md = gr.Markdown()
|
163 |
table_btn = gr.Button("Generate Table")
|
164 |
+
table_btn.click(
|
165 |
+
generate_table,
|
166 |
+
inputs=[disc, api_input],
|
167 |
+
outputs=[table_md]
|
168 |
+
)
|
169 |
|
170 |
+
# 💬 Chat Tab
|
171 |
with gr.Tab("💬 Chat"):
|
172 |
chatbot = gr.Chatbot()
|
173 |
msg_in = gr.Textbox(placeholder="Type your message...")
|
174 |
+
msg_in.submit(
|
175 |
+
chat_handler,
|
176 |
+
inputs=[api_input, msg_in, chatbot],
|
177 |
+
outputs=[chatbot]
|
178 |
+
)
|
179 |
|
180 |
if __name__ == "__main__":
|
181 |
+
demo.launch()
|