dwarkesh commited on
Commit
553b26d
·
verified ·
1 Parent(s): 3a12840

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +173 -0
app.py ADDED
@@ -0,0 +1,173 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import assemblyai as aai
3
+ from anthropic import Anthropic
4
+ import os
5
+ from pydub import AudioSegment
6
+ import tempfile
7
+
8
+ # Initialize API clients
9
+ aai.settings.api_key = os.getenv("AAI_KEY")
10
+ anthropic = Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))
11
+ model_name = "claude-3-5-sonnet-20240620"
12
+
13
+ # Default prompts from the initial Python file
14
+ DEFAULT_TITLE_PROMPT = """
15
+ Suggest a title for the podcast episode
16
+ Dwarkesh is the host, not the guest.
17
+ The format should be:
18
+ Guest Name - Title
19
+
20
+ Make it sexy! Enticing! No boilerplate!!
21
+
22
+ Don't output anything but the suggested podcast title. Don't use hashtags or Emojis. Titles should be around 80 characters long. The best titles take a number of ideas from the episode
23
+
24
+ Here are some examples of previous podcast episode titles:
25
+
26
+ Patrick Collison (Stripe CEO) - Craft, Beauty, & The Future of Payments
27
+ Tyler Cowen - Hayek, Keynes, & Smith on AI, Animal Spirits, Anarchy, & Growth
28
+ Jung Chang - Living through Cultural Revolution and the Crimes of Mao
29
+ Andrew Roberts - SV's Napoleon Cult, Why Hitler Lost WW2, Churchill as Applied Historian
30
+ Dominic Cummings - COVID, Brexit, & Fixing Western Governance
31
+ Paul Christiano - Preventing an AI Takeover
32
+ Shane Legg (DeepMind Founder) - 2028 AGI, New Architectures, Aligning Superhuman Models
33
+ Grant Sanderson (3Blue1Brown) - Past, Present, & Future of Mathematics
34
+ Sarah C. M. Paine - WW2, Taiwan, Ukraine, & Maritime vs Continental Powers
35
+ Dario Amodei (Anthropic CEO) - Scaling, Alignment, & AI Progress
36
+ Francois Chollet - LLMs won’t lead to AGI - $1,000,000 Prize to find true solution
37
+ Leopold Aschenbrenner - 2027 AGI, China/US Super-Intelligence Race, & The Return of History
38
+ John Schulman (OpenAI Cofounder) - Reasoning, RLHF, & Plan for 2027 AGI
39
+
40
+ Come up with a title for the following transcript using guidance above.
41
+
42
+ Come up 10 titles, each on a new line, so I can select the best one.
43
+ Titles:
44
+ """
45
+
46
+ DEFAULT_CLIP_PROMPT = """
47
+ Suggest some best portions of these episodes to make clips of.
48
+ Format this as "Aprox Timestamp: ____ - ____ || Title: "
49
+
50
+ Clips should be the most intriguing and critical parts of the episode. They should start right at the action and end once the topic has been resolved. They should be
51
+ 2-10 minutes in length. Good clips often feature debate, appealing rhetoric, core ideas, intresting stories, or counterintuitve facts.
52
+
53
+ Titles should be your 2-10 word description of what is in the clip. e.g: AGI Timelines debate, Lee Kuan Yu's best choices, Why LLMs are enough for AGI, etc.
54
+
55
+ Example Output: Aprox Timestamp: 1:10 - 5:12 || Title: The Million Dollar Prize for AGI
56
+ """
57
+
58
+
59
+ def transcribe_audio(audio_file):
60
+ # Handle both file objects and file paths
61
+ if isinstance(audio_file, str):
62
+ audio_path = audio_file
63
+ else:
64
+ audio_path = audio_file.name
65
+
66
+ # Convert audio to MP3 if it's not already
67
+ with tempfile.NamedTemporaryFile(suffix=".mp3", delete=False) as temp_file:
68
+ audio = AudioSegment.from_file(audio_path)
69
+ audio.export(temp_file.name, format="mp3")
70
+
71
+ # Transcribe the audio file
72
+ transcriber = aai.Transcriber()
73
+ transcript = transcriber.transcribe(
74
+ temp_file.name, config=aai.TranscriptionConfig(speaker_labels=True)
75
+ )
76
+
77
+ # Format the transcript
78
+ formatted_transcript = ""
79
+ for utterance in transcript.utterances:
80
+ formatted_transcript += f"{utterance.speaker} {format_timestamp(utterance.start)}\n{utterance.text}\n\n"
81
+
82
+ return formatted_transcript
83
+
84
+
85
+ def format_timestamp(milliseconds):
86
+ seconds = int(milliseconds / 1000)
87
+ minutes, seconds = divmod(seconds, 60)
88
+ hours, minutes = divmod(minutes, 60)
89
+ return f"{hours:02d}:{minutes:02d}:{seconds:02d}"
90
+
91
+
92
+ def generate_titles(transcript, prompt):
93
+ message = anthropic.messages.create(
94
+ model=model_name,
95
+ max_tokens=1024,
96
+ messages=[
97
+ {"role": "user", "content": f"{prompt}\n\nTranscript:\n{transcript}"},
98
+ ],
99
+ )
100
+ return message.content[0].text
101
+
102
+
103
+ def generate_clips(transcript, prompt):
104
+ message = anthropic.messages.create(
105
+ model=model_name,
106
+ max_tokens=1024,
107
+ messages=[
108
+ {"role": "user", "content": f"{prompt}\n\nTranscript:\n{transcript}"},
109
+ ],
110
+ )
111
+ return message.content[0].text
112
+
113
+
114
+ def process_transcript(audio_file):
115
+ transcript = transcribe_audio(audio_file)
116
+
117
+ # Save transcript to a temporary file
118
+ with tempfile.NamedTemporaryFile(
119
+ mode="w", delete=False, suffix=".txt"
120
+ ) as temp_file:
121
+ temp_file.write(transcript)
122
+ temp_file_path = temp_file.name
123
+
124
+ return transcript, temp_file_path
125
+
126
+
127
+ def process_title_and_clips(transcript, title_prompt, clip_prompt):
128
+ titles = generate_titles(transcript, title_prompt)
129
+ clips = generate_clips(transcript, clip_prompt)
130
+ return titles, clips
131
+
132
+
133
+ # Define the Gradio interface
134
+ with gr.Blocks() as app:
135
+ gr.Markdown("# Podcast Helper")
136
+
137
+ # with gr.Row():
138
+ audio_input = gr.Audio(type="filepath", label="Upload MP3")
139
+ transcribe_button = gr.Button("Generate Transcript")
140
+
141
+ with gr.Row():
142
+ transcript_output = gr.Textbox(label="Transcript", lines=10)
143
+ transcript_file = gr.File(label="Download Transcript")
144
+
145
+ with gr.Row():
146
+ title_prompt = gr.Textbox(
147
+ label="Title Generation Prompt", lines=3, value=DEFAULT_TITLE_PROMPT
148
+ )
149
+ clip_prompt = gr.Textbox(
150
+ label="Clip Search Prompt", lines=3, value=DEFAULT_CLIP_PROMPT
151
+ )
152
+
153
+ generate_button = gr.Button("Generate Title and Clips")
154
+
155
+ with gr.Row():
156
+ titles_output = gr.Textbox(label="Generated Titles", lines=10)
157
+ clips_output = gr.Textbox(label="Generated Clips", lines=10)
158
+
159
+ transcribe_button.click(
160
+ process_transcript,
161
+ inputs=[audio_input],
162
+ outputs=[transcript_output, transcript_file],
163
+ )
164
+
165
+ generate_button.click(
166
+ process_title_and_clips,
167
+ inputs=[transcript_output, title_prompt, clip_prompt],
168
+ outputs=[titles_output, clips_output],
169
+ )
170
+
171
+ # Launch the app
172
+ if __name__ == "__main__":
173
+ app.launch()