关于python:阿里云对象存储OSS的python-SDK示例

56次阅读

共计 4667 个字符,预计需要花费 12 分钟才能阅读完成。

背景

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

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,也算比拟低了。

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

存储类型(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 用来验证签名字符串的密钥,必须窃密。

oss python SDK

OssClient 反对的办法:
1、上传文件对象到 oss 存储空间
2、上传本地指定门路文件到 oss 存储空间
3、下载文件到文件流对象
4、下载文件到本地指定门路
5、生成加签的长期 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)
    ...

正文完
 0