Darsh1234Tayal commited on
Commit
a5d2546
·
verified ·
1 Parent(s): 7a2f1d7

Upload folder using huggingface_hub

Browse files
.ipynb_checkpoints/app-checkpoint.py ADDED
@@ -0,0 +1,389 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain_text_splitters import RecursiveCharacterTextSplitter
2
+ from langchain_chroma import Chroma
3
+ from langchain_huggingface import HuggingFaceEmbeddings
4
+ from bytez import Bytez
5
+ from youtube_transcript_api import YouTubeTranscriptApi
6
+ import gradio as gr
7
+ from dotenv import load_dotenv
8
+ import os
9
+ from urllib.parse import urlparse, parse_qs
10
+
11
+ load_dotenv("secrets.env")
12
+
13
+ api_key = os.getenv("BYTEZ_API_KEY")
14
+ sdk = Bytez(api_key)
15
+
16
+ #toy function
17
+ def video_id_extractor(link):
18
+ if "watch?v=" in link:
19
+ return link[32:43]
20
+ else:
21
+ return link[17:28]
22
+
23
+ #production ready function
24
+ def video_id_extractor(link):
25
+ parsed_url = urlparse(link)
26
+
27
+ if "youtube.com" in parsed_url.netloc:
28
+ return parse_qs(parsed_url.query).get("v", [None])[0]
29
+
30
+ elif "youtu.be" in parsed_url.netloc:
31
+ return parsed_url.path.lstrip("/")
32
+
33
+ return None
34
+
35
+ def generate_transcript(video_id):
36
+ trans = YouTubeTranscriptApi()
37
+ try:
38
+ transcript_raw = trans.fetch(video_id = video_id)
39
+ except Exception:
40
+ return None
41
+ transcript = ""
42
+ for i in transcript_raw.snippets:
43
+ transcript += f" {i.text}"
44
+ return transcript
45
+
46
+ def create_and_save_vs(trans):
47
+ try:
48
+ splitter = RecursiveCharacterTextSplitter(chunk_size = 100, chunk_overlap = 50)
49
+ docs = splitter.split_text(trans)
50
+ embeddings = HuggingFaceEmbeddings(model_name='sentence-transformers/all-mpnet-base-v2')
51
+ vector_store_db = Chroma.from_texts(docs, embeddings, persist_directory='chroma_db')
52
+ except Exception:
53
+ return None
54
+ return vector_store_db
55
+
56
+ def generate_summary(trans):
57
+ try:
58
+ model = sdk.model("openai/gpt-4o")
59
+ if len(trans.split(" ")) > 90000:
60
+ trans = trans.split(" ")[0:85000]
61
+ trans = " ".join(trans)
62
+ except Exception:
63
+ return None
64
+ Inp = [{"role": "system", "content": "You are a youtube transcipt sammurizer. Sammurize the transcript under 100 words"}, {"role":"user", "content":trans}]
65
+ trails = 4
66
+ failed = True
67
+ time_to_sleep = 3
68
+ while failed and trails > 0:
69
+ res = model.run(Inp)
70
+ if type(res) == list and len(res) == 3:
71
+ failed = False
72
+ trails -= 1
73
+ return res[0]["content"]
74
+ else:
75
+ time.sleep(time_to_sleep)
76
+ time_to_sleep = time_to_sleep **2
77
+ trails -= 1
78
+ return None
79
+
80
+ def setter(link):
81
+ yield gr.update(visible=False), gr.update(visible=True), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), "", ""
82
+ video_id = video_id_extractor(link)
83
+ if not video_id:
84
+ yield gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=True), gr.update(visible=False), gr.update(visible=False), "", ""
85
+ transcript = generate_transcript(video_id)
86
+ if not transcript:
87
+ yield gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=True), gr.update(visible=False), "", ""
88
+ vectorstore = create_and_save_vs(transcript)
89
+ if not vectorstore:
90
+ yield gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=True), "", ""
91
+ summary = generate_summary(transcript)
92
+ if not summary:
93
+ yield gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=True), "", ""
94
+ yield gr.update(visible=False), gr.update(visible=False), gr.update(visible=True), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), summary, vectorstore
95
+
96
+ def execute(vec, query):
97
+ try:
98
+ res = vec.similarity_search(query, k=3)
99
+ result = ""
100
+ for i in res:
101
+ result += f"\n{i.page_content}"
102
+ model = sdk.model("openai/gpt-4o")
103
+ inp = [{"role": "system", "content": "You are a helpful assistant - you will be asked a query and provided with a context. You have to answer that query based on the provided context - do not make things up. Do not reveal the whole context, answer as like you already knew the context"}, {"role":"user", "content":f"query: {query} | context: {result}"}]
104
+ res = model.run(inp)
105
+ return res[0]['content'], gr.update(visible=True), gr.update(visible=False)
106
+ except Exception:
107
+ return "", gr.update(visible=False), gr.update(visible=True)
108
+
109
+ with gr.Blocks(
110
+ theme=gr.themes.Soft(
111
+ primary_hue="blue",
112
+ secondary_hue="indigo",
113
+ ),
114
+ css="""
115
+ /* Global Styles */
116
+ .gradio-container {
117
+ font-family: 'Inter', 'Segoe UI', sans-serif !important;
118
+ max-width: 1200px !important;
119
+ margin: 0 auto !important;
120
+ }
121
+
122
+ /* Header Branding */
123
+ .header-brand {
124
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
125
+ padding: 2rem;
126
+ border-radius: 16px;
127
+ margin-bottom: 2rem;
128
+ box-shadow: 0 10px 40px rgba(102, 126, 234, 0.3);
129
+ animation: fadeInDown 0.8s ease-out;
130
+ }
131
+
132
+ .header-brand h1 {
133
+ color: white;
134
+ font-size: 2.5rem;
135
+ font-weight: 700;
136
+ margin: 0;
137
+ text-shadow: 2px 2px 4px rgba(0,0,0,0.2);
138
+ }
139
+
140
+ .header-brand p {
141
+ color: rgba(255,255,255,0.95);
142
+ font-size: 1.1rem;
143
+ margin: 0.5rem 0 0 0;
144
+ }
145
+
146
+ /* Footer Branding */
147
+ .footer-brand {
148
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
149
+ padding: 1.5rem;
150
+ border-radius: 12px;
151
+ margin-top: 2rem;
152
+ text-align: center;
153
+ box-shadow: 0 -5px 20px rgba(102, 126, 234, 0.2);
154
+ }
155
+
156
+ .footer-brand p {
157
+ color: white;
158
+ margin: 0.3rem 0;
159
+ font-size: 0.95rem;
160
+ }
161
+
162
+ .footer-brand a {
163
+ color: #ffd700;
164
+ text-decoration: none;
165
+ font-weight: 600;
166
+ transition: all 0.3s ease;
167
+ }
168
+
169
+ .footer-brand a:hover {
170
+ color: #fff;
171
+ text-shadow: 0 0 10px rgba(255,255,255,0.5);
172
+ }
173
+
174
+ /* Main Title Animation */
175
+ .main-title {
176
+ background: linear-gradient(90deg, #667eea, #764ba2, #667eea);
177
+ background-size: 200% auto;
178
+ color: white;
179
+ padding: 1.5rem;
180
+ border-radius: 12px;
181
+ text-align: center;
182
+ font-size: 1.8rem;
183
+ font-weight: 600;
184
+ margin-bottom: 2rem;
185
+ box-shadow: 0 8px 32px rgba(102, 126, 234, 0.4);
186
+ animation: gradientShift 3s ease infinite, fadeIn 1s ease-out;
187
+ }
188
+
189
+ /* Button Styles */
190
+ .gr-button {
191
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
192
+ border: none !important;
193
+ color: white !important;
194
+ font-weight: 600 !important;
195
+ padding: 12px 32px !important;
196
+ border-radius: 8px !important;
197
+ transition: all 0.3s ease !important;
198
+ box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4) !important;
199
+ text-transform: uppercase;
200
+ letter-spacing: 0.5px;
201
+ }
202
+
203
+ .gr-button:hover {
204
+ transform: translateY(-2px) !important;
205
+ box-shadow: 0 6px 25px rgba(102, 126, 234, 0.6) !important;
206
+ }
207
+
208
+ .gr-button:active {
209
+ transform: translateY(0px) !important;
210
+ }
211
+
212
+ /* Input Fields */
213
+ .gr-textbox, .gr-text-input {
214
+ border-radius: 8px !important;
215
+ border: 2px solid #e0e7ff !important;
216
+ transition: all 0.3s ease !important;
217
+ }
218
+
219
+ .gr-textbox:focus, .gr-text-input:focus {
220
+ border-color: #667eea !important;
221
+ box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1) !important;
222
+ }
223
+
224
+ /* Loading Animation */
225
+ .loading-container {
226
+ text-align: center;
227
+ padding: 3rem;
228
+ }
229
+
230
+ .loading-text {
231
+ font-size: 1.5rem;
232
+ color: #667eea;
233
+ animation: pulse 1.5s ease-in-out infinite;
234
+ }
235
+
236
+ /* Error Messages */
237
+ .error-message {
238
+ background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
239
+ color: white;
240
+ padding: 1.5rem;
241
+ border-radius: 12px;
242
+ text-align: center;
243
+ font-size: 1.3rem;
244
+ font-weight: 600;
245
+ box-shadow: 0 8px 32px rgba(245, 87, 108, 0.3);
246
+ animation: shake 0.5s ease-in-out;
247
+ }
248
+
249
+ /* Success/Summary Box */
250
+ .summary-box {
251
+ background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
252
+ padding: 1.5rem;
253
+ border-radius: 12px;
254
+ margin-bottom: 1.5rem;
255
+ box-shadow: 0 8px 24px rgba(168, 237, 234, 0.3);
256
+ animation: fadeInUp 0.6s ease-out;
257
+ }
258
+
259
+ /* Chat Section */
260
+ .chat-section {
261
+ animation: fadeInUp 0.8s ease-out;
262
+ }
263
+
264
+ /* Animations */
265
+ @keyframes fadeIn {
266
+ from {
267
+ opacity: 0;
268
+ }
269
+ to {
270
+ opacity: 1;
271
+ }
272
+ }
273
+
274
+ @keyframes fadeInDown {
275
+ from {
276
+ opacity: 0;
277
+ transform: translateY(-30px);
278
+ }
279
+ to {
280
+ opacity: 1;
281
+ transform: translateY(0);
282
+ }
283
+ }
284
+
285
+ @keyframes fadeInUp {
286
+ from {
287
+ opacity: 0;
288
+ transform: translateY(30px);
289
+ }
290
+ to {
291
+ opacity: 1;
292
+ transform: translateY(0);
293
+ }
294
+ }
295
+
296
+ @keyframes pulse {
297
+ 0%, 100% {
298
+ opacity: 1;
299
+ }
300
+ 50% {
301
+ opacity: 0.5;
302
+ }
303
+ }
304
+
305
+ @keyframes shake {
306
+ 0%, 100% { transform: translateX(0); }
307
+ 25% { transform: translateX(-10px); }
308
+ 75% { transform: translateX(10px); }
309
+ }
310
+
311
+ @keyframes gradientShift {
312
+ 0% {
313
+ background-position: 0% 50%;
314
+ }
315
+ 50% {
316
+ background-position: 100% 50%;
317
+ }
318
+ 100% {
319
+ background-position: 0% 50%;
320
+ }
321
+ }
322
+
323
+ /* Responsive Design */
324
+ @media (max-width: 768px) {
325
+ .header-brand h1 {
326
+ font-size: 1.8rem;
327
+ }
328
+ .main-title {
329
+ font-size: 1.3rem;
330
+ }
331
+ }
332
+ """
333
+ ) as ui:
334
+ # Header Branding
335
+ gr.HTML("""
336
+ <div class="header-brand">
337
+ <h1>🎓 AI YouTube Study Assistant</h1>
338
+ <p>Transform lengthy videos into concise knowledge</p>
339
+ </div>
340
+ """)
341
+
342
+ vs = gr.State()
343
+ gr.HTML('<div class="main-title">📹 Why watch long YouTube videos when you could study from AI?</div>')
344
+
345
+ with gr.Row(visible=True) as first_page:
346
+ youtube_link = gr.Textbox(
347
+ label="Enter the youtube link here: ",
348
+ lines=2,
349
+ placeholder="https://www.youtube.com/watch?v=..."
350
+ )
351
+ submit_button = gr.Button("SUBMIT!")
352
+
353
+ with gr.Row(visible=False) as chat_page:
354
+ with gr.Column():
355
+ summary = gr.Markdown(elem_classes="summary-box")
356
+ gr.Markdown("### 💬 Now ask any question about the video:")
357
+ ques = gr.Textbox(
358
+ label="Enter the question here: ",
359
+ lines=2,
360
+ placeholder="What is the main topic of this video?"
361
+ )
362
+ submit_answer = gr.Button("SUBMIT!")
363
+ answer = gr.TextArea(label="ANSWER")
364
+
365
+ with gr.Row(visible=False) as wrong_link_page:
366
+ gr.HTML('<div class="error-message">❌ Sorry, your link wasn\'t correct. Please try again!</div>')
367
+
368
+ with gr.Row(visible=False) as cc_not_enabled:
369
+ gr.HTML('<div class="error-message">⚠️ The link you provided was either not valid or subtitles weren\'t enabled in that video</div>')
370
+
371
+ with gr.Row(visible=False) as loading_page:
372
+ gr.HTML('<div class="loading-container"><div class="loading-text">⏳ Loading... Please Wait</div></div>')
373
+
374
+ with gr.Row(visible=False) as normal_error:
375
+ gr.HTML('<div class="error-message">😔 SORRY, SOME ERROR OCCURRED. PLEASE TRY AGAIN LATER</div>')
376
+
377
+ # Footer Branding
378
+ gr.HTML("""
379
+ <div class="footer-brand">
380
+ <p><strong>Developed by Darsh Tayal</strong></p>
381
+ <p>📧 <a href="mailto:darshtayal8@gmail.com">darshtayal8@gmail.com</a></p>
382
+ <p style="margin-top: 1rem; font-size: 0.85rem; opacity: 0.9;">© 2024 All Rights Reserved</p>
383
+ </div>
384
+ """)
385
+
386
+ submit_button.click(setter, inputs=[youtube_link], outputs=[first_page, loading_page, chat_page, wrong_link_page, cc_not_enabled, normal_error, summary, vs])
387
+ submit_answer.click(execute, inputs=[vs, ques], outputs=[answer, chat_page, normal_error])
388
+
389
+ ui.launch(inbrowser=True)
.ipynb_checkpoints/requirements-checkpoint.txt ADDED
File without changes
README.md CHANGED
@@ -1,12 +1,6 @@
1
  ---
2
- title: Youtube Summarizer - Basic
3
- emoji: 👁
4
- colorFrom: green
5
- colorTo: green
6
- sdk: gradio
7
- sdk_version: 5.49.1
8
  app_file: app.py
9
- pinned: false
 
10
  ---
11
-
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: Youtube_summarizer_-_basic
 
 
 
 
 
3
  app_file: app.py
4
+ sdk: gradio
5
+ sdk_version: 5.23.1
6
  ---
 
 
app.py ADDED
@@ -0,0 +1,389 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain_text_splitters import RecursiveCharacterTextSplitter
2
+ from langchain_chroma import Chroma
3
+ from langchain_huggingface import HuggingFaceEmbeddings
4
+ from bytez import Bytez
5
+ from youtube_transcript_api import YouTubeTranscriptApi
6
+ import gradio as gr
7
+ from dotenv import load_dotenv
8
+ import os
9
+ from urllib.parse import urlparse, parse_qs
10
+
11
+ load_dotenv("secrets.env")
12
+
13
+ api_key = os.getenv("BYTEZ_API_KEY")
14
+ sdk = Bytez(api_key)
15
+
16
+ #toy function
17
+ def video_id_extractor(link):
18
+ if "watch?v=" in link:
19
+ return link[32:43]
20
+ else:
21
+ return link[17:28]
22
+
23
+ #production ready function
24
+ def video_id_extractor(link):
25
+ parsed_url = urlparse(link)
26
+
27
+ if "youtube.com" in parsed_url.netloc:
28
+ return parse_qs(parsed_url.query).get("v", [None])[0]
29
+
30
+ elif "youtu.be" in parsed_url.netloc:
31
+ return parsed_url.path.lstrip("/")
32
+
33
+ return None
34
+
35
+ def generate_transcript(video_id):
36
+ trans = YouTubeTranscriptApi()
37
+ try:
38
+ transcript_raw = trans.fetch(video_id = video_id)
39
+ except Exception:
40
+ return None
41
+ transcript = ""
42
+ for i in transcript_raw.snippets:
43
+ transcript += f" {i.text}"
44
+ return transcript
45
+
46
+ def create_and_save_vs(trans):
47
+ try:
48
+ splitter = RecursiveCharacterTextSplitter(chunk_size = 100, chunk_overlap = 50)
49
+ docs = splitter.split_text(trans)
50
+ embeddings = HuggingFaceEmbeddings(model_name='sentence-transformers/all-mpnet-base-v2')
51
+ vector_store_db = Chroma.from_texts(docs, embeddings, persist_directory='chroma_db')
52
+ except Exception:
53
+ return None
54
+ return vector_store_db
55
+
56
+ def generate_summary(trans):
57
+ try:
58
+ model = sdk.model("openai/gpt-4o")
59
+ if len(trans.split(" ")) > 90000:
60
+ trans = trans.split(" ")[0:85000]
61
+ trans = " ".join(trans)
62
+ except Exception:
63
+ return None
64
+ Inp = [{"role": "system", "content": "You are a youtube transcipt sammurizer. Sammurize the transcript under 100 words"}, {"role":"user", "content":trans}]
65
+ trails = 4
66
+ failed = True
67
+ time_to_sleep = 3
68
+ while failed and trails > 0:
69
+ res = model.run(Inp)
70
+ if type(res) == list and len(res) == 3:
71
+ failed = False
72
+ trails -= 1
73
+ return res[0]["content"]
74
+ else:
75
+ time.sleep(time_to_sleep)
76
+ time_to_sleep = time_to_sleep **2
77
+ trails -= 1
78
+ return None
79
+
80
+ def setter(link):
81
+ yield gr.update(visible=False), gr.update(visible=True), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), "", ""
82
+ video_id = video_id_extractor(link)
83
+ if not video_id:
84
+ yield gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=True), gr.update(visible=False), gr.update(visible=False), "", ""
85
+ transcript = generate_transcript(video_id)
86
+ if not transcript:
87
+ yield gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=True), gr.update(visible=False), "", ""
88
+ vectorstore = create_and_save_vs(transcript)
89
+ if not vectorstore:
90
+ yield gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=True), "", ""
91
+ summary = generate_summary(transcript)
92
+ if not summary:
93
+ yield gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=True), "", ""
94
+ yield gr.update(visible=False), gr.update(visible=False), gr.update(visible=True), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), summary, vectorstore
95
+
96
+ def execute(vec, query):
97
+ try:
98
+ res = vec.similarity_search(query, k=3)
99
+ result = ""
100
+ for i in res:
101
+ result += f"\n{i.page_content}"
102
+ model = sdk.model("openai/gpt-4o")
103
+ inp = [{"role": "system", "content": "You are a helpful assistant - you will be asked a query and provided with a context. You have to answer that query based on the provided context - do not make things up. Do not reveal the whole context, answer as like you already knew the context"}, {"role":"user", "content":f"query: {query} | context: {result}"}]
104
+ res = model.run(inp)
105
+ return res[0]['content'], gr.update(visible=True), gr.update(visible=False)
106
+ except Exception:
107
+ return "", gr.update(visible=False), gr.update(visible=True)
108
+
109
+ with gr.Blocks(
110
+ theme=gr.themes.Soft(
111
+ primary_hue="blue",
112
+ secondary_hue="indigo",
113
+ ),
114
+ css="""
115
+ /* Global Styles */
116
+ .gradio-container {
117
+ font-family: 'Inter', 'Segoe UI', sans-serif !important;
118
+ max-width: 1200px !important;
119
+ margin: 0 auto !important;
120
+ }
121
+
122
+ /* Header Branding */
123
+ .header-brand {
124
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
125
+ padding: 2rem;
126
+ border-radius: 16px;
127
+ margin-bottom: 2rem;
128
+ box-shadow: 0 10px 40px rgba(102, 126, 234, 0.3);
129
+ animation: fadeInDown 0.8s ease-out;
130
+ }
131
+
132
+ .header-brand h1 {
133
+ color: white;
134
+ font-size: 2.5rem;
135
+ font-weight: 700;
136
+ margin: 0;
137
+ text-shadow: 2px 2px 4px rgba(0,0,0,0.2);
138
+ }
139
+
140
+ .header-brand p {
141
+ color: rgba(255,255,255,0.95);
142
+ font-size: 1.1rem;
143
+ margin: 0.5rem 0 0 0;
144
+ }
145
+
146
+ /* Footer Branding */
147
+ .footer-brand {
148
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
149
+ padding: 1.5rem;
150
+ border-radius: 12px;
151
+ margin-top: 2rem;
152
+ text-align: center;
153
+ box-shadow: 0 -5px 20px rgba(102, 126, 234, 0.2);
154
+ }
155
+
156
+ .footer-brand p {
157
+ color: white;
158
+ margin: 0.3rem 0;
159
+ font-size: 0.95rem;
160
+ }
161
+
162
+ .footer-brand a {
163
+ color: #ffd700;
164
+ text-decoration: none;
165
+ font-weight: 600;
166
+ transition: all 0.3s ease;
167
+ }
168
+
169
+ .footer-brand a:hover {
170
+ color: #fff;
171
+ text-shadow: 0 0 10px rgba(255,255,255,0.5);
172
+ }
173
+
174
+ /* Main Title Animation */
175
+ .main-title {
176
+ background: linear-gradient(90deg, #667eea, #764ba2, #667eea);
177
+ background-size: 200% auto;
178
+ color: white;
179
+ padding: 1.5rem;
180
+ border-radius: 12px;
181
+ text-align: center;
182
+ font-size: 1.8rem;
183
+ font-weight: 600;
184
+ margin-bottom: 2rem;
185
+ box-shadow: 0 8px 32px rgba(102, 126, 234, 0.4);
186
+ animation: gradientShift 3s ease infinite, fadeIn 1s ease-out;
187
+ }
188
+
189
+ /* Button Styles */
190
+ .gr-button {
191
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
192
+ border: none !important;
193
+ color: white !important;
194
+ font-weight: 600 !important;
195
+ padding: 12px 32px !important;
196
+ border-radius: 8px !important;
197
+ transition: all 0.3s ease !important;
198
+ box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4) !important;
199
+ text-transform: uppercase;
200
+ letter-spacing: 0.5px;
201
+ }
202
+
203
+ .gr-button:hover {
204
+ transform: translateY(-2px) !important;
205
+ box-shadow: 0 6px 25px rgba(102, 126, 234, 0.6) !important;
206
+ }
207
+
208
+ .gr-button:active {
209
+ transform: translateY(0px) !important;
210
+ }
211
+
212
+ /* Input Fields */
213
+ .gr-textbox, .gr-text-input {
214
+ border-radius: 8px !important;
215
+ border: 2px solid #e0e7ff !important;
216
+ transition: all 0.3s ease !important;
217
+ }
218
+
219
+ .gr-textbox:focus, .gr-text-input:focus {
220
+ border-color: #667eea !important;
221
+ box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1) !important;
222
+ }
223
+
224
+ /* Loading Animation */
225
+ .loading-container {
226
+ text-align: center;
227
+ padding: 3rem;
228
+ }
229
+
230
+ .loading-text {
231
+ font-size: 1.5rem;
232
+ color: #667eea;
233
+ animation: pulse 1.5s ease-in-out infinite;
234
+ }
235
+
236
+ /* Error Messages */
237
+ .error-message {
238
+ background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
239
+ color: white;
240
+ padding: 1.5rem;
241
+ border-radius: 12px;
242
+ text-align: center;
243
+ font-size: 1.3rem;
244
+ font-weight: 600;
245
+ box-shadow: 0 8px 32px rgba(245, 87, 108, 0.3);
246
+ animation: shake 0.5s ease-in-out;
247
+ }
248
+
249
+ /* Success/Summary Box */
250
+ .summary-box {
251
+ background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
252
+ padding: 1.5rem;
253
+ border-radius: 12px;
254
+ margin-bottom: 1.5rem;
255
+ box-shadow: 0 8px 24px rgba(168, 237, 234, 0.3);
256
+ animation: fadeInUp 0.6s ease-out;
257
+ }
258
+
259
+ /* Chat Section */
260
+ .chat-section {
261
+ animation: fadeInUp 0.8s ease-out;
262
+ }
263
+
264
+ /* Animations */
265
+ @keyframes fadeIn {
266
+ from {
267
+ opacity: 0;
268
+ }
269
+ to {
270
+ opacity: 1;
271
+ }
272
+ }
273
+
274
+ @keyframes fadeInDown {
275
+ from {
276
+ opacity: 0;
277
+ transform: translateY(-30px);
278
+ }
279
+ to {
280
+ opacity: 1;
281
+ transform: translateY(0);
282
+ }
283
+ }
284
+
285
+ @keyframes fadeInUp {
286
+ from {
287
+ opacity: 0;
288
+ transform: translateY(30px);
289
+ }
290
+ to {
291
+ opacity: 1;
292
+ transform: translateY(0);
293
+ }
294
+ }
295
+
296
+ @keyframes pulse {
297
+ 0%, 100% {
298
+ opacity: 1;
299
+ }
300
+ 50% {
301
+ opacity: 0.5;
302
+ }
303
+ }
304
+
305
+ @keyframes shake {
306
+ 0%, 100% { transform: translateX(0); }
307
+ 25% { transform: translateX(-10px); }
308
+ 75% { transform: translateX(10px); }
309
+ }
310
+
311
+ @keyframes gradientShift {
312
+ 0% {
313
+ background-position: 0% 50%;
314
+ }
315
+ 50% {
316
+ background-position: 100% 50%;
317
+ }
318
+ 100% {
319
+ background-position: 0% 50%;
320
+ }
321
+ }
322
+
323
+ /* Responsive Design */
324
+ @media (max-width: 768px) {
325
+ .header-brand h1 {
326
+ font-size: 1.8rem;
327
+ }
328
+ .main-title {
329
+ font-size: 1.3rem;
330
+ }
331
+ }
332
+ """
333
+ ) as ui:
334
+ # Header Branding
335
+ gr.HTML("""
336
+ <div class="header-brand">
337
+ <h1>🎓 AI YouTube Study Assistant</h1>
338
+ <p>Transform lengthy videos into concise knowledge</p>
339
+ </div>
340
+ """)
341
+
342
+ vs = gr.State()
343
+ gr.HTML('<div class="main-title">📹 Why watch long YouTube videos when you could study from AI?</div>')
344
+
345
+ with gr.Row(visible=True) as first_page:
346
+ youtube_link = gr.Textbox(
347
+ label="Enter the youtube link here: ",
348
+ lines=2,
349
+ placeholder="https://www.youtube.com/watch?v=..."
350
+ )
351
+ submit_button = gr.Button("SUBMIT!")
352
+
353
+ with gr.Row(visible=False) as chat_page:
354
+ with gr.Column():
355
+ summary = gr.Markdown(elem_classes="summary-box")
356
+ gr.Markdown("### 💬 Now ask any question about the video:")
357
+ ques = gr.Textbox(
358
+ label="Enter the question here: ",
359
+ lines=2,
360
+ placeholder="What is the main topic of this video?"
361
+ )
362
+ submit_answer = gr.Button("SUBMIT!")
363
+ answer = gr.TextArea(label="ANSWER")
364
+
365
+ with gr.Row(visible=False) as wrong_link_page:
366
+ gr.HTML('<div class="error-message">❌ Sorry, your link wasn\'t correct. Please try again!</div>')
367
+
368
+ with gr.Row(visible=False) as cc_not_enabled:
369
+ gr.HTML('<div class="error-message">⚠️ The link you provided was either not valid or subtitles weren\'t enabled in that video</div>')
370
+
371
+ with gr.Row(visible=False) as loading_page:
372
+ gr.HTML('<div class="loading-container"><div class="loading-text">⏳ Loading... Please Wait</div></div>')
373
+
374
+ with gr.Row(visible=False) as normal_error:
375
+ gr.HTML('<div class="error-message">😔 SORRY, SOME ERROR OCCURRED. PLEASE TRY AGAIN LATER</div>')
376
+
377
+ # Footer Branding
378
+ gr.HTML("""
379
+ <div class="footer-brand">
380
+ <p><strong>Developed by Darsh Tayal</strong></p>
381
+ <p>📧 <a href="mailto:darshtayal8@gmail.com">darshtayal8@gmail.com</a></p>
382
+ <p style="margin-top: 1rem; font-size: 0.85rem; opacity: 0.9;">© 2024 All Rights Reserved</p>
383
+ </div>
384
+ """)
385
+
386
+ submit_button.click(setter, inputs=[youtube_link], outputs=[first_page, loading_page, chat_page, wrong_link_page, cc_not_enabled, normal_error, summary, vs])
387
+ submit_answer.click(execute, inputs=[vs, ques], outputs=[answer, chat_page, normal_error])
388
+
389
+ ui.launch(inbrowser=True)
requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ gradio
2
+ langchain-chroma
3
+ langchain-huggingface
4
+ langchain-text-splitters
5
+ youtube-transcript-api
6
+ bytez
7
+ python-dotenv
8
+ sentence-transformers
9
+ chromadb