Add DashScope ASR model support and enhance related components
- Introduced DashScope as a new ASR model in the database initialization. - Updated ASRModel schema to include vendor information. - Enhanced ASR router to support DashScope-specific functionality, including connection testing and preview capabilities. - Modified frontend components to accommodate DashScope as a selectable vendor with appropriate default settings. - Added tests to validate DashScope ASR model creation, updates, and connectivity. - Updated backend API to handle DashScope-specific base URLs and vendor normalization.
This commit is contained in:
@@ -1,8 +1,21 @@
|
||||
"""Tests for ASR Model API endpoints"""
|
||||
import io
|
||||
import wave
|
||||
|
||||
import pytest
|
||||
from unittest.mock import patch, MagicMock
|
||||
|
||||
|
||||
def _make_wav_bytes(sample_rate: int = 16000) -> bytes:
|
||||
with io.BytesIO() as buffer:
|
||||
with wave.open(buffer, "wb") as wav_file:
|
||||
wav_file.setnchannels(1)
|
||||
wav_file.setsampwidth(2)
|
||||
wav_file.setframerate(sample_rate)
|
||||
wav_file.writeframes(b"\x00\x00" * sample_rate)
|
||||
return buffer.getvalue()
|
||||
|
||||
|
||||
class TestASRModelAPI:
|
||||
"""Test cases for ASR Model endpoints"""
|
||||
|
||||
@@ -75,6 +88,24 @@ class TestASRModelAPI:
|
||||
assert data["language"] == "en"
|
||||
assert data["enable_punctuation"] == False
|
||||
|
||||
def test_update_asr_model_vendor(self, client, sample_asr_model_data):
|
||||
"""Test updating ASR vendor metadata."""
|
||||
create_response = client.post("/api/asr", json=sample_asr_model_data)
|
||||
model_id = create_response.json()["id"]
|
||||
|
||||
response = client.put(
|
||||
f"/api/asr/{model_id}",
|
||||
json={
|
||||
"vendor": "DashScope",
|
||||
"model_name": "qwen3-asr-flash-realtime",
|
||||
"base_url": "wss://dashscope.aliyuncs.com/api-ws/v1/realtime",
|
||||
},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["vendor"] == "DashScope"
|
||||
assert data["model_name"] == "qwen3-asr-flash-realtime"
|
||||
|
||||
def test_delete_asr_model(self, client, sample_asr_model_data):
|
||||
"""Test deleting an ASR model"""
|
||||
# Create first
|
||||
@@ -234,6 +265,28 @@ class TestASRModelAPI:
|
||||
response = client.post(f"/api/asr/{model_id}/test")
|
||||
assert response.status_code == 200
|
||||
|
||||
def test_test_asr_model_dashscope(self, client, sample_asr_model_data, monkeypatch):
|
||||
"""Test DashScope ASR connectivity probe."""
|
||||
from app.routers import asr as asr_router
|
||||
|
||||
sample_asr_model_data["vendor"] = "DashScope"
|
||||
sample_asr_model_data["base_url"] = "wss://dashscope.aliyuncs.com/api-ws/v1/realtime"
|
||||
sample_asr_model_data["model_name"] = "qwen3-asr-flash-realtime"
|
||||
create_response = client.post("/api/asr", json=sample_asr_model_data)
|
||||
model_id = create_response.json()["id"]
|
||||
|
||||
def fake_probe(**kwargs):
|
||||
assert kwargs["api_key"] == sample_asr_model_data["api_key"]
|
||||
assert kwargs["model"] == "qwen3-asr-flash-realtime"
|
||||
|
||||
monkeypatch.setattr(asr_router, "_probe_dashscope_asr_connection", fake_probe)
|
||||
|
||||
response = client.post(f"/api/asr/{model_id}/test")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["success"] is True
|
||||
assert data["message"] == "DashScope realtime ASR connected"
|
||||
|
||||
@patch('httpx.Client')
|
||||
def test_test_asr_model_failure(self, mock_client_class, client, sample_asr_model_data):
|
||||
"""Test testing an ASR model with failed connection"""
|
||||
@@ -274,7 +327,7 @@ class TestASRModelAPI:
|
||||
|
||||
def test_different_asr_vendors(self, client):
|
||||
"""Test creating ASR models with different vendors"""
|
||||
vendors = ["SiliconFlow", "OpenAI", "Azure"]
|
||||
vendors = ["SiliconFlow", "OpenAI", "Azure", "DashScope"]
|
||||
for vendor in vendors:
|
||||
data = {
|
||||
"id": f"asr-vendor-{vendor.lower()}",
|
||||
@@ -345,3 +398,33 @@ class TestASRModelAPI:
|
||||
)
|
||||
assert response.status_code == 400
|
||||
assert "Only audio files are supported" in response.text
|
||||
|
||||
def test_preview_asr_model_dashscope(self, client, sample_asr_model_data, monkeypatch):
|
||||
"""Test ASR preview endpoint with DashScope realtime helper."""
|
||||
from app.routers import asr as asr_router
|
||||
|
||||
sample_asr_model_data["vendor"] = "DashScope"
|
||||
sample_asr_model_data["base_url"] = "wss://dashscope.aliyuncs.com/api-ws/v1/realtime"
|
||||
sample_asr_model_data["model_name"] = "qwen3-asr-flash-realtime"
|
||||
create_response = client.post("/api/asr", json=sample_asr_model_data)
|
||||
model_id = create_response.json()["id"]
|
||||
|
||||
def fake_preview(**kwargs):
|
||||
assert kwargs["base_url"] == sample_asr_model_data["base_url"]
|
||||
assert kwargs["model"] == sample_asr_model_data["model_name"]
|
||||
return {
|
||||
"transcript": "你好,这是实时识别",
|
||||
"language": "zh",
|
||||
"confidence": None,
|
||||
}
|
||||
|
||||
monkeypatch.setattr(asr_router, "_transcribe_dashscope_preview", fake_preview)
|
||||
|
||||
response = client.post(
|
||||
f"/api/asr/{model_id}/preview",
|
||||
files={"file": ("sample.wav", _make_wav_bytes(), "audio/wav")},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
payload = response.json()
|
||||
assert payload["success"] is True
|
||||
assert payload["transcript"] == "你好,这是实时识别"
|
||||
|
||||
Reference in New Issue
Block a user