File size: 4,789 Bytes
9b11602 3404e9a 9b11602 bd07fc2 8757c5b bd07fc2 9b11602 bd07fc2 8c7facc bd07fc2 9b92628 bd07fc2 45c0e10 9b92628 bd07fc2 9b11602 bd07fc2 8757c5b 2ca982d bd07fc2 9b11602 bd07fc2 9b11602 bd07fc2 0b6d459 25262d5 bd07fc2 25262d5 bd07fc2 0a42087 bd07fc2 9b11602 bd07fc2 0a42087 bd07fc2 9b11602 bd07fc2 0a42087 bd07fc2 9b11602 bd07fc2 42683f3 bd07fc2 9b92628 bd07fc2 9b92628 bd07fc2 9b11602 bd07fc2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
import asyncio
import os
import gradio as gr
from api_clients import OpenRouterClient, ElevenLabsClient
from logger import setup_logger
from config import Config
from scraper import scrape_url
logger = setup_logger("app")
# Default choices for dropdowns
default_voices = [("", "Enter API key to load voices")]
default_models = [("", "Enter API key to load models")]
class PodcasterUI:
def __init__(self, config: Config):
self.config = config
self.router_client = OpenRouterClient(os.getenv('OPENROUTER_API_KEY', ''))
self.elevenlabs_client = ElevenLabsClient(os.getenv('ELEVENLABS_API_KEY', ''))
# Store models and voices as instance variables
self.models = default_models
self.voices = default_voices
async def initialize(self):
"""Initialize API clients and fetch models/voices"""
try:
self.models = await self.router_client.get_models()
# Since get_voices() might not be async, remove await
self.voices = self.elevenlabs_client.get_voices()
logger.info(f"Initialized with {len(self.voices)} voices and {len(self.models)} models")
except Exception as e:
logger.error("Failed to initialize API clients", exc_info=True)
raise
async def on_submit(self, content: str, model_id: str, voice_id: str, prompt: str = "") -> tuple:
"""Handle form submission with async API calls"""
try:
# First scrape the webpage content
webpage_content = scrape_url(content)
if not webpage_content:
return "Failed to extract content from URL", None
# Generate script using the scraped content
script = await self.router_client.generate_script(webpage_content, prompt, model_id)
# Generate audio from the script (now synchronous)
audio = self.elevenlabs_client.generate_audio(script, voice_id)
return script, audio
except Exception as e:
logger.error("Failed to generate podcast", exc_info=True)
return str(e), None
def create_ui(self) -> gr.Interface:
with gr.Blocks(title='URL to Podcast Generator', theme='huggingface') as interface:
gr.Markdown('# URL to Podcast Generator')
gr.Markdown('Enter a URL to generate a podcast episode based on its content.')
with gr.Row():
with gr.Column(scale=2):
url_input = gr.Textbox(
label="Website URL",
placeholder="Enter the URL of the website you want to convert to a podcast"
)
with gr.Row():
with gr.Column():
openrouter_model = gr.Dropdown(
label='AI Model',
choices=self.models, # Each choice now has same id/display value
value=self.models[0][0] if len(self.models) > 1 else None,
)
with gr.Column():
voice_model = gr.Dropdown(
label='Voice',
choices=[(id, name) for id, name in self.voices],
value=self.voices[0][0] if len(self.voices) > 1 else None,
)
prompt_input = gr.Textbox(
label="Custom Prompt",
placeholder="Enter a custom prompt to guide the podcast generation (optional)",
lines=3
)
submit_btn = gr.Button('Generate Podcast', variant='primary')
with gr.Column(scale=1):
script_output = gr.Textbox(label="Generated Script", interactive=False)
audio_output = gr.Audio(label="Generated Podcast")
status = gr.Textbox(label='Status', interactive=False)
submit_btn.click(
fn=self.on_submit,
inputs=[url_input, openrouter_model, voice_model, prompt_input],
outputs=[script_output, audio_output]
)
return interface
def main():
config = Config()
app = PodcasterUI(config)
# Initialize before creating UI
loop = asyncio.get_event_loop()
loop.run_until_complete(app.initialize())
# Create UI with populated data
interface = app.create_ui()
interface.launch(
server_name="0.0.0.0",
server_port=7860,
share=True
)
if __name__ == "__main__":
main() |