simplytaps commited on
Commit
e4b878e
·
verified ·
1 Parent(s): 50feb1c

Upload groq_client.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. groq_client.py +191 -0
groq_client.py ADDED
@@ -0,0 +1,191 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Groq API client for LLM processing."""
2
+ import os
3
+ from typing import Optional, List, Dict, Any
4
+ from groq import Groq, RateLimitError, APIError
5
+ from config import config
6
+
7
+
8
+ class GroqClient:
9
+ """Client for interacting with Groq API."""
10
+
11
+ def __init__(self, api_key: Optional[str] = None, model: Optional[str] = None):
12
+ """
13
+ Initialize the Groq client.
14
+
15
+ Args:
16
+ api_key: Groq API key (defaults to config)
17
+ model: Model name (defaults to config)
18
+ """
19
+ self.api_key = api_key or config.GROQ_API_KEY
20
+ self.model = model or config.GROQ_MODEL
21
+ self.client = Groq(api_key=self.api_key)
22
+
23
+ # Model pricing (approximate, per million tokens)
24
+ self.pricing = {
25
+ "llama-3.3-70b-versatile": {"input": 0.59, "output": 1.99},
26
+ "llama-3.1-8b-instant": {"input": 0.05, "output": 0.08},
27
+ "mixtral-8x7b-32768": {"input": 0.24, "output": 0.24},
28
+ "gemma2-9b-it": {"input": 0.14, "output": 0.14},
29
+ }
30
+
31
+ def count_tokens(self, text: str) -> int:
32
+ """Estimate token count (rough approximation)."""
33
+ # Average: 4 characters per token
34
+ return len(text) // 4
35
+
36
+ def estimate_cost(self, input_tokens: int, output_tokens: int) -> float:
37
+ """Estimate cost for API call."""
38
+ pricing = self.pricing.get(self.model, {"input": 0.5, "output": 1.0})
39
+ input_cost = (input_tokens / 1_000_000) * pricing["input"]
40
+ output_cost = (output_tokens / 1_000_000) * pricing["output"]
41
+ return input_cost + output_cost
42
+
43
+ def chat_completion(
44
+ self,
45
+ messages: List[Dict[str, str]],
46
+ max_tokens: int = 8000,
47
+ temperature: float = 0.7,
48
+ system_prompt: Optional[str] = None,
49
+ ) -> Dict[str, Any]:
50
+ """
51
+ Send a chat completion request to Groq.
52
+
53
+ Args:
54
+ messages: List of message dictionaries
55
+ max_tokens: Maximum output tokens
56
+ temperature: Sampling temperature
57
+ system_prompt: Optional system prompt
58
+
59
+ Returns:
60
+ API response dictionary
61
+ """
62
+ # Add system prompt if provided
63
+ if system_prompt:
64
+ messages = [{"role": "system", "content": system_prompt}] + messages
65
+
66
+ try:
67
+ response = self.client.chat.completions.create(
68
+ model=self.model,
69
+ messages=messages,
70
+ max_tokens=max_tokens,
71
+ temperature=temperature,
72
+ )
73
+
74
+ input_tokens = response.usage.prompt_tokens
75
+ output_tokens = response.usage.completion_tokens
76
+ cost = self.estimate_cost(input_tokens, output_tokens)
77
+
78
+ return {
79
+ 'success': True,
80
+ 'content': response.choices[0].message.content,
81
+ 'usage': {
82
+ 'prompt_tokens': input_tokens,
83
+ 'completion_tokens': output_tokens,
84
+ 'total_tokens': input_tokens + output_tokens,
85
+ 'estimated_cost_usd': cost
86
+ },
87
+ 'model': self.model
88
+ }
89
+
90
+ except RateLimitError as e:
91
+ return {
92
+ 'success': False,
93
+ 'error': f"Rate limit exceeded: {str(e)}",
94
+ 'error_type': 'rate_limit'
95
+ }
96
+ except APIError as e:
97
+ return {
98
+ 'success': False,
99
+ 'error': f"API error: {str(e)}",
100
+ 'error_type': 'api_error'
101
+ }
102
+ except Exception as e:
103
+ return {
104
+ 'success': False,
105
+ 'error': f"Unexpected error: {str(e)}",
106
+ 'error_type': 'unknown'
107
+ }
108
+
109
+ def summarize_transcript(
110
+ self,
111
+ transcript: str,
112
+ prompt_template: str,
113
+ chunk_summaries: Optional[List[str]] = None,
114
+ max_tokens: int = 12000,
115
+ temperature: float = 0.5,
116
+ ) -> Dict[str, Any]:
117
+ """
118
+ Generate a comprehensive summary from transcript.
119
+
120
+ Args:
121
+ transcript: Full transcript text
122
+ prompt_template: The prompt template from youtube_summary.md
123
+ chunk_summaries: Optional pre-processed chunk summaries
124
+ max_tokens: Maximum output tokens
125
+ temperature: Sampling temperature
126
+
127
+ Returns:
128
+ Summary result dictionary
129
+ """
130
+ # Handle chunked transcripts
131
+ if chunk_summaries:
132
+ # Combine chunk summaries into an intermediate summary
133
+ combined_summary = "\n\n".join(chunk_summaries)
134
+ user_message = f"""Based on these chapter-by-chapter summaries, create a comprehensive book-style summary following the format below:
135
+
136
+ {combined_summary}
137
+
138
+ ---
139
+ {PROMPT_SUFFIX}
140
+ """
141
+ else:
142
+ user_message = f"""{transcript}
143
+
144
+ ---
145
+ {PROMPT_SUFFIX}
146
+ """
147
+
148
+ messages = [
149
+ {"role": "user", "content": user_message}
150
+ ]
151
+
152
+ response = self.chat_completion(
153
+ messages=messages,
154
+ system_prompt=prompt_template,
155
+ max_tokens=max_tokens,
156
+ temperature=temperature,
157
+ )
158
+
159
+ return response
160
+
161
+
162
+ # Prompt suffix used in summarize_transcript
163
+ PROMPT_SUFFIX = """Using the above content, create a comprehensive book-style summary following the youtube_summary.md template exactly. Include:
164
+ - Executive Overview (2-3 paragraphs)
165
+ - Introduction with background and presenter context
166
+ - Chapter-by-Chapter Summary with detailed analysis
167
+ - Key Concepts and Definitions
168
+ - Key Takeaways (numbered)
169
+ - Memorable Quotations (3-5 quotes)
170
+ - Practical Applications
171
+ - Critical Analysis
172
+ - Further Reading/Sources
173
+ - Conclusion
174
+
175
+ Write in flowing prose, avoid excessive lists, and maximize depth and value."""
176
+
177
+
178
+ def create_client(api_key: Optional[str] = None, model: Optional[str] = None) -> GroqClient:
179
+ """Factory function to create Groq client."""
180
+ return GroqClient(api_key=api_key, model=model)
181
+
182
+
183
+ if __name__ == "__main__":
184
+ # Test the client
185
+ client = create_client()
186
+
187
+ if not config.GROQ_API_KEY:
188
+ print("Warning: GROQ_API_KEY not set. Set it in .env file.")
189
+ else:
190
+ print(f"✓ Groq client initialized with model: {client.model}")
191
+ print(f" Available models: {list(client.pricing.keys())}")