Fix for translator test (#1280)

This commit is contained in:
Raivis Dejus 2025-11-09 11:52:20 +02:00 committed by GitHub
commit ccdeb09ac9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 58 additions and 44 deletions

View file

@ -64,7 +64,8 @@ class LocalWhisperCppServerTranscriber(OpenAIWhisperAPIFileTranscriber):
self.openai_client = OpenAI(
api_key="not-used",
base_url="http://127.0.0.1:3000"
base_url="http://127.0.0.1:3000",
max_retries=0
)
def transcribe(self) -> List[Segment]:

View file

@ -46,7 +46,8 @@ class OpenAIWhisperAPIFileTranscriber(FileTranscriber):
self.task = task.transcription_options.task
self.openai_client = OpenAI(
api_key=self.transcription_task.transcription_options.openai_access_token,
base_url=custom_openai_base_url if custom_openai_base_url else None
base_url=custom_openai_base_url if custom_openai_base_url else None,
max_retries=0
)
self.whisper_api_model = get_custom_api_whisper_model(custom_openai_base_url)
self.word_level_timings = self.transcription_task.transcription_options.word_level_timings

View file

@ -126,7 +126,8 @@ class RecordingTranscriber(QObject):
self.whisper_api_model = get_custom_api_whisper_model(custom_openai_base_url)
self.openai_client = OpenAI(
api_key=self.transcription_options.openai_access_token,
base_url=custom_openai_base_url if custom_openai_base_url else None
base_url=custom_openai_base_url if custom_openai_base_url else None,
max_retries=0
)
logging.debug("Will use whisper API on %s, %s",
custom_openai_base_url, self.whisper_api_model)

View file

@ -3,7 +3,7 @@ import logging
import queue
from typing import Optional
from openai import OpenAI
from openai import OpenAI, max_retries
from PyQt6.QtCore import QObject, pyqtSignal
from buzz.settings.settings import Settings
@ -15,7 +15,6 @@ from buzz.widgets.transcriber.advanced_settings_dialog import AdvancedSettingsDi
class Translator(QObject):
translation = pyqtSignal(str, int)
finished = pyqtSignal()
is_running = False
def __init__(
self,
@ -48,19 +47,22 @@ class Translator(QObject):
)
self.openai_client = OpenAI(
api_key=openai_api_key,
base_url=custom_openai_base_url if custom_openai_base_url else None
base_url=custom_openai_base_url if custom_openai_base_url else None,
max_retries=0
)
def start(self):
logging.debug("Starting translation queue")
self.is_running = True
while True:
item = self.queue.get() # Block until item available
while self.is_running:
try:
transcript, transcript_id = self.queue.get(timeout=1)
except queue.Empty:
continue
# Check for sentinel value (None means stop)
if item is None:
logging.debug("Translation queue received stop signal")
break
transcript, transcript_id = item
try:
completion = self.openai_client.chat.completions.create(
@ -69,7 +71,8 @@ class Translator(QObject):
{"role": "system", "content": self.transcription_options.llm_prompt},
{"role": "user", "content": transcript}
],
timeout=30.0
timeout=30.0,
)
except Exception as e:
completion = None
@ -84,6 +87,7 @@ class Translator(QObject):
self.translation.emit(next_translation, transcript_id)
logging.debug("Translation queue stopped")
self.finished.emit()
def on_transcription_options_changed(
@ -95,4 +99,5 @@ class Translator(QObject):
self.queue.put((transcript, transcript_id))
def stop(self):
self.is_running = False
# Send sentinel value to unblock and stop the worker thread
self.queue.put(None)

View file

@ -328,7 +328,7 @@ class ValidateOpenAIApiKeyJob(QRunnable):
client = OpenAI(
api_key=self.api_key,
base_url=custom_openai_base_url if custom_openai_base_url else None,
timeout=5,
timeout=15,
)
client.models.list()
self.signals.success.emit()

View file

@ -1351,8 +1351,15 @@ class TranscriptionViewerWidget(QWidget):
# Only wait if thread is actually running
if self.translation_thread.isRunning():
if not self.translation_thread.wait(45_000):
logging.warning("Translation thread did not finish within timeout")
# Wait up to 35 seconds for graceful shutdown
# (30s max API call timeout + 5s buffer)
if not self.translation_thread.wait(35_000):
logging.warning("Translation thread did not finish gracefully, terminating")
# Force terminate the thread if it doesn't stop
self.translation_thread.terminate()
# Give it a brief moment to terminate
if not self.translation_thread.wait(1_000):
logging.error("Translation thread could not be terminated")
super().closeEvent(event)

View file

@ -15,14 +15,12 @@ class TestTranslator:
@patch('buzz.translator.queue.Queue', autospec=True)
def test_start(self, mock_queue, mock_openai, qtbot):
def side_effect(*args, **kwargs):
side_effect.call_count += 1
if side_effect.call_count <= 1:
side_effect.call_count += 1
return ("Hello, how are you?", 1)
if side_effect.call_count >= 5:
translator.is_running = False
if side_effect.call_count < 3:
raise Empty
return "Hello, how are you?", None
# Finally return sentinel to stop
return None
side_effect.call_count = 0
@ -51,6 +49,8 @@ class TestTranslator:
mock_queue.get.assert_called()
mock_chat.completions.create.assert_called()
translator.stop()
@patch('buzz.translator.OpenAI', autospec=True)
def test_translator(self, mock_openai, qtbot):
@ -94,8 +94,7 @@ class TestTranslator:
self.translation_thread.start()
time.sleep(3)
assert self.translator.is_running
time.sleep(1) # Give thread time to start
self.translator.enqueue("Hello, how are you?")

View file

@ -778,24 +778,24 @@ class TestTranscriptionViewerWidgetAdditional:
widget.close()
# Skipped as it seems it is sending actual requests and maybe failing on CI
# def test_run_translation(self, qtbot: QtBot, transcription, transcription_service, shortcuts):
# """Test run_translation method"""
# widget = TranscriptionViewerWidget(
# transcription, transcription_service, shortcuts
# )
# qtbot.add_widget(widget)
#
# # Set required options
# widget.transcription_options.llm_model = "gpt-4"
# widget.transcription_options.llm_prompt = "Translate"
#
# widget.run_translation()
#
# # Should enqueue translation tasks
# assert hasattr(widget, 'run_translation')
#
# widget.close()
# TODO - it is sending actual requests, should mock
def test_run_translation(self, qtbot: QtBot, transcription, transcription_service, shortcuts):
"""Test run_translation method"""
widget = TranscriptionViewerWidget(
transcription, transcription_service, shortcuts
)
qtbot.add_widget(widget)
# Set required options
widget.transcription_options.llm_model = "gpt-4"
widget.transcription_options.llm_prompt = "Translate"
widget.run_translation()
# Should enqueue translation tasks
assert hasattr(widget, 'run_translation')
widget.close()
def test_restore_ui_state(self, qtbot: QtBot, transcription, transcription_service, shortcuts):
"""Test restore_ui_state method"""