|
|
@@ -1,6 +1,6 @@
|
|
|
"""
|
|
|
OSS 上传模块
|
|
|
-支持阿里云 OSS、MinIO、AWS S3 等兼容 S3 的对象存储
|
|
|
+支持兼容 S3 的对象存储(MinIO、AWS S3、阿里云 OSS 等)
|
|
|
"""
|
|
|
|
|
|
import os
|
|
|
@@ -13,21 +13,13 @@ from typing import Optional, Dict, Any, Tuple, List
|
|
|
from pathlib import Path
|
|
|
from datetime import datetime
|
|
|
from dataclasses import dataclass, field
|
|
|
-from enum import Enum
|
|
|
|
|
|
import cv2
|
|
|
import numpy as np
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
-# 尝试导入 OSS SDK
|
|
|
-try:
|
|
|
- import oss2
|
|
|
- ALIYUN_OSS_AVAILABLE = True
|
|
|
-except ImportError:
|
|
|
- ALIYUN_OSS_AVAILABLE = False
|
|
|
- logger.warning("阿里云 OSS SDK (oss2) 未安装,阿里云 OSS 功能不可用")
|
|
|
-
|
|
|
+# 尝试导入 boto3
|
|
|
try:
|
|
|
import boto3
|
|
|
from botocore.exceptions import ClientError
|
|
|
@@ -37,14 +29,6 @@ except ImportError:
|
|
|
logger.warning("boto3 未安装,S3 兼容存储功能不可用")
|
|
|
|
|
|
|
|
|
-class OSSProvider(Enum):
|
|
|
- """OSS 提供商类型"""
|
|
|
- ALIYUN = "aliyun"
|
|
|
- MINIO = "minio"
|
|
|
- AWS = "aws"
|
|
|
- CUSTOM = "custom"
|
|
|
-
|
|
|
-
|
|
|
@dataclass
|
|
|
class UploadTask:
|
|
|
"""上传任务"""
|
|
|
@@ -70,7 +54,7 @@ class UploadResult:
|
|
|
class OSSUploader:
|
|
|
"""
|
|
|
OSS 上传器
|
|
|
- 支持阿里云 OSS 和 S3 兼容存储
|
|
|
+ 支持兼容 S3 的对象存储(MinIO、AWS S3、阿里云 OSS 等)
|
|
|
"""
|
|
|
|
|
|
def __init__(self, config: Dict[str, Any] = None):
|
|
|
@@ -80,16 +64,11 @@ class OSSUploader:
|
|
|
Args:
|
|
|
config: OSS 配置字典
|
|
|
"""
|
|
|
- from config import OSS_CONFIG, S3_COMPATIBLE_CONFIG
|
|
|
+ from config import S3_COMPATIBLE_CONFIG
|
|
|
|
|
|
- self.config = config or OSS_CONFIG
|
|
|
- self.s3_config = S3_COMPATIBLE_CONFIG
|
|
|
+ self.config = config or S3_COMPATIBLE_CONFIG
|
|
|
|
|
|
self.enabled = self.config.get('enabled', False)
|
|
|
- self.provider = OSSProvider(self.config.get('provider', 'aliyun'))
|
|
|
-
|
|
|
- # 阿里云 OSS 客户端
|
|
|
- self.aliyun_bucket = None
|
|
|
|
|
|
# S3 客户端
|
|
|
self.s3_client = None
|
|
|
@@ -117,42 +96,11 @@ class OSSUploader:
|
|
|
def _init_client(self):
|
|
|
"""初始化 OSS 客户端"""
|
|
|
try:
|
|
|
- if self.provider == OSSProvider.ALIYUN:
|
|
|
- self._init_aliyun_oss()
|
|
|
- elif self.provider in [OSSProvider.MINIO, OSSProvider.AWS, OSSProvider.CUSTOM]:
|
|
|
- self._init_s3_client()
|
|
|
+ self._init_s3_client()
|
|
|
except Exception as e:
|
|
|
logger.error(f"[OSS] 初始化客户端失败: {e}")
|
|
|
self.enabled = False
|
|
|
|
|
|
- def _init_aliyun_oss(self):
|
|
|
- """初始化阿里云 OSS"""
|
|
|
- if not ALIYUN_OSS_AVAILABLE:
|
|
|
- logger.error("[OSS] 阿里云 OSS SDK 未安装")
|
|
|
- self.enabled = False
|
|
|
- return
|
|
|
-
|
|
|
- access_key_id = self.config.get('access_key_id', '')
|
|
|
- access_key_secret = self.config.get('access_key_secret', '')
|
|
|
- endpoint = self.config.get('endpoint', '')
|
|
|
- bucket_name = self.config.get('bucket_name', '')
|
|
|
-
|
|
|
- if not all([access_key_id, access_key_secret, endpoint, bucket_name]):
|
|
|
- logger.error("[OSS] 阿里云 OSS 配置不完整")
|
|
|
- self.enabled = False
|
|
|
- return
|
|
|
-
|
|
|
- auth = oss2.Auth(access_key_id, access_key_secret)
|
|
|
- self.aliyun_bucket = oss2.Bucket(auth, endpoint, bucket_name)
|
|
|
-
|
|
|
- # 测试连接
|
|
|
- try:
|
|
|
- self.aliyun_bucket.get_bucket_info()
|
|
|
- logger.info(f"[OSS] 阿里云 OSS 连接成功: {bucket_name}")
|
|
|
- except Exception as e:
|
|
|
- logger.error(f"[OSS] 阿里云 OSS 连接失败: {e}")
|
|
|
- self.enabled = False
|
|
|
-
|
|
|
def _init_s3_client(self):
|
|
|
"""初始化 S3 兼容客户端"""
|
|
|
if not BOTO3_AVAILABLE:
|
|
|
@@ -160,15 +108,15 @@ class OSSUploader:
|
|
|
self.enabled = False
|
|
|
return
|
|
|
|
|
|
- if not self.s3_config.get('enabled', False):
|
|
|
+ if not self.config.get('enabled', False):
|
|
|
logger.error("[OSS] S3 兼容配置未启用")
|
|
|
self.enabled = False
|
|
|
return
|
|
|
|
|
|
- endpoint_url = self.s3_config.get('endpoint_url', '')
|
|
|
- region_name = self.s3_config.get('region_name', 'us-east-1')
|
|
|
- access_key_id = self.s3_config.get('access_key_id', '')
|
|
|
- secret_access_key = self.s3_config.get('secret_access_key', '')
|
|
|
+ endpoint_url = self.config.get('endpoint_url', '')
|
|
|
+ region_name = self.config.get('region_name', 'us-east-1')
|
|
|
+ access_key_id = self.config.get('access_key_id', '')
|
|
|
+ secret_access_key = self.config.get('secret_access_key', '')
|
|
|
|
|
|
if not all([endpoint_url, access_key_id, secret_access_key]):
|
|
|
logger.error("[OSS] S3 配置不完整")
|
|
|
@@ -181,7 +129,7 @@ class OSSUploader:
|
|
|
region_name=region_name,
|
|
|
aws_access_key_id=access_key_id,
|
|
|
aws_secret_access_key=secret_access_key,
|
|
|
- use_ssl=self.s3_config.get('use_ssl', True),
|
|
|
+ use_ssl=self.config.get('use_ssl', True),
|
|
|
verify=False
|
|
|
)
|
|
|
|
|
|
@@ -266,25 +214,18 @@ class OSSUploader:
|
|
|
|
|
|
for attempt in range(max_retries):
|
|
|
try:
|
|
|
- if self.provider == OSSProvider.ALIYUN and self.aliyun_bucket:
|
|
|
- # 阿里云 OSS 上传
|
|
|
- self.aliyun_bucket.put_object_from_file(oss_key, local_path)
|
|
|
+ if self.s3_client:
|
|
|
+ # S3 兼容上传
|
|
|
+ bucket_name = self.config.get('bucket_name', '')
|
|
|
+ self.s3_client.upload_file(local_path, bucket_name, oss_key)
|
|
|
|
|
|
- # 生成访问 URL
|
|
|
+ # 生成 URL
|
|
|
custom_domain = self.config.get('custom_domain', '')
|
|
|
if custom_domain:
|
|
|
oss_url = f"{custom_domain}/{oss_key}"
|
|
|
else:
|
|
|
- oss_url = f"https://{self.config.get('bucket_name')}.{self.config.get('endpoint')}/{oss_key}"
|
|
|
-
|
|
|
- elif self.s3_client:
|
|
|
- # S3 兼容上传
|
|
|
- bucket_name = self.s3_config.get('bucket_name', '')
|
|
|
- self.s3_client.upload_file(local_path, bucket_name, oss_key)
|
|
|
-
|
|
|
- # 生成 URL
|
|
|
- endpoint_url = self.s3_config.get('endpoint_url', '')
|
|
|
- oss_url = f"{endpoint_url}/{bucket_name}/{oss_key}"
|
|
|
+ endpoint_url = self.config.get('endpoint_url', '')
|
|
|
+ oss_url = f"{endpoint_url}/{bucket_name}/{oss_key}"
|
|
|
else:
|
|
|
return UploadResult(
|
|
|
success=False,
|