一、前言
阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务。
本文主要介绍对象存储 OSS 的 Python SDK 各种使用场景下的示例代码。
附:阿里云OSS对象存储文档好文章 记得收藏+点赞+关注额 !!!
---- Nick.Peng
二、初始化 Bucket 类
- Python SDK 中的大部分操作都是通过
oss2.Service
和oss2.Bucket
这两个类进行的。
1、oss2.Service
类: 用于列举存储空间。
2、oss2.Bucket
类: 用于上传、下载、删除文件以及对存储空间进行各种配置。
初始化这两个类时,需要指定Endpoint。其中oss2.Service类不支持自定义域名访问。
# -*- coding: utf-8 -*-
import os
import re
import oss2
import json
import msgpack
from configs.celery import app
from configs.dbconfig import DB
# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录RAM控制台创建RAM账号。
# 这里的授权账号可以单独写在env配置文件中
auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
# Endpoint这里以北京为例
bucket = oss2.Bucket(auth, 'http://oss-cn-beijing.aliyuncs.com', '<yourBucketName>')
三、下载 OSS 文件到本地
- 如果出现文件下载失败,请检查 OSS 文件路径是否正确
def dl_file(audio_url):
"""
从OSS上下载文件到本地temp_audio_file目录,如果指定的本地文件存在会覆盖,不存在则新建
:param audio_url: 音频地址 转换前url
"""
file_name = re.search(r'/(\d+\.m4a)', audio_url).group(1) # 1585882769054.m4a
# OSS_BUCKET:在阿里云OSS存储对象控制台创建的bucket的名称
file_url = re.search(r'https://OSS_BUCKET.oss-cn-beijing.aliyuncs.com/(.+)', audio_url).group(1)
# local_path由本地文件路径加文件名包括后缀组成,例如/users/local/myfile.txt。
local_path = os.path.join(temp_audio_file) + file_name
bucket.get_object_to_file(file_url, local_path)
return file_url, local_path
四、给下载的本地文件进行格式转换
def convert_audio(local_path):
"""实现 m4a to mp3"""
new_path = local_path.replace('m4a', 'mp3')
# -y 存在文件则覆盖,-loglevel quiet 禁止控制台信息输出
os.system("ffmpeg -i " + local_path + " " + new_path + " -y -loglevel quiet")
return new_path
五、上传转换后的文件到 OSS
def up_file(mp3_url, new_path):
"""
上传转换后的文件到OSS
:param mp3_url: 音频地址 转换后
:param new_path: 音频本地路径
"""
try:
bucket.put_object_from_file(mp3_url, new_path)
return True
except:
traceback.print_exc()
六、删除本地和 OSS 文件
def del_temp_file(paths):
"""删除临时文件"""
for file in paths:
os.remove(file)
def del_oss_file(path):
"""删除oss文件"""
bucket.delete_object(path)
七、任务调度集成 Celery 异步
@app.task(base=MyTask, bind=True)
def audio(self, arg):
try:
arg = msgpack.unpackb(msgpack.packb(arg), encoding='utf-8') # msgpack 反序列化
atd_id = arg.get("atd_id")
name = db_name(arg.get("pid")) # 根据项目id获取数据库名称
audio_url = get_audio_url(name, attendance_detail_id) # 获取音频地址
if 'm4a' not in audio_url:
return "OK!"
# 以下为本文主要业务逻辑
file_url, local_path = dl_file(audio_url) # 下载音频
new_path = convert_audio(local_path) # 音频转换
new_f_url = file_url.split(".")[0] + ".mp3" # 转换后音频地址
up_file(new_f_url, new_path) # 上传音频
del_temp_file([local_path, new_path]) # 删除本地文件
update_db(name, atd_id) # 更新数据库
del_oss_file(audio_url.split('aliyuncs.com/')[-1]) # 删除 oss 云文件
except Exception as e:
raise self.retry(exc=e, countdown=2, max_retries=3) # 每隔2s重试一次,最多重试3次