dwarkesh commited on
Commit
299c2ce
·
verified ·
1 Parent(s): 949284e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +54 -50
app.py CHANGED
@@ -1,13 +1,15 @@
1
  import gradio as gr
2
  import asyncio
3
  from pathlib import Path
4
- import anthropic
 
5
  import os
6
  from dataclasses import dataclass
7
  from typing import Dict
8
  from youtube_transcript_api import YouTubeTranscriptApi
9
  import re
10
  import pandas as pd
 
11
 
12
  # Move relevant classes and functions into app.py
13
  @dataclass
@@ -15,41 +17,41 @@ class ContentRequest:
15
  prompt_key: str
16
 
17
  class ContentGenerator:
18
- def __init__(self):
19
  self.current_prompts = self._load_default_prompts()
20
- self.client = anthropic.Anthropic()
21
-
22
  def _load_default_prompts(self) -> Dict[str, str]:
23
  """Load default prompts and examples from files and CSVs."""
24
-
25
  # Load CSV examples
26
  try:
27
  timestamps_df = pd.read_csv("data/Timestamps.csv")
28
  titles_df = pd.read_csv("data/Titles & Thumbnails.csv")
29
  descriptions_df = pd.read_csv("data/Viral Episode Descriptions.csv")
30
  clips_df = pd.read_csv("data/Viral Twitter Clips.csv")
31
-
32
  # Format timestamp examples
33
  timestamp_examples = "\n\n".join(timestamps_df['Timestamps'].dropna().tolist())
34
-
35
  # Format title examples
36
  title_examples = "\n".join([
37
  f'Title: "{row.Titles}"\nThumbnail: "{row.Thumbnail}"'
38
  for _, row in titles_df.iterrows()
39
  ])
40
-
41
  # Format description examples
42
  description_examples = "\n".join([
43
  f'Tweet: "{row["Tweet Text"]}"'
44
  for _, row in descriptions_df.iterrows()
45
  ])
46
-
47
  # Format clip examples
48
  clip_examples = "\n\n".join([
49
  f'Tweet Text: "{row["Tweet Text"]}"\nClip Transcript: "{row["Clip Transcript"]}"'
50
  for _, row in clips_df.iterrows() if pd.notna(row["Tweet Text"])
51
  ])
52
-
53
  except Exception as e:
54
  print(f"Warning: Error loading CSV examples: {e}")
55
  timestamp_examples = ""
@@ -61,7 +63,7 @@ class ContentGenerator:
61
  prompts = {}
62
  for key in ["previews", "clips", "description", "timestamps", "titles_and_thumbnails"]:
63
  prompt = Path(f"prompts/{key}.txt").read_text()
64
-
65
  # Inject relevant examples
66
  if key == "timestamps":
67
  prompt = prompt.replace("{timestamps_examples}", timestamp_examples)
@@ -71,31 +73,30 @@ class ContentGenerator:
71
  prompt = prompt.replace("{description_examples}", description_examples)
72
  elif key == "clips":
73
  prompt = prompt.replace("{clip_examples}", clip_examples)
74
-
75
  prompts[key] = prompt
76
 
77
  return prompts
78
 
79
  async def generate_content(self, request: ContentRequest, transcript: str) -> str:
80
- """Generate content using Claude asynchronously."""
81
  try:
82
  print(f"\nFull prompt for {request.prompt_key}:")
83
  print("=== SYSTEM PROMPT ===")
84
  print(self.current_prompts[request.prompt_key])
85
  print("=== END SYSTEM PROMPT ===\n")
86
-
87
- response = self.client.messages.create(
88
- model="claude-3-5-sonnet-20241022",
89
- max_tokens=8192,
90
- system=self.current_prompts[request.prompt_key],
91
- messages=[{"role": "user", "content": f"Process this transcript:\n\n{transcript}"}]
92
  )
93
-
94
- if response and hasattr(response, 'content'):
95
- return response.content[0].text
96
  else:
97
  return f"Error: Unexpected response structure for {request.prompt_key}"
98
-
99
  except Exception as e:
100
  return f"Error generating content: {str(e)}"
101
 
@@ -117,7 +118,8 @@ def get_transcript(video_id: str) -> str:
117
 
118
  class TranscriptProcessor:
119
  def __init__(self):
120
- self.generator = ContentGenerator()
 
121
 
122
  def _get_youtube_transcript(self, url: str) -> str:
123
  """Get transcript from YouTube URL."""
@@ -128,14 +130,14 @@ class TranscriptProcessor:
128
  except Exception as e:
129
  raise Exception(f"Error fetching YouTube transcript: {str(e)}")
130
 
131
- async def process_transcript(self, input_text: str):
132
  """Process input and generate all content."""
 
133
  try:
134
- transcript = (
135
- self._get_youtube_transcript(input_text)
136
- if any(x in input_text for x in ["youtube.com", "youtu.be"])
137
- else input_text
138
- )
139
 
140
  # Process each type sequentially
141
  sections = {}
@@ -178,34 +180,36 @@ class TranscriptProcessor:
178
  ))
179
  return "Prompts updated for this session!"
180
 
 
 
181
  def create_interface():
182
  """Create the Gradio interface."""
183
  processor = TranscriptProcessor()
184
-
185
- with gr.Blocks(title="Podcast Content Generator") as app:
186
  gr.Markdown(
187
  """
188
- # Podcast Content Generator
189
- Generate preview clips, timestamps, descriptions and more from podcast transcripts or YouTube videos.
190
-
191
- Simply paste a YouTube URL or raw transcript text to get started!
192
  """
193
  )
194
-
195
  with gr.Tab("Generate Content"):
196
- input_text = gr.Textbox(
197
- label="Input",
198
- placeholder="YouTube URL or transcript text...",
199
- lines=10
200
  )
201
- submit_btn = gr.Button("Generate Content")
202
-
203
  output = gr.Markdown() # Single markdown output
204
 
205
  async def process_wrapper(text):
206
  print("Process wrapper started")
207
  print(f"Input text: {text[:100]}...")
208
-
209
  try:
210
  result = await processor.process_transcript(text)
211
  print("Process completed, got results")
@@ -216,7 +220,7 @@ def create_interface():
216
 
217
  submit_btn.click(
218
  fn=process_wrapper,
219
- inputs=input_text,
220
  outputs=output,
221
  queue=True
222
  )
@@ -224,10 +228,10 @@ def create_interface():
224
  with gr.Tab("Customize Prompts"):
225
  gr.Markdown(
226
  """
227
- ## Customize Generation Prompts
228
  Here you can experiment with different prompts during your session.
229
  Changes will remain active until you reload the page.
230
-
231
  Tip: Copy your preferred prompts somewhere safe if you want to reuse them later!
232
  """
233
  )
@@ -240,7 +244,7 @@ def create_interface():
240
  )
241
  for key in [
242
  "previews",
243
- "clips",
244
  "description",
245
  "timestamps",
246
  "titles_and_thumbnails"
@@ -257,7 +261,7 @@ def create_interface():
257
  )
258
 
259
  # Reset button
260
- reset_btn = gr.Button("Reset to Default Prompts")
261
  reset_btn.click(
262
  fn=lambda: (
263
  processor.update_prompts(*processor.generator.current_prompts.values()),
@@ -269,4 +273,4 @@ def create_interface():
269
  return app
270
 
271
  if __name__ == "__main__":
272
- create_interface().launch()
 
1
  import gradio as gr
2
  import asyncio
3
  from pathlib import Path
4
+ from google import genai
5
+ from google.genai import types
6
  import os
7
  from dataclasses import dataclass
8
  from typing import Dict
9
  from youtube_transcript_api import YouTubeTranscriptApi
10
  import re
11
  import pandas as pd
12
+ import assemblyai as aai
13
 
14
  # Move relevant classes and functions into app.py
15
  @dataclass
 
17
  prompt_key: str
18
 
19
  class ContentGenerator:
20
+ def __init__(self,api_key):
21
  self.current_prompts = self._load_default_prompts()
22
+ self.client = genai.Client(api_key=api_key)
23
+
24
  def _load_default_prompts(self) -> Dict[str, str]:
25
  """Load default prompts and examples from files and CSVs."""
26
+
27
  # Load CSV examples
28
  try:
29
  timestamps_df = pd.read_csv("data/Timestamps.csv")
30
  titles_df = pd.read_csv("data/Titles & Thumbnails.csv")
31
  descriptions_df = pd.read_csv("data/Viral Episode Descriptions.csv")
32
  clips_df = pd.read_csv("data/Viral Twitter Clips.csv")
33
+
34
  # Format timestamp examples
35
  timestamp_examples = "\n\n".join(timestamps_df['Timestamps'].dropna().tolist())
36
+
37
  # Format title examples
38
  title_examples = "\n".join([
39
  f'Title: "{row.Titles}"\nThumbnail: "{row.Thumbnail}"'
40
  for _, row in titles_df.iterrows()
41
  ])
42
+
43
  # Format description examples
44
  description_examples = "\n".join([
45
  f'Tweet: "{row["Tweet Text"]}"'
46
  for _, row in descriptions_df.iterrows()
47
  ])
48
+
49
  # Format clip examples
50
  clip_examples = "\n\n".join([
51
  f'Tweet Text: "{row["Tweet Text"]}"\nClip Transcript: "{row["Clip Transcript"]}"'
52
  for _, row in clips_df.iterrows() if pd.notna(row["Tweet Text"])
53
  ])
54
+
55
  except Exception as e:
56
  print(f"Warning: Error loading CSV examples: {e}")
57
  timestamp_examples = ""
 
63
  prompts = {}
64
  for key in ["previews", "clips", "description", "timestamps", "titles_and_thumbnails"]:
65
  prompt = Path(f"prompts/{key}.txt").read_text()
66
+
67
  # Inject relevant examples
68
  if key == "timestamps":
69
  prompt = prompt.replace("{timestamps_examples}", timestamp_examples)
 
73
  prompt = prompt.replace("{description_examples}", description_examples)
74
  elif key == "clips":
75
  prompt = prompt.replace("{clip_examples}", clip_examples)
76
+
77
  prompts[key] = prompt
78
 
79
  return prompts
80
 
81
  async def generate_content(self, request: ContentRequest, transcript: str) -> str:
82
+ """Generate content using Gemini asynchronously."""
83
  try:
84
  print(f"\nFull prompt for {request.prompt_key}:")
85
  print("=== SYSTEM PROMPT ===")
86
  print(self.current_prompts[request.prompt_key])
87
  print("=== END SYSTEM PROMPT ===\n")
88
+
89
+ response = self.client.models.generate_content(
90
+ model="gemini-2.5-pro-exp-03-25",
91
+ config=types.GenerateContentConfig(system_instruction=self.current_prompts[request.prompt_key]),
92
+ contents=transcript
 
93
  )
94
+
95
+ if response and hasattr(response, 'candidates'):
96
+ return response.text
97
  else:
98
  return f"Error: Unexpected response structure for {request.prompt_key}"
99
+
100
  except Exception as e:
101
  return f"Error generating content: {str(e)}"
102
 
 
118
 
119
  class TranscriptProcessor:
120
  def __init__(self):
121
+ self.generator = ContentGenerator(api_key=os.getenv("GOOGLE_API_KEY"))
122
+
123
 
124
  def _get_youtube_transcript(self, url: str) -> str:
125
  """Get transcript from YouTube URL."""
 
130
  except Exception as e:
131
  raise Exception(f"Error fetching YouTube transcript: {str(e)}")
132
 
133
+ async def process_transcript(self, audio_file):
134
  """Process input and generate all content."""
135
+ audio_path = audio_file.name
136
  try:
137
+ aai.settings.api_key = os.getenv("ASSEMBLYAI_API_KEY")
138
+ config = aai.TranscriptionConfig(speaker_labels=True, language_code="en")
139
+ transcript_iter = aai.Transcriber().transcribe(str(audio_path), config=config)
140
+ transcript = transcript_iter.text
 
141
 
142
  # Process each type sequentially
143
  sections = {}
 
180
  ))
181
  return "Prompts updated for this session!"
182
 
183
+
184
+
185
  def create_interface():
186
  """Create the Gradio interface."""
187
  processor = TranscriptProcessor()
188
+
189
+ with gr.Blocks(title="Gemini Podcast Content Generator") as app:
190
  gr.Markdown(
191
  """
192
+ # Gemini Podcast Content Generator
193
+ Generate preview clips, timestamps, descriptions and more from podcast transcripts using Gemini.
194
+
195
+ Upload an audio file to get started!
196
  """
197
  )
198
+
199
  with gr.Tab("Generate Content"):
200
+ input_audio = gr.File(
201
+ label="Upload Audio File",
202
+ file_count="single",
203
+ file_types=["audio"]
204
  )
205
+ submit_btn = gr.Button("Generate Content with Gemini")
206
+
207
  output = gr.Markdown() # Single markdown output
208
 
209
  async def process_wrapper(text):
210
  print("Process wrapper started")
211
  print(f"Input text: {text[:100]}...")
212
+
213
  try:
214
  result = await processor.process_transcript(text)
215
  print("Process completed, got results")
 
220
 
221
  submit_btn.click(
222
  fn=process_wrapper,
223
+ inputs=input_audio,
224
  outputs=output,
225
  queue=True
226
  )
 
228
  with gr.Tab("Customize Prompts"):
229
  gr.Markdown(
230
  """
231
+ ## Customize Generation Prompts for Gemini
232
  Here you can experiment with different prompts during your session.
233
  Changes will remain active until you reload the page.
234
+
235
  Tip: Copy your preferred prompts somewhere safe if you want to reuse them later!
236
  """
237
  )
 
244
  )
245
  for key in [
246
  "previews",
247
+ "clips",
248
  "description",
249
  "timestamps",
250
  "titles_and_thumbnails"
 
261
  )
262
 
263
  # Reset button
264
+ reset_btn = gr.Button("Reset to Default Gemini Prompts")
265
  reset_btn.click(
266
  fn=lambda: (
267
  processor.update_prompts(*processor.generator.current_prompts.values()),
 
273
  return app
274
 
275
  if __name__ == "__main__":
276
+ create_interface().launch()