From 5af5e8e68dea867274cb3c7c214e42c0a90740e0 Mon Sep 17 00:00:00 2001 From: lustresix Date: Fri, 6 Mar 2026 23:46:15 +0800 Subject: [PATCH 1/3] fix(provider): support 84-char Azure TTS subscription keys --- astrbot/core/provider/sources/azure_tts_source.py | 7 ++++--- tests/test_azure_tts_provider.py | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 tests/test_azure_tts_provider.py diff --git a/astrbot/core/provider/sources/azure_tts_source.py b/astrbot/core/provider/sources/azure_tts_source.py index 0e8f00ce52..2fa9ff4384 100644 --- a/astrbot/core/provider/sources/azure_tts_source.py +++ b/astrbot/core/provider/sources/azure_tts_source.py @@ -20,6 +20,7 @@ TEMP_DIR = Path(get_astrbot_temp_path()) / "azure_tts" TEMP_DIR.mkdir(parents=True, exist_ok=True) +AZURE_TTS_SUBSCRIPTION_KEY_PATTERN = r"^[a-zA-Z0-9]{32,84}$" class OTTSProvider: @@ -116,7 +117,7 @@ def __init__(self, provider_config: dict, provider_settings: dict) -> None: "azure_tts_subscription_key", "", ).strip() - if not re.fullmatch(r"^[a-zA-Z0-9]{32}$", self.subscription_key): + if not re.fullmatch(AZURE_TTS_SUBSCRIPTION_KEY_PATTERN, self.subscription_key): raise ValueError("无效的Azure订阅密钥") self.region = provider_config.get("azure_tts_region", "eastus").strip() self.endpoint = ( @@ -235,9 +236,9 @@ def _parse_provider( raise ValueError(error_msg) from e except KeyError as e: raise ValueError(f"配置错误: 缺少必要参数 {e}") from e - if re.fullmatch(r"^[a-zA-Z0-9]{32}$", key_value): + if re.fullmatch(AZURE_TTS_SUBSCRIPTION_KEY_PATTERN, key_value): return AzureNativeProvider(config, self.provider_settings) - raise ValueError("订阅密钥格式无效,应为32位字母数字或other[...]格式") + raise ValueError("订阅密钥格式无效,应为32位或84位字母数字或other[...]格式") async def get_audio(self, text: str) -> str: if isinstance(self.provider, OTTSProvider): diff --git a/tests/test_azure_tts_provider.py b/tests/test_azure_tts_provider.py new file mode 100644 index 0000000000..96159242ed --- /dev/null +++ b/tests/test_azure_tts_provider.py @@ -0,0 +1,15 @@ +import pytest + +from astrbot.core.provider.sources.azure_tts_source import AzureTTSProvider + + +@pytest.mark.parametrize("key_length", [32, 84]) +def test_azure_tts_accepts_subscription_keys_with_supported_lengths(key_length: int): + config = { + "azure_tts_subscription_key": "A" * key_length, + "azure_tts_region": "eastus", + "azure_tts_voice": "zh-CN-XiaoxiaoNeural", + } + + provider = AzureTTSProvider(config, {}) + assert provider.provider is not None From bb71ed5a701b60e32a42aed760970de22f1678fc Mon Sep 17 00:00:00 2001 From: lustresix Date: Sat, 7 Mar 2026 00:15:54 +0800 Subject: [PATCH 2/3] test(provider): add negative Azure TTS key validation cases --- .../core/provider/sources/azure_tts_source.py | 2 +- tests/test_azure_tts_provider.py | 24 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/astrbot/core/provider/sources/azure_tts_source.py b/astrbot/core/provider/sources/azure_tts_source.py index 2fa9ff4384..fc2bb6c09e 100644 --- a/astrbot/core/provider/sources/azure_tts_source.py +++ b/astrbot/core/provider/sources/azure_tts_source.py @@ -20,7 +20,7 @@ TEMP_DIR = Path(get_astrbot_temp_path()) / "azure_tts" TEMP_DIR.mkdir(parents=True, exist_ok=True) -AZURE_TTS_SUBSCRIPTION_KEY_PATTERN = r"^[a-zA-Z0-9]{32,84}$" +AZURE_TTS_SUBSCRIPTION_KEY_PATTERN = r"^(?:[a-zA-Z0-9]{32}|[a-zA-Z0-9]{84})$" class OTTSProvider: diff --git a/tests/test_azure_tts_provider.py b/tests/test_azure_tts_provider.py index 96159242ed..8fae09b140 100644 --- a/tests/test_azure_tts_provider.py +++ b/tests/test_azure_tts_provider.py @@ -13,3 +13,27 @@ def test_azure_tts_accepts_subscription_keys_with_supported_lengths(key_length: provider = AzureTTSProvider(config, {}) assert provider.provider is not None + + +@pytest.mark.parametrize( + "invalid_key", + [ + "", + "A" * 31, + "A" * 33, + "A" * 83, + "A" * 85, + ("A" * 31) + "-", + ("A" * 31) + "_", + ("A" * 31) + "~", + ], +) +def test_azure_tts_rejects_invalid_subscription_keys(invalid_key: str): + config = { + "azure_tts_subscription_key": invalid_key, + "azure_tts_region": "eastus", + "azure_tts_voice": "zh-CN-XiaoxiaoNeural", + } + + with pytest.raises(ValueError): + AzureTTSProvider(config, {}) From 0138d855107257a119ba663b995328f48533a6bb Mon Sep 17 00:00:00 2001 From: Soulter <905617992@qq.com> Date: Tue, 10 Mar 2026 17:07:05 +0800 Subject: [PATCH 3/3] chore: delete test --- tests/test_azure_tts_provider.py | 39 -------------------------------- 1 file changed, 39 deletions(-) delete mode 100644 tests/test_azure_tts_provider.py diff --git a/tests/test_azure_tts_provider.py b/tests/test_azure_tts_provider.py deleted file mode 100644 index 8fae09b140..0000000000 --- a/tests/test_azure_tts_provider.py +++ /dev/null @@ -1,39 +0,0 @@ -import pytest - -from astrbot.core.provider.sources.azure_tts_source import AzureTTSProvider - - -@pytest.mark.parametrize("key_length", [32, 84]) -def test_azure_tts_accepts_subscription_keys_with_supported_lengths(key_length: int): - config = { - "azure_tts_subscription_key": "A" * key_length, - "azure_tts_region": "eastus", - "azure_tts_voice": "zh-CN-XiaoxiaoNeural", - } - - provider = AzureTTSProvider(config, {}) - assert provider.provider is not None - - -@pytest.mark.parametrize( - "invalid_key", - [ - "", - "A" * 31, - "A" * 33, - "A" * 83, - "A" * 85, - ("A" * 31) + "-", - ("A" * 31) + "_", - ("A" * 31) + "~", - ], -) -def test_azure_tts_rejects_invalid_subscription_keys(invalid_key: str): - config = { - "azure_tts_subscription_key": invalid_key, - "azure_tts_region": "eastus", - "azure_tts_voice": "zh-CN-XiaoxiaoNeural", - } - - with pytest.raises(ValueError): - AzureTTSProvider(config, {})