11import asyncio
2+ import logging
3+ import os
4+ import sys
5+ import warnings
6+ from contextlib import contextmanager
27from typing import Callable , Optional
38
49from google import genai
1419
1520
1621def proofread () -> None :
17- """Proofread the source SRT file with Gemini."""
22+ """Proofread the source SRT file using Gemini."""
1823
1924 if should_skip (f"{ config .source_language } .srt" ):
2025 return
@@ -23,7 +28,7 @@ def proofread() -> None:
2328
2429
2530async def _proofread () -> None :
26- info ("Proofreading with Gemini..." )
31+ info ("Proofreading using Gemini..." )
2732
2833 language_code = config .source_language
2934 language = get_language_name (language_code )
@@ -65,7 +70,7 @@ async def _proofread() -> None:
6570
6671
6772def translate () -> None :
68- """Translate the source SRT file with Gemini."""
73+ """Translate the source SRT file using Gemini."""
6974
7075 asyncio .run (_translate ())
7176
@@ -87,7 +92,7 @@ async def _translate() -> None:
8792 if not target_language_codes :
8893 return
8994
90- info ("Translating with Gemini..." )
95+ info ("Translating using Gemini..." )
9196
9297 tasks = []
9398
@@ -116,6 +121,57 @@ async def _translate() -> None:
116121 await asyncio .gather (* tasks )
117122
118123
124+ @contextmanager
125+ def _suppress_gemini_output ():
126+ """
127+ Context manager to suppress all Gemini API output unless in debug mode.
128+
129+ Suppresses:
130+ - All warnings from google.genai and related libraries
131+ - All logging output from these libraries
132+ - All stdout/stderr output
133+ """
134+ if config .debug :
135+ yield
136+ return
137+
138+ # Suppress warnings
139+ with warnings .catch_warnings ():
140+ warnings .filterwarnings ("ignore" )
141+
142+ # Suppress logging
143+ logging_modules = [
144+ "google" ,
145+ "google.genai" ,
146+ "google.api_core" ,
147+ "grpc" ,
148+ ]
149+ original_levels = {}
150+ for module_name in logging_modules :
151+ logger = logging .getLogger (module_name )
152+ original_levels [module_name ] = logger .level
153+ logger .setLevel (logging .ERROR )
154+
155+ # Suppress stdout/stderr
156+ original_stdout = sys .stdout
157+ original_stderr = sys .stderr
158+
159+ with open (os .devnull , "w" ) as devnull :
160+ sys .stdout = devnull
161+ sys .stderr = devnull
162+
163+ try :
164+ yield
165+ finally :
166+ # Restore stdout/stderr
167+ sys .stdout = original_stdout
168+ sys .stderr = original_stderr
169+
170+ # Restore logging levels
171+ for module_name , level in original_levels .items ():
172+ logging .getLogger (module_name ).setLevel (level )
173+
174+
119175async def _translate_language (
120176 file : types .File ,
121177 srt_content : str ,
@@ -173,50 +229,53 @@ async def _call_gemini_api(
173229 """
174230 Helper method to call Gemini API with retries for rate limits.
175231 """
176- client = genai .Client (api_key = config .gemini_api_key )
177-
178- # Build parts for the content
179- parts = []
180- if file :
181- parts .append (file )
182- if text :
183- parts .append (types .Part .from_text (text = text ))
184-
185- tools = [
186- types .Tool (google_search = types .GoogleSearch ()),
187- ]
188-
189- for attempt in range (config .retry ):
190- try :
191- response = await client .aio .models .generate_content (
192- model = config .gemini_model ,
193- contents = parts ,
194- config = types .GenerateContentConfig (
195- system_instruction = system_instruction ,
196- thinking_config = types .ThinkingConfig (
197- include_thoughts = True , thinking_level = types .ThinkingLevel .HIGH
232+ with _suppress_gemini_output ():
233+ client = genai .Client (api_key = config .gemini_api_key )
234+
235+ # Build parts for the content
236+ parts = []
237+ if file :
238+ parts .append (file )
239+ if text :
240+ parts .append (types .Part .from_text (text = text ))
241+
242+ tools = [
243+ types .Tool (google_search = types .GoogleSearch ()),
244+ ]
245+
246+ for attempt in range (config .retry ):
247+ try :
248+ response = await client .aio .models .generate_content (
249+ model = config .gemini_model ,
250+ contents = parts ,
251+ config = types .GenerateContentConfig (
252+ system_instruction = system_instruction ,
253+ thinking_config = types .ThinkingConfig (
254+ include_thoughts = True ,
255+ thinking_level = types .ThinkingLevel .HIGH ,
256+ ),
257+ tools = tools ,
198258 ),
199- tools = tools ,
200- ),
201- )
202- text = response . text
203- if text :
204- with open ( output_file , "w" ) as f :
205- f . write ( text )
206- return
207-
208- except google_exceptions . ResourceExhausted as e :
209- if attempt < config . retry - 1 :
210- wait_time = 2 ** attempt # Exponential backoff: 1, 2, 4 seconds
211- await asyncio . sleep ( wait_time )
212- continue
213- else :
259+ )
260+ text = response . text
261+ if text :
262+ with open ( output_file , "w" ) as f :
263+ f . write ( text )
264+ return
265+
266+ except google_exceptions . ResourceExhausted as e :
267+ if attempt < config . retry - 1 :
268+ wait_time = 2 ** attempt # Exponential backoff: 1, 2, 4 seconds
269+ await asyncio . sleep ( wait_time )
270+ continue
271+ else :
272+ raise e
273+ except Exception as e :
214274 raise e
215- except Exception as e :
216- raise e
217275
218276
219277def _upload_file (file_path : str ) -> types .File :
220- client = genai .Client (api_key = config .gemini_api_key )
221- file = client .files .upload (file = file_path )
222- return file
278+ with _suppress_gemini_output ():
279+ client = genai .Client (api_key = config .gemini_api_key )
280+ file = client .files .upload (file = file_path )
281+ return file
0 commit comments