Spaces:
Running
Running
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,280 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import streamlit as st
|
3 |
+
from googleapiclient.discovery import build
|
4 |
+
import speech_recognition as sr
|
5 |
+
import wikipediaapi
|
6 |
+
import datetime
|
7 |
+
from reportlab.lib.pagesizes import letter
|
8 |
+
from reportlab.pdfgen import canvas
|
9 |
+
import tempfile
|
10 |
+
from gtts import gTTS
|
11 |
+
import requests
|
12 |
+
import json
|
13 |
+
import pandas as pd
|
14 |
+
import altair as alt
|
15 |
+
from datetime import date
|
16 |
+
|
17 |
+
# Set up YouTube API
|
18 |
+
API_KEY_YOUTUBE = "AIzaSyA20DXMC3HeqHs9sOMQUQ041wEkgsoFXb4" # Replace with your YouTube Data API v3 key
|
19 |
+
youtube = build('youtube', 'v3', developerKey=API_KEY_YOUTUBE)
|
20 |
+
|
21 |
+
# Hugging Face Setup
|
22 |
+
HF_API_KEY = os.getenv("KEY")
|
23 |
+
HF_MISTRAL_URL = "https://api-inference.huggingface.co/models/mistralai/Mistral-7B-Instruct-v0.3"
|
24 |
+
|
25 |
+
def chat_with_mistral_hf(prompt):
|
26 |
+
if not HF_API_KEY:
|
27 |
+
return "Error: API key not found. Please set it in Hugging Face Secrets."
|
28 |
+
|
29 |
+
headers = {"Authorization": f"Bearer {HF_API_KEY}"}
|
30 |
+
payload = {"inputs": prompt, "parameters": {"max_length": 200, "temperature": 0.7}}
|
31 |
+
|
32 |
+
response = requests.post(HF_MISTRAL_URL, json=payload, headers=headers)
|
33 |
+
|
34 |
+
if response.status_code == 200:
|
35 |
+
return response.json()[0]["generated_text"]
|
36 |
+
else:
|
37 |
+
return f"Error: {response.json()}"
|
38 |
+
|
39 |
+
# Function to search YouTube videos
|
40 |
+
def search_youtube(query, max_results=5):
|
41 |
+
try:
|
42 |
+
request = youtube.search().list(
|
43 |
+
q=query,
|
44 |
+
part='id,snippet',
|
45 |
+
maxResults=max_results,
|
46 |
+
type='video'
|
47 |
+
)
|
48 |
+
response = request.execute()
|
49 |
+
|
50 |
+
videos = []
|
51 |
+
for item in response['items']:
|
52 |
+
video_id = item['id']['videoId']
|
53 |
+
title = item['snippet']['title']
|
54 |
+
thumbnail = item['snippet']['thumbnails']['default']['url']
|
55 |
+
url = f'https://www.youtube.com/watch?v={video_id}'
|
56 |
+
videos.append({'title': title, 'url': url, 'video_id': video_id, 'thumbnail': thumbnail})
|
57 |
+
return videos
|
58 |
+
except Exception as e:
|
59 |
+
st.write(f"Error fetching videos: {e}")
|
60 |
+
return []
|
61 |
+
|
62 |
+
# Function for voice recognition
|
63 |
+
def voice_search():
|
64 |
+
recognizer = sr.Recognizer()
|
65 |
+
with sr.Microphone() as source:
|
66 |
+
st.write("Listening...")
|
67 |
+
audio = recognizer.listen(source)
|
68 |
+
try:
|
69 |
+
query = recognizer.recognize_google(audio)
|
70 |
+
st.success(f"You said: {query}")
|
71 |
+
return query
|
72 |
+
except sr.UnknownValueError:
|
73 |
+
st.error("Could not understand audio")
|
74 |
+
return ""
|
75 |
+
except sr.RequestError as e:
|
76 |
+
st.error(f"Could not request results from Google Speech Recognition service; {e}")
|
77 |
+
return ""
|
78 |
+
|
79 |
+
# Wikipedia summary function with character limit and summary levels
|
80 |
+
def get_wikipedia_summary(query, lang_code, char_limit, summary_level):
|
81 |
+
user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)"
|
82 |
+
wiki = wikipediaapi.Wikipedia(language=lang_code, extract_format=wikipediaapi.ExtractFormat.WIKI, user_agent=user_agent)
|
83 |
+
page = wiki.page(query)
|
84 |
+
if not page.exists():
|
85 |
+
return "Page not found."
|
86 |
+
if summary_level == "Brief":
|
87 |
+
return page.summary[:char_limit]
|
88 |
+
elif summary_level == "Detailed":
|
89 |
+
return page.summary # Full summary
|
90 |
+
elif summary_level == "Bullet Points":
|
91 |
+
points = page.summary.split('. ')
|
92 |
+
return '\n'.join(f"- {p.strip()}" for p in points if p)[:char_limit]
|
93 |
+
|
94 |
+
# Save chat history as PDF with a user-defined filename
|
95 |
+
def save_chat_history_as_pdf(chat_history, file_name):
|
96 |
+
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
97 |
+
with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as tmp_file:
|
98 |
+
pdf = canvas.Canvas(tmp_file.name, pagesize=letter)
|
99 |
+
pdf.setTitle(file_name)
|
100 |
+
pdf.drawString(30, 750, f"{file_name} - Saved on {timestamp}")
|
101 |
+
y_position = 720
|
102 |
+
for query, response in chat_history:
|
103 |
+
pdf.drawString(30, y_position, f"User: {query}")
|
104 |
+
y_position -= 20
|
105 |
+
pdf.drawString(30, y_position, f"Bot: {response}")
|
106 |
+
y_position -= 40
|
107 |
+
if y_position < 40:
|
108 |
+
pdf.showPage()
|
109 |
+
y_position = 750
|
110 |
+
pdf.save()
|
111 |
+
return tmp_file.name
|
112 |
+
|
113 |
+
# Text-to-speech using gTTS
|
114 |
+
def text_to_speech(text, filename, lang="en"):
|
115 |
+
tts = gTTS(text=text, lang=lang)
|
116 |
+
tts.save(filename)
|
117 |
+
return filename
|
118 |
+
|
119 |
+
# Function to perform Google Search
|
120 |
+
def google_search(api_key, cse_id, query, num_results=10):
|
121 |
+
url = "https://www.googleapis.com/customsearch/v1"
|
122 |
+
params = {'key': api_key, 'cx': cse_id, 'q': query, 'num': num_results}
|
123 |
+
response = requests.get(url, params=params)
|
124 |
+
return response.json()
|
125 |
+
|
126 |
+
# Display Google Search Results
|
127 |
+
def display_google_results(results):
|
128 |
+
if "items" in results:
|
129 |
+
for item in results['items']:
|
130 |
+
st.write(f"**{item['title']}**")
|
131 |
+
st.write(item['snippet'])
|
132 |
+
st.write(f"[Read more]({item['link']})")
|
133 |
+
st.write("---")
|
134 |
+
else:
|
135 |
+
st.error("No results found.")
|
136 |
+
|
137 |
+
# News Search Function
|
138 |
+
def search_news(query, from_date=None, to_date=None):
|
139 |
+
api_key = '43283de608cc43b7a49ad17ceda39636' # Replace with your News API key
|
140 |
+
url = f"https://newsapi.org/v2/everything?q={query}&apiKey={api_key}"
|
141 |
+
if from_date and to_date:
|
142 |
+
url += f"&from={from_date}&to={to_date}"
|
143 |
+
response = requests.get(url)
|
144 |
+
return response.json()
|
145 |
+
|
146 |
+
# Display News Results
|
147 |
+
def display_news(articles):
|
148 |
+
if "articles" in articles:
|
149 |
+
for article in articles['articles']:
|
150 |
+
st.write(f"**{article['title']}**")
|
151 |
+
st.write(article['description'])
|
152 |
+
st.write(f"[Read more]({article['url']})")
|
153 |
+
st.write("---")
|
154 |
+
else:
|
155 |
+
st.error("No news articles found.")
|
156 |
+
|
157 |
+
def main():
|
158 |
+
st.set_page_config(page_title="Multi-Search Application", layout="wide")
|
159 |
+
|
160 |
+
# Initialize chat history if not present
|
161 |
+
if "chat_history" not in st.session_state:
|
162 |
+
st.session_state.chat_history = []
|
163 |
+
|
164 |
+
# Sidebar options
|
165 |
+
st.sidebar.title("Options")
|
166 |
+
search_type = st.sidebar.radio("Select Search Type", ("Wikipedia", "Google", "YouTube", "News", "Chat"))
|
167 |
+
|
168 |
+
if st.sidebar.button("Voice Search"):
|
169 |
+
query = voice_search()
|
170 |
+
if query:
|
171 |
+
st.session_state.query = query
|
172 |
+
else:
|
173 |
+
st.session_state.query = ""
|
174 |
+
|
175 |
+
# Chat-specific sidebar settings
|
176 |
+
chat_title = "Temporary Chat"
|
177 |
+
if search_type == "Chat":
|
178 |
+
chat_title = st.sidebar.text_input("Rename Chat:", "Temporary Chat")
|
179 |
+
|
180 |
+
# Last seen timestamp
|
181 |
+
st.sidebar.write(f"Last seen: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
182 |
+
|
183 |
+
if search_type == "Wikipedia":
|
184 |
+
lang_map = {"English": "en", "Spanish": "es", "Chinese": "zh", "Hindi": "hi", "Telugu": "te"}
|
185 |
+
selected_lang = st.sidebar.selectbox("Wikipedia Language", list(lang_map.keys()))
|
186 |
+
summary_levels = ["Brief", "Detailed", "Bullet Points"]
|
187 |
+
summary_level = st.sidebar.selectbox("Summarization Level", summary_levels)
|
188 |
+
char_limit = st.sidebar.slider("Character Limit", min_value=100, max_value=2000, value=500, step=100)
|
189 |
+
|
190 |
+
st.title("Wikipedia Summary & Text-to-Speech")
|
191 |
+
query = st.text_input("Enter a topic to search on Wikipedia:", value=st.session_state.query)
|
192 |
+
|
193 |
+
if query:
|
194 |
+
lang_code = lang_map[selected_lang]
|
195 |
+
summary = get_wikipedia_summary(query, lang_code, char_limit, summary_level)
|
196 |
+
st.markdown(f"### Summary for: {query}")
|
197 |
+
st.write(summary)
|
198 |
+
|
199 |
+
tts_filename = f"{query}_speech.mp3"
|
200 |
+
if st.button("Play Text-to-Speech"):
|
201 |
+
text_to_speech(summary, tts_filename, lang=lang_code)
|
202 |
+
st.audio(tts_filename, format="audio/mp3")
|
203 |
+
|
204 |
+
st.write("---")
|
205 |
+
st.write("### Footer")
|
206 |
+
st.write("This is a Wikipedia search section. You can find detailed information and summaries here.")
|
207 |
+
|
208 |
+
elif search_type == "Google":
|
209 |
+
st.title("Google Search")
|
210 |
+
query = st.text_input("Enter a search query for Google:", value=st.session_state.query)
|
211 |
+
if query and st.button("Search"):
|
212 |
+
results = google_search("AIzaSyBvnTpjwspsYBMlHN4nMEvybEmZL8mwAQ4", "464947c4e602c4ee8", query)
|
213 |
+
display_google_results(results)
|
214 |
+
|
215 |
+
st.write("---")
|
216 |
+
st.write("### Footer")
|
217 |
+
st.write("This is a Google search section. Use it to find websites and online resources.")
|
218 |
+
|
219 |
+
elif search_type == "YouTube":
|
220 |
+
st.title("YouTube Search")
|
221 |
+
query = st.text_input("Enter a topic to search on YouTube:", value=st.session_state.query)
|
222 |
+
if query and st.button("Search"):
|
223 |
+
videos = search_youtube(query)
|
224 |
+
if videos:
|
225 |
+
for video in videos:
|
226 |
+
st.write(f"[{video['title']}]({video['url']})")
|
227 |
+
st.image(video['thumbnail'])
|
228 |
+
st.video(video['url'])
|
229 |
+
st.write("---")
|
230 |
+
|
231 |
+
st.write("---")
|
232 |
+
st.write("### Footer")
|
233 |
+
st.write("This is a YouTube search section. Watch videos directly from your search results.")
|
234 |
+
|
235 |
+
elif search_type == "News":
|
236 |
+
st.subheader("Select Date Range")
|
237 |
+
start_date = st.date_input("From", datetime.date.today() - datetime.timedelta(days=7))
|
238 |
+
end_date = st.date_input("To", datetime.date.today())
|
239 |
+
|
240 |
+
st.title("News Search")
|
241 |
+
query = st.text_input("Enter a news topic to search:", value=st.session_state.query)
|
242 |
+
if query and st.button("Search"):
|
243 |
+
articles = search_news(query, start_date, end_date)
|
244 |
+
display_news(articles)
|
245 |
+
|
246 |
+
st.write("---")
|
247 |
+
st.write("### Footer")
|
248 |
+
st.write("This is a news search section. Find the latest news articles here.")
|
249 |
+
|
250 |
+
elif search_type == "Chat":
|
251 |
+
st.title(chat_title)
|
252 |
+
|
253 |
+
for chat in st.session_state.chat_history:
|
254 |
+
with st.chat_message(chat["role"]):
|
255 |
+
st.write(chat["content"])
|
256 |
+
|
257 |
+
user_input = st.text_area("Ask AI:", height=100, key="query", label_visibility="collapsed")
|
258 |
+
|
259 |
+
if st.button("Generate Response"):
|
260 |
+
if user_input.strip():
|
261 |
+
with st.spinner("Generating response..."):
|
262 |
+
response = chat_with_mistral_hf(user_input)
|
263 |
+
|
264 |
+
st.session_state.chat_history.append({"role": "user", "content": user_input})
|
265 |
+
st.session_state.chat_history.append({"role": "assistant", "content": response})
|
266 |
+
st.rerun()
|
267 |
+
else:
|
268 |
+
st.warning("Please enter a prompt before clicking Generate Response.")
|
269 |
+
|
270 |
+
# Save chat history as PDF
|
271 |
+
if st.button("Save Chat History as PDF"):
|
272 |
+
chat_history = []
|
273 |
+
if st.session_state.query:
|
274 |
+
chat_history.append((st.session_state.query, "Your response here"))
|
275 |
+
file_name = st.text_input("Enter filename for PDF:", "chat_history.pdf")
|
276 |
+
pdf_file = save_chat_history_as_pdf(chat_history, file_name)
|
277 |
+
st.success(f"Chat history saved as PDF: {pdf_file}")
|
278 |
+
|
279 |
+
if __name__ == "__main__":
|
280 |
+
main()
|