Merge branch 'main' into chore/refactor-config-var

This commit is contained in:
Joel 2025-12-29 15:41:26 +08:00 committed by GitHub
commit 42a55a3c64
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_SECRET_ID=your-secret-id
TENCENT_COS_REGION=your-region TENCENT_COS_REGION=your-region
TENCENT_COS_SCHEME=your-scheme TENCENT_COS_SCHEME=your-scheme
TENCENT_COS_CUSTOM_DOMAIN=your-custom-domain
# Huawei OBS Storage Configuration # Huawei OBS Storage Configuration
HUAWEI_OBS_BUCKET_NAME=your-bucket-name 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'", description="Protocol scheme for COS requests: 'https' (recommended) or 'http'",
default=None, default=None,
) )
TENCENT_COS_CUSTOM_DOMAIN: str | None = Field(
description="Tencent Cloud COS custom domain setting",
default=None,
)

View File

@ -13,6 +13,14 @@ class TencentCosStorage(BaseStorage):
super().__init__() super().__init__()
self.bucket_name = dify_config.TENCENT_COS_BUCKET_NAME self.bucket_name = dify_config.TENCENT_COS_BUCKET_NAME
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( config = CosConfig(
Region=dify_config.TENCENT_COS_REGION, Region=dify_config.TENCENT_COS_REGION,
SecretId=dify_config.TENCENT_COS_SECRET_ID, SecretId=dify_config.TENCENT_COS_SECRET_ID,

View File

@ -1,4 +1,4 @@
from unittest.mock import patch from unittest.mock import MagicMock, patch
import pytest import pytest
from qcloud_cos import CosConfig from qcloud_cos import CosConfig
@ -18,3 +18,72 @@ class TestTencentCos(BaseStorageTest):
with patch.object(CosConfig, "__init__", return_value=None): with patch.object(CosConfig, "__init__", return_value=None):
self.storage = TencentCosStorage() self.storage = TencentCosStorage()
self.storage.bucket_name = get_example_bucket() 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_SECRET_ID=your-secret-id
TENCENT_COS_REGION=your-region TENCENT_COS_REGION=your-region
TENCENT_COS_SCHEME=your-scheme TENCENT_COS_SCHEME=your-scheme
TENCENT_COS_CUSTOM_DOMAIN=your-custom-domain
# Oracle Storage Configuration # 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_SECRET_ID: ${TENCENT_COS_SECRET_ID:-your-secret-id}
TENCENT_COS_REGION: ${TENCENT_COS_REGION:-your-region} TENCENT_COS_REGION: ${TENCENT_COS_REGION:-your-region}
TENCENT_COS_SCHEME: ${TENCENT_COS_SCHEME:-your-scheme} 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_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_BUCKET_NAME: ${OCI_BUCKET_NAME:-your-bucket-name}
OCI_ACCESS_KEY: ${OCI_ACCESS_KEY:-your-access-key} OCI_ACCESS_KEY: ${OCI_ACCESS_KEY:-your-access-key}