阿里云对象存储OSS的python SDK示例

背景

最近公司项目须要使用阿里云的oss存储来线上实时存储图片文件。所以调研开发了python版本的阿里云oss SDK。这里咱们介绍一下oss以及python oss的经常使用方法。python

oss介绍

阿里云对象存储OSS(Object Storage Service)是阿里云提供的海量、安全、低成本、高持久的云存储服务。其数据设计持久性不低于99.9999999999%(12个9),服务可用性(或业务连续性)不低于99.995%。
OSS具备与平台无关的RESTful API接口,您能够在任何应用、任什么时候间、任何地点存储和访问任意类型的数据。
您可使用阿里云提供的API、SDK接口或者OSS迁移工具轻松地将海量数据移入或移出阿里云OSS。数据存储到阿里云OSS之后,您能够选择标准存储(Standard)做为移动应用、大型网站、图片分享或热点音视频的主要存储方式,也能够选择成本更低、存储期限更长的低频访问存储(Infrequent Access)、归档存储(Archive)、冷归档存储(Cold Archive)做为不常常访问数据的存储方式。
以上是阿里云官方对于oss的介绍,总结来看,就是其能够提供高可用,高持久、低成本、支持多种文件及数据格式、支持RESTful API接口的云存储服务。就咱们实际使用来讲确实还不错,成本的话咱们申请的海外节点,30多T数据每个月差很少5000,也算比较低了。json

在代码示例前,咱们先认识一些概念:安全

存储类型(Storage Class)

OSS提供标准、低频访问、归档、冷归档四种存储类型,全面覆盖从热到冷的各类数据存储场景。其中标准存储类型提供高持久、高可用、高性能的对象存储服务,可以支持频繁的数据访问;低频访问存储类型适合长期保存不常常访问的数据(平均每个月访问频率1到2次),存储单价低于标准类型;归档存储类型适合须要长期保存(建议半年以上)的归档数据;冷归档存储适合须要超长时间存放的极冷数据。工具

存储空间(Bucket)

存储空间是您用于存储对象(Object)的容器,全部的对象都必须隶属于某个存储空间。存储空间具备各类配置属性,包括地域、访问权限、存储类型等。您能够根据实际需求,建立不一样类型的存储空间来存储不一样的数据。性能

对象(Object)

对象是OSS存储数据的基本单元,也被称为OSS的文件。对象由元信息(Object Meta)、用户数据(Data)和文件名(Key)组成。对象由存储空间内部惟一的Key来标识。对象元信息是一组键值对,表示了对象的一些属性,例如最后修改时间、大小等信息,同时您也能够在元信息中存储一些自定义的信息。网站

地域(Region)

地域表示OSS的数据中心所在物理位置。您能够根据费用、请求来源等选择合适的地域建立Bucket。阿里云

访问域名(Endpoint)

Endpoint表示OSS对外服务的访问域名。OSS以HTTP RESTful API的形式对外提供服务,当访问不一样地域的时候,须要不一样的域名。经过内网和外网访问同一个地域所须要的域名也是不一样的。加密

访问密钥(AccessKey)

AccessKey简称AK,指的是访问身份验证中用到的AccessKey Id和AccessKey Secret。OSS经过使用AccessKey Id和AccessKey Secret对称加密的方法来验证某个请求的发送者身份。AccessKey Id用于标识用户;AccessKey Secret是用户用于加密签名字符串和OSS用来验证签名字符串的密钥,必须保密。url

oss python SDK

OssClient支持的方法:
一、上传文件对象到oss存储空间
二、上传本地指定路径文件到oss存储空间
三、下载文件到文件流对象
四、下载文件到本地指定路径
五、生成加签的临时URL以供授信用户下载设计

以上功能基本能够知足平常业务需求,固然oss也提供了不少个性化的操做,好比断点下载、范围下载、断点上传、追加上传、上传回调、图片调整等等,这里再也不赘述,都有专门的接口方法。
如下列举了接口实现方法,并无在其中加入各类判断逻辑,好比文件是否存在、权限控制、是否覆盖、是否加密等等。有须要的能够本身添加逻辑

import oss2


AccessKeyId = 'LTA************hpmoN9'
AccessKeySecret = '0ise*************bkIyF'
BucketName = '*******'
Endpoint = 'http://oss-ap-south-1.aliyuncs.com'


class OssClient(object):
    __instance = None
    __first_init = False

    # 单例模式
    def __new__(cls, *args, **kwargs):
        if not cls.__instance:
            cls.__instance = super().__new__(cls)
        return cls.__instance

    def __init__(self):
        cls = self.__class__
        if not cls.__first_init:
            self.auth = oss2.Auth(AccessKeyId, AccessKeySecret)
            self.bucket = oss2.Bucket(self.auth, Endpoint, BucketName)
            cls.__first_init = True


    def upload_file_from_fileobj(self):
        """
            upload_file_from_fileobj方法:上传文件对象到oss存储空间, 该方法可用于咱们从上游服务接收了图片参数,而后以二进制形式读文件,上传到oss存储空间指定位置(abc/efg/00),
        固然也能够将本地文件上传到oss咱们的bucket. 其中fileobj不止能够是文件对象,也能够是本地文件路径。 put_object方法底层还是RESTful API的调用,能够指定headers,规定Content-Type等内容
        """
        # 判断bucket中文件是否存在,也能够不判断,会上传更新
        exist = self.bucket.object_exists('abc/efg/00') #<yourObjectName>
        if exist:
            return True
        with open('/home/rong/www/0', 'rb') as fileobj:
            result = self.bucket.put_object('abc/efg/00', fileobj, headers=None) #<yourObjectName>
        if result.status == 200:
            return True
        else:
            return False


    def upload_file_from_loaclfilepath(self):
        """
            upload_file_from_loaclfilepath:上传本地指定路径文件(/home/rong/www/0)到oss存储空间指定位置(abc/efg/0)。与put_object方法不一样,put_object_from_file的第二个参数只能是本地文件路径
        """
        # 判断bucket中文件是否存在,也能够不判断,会上传更新
        exist = self.bucket.object_exists('abc/efg/0') #<yourObjectName>
        if exist:
            return True
        result = self.bucket.put_object_from_file('abc/efg/0', '/home/rong/www/0', headers=None) #(<yourObjectName>, <yourLocalFile>)
        if result.status == 200:
            return True
        else:
            return False


    def download_file_to_fileobj(self):
        """
            download_file_to_fileobj:下载文件到文件流对象。因为get_object接口返回的是一个stream流,须要执行read()后才能计算出返回Object数据的CRC checksum,所以须要在调用该接口后作CRC校验。
        """
        object_stream = self.bucket.get_object('abc/efg/0') #<yourObjectName>
        result = object_stream.read()
        if object_stream.client_crc != object_stream.server_crc:
            print("The CRC checksum between client and server is inconsistent!")
            result = None
        return result


    def download_file_to_loaclfilepath(self):
        """
            download_file_to_loaclfilepath:下载文件到本地路径。get_object和get_object_to_file的区别是前者是获取文件流实例,可用于代码处理和远程调用参赛。后者是存储到本地路径,返回的是一个http状态的json结果
        """
        result = self.bucket.get_object_to_file('abc/efg/0', '/home/rong/www/download/0') # ('<yourObjectName>', '<yourLocalFile>')
        if result.status == 200:
            return True
        else:
            return False

    def generate_temporary_download_url(self):
        """
            generate_temporary_download_url: 生成加签的临时URL以供授信用户下载。通常在实际业务中,咱们是提供给调用方一个临时下载连接,来让其获取文件数据,而不是直接使用以上暴露AccessKeyId和AccessKeySecret的方法。
            所以通常咱们会存储某条数据oss的路径(<yourObjectName>)与调用方某个惟一标识的对应关系(如手机号身份证号),在调用方请求时,经过该标识获取其数据的oss文件路径(<yourObjectName>),
            而后制定过时时间,为其生成临时下载连接
            http://bucketname.oss-ap-south-1.aliyuncs.com/abc/efg/0?OSSAccessKeyId=LTA************oN9&Expires=1604638842&Signature=tPgvWz*************Uk%3D
        """
        res_temporary_url = self.bucket.sign_url('GET', 'abc/efg/0', 60, slash_safe=True)
        return res_temporary_url


if __name__ == '__main__':
    oss_client = OssClient()
    print(oss_client.bucket.bucket_name)
    print(oss_client.bucket.ACL)
    from itertools import islice
    for b in islice(oss2.ObjectIterator(oss_client.bucket), 10):
        print(b.key)
    ...
相关文章
相关标签/搜索