| import gradio as gr |
| import json |
| import os |
| from openai import OpenAI |
|
|
| |
| SYSTEM_PROMPT = """You are Herman Poppleberry, a friendly and slightly eccentric donkey who lives with Daniel in Jerusalem. You have a brother called Corn who is a sloth. |
| |
| Your task is as follows: |
| |
| The user (Daniel) will provide you with a prompt. You should infer this prompt to be a question. If the text provided does not ask a direction question, understand it as if it did. |
| |
| You must answer the prompt by generating a podcast episode based upon it. The podcast is called 'The Daniel Prompt Hour' and it consists of you answering the prompts which Daniel sends in. |
| |
| The outputs you provide are single-turn. In response to Daniel's prompt/request, you must provide the following in a JSON array: |
| |
| - episode_title: A catchy episode name that encapsulates the subject manner. Make this slightly clickbaity and capricious. |
| - episode_description: Up to 100 words describing the episode |
| - episode_transcript: The entire episode transcript |
| |
| The episode transcript which you generate must be: |
| |
| - Written in plain text |
| - Containing no elements which would be inappropriate for text to speech generation. For example, you do not include URLs or reference footnotes. |
| - Written in the format of a typical podcast episode: you begin by welcoming listeners to another edition; then provide your answer to Daniel's question; then thank the audience for listening. |
| |
| Your answers to Daniel's questions should be well researched and informative. You have a dry and slightly sly sense of humor. |
| You are a donkey. You mention this in passing but do not dwell upon the fact. You sometimes make joking comments about your brother Corn (the sloth). |
| |
| The episode transcripts should be about 1,500 words each.""" |
|
|
| def generate_podcast_transcript(user_prompt, api_key, model_choice="gpt-4o-mini"): |
| """ |
| Generate a podcast transcript using Herman Poppleberry persona |
| """ |
| if not api_key or api_key.strip() == "": |
| return "❌ **Error**: Please provide your OpenAI API key to generate podcast episodes.\n\nYou can get an API key at: https://platform.openai.com/api-keys" |
| |
| try: |
| |
| client = OpenAI(api_key=api_key.strip()) |
| |
| |
| response = client.chat.completions.create( |
| model=model_choice, |
| messages=[ |
| {"role": "system", "content": SYSTEM_PROMPT}, |
| {"role": "user", "content": f"User prompt: {user_prompt}\n\nPlease generate the podcast episode in JSON format with episode_title, episode_description, and episode_transcript fields."} |
| ], |
| max_tokens=3000, |
| temperature=0.7, |
| top_p=0.9 |
| ) |
| |
| |
| response_text = response.choices[0].message.content |
| |
| |
| try: |
| |
| clean_text = response_text.strip() |
| if clean_text.startswith("```json"): |
| clean_text = clean_text[7:] |
| if clean_text.endswith("```"): |
| clean_text = clean_text[:-3] |
| |
| podcast_data = json.loads(clean_text) |
| |
| |
| formatted_output = f"""# {podcast_data.get('episode_title', 'The Daniel Prompt Hour Episode')} |
| |
| ## Episode Description |
| {podcast_data.get('episode_description', 'No description available')} |
| |
| ## Episode Transcript |
| {podcast_data.get('episode_transcript', 'No transcript available')}""" |
| |
| return formatted_output |
| |
| except json.JSONDecodeError: |
| |
| return f"# The Daniel Prompt Hour Episode\n\n## Raw Response\n{response_text}" |
| |
| except Exception as e: |
| return f"Error generating podcast transcript: {str(e)}" |
|
|
| |
| with gr.Blocks( |
| title="The Daniel Prompt Hour - Podcast Generator", |
| theme=gr.themes.Soft(), |
| css=""" |
| .gradio-container { |
| max-width: 900px !important; |
| } |
| .header { |
| text-align: center; |
| margin-bottom: 20px; |
| } |
| """ |
| ) as demo: |
| |
| gr.HTML(""" |
| <div class="header"> |
| <img src="https://res.cloudinary.com/drrvnflqy/image/upload/v1757667960/Flux_Dev_a_donkey_wearing_a_top_hat_is_in_a_recording_studio_s_3_czrkbs.jpg" |
| alt="Herman Poppleberry in the recording studio" |
| style="width: 200px; height: 200px; object-fit: cover; border-radius: 15px; margin-bottom: 20px; box-shadow: 0 4px 8px rgba(0,0,0,0.1);"> |
| <h1>🎙️ The Daniel Prompt Hour</h1> |
| <h3>Featuring Herman Poppleberry, the Donkey 🫏</h3> |
| <p>Enter any prompt and Herman will turn it into a podcast episode!</p> |
| </div> |
| """) |
| |
| with gr.Row(): |
| with gr.Column(scale=2): |
| api_key_input = gr.Textbox( |
| label="OpenAI API Key", |
| placeholder="Enter your OpenAI API key (sk-...)", |
| type="password", |
| info="Your API key is not stored and only used for this session" |
| ) |
| |
| user_input = gr.Textbox( |
| label="Your Prompt", |
| placeholder="Enter any question or topic you'd like Herman to discuss in a podcast episode...", |
| lines=3, |
| max_lines=5 |
| ) |
| |
| model_dropdown = gr.Dropdown( |
| choices=[ |
| "gpt-4o-mini", |
| "gpt-4o", |
| "gpt-4-turbo", |
| "gpt-3.5-turbo" |
| ], |
| value="gpt-4o-mini", |
| label="OpenAI Model", |
| info="Choose the OpenAI model to generate the podcast transcript" |
| ) |
| |
| generate_btn = gr.Button("🎙️ Generate Podcast Episode", variant="primary", size="lg") |
| |
| with gr.Column(scale=3): |
| output = gr.Markdown( |
| label="Generated Podcast Episode", |
| value="Enter a prompt and click 'Generate Podcast Episode' to see Herman's response!", |
| height=600 |
| ) |
| |
| |
| gr.Examples( |
| examples=[ |
| ["What's the future of artificial intelligence?"], |
| ["How do I make the perfect hummus?"], |
| ["Why do cats purr?"], |
| ["What's the meaning of life?"], |
| ["How does quantum computing work?"], |
| ["What makes a good podcast?"] |
| ], |
| inputs=user_input, |
| label="Example Prompts" |
| ) |
| |
| |
| generate_btn.click( |
| fn=generate_podcast_transcript, |
| inputs=[user_input, api_key_input, model_dropdown], |
| outputs=output, |
| show_progress=True |
| ) |
| |
| user_input.submit( |
| fn=generate_podcast_transcript, |
| inputs=[user_input, api_key_input, model_dropdown], |
| outputs=output, |
| show_progress=True |
| ) |
|
|
| |
| if __name__ == "__main__": |
| demo.launch( |
| server_name="0.0.0.0", |
| server_port=7860, |
| share=False |
| ) |
|
|