aicheckv2-api/utils/file/aliyun_oss.py
2025-04-11 08:54:28 +08:00

107 lines
4.3 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.

#!/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