通过python管理阿里云oss文件

  • 梦影无痕丶
  • 8 Minutes
  • February 21, 2018

前言

本文参考阿里云提供的帮助文档,代码已验证过,可以顺利运行

安装SDK

通过pip安装

pip install oss2

源码安装 (推荐)

github下载相应版本的SDK包,解压后进入目录

python setup.py install

验证安装

再命令行中打开python,运行

>>> import oss2
>>> oss2.__version__
'2.4.0'

Bucket 管理

查看Bucket列表

# -*- coding: utf-8 -*-

import oss2
auth = oss2.Auth('您的AccessKeyId', '您的AccessKeySecret')
service = oss2.Service(auth, '您的Endpoint')
print([b.name for b in oss2.BucketIterator(service)])

新建bucket

bucket = oss2.Bucket(auth, 'http://您的Endpoint名', '您的bucket名')
bucket.create_bucket(oss2.models.BUCKET_ACL_PRIVATE)  #读写权限为私有

删除bucket

try:
    bucket.delete_bucket()
except oss2.exceptions.BucketNotEmpty:
    print('bucket is not empty.')
except oss2.exceptions.NoSuchBucket:
    print('bucket does not exist')

查看Bucket访问权限

print(bucket.get_bucket_acl().acl)

设置Bucket访问权限

把Bucket的访问权限设为私有:

bucket.put_bucket_acl(oss2.BUCKET_ACL_PRIVATE)

Bucket的访问权限私有读写、公共读私有写、公共读写,分别对应oss2.BUCKET_ACL_PRIVATE、oss2.BUCKET_ACL_PUBLIC_READ、oss2.BUCKET_ACL_PUBLIC_READ_WRITE。

文件管理

上传文件

上传字符串

通过 Bucket.put_object 方法,可以上传一个普通文件。
示例:

# -*- coding: utf-8 -*-
import oss2
auth = oss2.Auth('您的AccessKeyId', '您的AccessKeySecret')
bucket = oss2.Bucket(auth, '您的Endpoint', '您的Bucket名')
bucket.put_object('remote.txt', 'content of object')

其中AccessKeyId,AccessKeySecret,Endpoint,Bucket名都可以在 阿里云管理控制台->对象存储oss 中找到。

运行程序后再对象存储->文件管理中发现文件已经上传成功。

上传本地文件

在项目中添加一个资源文件,右键项目->添加->现有项。 如一张图片
使用命令:

with open('1.jpg', 'rb') as fileobj:
    bucket.put_object('remotePic.jpg', fileobj)

或者直接使用命令:

bucket.put_object_from_file('remotePic1.jpg', '1.jpg')

运行后在控制台查看,文件已经存在。

上传文件到文件夹下

在上传文件名中使用文件夹分割符即可。例如,把 1.jpg 上传至 jpg 目录下

bucket.put_object_from_file('jpg/remotePic1.jpg', '1.jpg')

下载文件

流式下载

使用Bucket.get_object接口:它的返回值是一个类文件对象(file-like object),同时也是一个可迭代对象(iterable)

remote_stream = bucket.get_object('remote.txt')
print(remote_stream.read())

由于返回值又是一个可迭代对象,所以可以把它流式的拷贝到另一个Object:

bucket.put_object('remote-backup.txt', remote_stream)

下载到本地文件

bucket.get_object_to_file('remote.txt', 'local-backup.txt')

进度条显示

下载接口提供了可选参数 progress_callback ,用来实现进度条功能

# -*- coding: utf-8 -*-
import os, sys
import oss2
auth = oss2.Auth('您的AccessKeyId', '您的AccessKeySecret')
bucket = oss2.Bucket(auth, '您的Endpoint', '您的Bucket名')
def percentage(consumed_bytes, total_bytes):
    if total_bytes:
        rate = int(100 * (float(consumed_bytes) / float(total_bytes)))
        print('\r{0}% '.format(rate), end='')
        sys.stdout.flush()
bucket.get_object_to_file('remote.txt', 'local-backup.txt', progress_callback=percentage)

删除文件

删除单个文件:

bucket.delete_object('remote.txt')

删除多个文件,同时打印成功删除的文件名

result = bucket.batch_delete_objects(['a.txt', 'b.txt', 'c.txt'])
print('\n'.join(result.deleted_keys))

列举文件

列举Bucket下的10个文件:

from itertools import islice

for b in islice(oss2.ObjectIterator(bucket), 10):
    print(b.key)

只列举前缀为”img-“的所有文件:

for obj in oss2.ObjectIterator(bucket, prefix='img-'):
print(obj.key)

模拟文件夹功能

OSS的存储空间(Bucket)本身是扁平结构的,并没有文件夹或目录的概念。用户可以通过在文件名里加入”/“来模拟文件夹。在列举的时候,则要设置delimiter参数(目录分隔符)为”/“,并通过是否为“公共前缀”来判断是否为文件夹。模拟罗列文件夹这个操作比较低效。

for obj in oss2.ObjectIterator(bucket, delimiter='/'):
    if obj.is_prefix():  # 文件夹
        print('directory: ' + obj.key)
    else:                # 文件
        print('file: ' + obj.key)

判断文件是否存在

通过 object_exists 判断文件是否存在。返回值为 true 文件存在,为 false 文件不存在。

exist = bucket.object_exists('remote.txt')
if exist:
    print('object exist')
else:
    print('object not eixst')

拷贝文件

把Bucket名为src-bucket下的source.txt拷贝到当前Bucket的target.txt文件。

bucket.copy_object('src-bucket', 'source.txt', 'target.txt')

查看文件访问权限

print(bucket.get_object_acl('story.txt').acl)

设置文件访问权限

文件的访问权限有四种:default(默认)、private(私有读写)、public-read(公共读私有写)、public-read-write(公共读写),分别对应oss2.OBJECT_ACL_DEFAULT、oss2.OBJECT_ACL_PRIVATE、oss2.OBJECT_ACL_PUBLIC_READ、oss2.OBJECT_ACL_PUBLIC_READ_WRITE 。

bucket.put_object_acl('story.txt', oss2.OBJECT_ACL_PUBLIC_READ)

获取上传文件外网地址

如果是公共读/公共读写权限,那么访问URL的格式为——域名/Object名称,如访问githubblogpic bucket 下 18-2-21 文件夹中的 52682404.jpg 文件。

http://githubblogpic.oss-cn-huhehaote.aliyuncs.com/18-2-21/52682404.jpg