Narayana02 commited on
Commit
e73e4ff
·
verified ·
1 Parent(s): 4654e9b

Create utils.py

Browse files
Files changed (1) hide show
  1. utils.py +104 -0
utils.py ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from groq import Groq
2
+ from pydantic import BaseModel, ValidationError
3
+ from typing import List, Literal
4
+ import os
5
+ import tiktoken
6
+ import json
7
+ import re
8
+ import tempfile
9
+ from gtts import gTTS
10
+ from bs4 import BeautifulSoup
11
+ import requests
12
+
13
+ groq_client = Groq(api_key=os.environ["GROQ_API_KEY"])
14
+ tokenizer = tiktoken.get_encoding("cl100k_base")
15
+
16
+ class DialogueItem(BaseModel):
17
+ speaker: Literal["Sarah", "Maria"]
18
+ text: str
19
+
20
+ class Dialogue(BaseModel):
21
+ dialogue: List[DialogueItem]
22
+
23
+ def truncate_text(text, max_tokens=2048):
24
+ tokens = tokenizer.encode(text)
25
+ if len(tokens) > max_tokens:
26
+ return tokenizer.decode(tokens[:max_tokens])
27
+ return text
28
+
29
+ def extract_text_from_url(url):
30
+ try:
31
+ response = requests.get(url)
32
+ response.raise_for_status()
33
+ soup = BeautifulSoup(response.text, 'html.parser')
34
+
35
+ for script in soup(["script", "style"]):
36
+ script.decompose()
37
+
38
+ text = soup.get_text()
39
+ lines = (line.strip() for line in text.splitlines())
40
+ chunks = (phrase.strip() for line in lines for phrase in line.split(" "))
41
+ text = '\n'.join(chunk for chunk in chunks if chunk)
42
+
43
+ return text
44
+ except Exception as e:
45
+ raise ValueError(f"Error extracting text from URL: {str(e)}")
46
+
47
+ def generate_script(system_prompt: str, input_text: str, tone: str, target_length: str):
48
+ input_text = truncate_text(input_text)
49
+ word_limit = 300 if target_length == "Short (1-2 min)" else 750
50
+
51
+ prompt = f"""
52
+ {system_prompt}
53
+ TONE: {tone}
54
+ TARGET LENGTH: {target_length} (approximately {word_limit} words)
55
+ INPUT TEXT: {input_text}
56
+ Generate a complete, well-structured podcast script that:
57
+ 1. Starts with a proper introduction
58
+ 2. Covers the main points from the input text
59
+ 3. Has a natural flow of conversation between Sarah (American accent) and Maria (British accent)
60
+ 4. Concludes with a summary and sign-off
61
+ 5. Fits within the {word_limit} word limit for the target length of {target_length}
62
+ 6. Strongly emphasizes the {tone} tone throughout the conversation
63
+ For a humorous tone, include jokes, puns, and playful banter.
64
+ For a casual tone, use colloquial language and make it sound like a conversation between college students.
65
+ For a formal tone, maintain a professional podcast style with well-structured arguments and formal language.
66
+ Ensure the script is not abruptly cut off and forms a complete conversation.
67
+ """
68
+
69
+ response = groq_client.chat.completions.create(
70
+ messages=[
71
+ {"role": "system", "content": prompt},
72
+ ],
73
+ model="llama-3.1-70b-versatile",
74
+ max_tokens=2048,
75
+ temperature=0.7
76
+ )
77
+
78
+ content = response.choices[0].message.content
79
+ content = re.sub(r'```json\s*|\s*```', '', content)
80
+
81
+ try:
82
+ json_data = json.loads(content)
83
+ dialogue = Dialogue.model_validate(json_data)
84
+ except json.JSONDecodeError as json_error:
85
+ match = re.search(r'\{.*\}', content, re.DOTALL)
86
+ if match:
87
+ try:
88
+ json_data = json.loads(match.group())
89
+ dialogue = Dialogue.model_validate(json_data)
90
+ except (json.JSONDecodeError, ValidationError) as e:
91
+ raise ValueError(f"Failed to parse dialogue JSON: {e}\nContent: {content}")
92
+ else:
93
+ raise ValueError(f"Failed to find valid JSON in the response: {content}")
94
+ except ValidationError as e:
95
+ raise ValueError(f"Failed to validate dialogue structure: {e}\nContent: {content}")
96
+
97
+ return dialogue
98
+
99
+ def generate_audio(text: str, speaker: str) -> str:
100
+ tld = 'com' if speaker == "Sarah" else 'co.uk'
101
+ tts = gTTS(text=text, lang='en', tld=tld)
102
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as temp_audio:
103
+ tts.save(temp_audio.name)
104
+ return temp_audio.name