MuhammadAhmad332 commited on
Commit
ef51a4d
·
verified ·
1 Parent(s): 892819a

Upload 5 files

Browse files
Files changed (5) hide show
  1. .env +3 -0
  2. app.py +269 -0
  3. chat_history.json +10 -0
  4. preferences.json +3 -0
  5. requirements.txt +6 -0
.env ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ GROQ_API_KEY=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
2
+ BRIGHT_API_KEY=ded1bc00-4d84-4dee-b4d6-c896cadf2417
3
+ BRIGHT_ZONE=web_unlocker2
app.py ADDED
@@ -0,0 +1,269 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import json
3
+ import requests
4
+ import re
5
+ from bs4 import BeautifulSoup
6
+ from groq import Groq
7
+ import gradio as gr
8
+ from dotenv import load_dotenv
9
+ from youtube_transcript_api import YouTubeTranscriptApi
10
+
11
+ load_dotenv()
12
+
13
+
14
+ # ENV VARIABLES
15
+
16
+ GROQ_API_KEY = os.getenv("GROQ_API_KEY")
17
+ BRIGHT_API_KEY = os.getenv("BRIGHT_API_KEY")
18
+ BRIGHT_ZONE = os.getenv("BRIGHT_ZONE")
19
+
20
+ client = Groq(api_key=GROQ_API_KEY)
21
+
22
+ CHAT_FILE = "chat_history.json"
23
+ PREF_FILE = "preferences.json"
24
+
25
+
26
+ # SAFE LOAD & SAVE
27
+
28
+ def load_json(file, default):
29
+ if os.path.exists(file):
30
+ try:
31
+ with open(file, "r") as f:
32
+ return json.load(f)
33
+ except:
34
+ return default
35
+ return default
36
+
37
+ def save_json(file, data):
38
+ with open(file, "w") as f:
39
+ json.dump(data, f, indent=4)
40
+
41
+ conversation_history = load_json(CHAT_FILE, [])
42
+ user_preferences = load_json(PREF_FILE, {"style": "Default"})
43
+
44
+
45
+ # BRIGHT DATA SCRAPER
46
+
47
+ def brightdata_request(target_url):
48
+ response = requests.post(
49
+ "https://api.brightdata.com/request",
50
+ headers={
51
+ "Content-Type": "application/json",
52
+ "Authorization": f"Bearer {BRIGHT_API_KEY}"
53
+ },
54
+ json={
55
+ "zone": BRIGHT_ZONE,
56
+ "url": target_url,
57
+ "format": "raw"
58
+ }
59
+ )
60
+ return response.text
61
+
62
+
63
+ def scrape_goodreads(url):
64
+ html = brightdata_request(url)
65
+ soup = BeautifulSoup(html, "html.parser")
66
+
67
+ books = []
68
+ rows = soup.find_all("tr")
69
+
70
+ for row in rows:
71
+ title_tag = row.find("a", class_="bookTitle")
72
+ author_tag = row.find("a", class_="authorName")
73
+ rating_tag = row.find("span", class_="minirating")
74
+
75
+ if title_tag and author_tag and rating_tag:
76
+ books.append({
77
+ "title": title_tag.get_text(strip=True),
78
+ "author": author_tag.get_text(strip=True),
79
+ "rating": rating_tag.get_text(strip=True)
80
+ })
81
+
82
+ return books[:10]
83
+
84
+
85
+ def qa_bot(url, question):
86
+ books = scrape_goodreads(url)
87
+
88
+ if not books:
89
+ return "No book data found."
90
+
91
+ context = "\n".join(
92
+ [f"{i+1}. {b['title']} by {b['author']} - {b['rating']}"
93
+ for i, b in enumerate(books)]
94
+ )
95
+
96
+ system_prompt = f"""
97
+ You are a helpful assistant.
98
+ Answer ONLY using the following scraped Goodreads data.
99
+
100
+ {context}
101
+ """
102
+
103
+ response = client.chat.completions.create(
104
+ model="llama-3.1-8b-instant",
105
+ messages=[
106
+ {"role": "system", "content": system_prompt},
107
+ {"role": "user", "content": question}
108
+ ]
109
+ )
110
+
111
+ return response.choices[0].message.content
112
+
113
+ # YOUTUBE TRANSCRIPT
114
+
115
+ def extract_video_id(url):
116
+ pattern = r"(?:v=|youtu\.be/)([a-zA-Z0-9_-]{11})"
117
+ match = re.search(pattern, url)
118
+ return match.group(1) if match else None
119
+
120
+
121
+ def get_youtube_transcript(url):
122
+ video_id = extract_video_id(url)
123
+
124
+ if not video_id:
125
+ return "Invalid YouTube URL."
126
+
127
+ try:
128
+ api = YouTubeTranscriptApi()
129
+ transcript = api.fetch(video_id)
130
+ full_text = " ".join([entry.text for entry in transcript])
131
+ return full_text
132
+ except:
133
+ return "No transcript available for this video."
134
+
135
+
136
+ def youtube_qa(video_url, question):
137
+ transcript = get_youtube_transcript(video_url)
138
+
139
+ if transcript.startswith("No") or transcript.startswith("Invalid"):
140
+ return transcript
141
+
142
+ system_prompt = f"""
143
+ You are a helpful assistant.
144
+ Answer ONLY using this transcript.
145
+
146
+ Transcript:
147
+ {transcript[:6000]}
148
+ """
149
+
150
+ response = client.chat.completions.create(
151
+ model="llama-3.1-8b-instant",
152
+ messages=[
153
+ {"role": "system", "content": system_prompt},
154
+ {"role": "user", "content": question}
155
+ ]
156
+ )
157
+
158
+ return response.choices[0].message.content
159
+
160
+
161
+ # VERSION 3 — MEMORY CHAT
162
+
163
+ def chat_with_memory(user_message, preference_text):
164
+
165
+ global conversation_history, user_preferences
166
+
167
+ if preference_text and preference_text.strip():
168
+ user_preferences["style"] = preference_text
169
+ save_json(PREF_FILE, user_preferences)
170
+
171
+ system_prompt = f"""
172
+ You are a helpful AI assistant.
173
+
174
+ User Preferences:
175
+ {user_preferences.get("style", "Default")}
176
+
177
+ Follow the preferred style in all responses.
178
+ Maintain conversational memory.
179
+ """
180
+
181
+ messages = [{"role": "system", "content": system_prompt}]
182
+ messages.extend(conversation_history)
183
+ messages.append({"role": "user", "content": user_message})
184
+
185
+ response = client.chat.completions.create(
186
+ model="llama-3.1-8b-instant",
187
+ messages=messages
188
+ )
189
+
190
+ assistant_reply = response.choices[0].message.content
191
+
192
+ conversation_history.append({"role": "user", "content": user_message})
193
+ conversation_history.append({"role": "assistant", "content": assistant_reply})
194
+
195
+ save_json(CHAT_FILE, conversation_history)
196
+
197
+ return assistant_reply
198
+
199
+
200
+ def clear_memory():
201
+ global conversation_history
202
+ conversation_history = []
203
+ save_json(CHAT_FILE, [])
204
+ return []
205
+
206
+
207
+ # GRADIO MULTI-TAB UI
208
+
209
+ with gr.Blocks() as demo:
210
+
211
+ gr.Markdown("# 🚀 Full AI Assistant (V1 + V2 + V3)")
212
+
213
+ # TAB 1
214
+ with gr.Tab("🌐 Website Scraper Q&A"):
215
+ url_input = gr.Textbox(label="Enter Goodreads URL",
216
+ value="https://www.goodreads.com/list/show/1.Best_Books_Ever")
217
+ question_input = gr.Textbox(label="Ask your question")
218
+ output1 = gr.Textbox(label="Answer")
219
+ btn1 = gr.Button("Submit")
220
+
221
+ btn1.click(qa_bot, inputs=[url_input, question_input], outputs=output1)
222
+
223
+ # TAB 2
224
+ with gr.Tab("🎥 YouTube Transcript Q&A"):
225
+ video_input = gr.Textbox(label="Enter YouTube URL")
226
+ yt_question = gr.Textbox(label="Ask your question")
227
+ output2 = gr.Textbox(label="Answer")
228
+ btn2 = gr.Button("Submit")
229
+
230
+ btn2.click(youtube_qa, inputs=[video_input, yt_question], outputs=output2)
231
+
232
+ # TAB 3
233
+ with gr.Tab("🧠 Multi-Turn Assistant (Persistent Memory)"):
234
+
235
+ chatbot = gr.Chatbot(label="Conversation", value=conversation_history)
236
+
237
+ preference_input = gr.Textbox(
238
+ label="User Preferences (Optional)",
239
+ placeholder="Example: Respond formally / Be concise / Use bullet points"
240
+ )
241
+
242
+ user_message = gr.Textbox(label="Your Message")
243
+ send_btn = gr.Button("Send")
244
+ clear_btn = gr.Button("Clear Memory")
245
+
246
+ def chat_interface(user_message, preference_text, chat_display):
247
+ if not user_message.strip():
248
+ return "", chat_display
249
+
250
+ assistant_reply = chat_with_memory(user_message, preference_text)
251
+
252
+ chat_display.append({"role": "user", "content": user_message})
253
+ chat_display.append({"role": "assistant", "content": assistant_reply})
254
+
255
+ return "", chat_display
256
+
257
+ send_btn.click(
258
+ chat_interface,
259
+ inputs=[user_message, preference_input, chatbot],
260
+ outputs=[user_message, chatbot]
261
+ )
262
+
263
+ clear_btn.click(
264
+ clear_memory,
265
+ outputs=chatbot
266
+ )
267
+
268
+ if __name__ == "__main__":
269
+ demo.launch()
chat_history.json ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "role": "user",
4
+ "content": "can you tell me my name"
5
+ },
6
+ {
7
+ "role": "assistant",
8
+ "content": "I don't have any information about your name. We just started our conversation, and I'm a new AI each time you interact with me. I don't have any prior knowledge or memory of previous conversations. \n\nHowever, I can ask: If you'd like, you can tell me your name, and I can remember it and use it in our conversation."
9
+ }
10
+ ]
preferences.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ {
2
+ "style": "provide all ways python code"
3
+ }
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ gradio
2
+ groq
3
+ requests
4
+ beautifulsoup4
5
+ python-dotenv
6
+ youtube-transcript-api