Spaces:
Sleeping
Sleeping
# β Gemini-Based Stock Recommendation Extractor (No Audio, No Whisper) | |
# Uses video metadata (title + description) + Gemini Flash to extract stock info | |
import gradio as gr | |
import os | |
import tempfile | |
import json | |
import google.generativeai as genai | |
from yt_dlp import YoutubeDL | |
# β Gemini Configuration | |
GEMINI_MODEL = None | |
def configure_gemini(api_key): | |
try: | |
genai.configure(api_key=api_key) | |
global GEMINI_MODEL | |
GEMINI_MODEL = genai.GenerativeModel("gemini-1.5-flash-latest") | |
return "β Gemini API key configured successfully." | |
except Exception as e: | |
return f"β Gemini configuration failed: {str(e)}" | |
# β Extract video metadata only (no download) | |
def extract_metadata(url, cookies_file=None): | |
try: | |
ydl_opts = { | |
'quiet': True, | |
'skip_download': True, | |
'noplaylist': True, | |
} | |
if cookies_file and os.path.exists(cookies_file): | |
ydl_opts['cookiefile'] = cookies_file | |
with YoutubeDL(ydl_opts) as ydl: | |
info = ydl.extract_info(url, download=False) | |
return { | |
'title': info.get("title", ""), | |
'description': info.get("description", ""), | |
'duration': info.get("duration", 0), | |
'uploader': info.get("uploader", ""), | |
'view_count': info.get("view_count", 0), | |
'upload_date': info.get("upload_date", "") | |
}, "β Video metadata extracted" | |
except Exception as e: | |
return None, f"β Metadata extraction failed: {str(e)}" | |
# β Gemini Prompt for Stock Extraction | |
def query_gemini_stock_analysis(meta): | |
if GEMINI_MODEL is None: | |
return "β Gemini model is not initialized." | |
prompt = f""" | |
Analyze the following YouTube video metadata and extract any stock trading recommendations: | |
Title: {meta['title']} | |
Description: {meta['description']} | |
Please extract: | |
- Mentioned companies or stock symbols | |
- Any price targets, buy/sell/hold recommendations | |
- Bullish/bearish sentiments if expressed | |
- If no stock info is present, clearly say "No financial or trading recommendations found." | |
- Keep the output short and to the point | |
""" | |
try: | |
response = GEMINI_MODEL.generate_content(prompt) | |
return response.text if response else "β οΈ No response from Gemini." | |
except Exception as e: | |
return f"β Gemini query failed: {str(e)}" | |
# β Main Pipeline | |
def run_pipeline(api_key, url, cookies): | |
status = configure_gemini(api_key) | |
if not status.startswith("β "): | |
return status, "" | |
# Save cookies if provided | |
cookie_path = None | |
if cookies: | |
cookie_path = tempfile.mktemp(suffix=".txt") | |
with open(cookie_path, "wb") as f: | |
f.write(cookies.read()) | |
metadata, meta_status = extract_metadata(url, cookie_path) | |
if not metadata: | |
return meta_status, "" | |
result = query_gemini_stock_analysis(metadata) | |
return meta_status, result | |
# β Gradio UI | |
with gr.Blocks(title="Gemini Stock Extractor") as demo: | |
gr.Markdown(""" | |
# π Gemini-Based Stock Recommendation Extractor | |
Paste a YouTube link and get stock-related insights using only the title + description. | |
No audio, no transcription required. Fast and simple. | |
""") | |
with gr.Row(): | |
api_input = gr.Textbox(label="π Gemini API Key", type="password") | |
url_input = gr.Textbox(label="YouTube Video URL") | |
cookies_input = gr.File(label="cookies.txt (optional)", file_types=[".txt"]) | |
go_btn = gr.Button("π Analyze") | |
status_box = gr.Textbox(label="Status", lines=1) | |
output_box = gr.Textbox(label="Extracted Stock Insights", lines=12) | |
go_btn.click(fn=run_pipeline, inputs=[api_input, url_input, cookies_input], outputs=[status_box, output_box]) | |
if __name__ == "__main__": | |
demo.launch(debug=True) | |