api/app/services/cos.py
2025-04-10 11:38:15 +08:00

103 lines
3.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import logging
import os
import uuid
from datetime import datetime
from qcloud_cos import CosConfig, CosS3Client
from app.core.config import settings
logger = logging.getLogger(__name__)
# 腾讯云COS配置
config = CosConfig(
Region=settings.COS_REGION,
SecretId=settings.COS_SECRET_ID,
SecretKey=settings.COS_SECRET_KEY
)
# 创建客户端
cos_client = CosS3Client(config)
def generate_file_path(directory: str, file_extension: str) -> str:
"""生成文件路径"""
today = datetime.now().strftime("%Y%m%d")
filename = f"{uuid.uuid4().hex}{file_extension}"
return f"{directory}/{today}/{filename}"
async def upload_file(file_content: bytes, file_extension: str, directory: str = "uploads") -> str:
"""上传文件到腾讯云COS"""
try:
# 生成唯一文件路径
file_path = generate_file_path(directory, file_extension)
# 上传到腾讯云COS
cos_client.put_object(
Bucket=settings.COS_BUCKET,
Body=file_content,
Key=file_path
)
# 返回可访问的URL
url = f"https://{settings.COS_BUCKET}.cos.{settings.COS_REGION}.myqcloud.com/{file_path}"
logger.info(f"文件上传成功: {url}")
return url
except Exception as e:
logger.error(f"文件上传失败: {str(e)}")
raise
async def upload_file_from_url(url: str, directory: str = "uploads") -> str:
"""从URL下载文件并上传到腾讯云COS"""
try:
import requests
# 下载文件
response = requests.get(url, timeout=10)
response.raise_for_status()
# 获取文件扩展名
file_extension = os.path.splitext(url)[1]
if not file_extension:
# 如果URL没有扩展名根据内容类型判断
content_type = response.headers.get("Content-Type", "")
if "jpeg" in content_type or "jpg" in content_type:
file_extension = ".jpg"
elif "png" in content_type:
file_extension = ".png"
elif "gif" in content_type:
file_extension = ".gif"
else:
file_extension = ".bin" # 默认二进制文件
# 上传到腾讯云COS
return await upload_file(response.content, file_extension, directory)
except Exception as e:
logger.error(f"从URL上传文件失败: {str(e)}")
raise
async def get_presigned_url(key: str, expires: int = 3600) -> str:
"""获取预签名URL"""
try:
# 生成预签名URL
url = cos_client.get_presigned_url(
Method='GET',
Bucket=settings.COS_BUCKET,
Key=key,
Expired=expires
)
return url
except Exception as e:
logger.error(f"获取预签名URL失败: {str(e)}")
raise
async def delete_file(key: str) -> bool:
"""删除文件"""
try:
# 删除文件
cos_client.delete_object(
Bucket=settings.COS_BUCKET,
Key=key
)
logger.info(f"文件删除成功: {key}")
return True
except Exception as e:
logger.error(f"文件删除失败: {str(e)}")
return False