融合接口

分片上传步骤较多,包括初始化、文件切片、各个分片上传、完成上传。为了简化分片上传,SDK提供了方便的融合接口用于上传文件,用户不需要关心文件的大小,SDK会自动对大文件使用分片上传。

class TransferDemo(object):
    def __init__(self):
        config = botocore.config.Config(
            signature_version='s3v4',  # 签名版本,s3 or s3v4
        )

        self.bucket = s3config.bucket
        session = botocore.session.get_session()
        self.s3_client = session.create_client(
            's3',
            aws_access_key_id=s3config.access_key,
            aws_secret_access_key=s3config.secret_key,
            endpoint_url=s3config.end_point,
            config=config)

        MB = 1024 * 1024
        transConfig = s3transfer.manager.TransferConfig(
            multipart_threshold=5 * MB,  # 大于该值使用分片上传
            multipart_chunksize=5 * MB,  # 分片大小
            max_request_concurrency=2,
            )

        # 设置带宽,不填表示不限制
        # transConfig.max_bandwidth = 1 * MB

        self.transfer = s3transfer.manager.TransferManager(self.s3_client, transConfig)

    def upload(self):
        print(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f'), "upload start")
        key = 'ExampleObject.txt'
        
        # 扩展配置,可以设置ContentType和ACL
        extraArgs = {'ContentType': 'text/plain', 'ACL': 'public-read'}
        
        with open('E:/ExampleObject1.txt', 'rb') as f:
            future = self.transfer.upload(f, self.bucket, key, extra_args=extraArgs)
            future.result()

upload方法参数,

参数 类型 说明
bucket str 桶名
key str 对象名
fileobj fileobj 打开的文件对象
extra_args dict 扩展配置,可以设置ContentType和ACL;ACL取值private | public-read | public-read-write

TransferConfig参数,

参数 类型 说明
multipart_threshold int 大于该值使用分片上传
multipart_chunksize int 分片大小,默认5MB
max_request_concurrency int 上传分片并发数

关于Content-Type的配置

Content-Type用于标识文件的资源类型,比如image/pngimage/jpg 是图片类型,video/mpegvideo/mp4是视频类型,text/plaintext/html是文本类型, 浏览器针对不同的Content-Type会有不同的操作,比如图片类型可以预览,视频类型可以播放,文本类型可以直接打开。application/octet-stream类型会直接打开下载窗口。

有些用户反馈图片和视频无法预览的问题,主要就是Content-Type没有正确设置导致的;Content-Type参数需要用户主动设置,默认是application/octet-stream。在python sdk中,可以根据对象key值后缀扩展名来决定文件的Content-Type,参考代码如下,

import mimetypes

def mime_type(key):
    mt = mimetypes.guess_type(key)[0]
    if mt == None :
        return ""
    return mt