praveen1209's picture
Update app.py
6f0ab7e verified
# -*- coding: utf-8 -*-
"""youtube_video_recommendation.ipynb
Automatically generated by Colab.
Original file is located at
https://colab.research.google.com/drive/1pLpvcg7hC7hp2PmGBc8qe86ktv3eT9gp
"""
import gradio as gr
import requests
import os
API_KEY = os.getenv("API_KEY")# Replace with your own API key
def search_youtube(query):
if not query.strip():
return "<b>Please enter a search term.</b>"
search_url = "https://www.googleapis.com/youtube/v3/search"
search_params = {
"part": "snippet",
"q": query,
"type": "video",
"maxResults": 25,
"key": API_KEY
}
search_response = requests.get(search_url, params=search_params).json()
video_ids = [item["id"]["videoId"] for item in search_response.get("items", [])]
if not video_ids:
return "<b>❌ No results found.</b>"
stats_url = "https://www.googleapis.com/youtube/v3/videos"
stats_params = {
"part": "snippet,statistics",
"id": ",".join(video_ids),
"key": API_KEY
}
stats_response = requests.get(stats_url, params=stats_params).json()
if "items" not in stats_response:
return "<b>❌ No results found or API limit reached.</b>"
results = []
for item in stats_response["items"]:
snippet = item["snippet"]
title = snippet["title"]
description = snippet.get("description", "")
channel = snippet.get("channelTitle", "")
tags = snippet.get("tags", [])
video_id = item["id"]
url = f"https://www.youtube.com/watch?v={video_id}"
# Skip YouTube Shorts
if "shorts" in title.lower() or "/shorts/" in url.lower():
continue
combined_text = " ".join([title, description, channel] + tags).lower()
stats = item.get("statistics", {})
thumbnail = snippet["thumbnails"]["medium"]["url"]
views = int(stats.get("viewCount", 0))
likes = int(stats.get("likeCount", 0))
results.append({
"title": title,
"thumbnail": thumbnail,
"views": views,
"likes": likes,
"channel": channel,
"url": url
})
if not results:
return "<b>❌ No suitable videos found.</b>"
# Grid layout for results
grid_cards = ""
for vid in results:
grid_cards += f"""
<div style="background: #1e1e1e; color: white; border-radius: 12px; padding: 10px; box-shadow: 0 0 10px #333;">
<a href="{vid['url']}" target="_blank" style="text-decoration: none; color: inherit;">
<img src="{vid['thumbnail']}" style="width: 100%; height: auto; object-fit: cover; border-radius: 8px;" />
<div style="margin-top: 8px;">
<div style="color: #33ccff; font-size: 16px; font-weight: bold;">{vid['title']}</div>
<div style="font-size: 14px; margin-top: 4px;">πŸŽ™οΈ {vid['channel']}</div>
<div style="font-size: 14px;">πŸ‘οΈ {vid['views']:,} views &nbsp; ❀️ {vid['likes']:,} likes</div>
</div>
</a>
</div>
"""
return f"""
<div style='font-family: "Segoe UI", sans-serif; padding: 10px; max-height: 600px; overflow-y: auto;'>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px;">
{grid_cards}
</div>
</div>
"""
# 🎨 Gradio Interface (UI/Color/Font preserved)
with gr.Blocks(theme=gr.themes.Base(), title="YouTube Course Finder") as demo:
gr.HTML("<h1 style='text-align: center; background: linear-gradient(90deg, #ff0066, #6600ff); color: white; padding: 15px; border-radius: 10px;'>πŸ”₯ YouTube Course Finder</h1>")
gr.Markdown("Search for top YouTube courses by topic. Only regular videos shown, Shorts are excluded.")
with gr.Row():
query = gr.Textbox(label="Search Topic", placeholder="e.g. Python full course, HTML tutorial", lines=1)
search_btn = gr.Button("πŸ” Search")
output = gr.HTML()
search_btn.click(fn=search_youtube, inputs=query, outputs=output)
demo.launch(share=True)