producer / app.py
dwarkesh's picture
generates previews
d34ceb2
import gradio as gr
import asyncio
from pathlib import Path
from utils.content_generator import ContentGenerator, ContentRequest
from utils.youtube_utils import get_transcript, extract_video_id
class TranscriptProcessor:
def __init__(self):
self.generator = ContentGenerator()
def _get_youtube_transcript(self, url: str) -> str:
"""Get transcript from YouTube URL."""
try:
if video_id := extract_video_id(url):
return get_transcript(video_id)
raise Exception("Invalid YouTube URL")
except Exception as e:
raise Exception(f"Error fetching YouTube transcript: {str(e)}")
async def process_transcript(self, input_text: str):
"""Process input and generate all content."""
try:
# Get transcript from URL or use direct input
transcript = (
self._get_youtube_transcript(input_text)
if any(x in input_text for x in ["youtube.com", "youtu.be"])
else input_text
)
# Define content generation requests
requests = [
ContentRequest("previews", max_tokens=8192),
ContentRequest("clips", max_tokens=8192),
ContentRequest("description"),
ContentRequest("timestamps"),
ContentRequest("titles_and_thumbnails"),
]
# Generate all content concurrently
results = await asyncio.gather(
*[self.generator.generate_content(req, transcript) for req in requests]
)
return tuple(results)
except Exception as e:
return (f"Error processing input: {str(e)}",) * 5
def update_prompts(self, *values) -> str:
"""Update the current session's prompts."""
self.generator.current_prompts.update(zip(
["previews", "clips", "description", "timestamps", "titles_and_thumbnails"],
values
))
return "Prompts updated for this session!"
def create_interface():
"""Create the Gradio interface."""
processor = TranscriptProcessor()
with gr.Blocks(title="Podcast Transcript Analyzer") as app:
with gr.Tab("Generate Content"):
gr.Markdown("# Podcast Content Generator")
input_text = gr.Textbox(label="Input", placeholder="YouTube URL or transcript...", lines=10)
submit_btn = gr.Button("Generate Content")
outputs = [
gr.Textbox(label=label, lines=10, interactive=False)
for label in ["Preview Clips", "Twitter Clips", "Twitter Description", "Timestamps", "Title & Thumbnail Suggestions"]
]
async def process_wrapper(text):
return await processor.process_transcript(text)
submit_btn.click(fn=process_wrapper, inputs=[input_text], outputs=outputs)
with gr.Tab("Experiment with Prompts"):
gr.Markdown("# Experiment with Prompts")
gr.Markdown(
"""
Here you can experiment with different prompts during your session.
Changes will remain active until you reload the page.
Tip: Copy your preferred prompts somewhere safe if you want to reuse them later!
"""
)
prompt_inputs = [
gr.Textbox(
label="Preview Clips Prompt", lines=10, value=processor.generator.current_prompts["previews"]
),
gr.Textbox(
label="Clips Prompt", lines=10, value=processor.generator.current_prompts["clips"]
),
gr.Textbox(
label="Description Prompt",
lines=10,
value=processor.generator.current_prompts["description"],
),
gr.Textbox(
label="Timestamps Prompt",
lines=10,
value=processor.generator.current_prompts["timestamps"],
),
gr.Textbox(
label="Titles & Thumbnails Prompt",
lines=10,
value=processor.generator.current_prompts["titles_and_thumbnails"],
),
]
status = gr.Textbox(label="Status", interactive=False)
# Update prompts when they change
for prompt in prompt_inputs:
prompt.change(fn=processor.update_prompts, inputs=prompt_inputs, outputs=[status])
# Reset button
reset_btn = gr.Button("Reset to Default Prompts")
reset_btn.click(
fn=lambda: (
processor.update_prompts(*processor.generator.current_prompts.values()),
*processor.generator.current_prompts.values(),
),
outputs=[status] + prompt_inputs,
)
return app
if __name__ == "__main__":
create_interface().launch()