Update app.py
Browse files
app.py
CHANGED
@@ -10,6 +10,7 @@ from streamlit.components.v1 import html
|
|
10 |
from PIL import Image
|
11 |
import re
|
12 |
from urllib.parse import quote
|
|
|
13 |
|
14 |
# Set up the Anthropic client
|
15 |
client = anthropic.Anthropic(api_key=os.environ.get("ANTHROPIC_API_KEY"))
|
@@ -18,73 +19,44 @@ client = anthropic.Anthropic(api_key=os.environ.get("ANTHROPIC_API_KEY"))
|
|
18 |
if "chat_history" not in st.session_state:
|
19 |
st.session_state.chat_history = []
|
20 |
|
21 |
-
#
|
22 |
-
def get_download_link(file_path):
|
23 |
-
with open(file_path, "rb") as file:
|
24 |
-
contents = file.read()
|
25 |
-
b64 = base64.b64encode(contents).decode()
|
26 |
-
file_name = os.path.basename(file_path)
|
27 |
-
return f'<a href="data:file/txt;base64,{b64}" download="{file_name}">Download {file_name}</a>'
|
28 |
-
|
29 |
-
# Function to generate filename
|
30 |
-
def generate_filename(prompt, file_type):
|
31 |
-
central = pytz.timezone('US/Central')
|
32 |
-
safe_date_time = datetime.now(central).strftime("%m%d_%H%M")
|
33 |
-
replaced_prompt = prompt.replace(" ", "_").replace("\n", "_")
|
34 |
-
safe_prompt = "".join(x for x in replaced_prompt if x.isalnum() or x == "_")[:90]
|
35 |
-
return f"{safe_date_time}_{safe_prompt}.{file_type}"
|
36 |
-
|
37 |
-
# Function to create file
|
38 |
-
def create_file(filename, prompt, response, should_save=True):
|
39 |
-
if not should_save:
|
40 |
-
return
|
41 |
-
with open(filename, 'w', encoding='utf-8') as file:
|
42 |
-
file.write(prompt + "\n\n" + response)
|
43 |
-
|
44 |
-
# Function to load file content
|
45 |
-
def load_file(file_name):
|
46 |
-
with open(file_name, "r", encoding='utf-8') as file:
|
47 |
-
content = file.read()
|
48 |
-
return content
|
49 |
-
|
50 |
-
# Function to display glossary entity
|
51 |
-
def display_glossary_entity(k):
|
52 |
-
search_urls = {
|
53 |
-
"🚀🌌ArXiv": lambda k: f"/?q={quote(k)}",
|
54 |
-
"📖": lambda k: f"https://en.wikipedia.org/wiki/{quote(k)}",
|
55 |
-
"🔍": lambda k: f"https://www.google.com/search?q={quote(k)}",
|
56 |
-
"🎥": lambda k: f"https://www.youtube.com/results?search_query={quote(k)}",
|
57 |
-
}
|
58 |
-
links_md = ' '.join([f"[{emoji}]({url(k)})" for emoji, url in search_urls.items()])
|
59 |
-
st.markdown(f"**{k}** <small>{links_md}</small>", unsafe_allow_html=True)
|
60 |
-
|
61 |
-
# Function to create zip of files
|
62 |
-
def create_zip_of_files(files):
|
63 |
-
import zipfile
|
64 |
-
zip_name = "all_files.zip"
|
65 |
-
with zipfile.ZipFile(zip_name, 'w') as zipf:
|
66 |
-
for file in files:
|
67 |
-
zipf.write(file)
|
68 |
-
return zip_name
|
69 |
-
|
70 |
-
# Function to get zip download link
|
71 |
-
def get_zip_download_link(zip_file):
|
72 |
-
with open(zip_file, 'rb') as f:
|
73 |
-
data = f.read()
|
74 |
-
b64 = base64.b64encode(data).decode()
|
75 |
-
href = f'<a href="data:application/zip;base64,{b64}" download="{zip_file}">Download All</a>'
|
76 |
-
return href
|
77 |
|
78 |
# Function to create HTML for autoplaying and looping video
|
79 |
-
def get_video_html(video_path):
|
80 |
video_url = f"data:video/mp4;base64,{base64.b64encode(open(video_path, 'rb').read()).decode()}"
|
81 |
return f'''
|
82 |
-
<video width="
|
83 |
<source src="{video_url}" type="video/mp4">
|
84 |
Your browser does not support the video tag.
|
85 |
</video>
|
86 |
'''
|
87 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
# Streamlit app
|
89 |
def main():
|
90 |
st.title("Claude 3.5 Sonnet API Demo")
|
@@ -92,39 +64,17 @@ def main():
|
|
92 |
# Sidebar
|
93 |
st.sidebar.title("File Operations")
|
94 |
|
95 |
-
#
|
96 |
-
all_files = glob.glob("*.md")
|
97 |
-
all_files = [file for file in all_files if len(os.path.splitext(file)[0]) >= 10]
|
98 |
-
all_files.sort(key=lambda x: (os.path.splitext(x)[1], x), reverse=True)
|
99 |
-
|
100 |
-
if st.sidebar.button("🗑 Delete All"):
|
101 |
-
for file in all_files:
|
102 |
-
os.remove(file)
|
103 |
-
st.rerun()
|
104 |
-
|
105 |
-
if st.sidebar.button("⬇️ Download All"):
|
106 |
-
zip_file = create_zip_of_files(all_files)
|
107 |
-
st.sidebar.markdown(get_zip_download_link(zip_file), unsafe_allow_html=True)
|
108 |
-
|
109 |
-
for file in all_files:
|
110 |
-
col1, col2, col3, col4 = st.sidebar.columns([1,3,1,1])
|
111 |
-
with col1:
|
112 |
-
if st.button("🌐", key="view_"+file):
|
113 |
-
st.session_state.current_file = file
|
114 |
-
st.session_state.file_content = load_file(file)
|
115 |
-
with col2:
|
116 |
-
st.markdown(get_download_link(file), unsafe_allow_html=True)
|
117 |
-
with col3:
|
118 |
-
if st.button("📂", key="edit_"+file):
|
119 |
-
st.session_state.current_file = file
|
120 |
-
st.session_state.file_content = load_file(file)
|
121 |
-
with col4:
|
122 |
-
if st.button("🗑", key="delete_"+file):
|
123 |
-
os.remove(file)
|
124 |
-
st.rerun()
|
125 |
|
126 |
# Main content area
|
127 |
user_input = st.text_area("Enter your message:", height=100)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
128 |
|
129 |
if st.button("Send"):
|
130 |
if user_input:
|
@@ -146,28 +96,15 @@ def main():
|
|
146 |
# Add to chat history
|
147 |
st.session_state.chat_history.append({"user": user_input, "claude": response.content[0].text})
|
148 |
|
149 |
-
#
|
150 |
-
st.subheader("Chat History")
|
151 |
-
for chat in st.session_state.chat_history:
|
152 |
-
st.text_area("You:", chat["user"], height=100, disabled=True)
|
153 |
-
st.text_area("Claude:", chat["claude"], height=200, disabled=True)
|
154 |
-
st.markdown("---")
|
155 |
-
|
156 |
-
# File content viewer/editor
|
157 |
-
if hasattr(st.session_state, 'current_file'):
|
158 |
-
st.subheader(f"Editing: {st.session_state.current_file}")
|
159 |
-
new_content = st.text_area("File Content:", st.session_state.file_content, height=300)
|
160 |
-
if st.button("Save Changes"):
|
161 |
-
with open(st.session_state.current_file, 'w', encoding='utf-8') as file:
|
162 |
-
file.write(new_content)
|
163 |
-
st.success("File updated successfully!")
|
164 |
|
165 |
# Image Gallery
|
166 |
st.subheader("Image Gallery")
|
167 |
image_files = glob.glob("*.png") + glob.glob("*.jpg") + glob.glob("*.jpeg")
|
168 |
-
|
|
|
169 |
for idx, image_file in enumerate(image_files):
|
170 |
-
with cols[idx %
|
171 |
img = Image.open(image_file)
|
172 |
st.image(img, caption=image_file, use_column_width=True)
|
173 |
display_glossary_entity(os.path.splitext(image_file)[0])
|
@@ -175,9 +112,22 @@ def main():
|
|
175 |
# Video Gallery
|
176 |
st.subheader("Video Gallery")
|
177 |
video_files = glob.glob("*.mp4")
|
178 |
-
|
179 |
-
|
180 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
181 |
|
182 |
if __name__ == "__main__":
|
183 |
main()
|
|
|
10 |
from PIL import Image
|
11 |
import re
|
12 |
from urllib.parse import quote
|
13 |
+
import speech_recognition as sr
|
14 |
|
15 |
# Set up the Anthropic client
|
16 |
client = anthropic.Anthropic(api_key=os.environ.get("ANTHROPIC_API_KEY"))
|
|
|
19 |
if "chat_history" not in st.session_state:
|
20 |
st.session_state.chat_history = []
|
21 |
|
22 |
+
# ... (previous helper functions remain unchanged)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
|
24 |
# Function to create HTML for autoplaying and looping video
|
25 |
+
def get_video_html(video_path, width="100%"):
|
26 |
video_url = f"data:video/mp4;base64,{base64.b64encode(open(video_path, 'rb').read()).decode()}"
|
27 |
return f'''
|
28 |
+
<video width="{width}" controls autoplay muted loop>
|
29 |
<source src="{video_url}" type="video/mp4">
|
30 |
Your browser does not support the video tag.
|
31 |
</video>
|
32 |
'''
|
33 |
|
34 |
+
# Function to create HTML for audio player
|
35 |
+
def get_audio_html(audio_path, width="100%"):
|
36 |
+
audio_url = f"data:audio/mpeg;base64,{base64.b64encode(open(audio_path, 'rb').read()).decode()}"
|
37 |
+
return f'''
|
38 |
+
<audio controls style="width: {width};">
|
39 |
+
<source src="{audio_url}" type="audio/mpeg">
|
40 |
+
Your browser does not support the audio element.
|
41 |
+
</audio>
|
42 |
+
'''
|
43 |
+
|
44 |
+
# Function to transcribe speech
|
45 |
+
def transcribe_speech():
|
46 |
+
r = sr.Recognizer()
|
47 |
+
with sr.Microphone() as source:
|
48 |
+
st.write("Speak now...")
|
49 |
+
audio = r.listen(source)
|
50 |
+
st.write("Processing speech...")
|
51 |
+
try:
|
52 |
+
text = r.recognize_google(audio)
|
53 |
+
return text
|
54 |
+
except sr.UnknownValueError:
|
55 |
+
st.error("Sorry, I couldn't understand that.")
|
56 |
+
except sr.RequestError:
|
57 |
+
st.error("Sorry, there was an error processing your speech.")
|
58 |
+
return None
|
59 |
+
|
60 |
# Streamlit app
|
61 |
def main():
|
62 |
st.title("Claude 3.5 Sonnet API Demo")
|
|
|
64 |
# Sidebar
|
65 |
st.sidebar.title("File Operations")
|
66 |
|
67 |
+
# ... (file management code remains unchanged)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
68 |
|
69 |
# Main content area
|
70 |
user_input = st.text_area("Enter your message:", height=100)
|
71 |
+
|
72 |
+
# Speech input
|
73 |
+
if st.button("🎤 Speech Input"):
|
74 |
+
speech_text = transcribe_speech()
|
75 |
+
if speech_text:
|
76 |
+
user_input = speech_text
|
77 |
+
st.text_area("Transcribed Text:", speech_text, height=100)
|
78 |
|
79 |
if st.button("Send"):
|
80 |
if user_input:
|
|
|
96 |
# Add to chat history
|
97 |
st.session_state.chat_history.append({"user": user_input, "claude": response.content[0].text})
|
98 |
|
99 |
+
# ... (chat history and file content viewer/editor remain unchanged)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
|
101 |
# Image Gallery
|
102 |
st.subheader("Image Gallery")
|
103 |
image_files = glob.glob("*.png") + glob.glob("*.jpg") + glob.glob("*.jpeg")
|
104 |
+
image_cols = st.slider("Image Gallery Columns", min_value=1, max_value=5, value=3)
|
105 |
+
cols = st.columns(image_cols)
|
106 |
for idx, image_file in enumerate(image_files):
|
107 |
+
with cols[idx % image_cols]:
|
108 |
img = Image.open(image_file)
|
109 |
st.image(img, caption=image_file, use_column_width=True)
|
110 |
display_glossary_entity(os.path.splitext(image_file)[0])
|
|
|
112 |
# Video Gallery
|
113 |
st.subheader("Video Gallery")
|
114 |
video_files = glob.glob("*.mp4")
|
115 |
+
video_cols = st.slider("Video Gallery Columns", min_value=1, max_value=5, value=3)
|
116 |
+
cols = st.columns(video_cols)
|
117 |
+
for idx, video_file in enumerate(video_files):
|
118 |
+
with cols[idx % video_cols]:
|
119 |
+
st.markdown(get_video_html(video_file, width="100%"), unsafe_allow_html=True)
|
120 |
+
display_glossary_entity(os.path.splitext(video_file)[0])
|
121 |
+
|
122 |
+
# Audio Gallery
|
123 |
+
st.subheader("Audio Gallery")
|
124 |
+
audio_files = glob.glob("*.mp3") + glob.glob("*.wav")
|
125 |
+
audio_cols = st.slider("Audio Gallery Columns", min_value=1, max_value=5, value=3)
|
126 |
+
cols = st.columns(audio_cols)
|
127 |
+
for idx, audio_file in enumerate(audio_files):
|
128 |
+
with cols[idx % audio_cols]:
|
129 |
+
st.markdown(get_audio_html(audio_file, width="100%"), unsafe_allow_html=True)
|
130 |
+
display_glossary_entity(os.path.splitext(audio_file)[0])
|
131 |
|
132 |
if __name__ == "__main__":
|
133 |
main()
|