feat: support tencent cos custom domain (#30193)

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
wangxiaolei 2025-12-29 15:41:02 +08:00 committed by GitHub
parent 6d0e36479b
commit 2c919efa69
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 92 additions and 7 deletions

View File

@ -128,6 +128,7 @@ TENCENT_COS_SECRET_KEY=your-secret-key
TENCENT_COS_SECRET_ID=your-secret-id
TENCENT_COS_REGION=your-region
TENCENT_COS_SCHEME=your-scheme
TENCENT_COS_CUSTOM_DOMAIN=your-custom-domain
# Huawei OBS Storage Configuration
HUAWEI_OBS_BUCKET_NAME=your-bucket-name

View File

@ -31,3 +31,8 @@ class TencentCloudCOSStorageConfig(BaseSettings):
description="Protocol scheme for COS requests: 'https' (recommended) or 'http'",
default=None,
)
TENCENT_COS_CUSTOM_DOMAIN: str | None = Field(
description="Tencent Cloud COS custom domain setting",
default=None,
)

View File

@ -13,12 +13,20 @@ class TencentCosStorage(BaseStorage):
super().__init__()
self.bucket_name = dify_config.TENCENT_COS_BUCKET_NAME
config = CosConfig(
Region=dify_config.TENCENT_COS_REGION,
SecretId=dify_config.TENCENT_COS_SECRET_ID,
SecretKey=dify_config.TENCENT_COS_SECRET_KEY,
Scheme=dify_config.TENCENT_COS_SCHEME,
)
if dify_config.TENCENT_COS_CUSTOM_DOMAIN:
config = CosConfig(
Domain=dify_config.TENCENT_COS_CUSTOM_DOMAIN,
SecretId=dify_config.TENCENT_COS_SECRET_ID,
SecretKey=dify_config.TENCENT_COS_SECRET_KEY,
Scheme=dify_config.TENCENT_COS_SCHEME,
)
else:
config = CosConfig(
Region=dify_config.TENCENT_COS_REGION,
SecretId=dify_config.TENCENT_COS_SECRET_ID,
SecretKey=dify_config.TENCENT_COS_SECRET_KEY,
Scheme=dify_config.TENCENT_COS_SCHEME,
)
self.client = CosS3Client(config)
def save(self, filename, data):

View File

@ -1,4 +1,4 @@
from unittest.mock import patch
from unittest.mock import MagicMock, patch
import pytest
from qcloud_cos import CosConfig
@ -18,3 +18,72 @@ class TestTencentCos(BaseStorageTest):
with patch.object(CosConfig, "__init__", return_value=None):
self.storage = TencentCosStorage()
self.storage.bucket_name = get_example_bucket()
class TestTencentCosConfiguration:
"""Tests for TencentCosStorage initialization with different configurations."""
def test_init_with_custom_domain(self):
"""Test initialization with custom domain configured."""
# Mock dify_config to return custom domain configuration
mock_dify_config = MagicMock()
mock_dify_config.TENCENT_COS_CUSTOM_DOMAIN = "cos.example.com"
mock_dify_config.TENCENT_COS_SECRET_ID = "test-secret-id"
mock_dify_config.TENCENT_COS_SECRET_KEY = "test-secret-key"
mock_dify_config.TENCENT_COS_SCHEME = "https"
# Mock CosConfig and CosS3Client
mock_config_instance = MagicMock()
mock_client = MagicMock()
with (
patch("extensions.storage.tencent_cos_storage.dify_config", mock_dify_config),
patch(
"extensions.storage.tencent_cos_storage.CosConfig", return_value=mock_config_instance
) as mock_cos_config,
patch("extensions.storage.tencent_cos_storage.CosS3Client", return_value=mock_client),
):
TencentCosStorage()
# Verify CosConfig was called with Domain parameter (not Region)
mock_cos_config.assert_called_once()
call_kwargs = mock_cos_config.call_args[1]
assert "Domain" in call_kwargs
assert call_kwargs["Domain"] == "cos.example.com"
assert "Region" not in call_kwargs
assert call_kwargs["SecretId"] == "test-secret-id"
assert call_kwargs["SecretKey"] == "test-secret-key"
assert call_kwargs["Scheme"] == "https"
def test_init_with_region(self):
"""Test initialization with region configured (no custom domain)."""
# Mock dify_config to return region configuration
mock_dify_config = MagicMock()
mock_dify_config.TENCENT_COS_CUSTOM_DOMAIN = None
mock_dify_config.TENCENT_COS_REGION = "ap-guangzhou"
mock_dify_config.TENCENT_COS_SECRET_ID = "test-secret-id"
mock_dify_config.TENCENT_COS_SECRET_KEY = "test-secret-key"
mock_dify_config.TENCENT_COS_SCHEME = "https"
# Mock CosConfig and CosS3Client
mock_config_instance = MagicMock()
mock_client = MagicMock()
with (
patch("extensions.storage.tencent_cos_storage.dify_config", mock_dify_config),
patch(
"extensions.storage.tencent_cos_storage.CosConfig", return_value=mock_config_instance
) as mock_cos_config,
patch("extensions.storage.tencent_cos_storage.CosS3Client", return_value=mock_client),
):
TencentCosStorage()
# Verify CosConfig was called with Region parameter (not Domain)
mock_cos_config.assert_called_once()
call_kwargs = mock_cos_config.call_args[1]
assert "Region" in call_kwargs
assert call_kwargs["Region"] == "ap-guangzhou"
assert "Domain" not in call_kwargs
assert call_kwargs["SecretId"] == "test-secret-id"
assert call_kwargs["SecretKey"] == "test-secret-key"
assert call_kwargs["Scheme"] == "https"

View File

@ -478,6 +478,7 @@ TENCENT_COS_SECRET_KEY=your-secret-key
TENCENT_COS_SECRET_ID=your-secret-id
TENCENT_COS_REGION=your-region
TENCENT_COS_SCHEME=your-scheme
TENCENT_COS_CUSTOM_DOMAIN=your-custom-domain
# Oracle Storage Configuration
#

View File

@ -141,6 +141,7 @@ x-shared-env: &shared-api-worker-env
TENCENT_COS_SECRET_ID: ${TENCENT_COS_SECRET_ID:-your-secret-id}
TENCENT_COS_REGION: ${TENCENT_COS_REGION:-your-region}
TENCENT_COS_SCHEME: ${TENCENT_COS_SCHEME:-your-scheme}
TENCENT_COS_CUSTOM_DOMAIN: ${TENCENT_COS_CUSTOM_DOMAIN:-your-custom-domain}
OCI_ENDPOINT: ${OCI_ENDPOINT:-https://your-object-storage-namespace.compat.objectstorage.us-ashburn-1.oraclecloud.com}
OCI_BUCKET_NAME: ${OCI_BUCKET_NAME:-your-bucket-name}
OCI_ACCESS_KEY: ${OCI_ACCESS_KEY:-your-access-key}