aicheckv2-api/utils/file/aliyun_oss.py

107 lines
4.3 KiB
Python
Raw Normal View History

2025-04-11 08:54:28 +08:00
#!/usr/bin/python
# -*- coding: utf-8 -*-
# @version : 1.0
# @Create Time : 2022/4/28 22:32
# @File : aliyun_oss.py
# @IDE : PyCharm
# @desc : 阿里云对象存储
import os.path
from fastapi import UploadFile
from pydantic import BaseModel
import oss2 # 安装依赖库pip install oss2
from oss2.models import PutObjectResult
from core.exception import CustomException
from core.logger import logger
from utils import status
from utils.file.file_manage import FileManage
from utils.file.file_base import FileBase
class BucketConf(BaseModel):
accessKeyId: str
accessKeySecret: str
endpoint: str
bucket: str
baseUrl: str
class AliyunOSS(FileBase):
"""
阿里云对象存储
常见报错https://help.aliyun.com/document_detail/185228.htm?spm=a2c4g.11186623.0.0.6de530e5pxNK76#concept-1957777
官方文档https://help.aliyun.com/document_detail/32026.html
使用Python SDK时大部分操作都是通过oss2.Service和oss2.Bucket两个类进行
oss2.Service类用于列举存储空间
oss2.Bucket类用于上传下载删除文件以及对存储空间进行各种配置
"""
def __init__(self, bucket: BucketConf):
# 阿里云账号AccessKey拥有所有API的访问权限风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维请登录RAM控制台创建RAM用户。
auth = oss2.Auth(bucket.accessKeyId, bucket.accessKeySecret)
# yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1杭州为例Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
# 填写Bucket名称。
self.bucket = oss2.Bucket(auth, bucket.endpoint, bucket.bucket)
self.baseUrl = bucket.baseUrl
async def upload_image(self, path: str, file: UploadFile, max_size: int = 10) -> str:
"""
上传图片
:param path: path由包含文件后缀不包含Bucket名称组成的Object完整路径例如abc/efg/123.jpg
:param file: 文件对象
:param max_size: 图片文件最大值单位 MB默认 10MB
:return: 上传后的文件oss链接
"""
# 验证图片类型
await self.validate_file(file, max_size, self.IMAGE_ACCEPT)
# 生成文件路径
path = self.generate_relative_path(path, file.filename)
file_data = await file.read()
return await self.__upload_file_to_oss(path, file_data)
async def upload_video(self, path: str, file: UploadFile, max_size: int = 100) -> str:
"""
上传视频
:param path: path由包含文件后缀不包含Bucket名称组成的Object完整路径例如abc/efg/123.jpg
:param file: 文件对象
:param max_size: 视频文件最大值单位 MB默认 100MB
:return: 上传后的文件oss链接
"""
# 验证图片类型
await self.validate_file(file, max_size, self.VIDEO_ACCEPT)
# 生成文件路径
path = self.generate_relative_path(path, file.filename)
file_data = await file.read()
return await self.__upload_file_to_oss(path, file_data)
async def upload_file(self, path: str, file: UploadFile) -> str:
"""
上传文件
:param path: path由包含文件后缀不包含Bucket名称组成的Object完整路径例如abc/efg/123.jpg
:param file: 文件对象
:return: 上传后的文件oss链接
"""
path = self.generate_relative_path(path, file.filename)
file_data = await file.read()
return await self.__upload_file_to_oss(path, file_data)
async def __upload_file_to_oss(self, path: str, file_data: bytes) -> str:
"""
上传文件到OSS
:param path: path由包含文件后缀不包含Bucket名称组成的Object完整路径例如abc/efg/123.jpg
:param file_data: 文件数据
:return: 上传后的文件oss链接
"""
result = self.bucket.put_object(path, file_data)
assert isinstance(result, PutObjectResult)
if result.status != 200:
logger.error(f"文件上传到OSS失败状态码{result.status}")
raise CustomException("上传文件失败", code=status.HTTP_ERROR)
return self.baseUrl + path