当前位置: 首页 > 后端技术 > Python

阿里云对象存储OSSpythonSDK示例_0

时间:2023-03-26 18:54:27 Python

背景最近公司项目需要使用阿里云的oss存储在线实时存储图片文件。因此,我们研发了python版的阿里云ossSDK。这里介绍一下oss和pythonoss的常用方法。oss介绍阿里云对象存储OSS(ObjectStorageService)是阿里云提供的海量、安全、低成本、高持久的云存储服务。其数据设计持久性不低于99.9999999999%(12个9),服务可用性(或业务连续性)不低于99.995%。OSS具有平台无关的RESTfulAPI接口,您可以在任何应用程序、任何时间、任何地点存储和访问任何类型的数据。您可以使用阿里云提供的API、SDK接口或OSS迁移工具,轻松将海量数据迁入或迁出阿里云OSS。数据存储到阿里云OSS后,对于移动应用、大型网站、图片分享、热门音视频等,可以选择标准存储(Standard)作为主要存储方式,也可以选择低频访问存储(InfrequentAccess))、归档存储(Archive)、冷归档存储(ColdArchive)作为不常访问数据的存储方式。以上是阿里云官方对oss的介绍。综上所述,它可以提供高可用、高持久、低成本、支持多种文件和数据格式、支持RESTfulAPI接口的云存储服务。就我们实际使用来说,确实还不错。成本方面,我们申请的海外节点,30多TB的数据,一个月差不多5000,比较低。在代码示例之前,先了解一些概念:存储类(StorageClass)OSS提供标准、不常访问、归档、冷归档四种存储类型,全面覆盖从热到冷的各种数据存储场景。其中,标准存储类型提供高持久、高可用、高性能的对象存储服务,可以支持频繁的数据访问;低频访问存储型适合长期存储不常访问的数据(平均每月访问频率1~2次),存储单价低于标准型;归档存储类型适用于需要长期存储的归档数据(建议半年以上);归档冷存储适用于需要长期保存的极冷数据。Bucket是你用来存储对象的容器。所有对象都必须属于一个桶。存储空间具有各种配置属性,包括区域、访问权限、存储类型等。您可以根据实际需要创建不同类型的存储空间来存储不同的数据。对象(Object)是OSS数据存储的基本单位,也称为OSS文件。一个对象由元信息(ObjectMeta)、用户数据(Data)和文件名(Key)组成。对象由存储空间内唯一的Key标识。对象元信息是一组键值对,代表对象的一些属性,比如最后修改时间、大小等,你也可以在元信息中存储一些自定义信息。地域(Region)表示OSS数据中心的物理位置。您可以根据成本和请求来源选择合适的地域创建Bucket。访问域名(Endpoint)Endpoint表示OSS对外服务的访问域名。OSS以HTTPRESTfulAPI的形式对外提供服务。访问不同地区时,需要使用不同的域名。内网和外网访问同一个地域所需要的域名也不一样。访问密钥(AccessKey)AccessKey简称AK,是指用于访问认证的AccessKeyId和AccessKeySecret。OSS通过AccessKeyId和AccessKeySecret对称加密方式来验证请求发送者的身份。AccessKeyId用于标识用户;AccessKeySecret是用户加密签名串和OSS验证签名串的密钥,必须保密。osspythonSDKOssClient支持的方法:1.上传文件对象到oss存储空间2.上传本地指定路径文件到oss存储空间3.下载文件到文件流对象4.下载文件到本地指定路径5.生成签名临时文件以上功能基本可以满足日常业务需求。当然oss也提供了很多个性化的操作,比如断点下载、范围下载、断点上传、附加上传、上传回调、图片调整等等,这里就不多说了,都有专门的接口方法。下面列出接口实现方法,没有添加文件是否存在、权限控制、是否覆盖、是否加密等各种判断逻辑。如果需要,可以添加逻辑importoss2AccessKeyId='LTA************hpmoN9'AccessKeySecret='0ise************bkIyF'BucketName='*******'Endpoint='http://oss-ap-south-1.aliyuncs.com'classOssClient(object):__instance=None__first_init=False#单例模式def__new__(cls,*args,**kwargs):如果不是cls.__instance:cls.__instance=super().__new__(cls)返回cls.__instancedef__init__(self):cls=self.__class__如果不是cls.__first_init:self.auth=oss2.Auth(AccessKeyId,AccessKeySecret)self.bucket=oss2.Bucket(self.auth,Endpoint,BucketName)cls.__first_init=Truedefupload_file_from_fileobj(self):"""upload_file_from_fileobj方法:上传文件对象到oss存储空间,这个方法可以用我们从upstream服务接收到图片参数,然后读取二进制形式的文件,上传到oss存储空间的指定位置(abc/efg/00),当然我们也可以将本地文件上传到我们的ossbucket,其中fileobj可以是不仅仅是一个文件对象,它也可以是一个本地文件路径。put_object方法底层依然是RESTfulAPI调用,可以指定headers,指定Content-Type等内容"""#判断文件是否存在于bucket中,不存在则上传并更新exist=self.bucket.object_exists('abc/efg/00')#如果存在:返回Truewithopen('/home/rong/www/0','rb')asfileobj:result=self.bucket.put_object('abc/efg/00',fileobj,headers=None)#ifresult.status==200:returnTrueelse:returnFalsedefupload_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')#如果存在:返回Trueresult=self.bucket.put_object_from_file('abc/efg/0','/home/rong/www/0',headers=None)#(,)ifresult.status==200:returnTrueelse:returnFalsedefdownload_file_to_fileobj(self):"""download_file_to_fileobj:将文件下载到文件流对象。由于get_object接口返回的是stream,执行read()后需要对返回的Object数据进行CRC校验,所以调用该接口后需要进行CRC校验。"""object_stream=self.bucket.get_object('abc/efg/0')#result=object_stream.read()ifobject_stream.client_crc!=object_stream.server_crc:print("客户端和服务器之间的CRC校验和不一致!”)result=Nonereturnresultdefdownload_file_to_loaclfilepath(self):"""download_file_to_loaclfilepath:下载文件到本地路径。get_object和get_object_to_file的区别在于前者是获取一个文件流实例,可用于代码处理和远程调用竞争。后者存储在本地路径,返回一个httpstatus"""的json结果result=self.bucket.get_object_to_file('abc/efg/0','/home/rong/www/download/0')#('','')ifresult.status==200:returnTrueelse:returnFalsedefgenerate_temporary_download_url(self):"""generate_temporary_download_url:生成签名的临时URL供可信用户下载。一般在实际业务中,我们会为调用方提供一个临时下载链接来获取文件数据,而不是直接使用上述暴露AccessKeyId和AccessKeySecret的方法。因此,一般我们会存储某个数据oss()的路径与调用者唯一标识(如手机号、身份证号)的对应关系,获取其数据的oss文件调用者请求Path()时通过这个标识,然后设置过期时间生成临时下载链接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)returnres_temporary_urlif__name__=='__main__':oss_client=OssClient()print(oss_client.bucket.bucket_name)print(oss_client.bucket.ACL)fromitertoolsimportisliceforbinislice(oss2.ObjectIterator(oss_client.bucket),10):print(b.key)...