Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
Update app.py
Browse files
app.py
CHANGED
@@ -50,6 +50,44 @@ st.set_page_config(
|
|
50 |
}
|
51 |
)
|
52 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
# Custom CSS
|
54 |
st.markdown("""
|
55 |
<style>
|
@@ -90,33 +128,6 @@ st.markdown("""
|
|
90 |
</style>
|
91 |
""", unsafe_allow_html=True)
|
92 |
|
93 |
-
# 2. Load environment variables and initialize clients
|
94 |
-
load_dotenv()
|
95 |
-
|
96 |
-
# OpenAI setup
|
97 |
-
openai.api_key = os.getenv('OPENAI_API_KEY')
|
98 |
-
if openai.api_key == None:
|
99 |
-
openai.api_key = st.secrets['OPENAI_API_KEY']
|
100 |
-
|
101 |
-
openai_client = OpenAI(
|
102 |
-
api_key=os.getenv('OPENAI_API_KEY'),
|
103 |
-
organization=os.getenv('OPENAI_ORG_ID')
|
104 |
-
)
|
105 |
-
|
106 |
-
# Claude setup
|
107 |
-
anthropic_key = os.getenv("ANTHROPIC_API_KEY_3")
|
108 |
-
if anthropic_key == None:
|
109 |
-
anthropic_key = st.secrets["ANTHROPIC_API_KEY"]
|
110 |
-
claude_client = anthropic.Anthropic(api_key=anthropic_key)
|
111 |
-
|
112 |
-
# Initialize session states
|
113 |
-
if "chat_history" not in st.session_state:
|
114 |
-
st.session_state.chat_history = []
|
115 |
-
if "openai_model" not in st.session_state:
|
116 |
-
st.session_state["openai_model"] = "gpt-4o-2024-05-13"
|
117 |
-
if "messages" not in st.session_state:
|
118 |
-
st.session_state.messages = []
|
119 |
-
|
120 |
# Bike Collections
|
121 |
bike_collections = {
|
122 |
"Celestial Collection π": {
|
@@ -171,19 +182,27 @@ bike_collections = {
|
|
171 |
|
172 |
# Helper Functions
|
173 |
def generate_filename(prompt, file_type):
|
|
|
174 |
central = pytz.timezone('US/Central')
|
175 |
safe_date_time = datetime.now(central).strftime("%m%d_%H%M")
|
176 |
replaced_prompt = re.sub(r'[<>:"/\\|?*\n]', ' ', prompt)
|
177 |
safe_prompt = re.sub(r'\s+', ' ', replaced_prompt).strip()[:240]
|
178 |
return f"{safe_date_time}_{safe_prompt}.{file_type}"
|
179 |
|
|
|
|
|
|
|
|
|
180 |
def create_file(filename, prompt, response, should_save=True):
|
181 |
if not should_save:
|
182 |
return
|
183 |
with open(filename, 'w', encoding='utf-8') as file:
|
184 |
file.write(prompt + "\n\n" + response)
|
185 |
|
|
|
|
|
186 |
def create_and_save_file(content, file_type="md", prompt=None, is_image=False, should_save=True):
|
|
|
187 |
if not should_save:
|
188 |
return None
|
189 |
filename = generate_filename(prompt if prompt else content, file_type)
|
@@ -195,42 +214,41 @@ def create_and_save_file(content, file_type="md", prompt=None, is_image=False, s
|
|
195 |
return filename
|
196 |
|
197 |
def get_download_link(file_path):
|
|
|
198 |
with open(file_path, "rb") as file:
|
199 |
contents = file.read()
|
200 |
b64 = base64.b64encode(contents).decode()
|
201 |
return f'<a href="data:file/txt;base64,{b64}" download="{os.path.basename(file_path)}">Download {os.path.basename(file_path)}π</a>'
|
202 |
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
Your browser does not support the audio element.
|
229 |
-
</audio>
|
230 |
-
'''
|
231 |
|
232 |
# Media Processing Functions
|
233 |
def process_image(image_input, user_prompt):
|
|
|
234 |
if isinstance(image_input, str):
|
235 |
with open(image_input, "rb") as image_file:
|
236 |
image_input = image_file.read()
|
@@ -254,6 +272,7 @@ def process_image(image_input, user_prompt):
|
|
254 |
return response.choices[0].message.content
|
255 |
|
256 |
def process_audio(audio_input, text_input=''):
|
|
|
257 |
if isinstance(audio_input, str):
|
258 |
with open(audio_input, "rb") as file:
|
259 |
audio_input = file.read()
|
@@ -267,11 +286,13 @@ def process_audio(audio_input, text_input=''):
|
|
267 |
|
268 |
with st.chat_message("assistant"):
|
269 |
st.markdown(transcription.text)
|
|
|
270 |
|
271 |
filename = generate_filename(transcription.text, "wav")
|
272 |
create_and_save_file(audio_input, "wav", transcription.text, True)
|
273 |
|
274 |
def process_video(video_path, seconds_per_frame=1):
|
|
|
275 |
base64Frames = []
|
276 |
video = cv2.VideoCapture(video_path)
|
277 |
total_frames = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
|
@@ -302,6 +323,7 @@ def process_video(video_path, seconds_per_frame=1):
|
|
302 |
return base64Frames, audio_path
|
303 |
|
304 |
def process_video_with_gpt(video_input, user_prompt):
|
|
|
305 |
base64Frames, audio_path = process_video(video_input)
|
306 |
|
307 |
response = openai_client.chat.completions.create(
|
@@ -317,9 +339,104 @@ def process_video_with_gpt(video_input, user_prompt):
|
|
317 |
)
|
318 |
|
319 |
return response.choices[0].message.content
|
320 |
-
|
321 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
322 |
def create_media_gallery():
|
|
|
323 |
st.header("π¬ Media Gallery")
|
324 |
|
325 |
tabs = st.tabs(["πΌοΈ Images", "π΅ Audio", "π₯ Video", "π¨ Scene Generator"])
|
|
|
50 |
}
|
51 |
)
|
52 |
|
53 |
+
# 2. Load environment variables and initialize clients
|
54 |
+
load_dotenv()
|
55 |
+
|
56 |
+
# OpenAI setup
|
57 |
+
openai.api_key = os.getenv('OPENAI_API_KEY')
|
58 |
+
if openai.api_key == None:
|
59 |
+
openai.api_key = st.secrets['OPENAI_API_KEY']
|
60 |
+
|
61 |
+
openai_client = OpenAI(
|
62 |
+
api_key=os.getenv('OPENAI_API_KEY'),
|
63 |
+
organization=os.getenv('OPENAI_ORG_ID')
|
64 |
+
)
|
65 |
+
|
66 |
+
# Claude setup
|
67 |
+
anthropic_key = os.getenv("ANTHROPIC_API_KEY_3")
|
68 |
+
if anthropic_key == None:
|
69 |
+
anthropic_key = st.secrets["ANTHROPIC_API_KEY"]
|
70 |
+
claude_client = anthropic.Anthropic(api_key=anthropic_key)
|
71 |
+
|
72 |
+
# HuggingFace setup
|
73 |
+
API_URL = os.getenv('API_URL')
|
74 |
+
HF_KEY = os.getenv('HF_KEY')
|
75 |
+
MODEL1 = "meta-llama/Llama-2-7b-chat-hf"
|
76 |
+
MODEL2 = "openai/whisper-small.en"
|
77 |
+
|
78 |
+
headers = {
|
79 |
+
"Authorization": f"Bearer {HF_KEY}",
|
80 |
+
"Content-Type": "application/json"
|
81 |
+
}
|
82 |
+
|
83 |
+
# Initialize session states
|
84 |
+
if "chat_history" not in st.session_state:
|
85 |
+
st.session_state.chat_history = []
|
86 |
+
if "openai_model" not in st.session_state:
|
87 |
+
st.session_state["openai_model"] = "gpt-4o-2024-05-13"
|
88 |
+
if "messages" not in st.session_state:
|
89 |
+
st.session_state.messages = []
|
90 |
+
|
91 |
# Custom CSS
|
92 |
st.markdown("""
|
93 |
<style>
|
|
|
128 |
</style>
|
129 |
""", unsafe_allow_html=True)
|
130 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
131 |
# Bike Collections
|
132 |
bike_collections = {
|
133 |
"Celestial Collection π": {
|
|
|
182 |
|
183 |
# Helper Functions
|
184 |
def generate_filename(prompt, file_type):
|
185 |
+
"""Generate a safe filename using the prompt and file type."""
|
186 |
central = pytz.timezone('US/Central')
|
187 |
safe_date_time = datetime.now(central).strftime("%m%d_%H%M")
|
188 |
replaced_prompt = re.sub(r'[<>:"/\\|?*\n]', ' ', prompt)
|
189 |
safe_prompt = re.sub(r'\s+', ' ', replaced_prompt).strip()[:240]
|
190 |
return f"{safe_date_time}_{safe_prompt}.{file_type}"
|
191 |
|
192 |
+
|
193 |
+
|
194 |
+
|
195 |
+
# Function to create and save a file (and avoid the black hole of lost data π³)
|
196 |
def create_file(filename, prompt, response, should_save=True):
|
197 |
if not should_save:
|
198 |
return
|
199 |
with open(filename, 'w', encoding='utf-8') as file:
|
200 |
file.write(prompt + "\n\n" + response)
|
201 |
|
202 |
+
|
203 |
+
|
204 |
def create_and_save_file(content, file_type="md", prompt=None, is_image=False, should_save=True):
|
205 |
+
"""Create and save file with proper handling of different types."""
|
206 |
if not should_save:
|
207 |
return None
|
208 |
filename = generate_filename(prompt if prompt else content, file_type)
|
|
|
214 |
return filename
|
215 |
|
216 |
def get_download_link(file_path):
|
217 |
+
"""Create download link for file."""
|
218 |
with open(file_path, "rb") as file:
|
219 |
contents = file.read()
|
220 |
b64 = base64.b64encode(contents).decode()
|
221 |
return f'<a href="data:file/txt;base64,{b64}" download="{os.path.basename(file_path)}">Download {os.path.basename(file_path)}π</a>'
|
222 |
|
223 |
+
@st.cache_resource
|
224 |
+
def SpeechSynthesis(result):
|
225 |
+
"""HTML5 Speech Synthesis."""
|
226 |
+
documentHTML5 = f'''
|
227 |
+
<!DOCTYPE html>
|
228 |
+
<html>
|
229 |
+
<head>
|
230 |
+
<title>Read It Aloud</title>
|
231 |
+
<script type="text/javascript">
|
232 |
+
function readAloud() {{
|
233 |
+
const text = document.getElementById("textArea").value;
|
234 |
+
const speech = new SpeechSynthesisUtterance(text);
|
235 |
+
window.speechSynthesis.speak(speech);
|
236 |
+
}}
|
237 |
+
</script>
|
238 |
+
</head>
|
239 |
+
<body>
|
240 |
+
<h1>π Read It Aloud</h1>
|
241 |
+
<textarea id="textArea" rows="10" cols="80">{result}</textarea>
|
242 |
+
<br>
|
243 |
+
<button onclick="readAloud()">π Read Aloud</button>
|
244 |
+
</body>
|
245 |
+
</html>
|
246 |
+
'''
|
247 |
+
components.html(documentHTML5, width=1280, height=300)
|
|
|
|
|
|
|
248 |
|
249 |
# Media Processing Functions
|
250 |
def process_image(image_input, user_prompt):
|
251 |
+
"""Process image with GPT-4o vision."""
|
252 |
if isinstance(image_input, str):
|
253 |
with open(image_input, "rb") as image_file:
|
254 |
image_input = image_file.read()
|
|
|
272 |
return response.choices[0].message.content
|
273 |
|
274 |
def process_audio(audio_input, text_input=''):
|
275 |
+
"""Process audio with Whisper and GPT."""
|
276 |
if isinstance(audio_input, str):
|
277 |
with open(audio_input, "rb") as file:
|
278 |
audio_input = file.read()
|
|
|
286 |
|
287 |
with st.chat_message("assistant"):
|
288 |
st.markdown(transcription.text)
|
289 |
+
SpeechSynthesis(transcription.text)
|
290 |
|
291 |
filename = generate_filename(transcription.text, "wav")
|
292 |
create_and_save_file(audio_input, "wav", transcription.text, True)
|
293 |
|
294 |
def process_video(video_path, seconds_per_frame=1):
|
295 |
+
"""Process video files for frame extraction and audio."""
|
296 |
base64Frames = []
|
297 |
video = cv2.VideoCapture(video_path)
|
298 |
total_frames = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
|
|
|
323 |
return base64Frames, audio_path
|
324 |
|
325 |
def process_video_with_gpt(video_input, user_prompt):
|
326 |
+
"""Process video with GPT-4o vision."""
|
327 |
base64Frames, audio_path = process_video(video_input)
|
328 |
|
329 |
response = openai_client.chat.completions.create(
|
|
|
339 |
)
|
340 |
|
341 |
return response.choices[0].message.content
|
342 |
+
|
343 |
+
# ArXiv Search Functions
|
344 |
+
def search_arxiv(query):
|
345 |
+
"""Search ArXiv papers using Hugging Face client."""
|
346 |
+
client = Client("awacke1/Arxiv-Paper-Search-And-QA-RAG-Pattern")
|
347 |
+
response = client.predict(
|
348 |
+
query,
|
349 |
+
"mistralai/Mixtral-8x7B-Instruct-v0.1",
|
350 |
+
True,
|
351 |
+
api_name="/ask_llm"
|
352 |
+
)
|
353 |
+
return response
|
354 |
+
|
355 |
+
# Chat Processing Functions
|
356 |
+
def process_with_gpt(text_input):
|
357 |
+
"""Process text with GPT-4o."""
|
358 |
+
if text_input:
|
359 |
+
st.session_state.messages.append({"role": "user", "content": text_input})
|
360 |
+
|
361 |
+
with st.chat_message("user"):
|
362 |
+
st.markdown(text_input)
|
363 |
+
|
364 |
+
with st.chat_message("assistant"):
|
365 |
+
completion = openai_client.chat.completions.create(
|
366 |
+
model=st.session_state["openai_model"],
|
367 |
+
messages=[
|
368 |
+
{"role": m["role"], "content": m["content"]}
|
369 |
+
for m in st.session_state.messages
|
370 |
+
],
|
371 |
+
stream=False
|
372 |
+
)
|
373 |
+
return_text = completion.choices[0].message.content
|
374 |
+
st.write("GPT-4o: " + return_text)
|
375 |
+
|
376 |
+
filename = generate_filename(text_input, "md")
|
377 |
+
create_file(filename, text_input, return_text)
|
378 |
+
st.session_state.messages.append({"role": "assistant", "content": return_text})
|
379 |
+
return return_text
|
380 |
+
|
381 |
+
def process_with_claude(text_input):
|
382 |
+
"""Process text with Claude."""
|
383 |
+
if text_input:
|
384 |
+
response = claude_client.messages.create(
|
385 |
+
model="claude-3-sonnet-20240229",
|
386 |
+
max_tokens=1000,
|
387 |
+
messages=[
|
388 |
+
{"role": "user", "content": text_input}
|
389 |
+
]
|
390 |
+
)
|
391 |
+
response_text = response.content[0].text
|
392 |
+
st.write("Claude: " + response_text)
|
393 |
+
|
394 |
+
filename = generate_filename(text_input, "md")
|
395 |
+
create_file(filename, text_input, response_text)
|
396 |
+
|
397 |
+
st.session_state.chat_history.append({
|
398 |
+
"user": text_input,
|
399 |
+
"claude": response_text
|
400 |
+
})
|
401 |
+
return response_text
|
402 |
+
|
403 |
+
# File Management Functions
|
404 |
+
def load_file(file_name):
|
405 |
+
"""Load file content."""
|
406 |
+
with open(file_name, "r", encoding='utf-8') as file:
|
407 |
+
content = file.read()
|
408 |
+
return content
|
409 |
+
|
410 |
+
def create_zip_of_files(files):
|
411 |
+
"""Create zip archive of files."""
|
412 |
+
zip_name = "all_files.zip"
|
413 |
+
with zipfile.ZipFile(zip_name, 'w') as zipf:
|
414 |
+
for file in files:
|
415 |
+
zipf.write(file)
|
416 |
+
return zip_name
|
417 |
+
|
418 |
+
|
419 |
+
|
420 |
+
def get_media_html(media_path, media_type="video", width="100%"):
|
421 |
+
"""Generate HTML for media player."""
|
422 |
+
media_data = base64.b64encode(open(media_path, 'rb').read()).decode()
|
423 |
+
if media_type == "video":
|
424 |
+
return f'''
|
425 |
+
<video width="{width}" controls autoplay muted loop>
|
426 |
+
<source src="data:video/mp4;base64,{media_data}" type="video/mp4">
|
427 |
+
Your browser does not support the video tag.
|
428 |
+
</video>
|
429 |
+
'''
|
430 |
+
else: # audio
|
431 |
+
return f'''
|
432 |
+
<audio controls style="width: {width};">
|
433 |
+
<source src="data:audio/mpeg;base64,{media_data}" type="audio/mpeg">
|
434 |
+
Your browser does not support the audio element.
|
435 |
+
</audio>
|
436 |
+
'''
|
437 |
+
|
438 |
def create_media_gallery():
|
439 |
+
"""Create the media gallery interface."""
|
440 |
st.header("π¬ Media Gallery")
|
441 |
|
442 |
tabs = st.tabs(["πΌοΈ Images", "π΅ Audio", "π₯ Video", "π¨ Scene Generator"])
|