完成整个分块上传(Complete Multipart Upload)。当所有分块上传完毕后,需按分块编号升序提交每个分块的
PartNumber 与 ETag,服务端据此将分块合并为完整对象。对高性能桶发起请求时,SDK 自动完成会话鉴权。注意事项
Key 必须与初始化时一致,表示不以 / 结尾的文件对象。返回的
ETag 用于标识合并后的对象,不应将其当作完整对象内容的 MD5。PartNumber 取值为1~10000;提交列表必须严格递增且不能重复,否则返回 InvalidPartOrder。编号无需连续,例如已上传且 ETag、大小均有效的分块1、3可以按此顺序提交。除最后一块外,分块小于 1MB 会返回
EntityTooSmall;UploadId 不存在会返回 NoSuchUpload。防覆盖条件以本次完成请求为准。需要保留同名文件时,必须在本次调用中显式设置
ForbidOverwrite='true',已有同名文件会返回 409 FileAlreadyExists;省略或设置 'false' 允许覆盖文件。初始化阶段的设置不能替代本次参数。完成分块上传属于数据面接口,SDK 使用 session 临时凭证签名。
请求
方法原型
def complete_multipart_upload(self, Bucket, Key, UploadId, MultipartUpload={}, **kwargs)
参数说明
参数名称 | 参数描述 | 类型 | 是否必选 |
Bucket | 高性能桶完整名称,格式为 <BucketName>-x--<APPID> | string | 是 |
Key | 对象键(Object Key) | string | 是 |
UploadId | 初始化分块上传返回的 UploadId | string | 是 |
MultipartUpload | 分块信息, dict 类型,含 Part 列表 | dict | 是 |
ForbidOverwrite | 本次完成请求的文件防覆盖条件,字符串 "true" 或 "false";通过关键字传入 | string | 否 |
kwargs | 可选请求参数,使用本文列出的参数 | dict | 否 |
MultipartUpload 结构:# -*- coding: utf-8 -*-{'Part': [{'PartNumber': 1, 'ETag': '"..."'},{'PartNumber': 3, 'ETag': '"..."'},# 按 PartNumber 升序排列]}
参数名称 | 参数描述 | 类型 | 是否必选 |
Part | 待合并的分块列表,每项含 PartNumber 与 ETag,且按 PartNumber 升序排列 | list | 是 |
响应
返回值为字典:
参数名称 | 参数描述 | 类型 |
Bucket | 对象所在的桶名 | string |
Key | 对象键 | string |
ETag | 合并后对象的 ETag | string |
错误码
实际案例
# -*- coding=utf-8 -*-import osfrom qcloud_cos import CosConfig, CosS3Client# 高性能桶经 VPC 内网 HTTP 80 端口接入,SDK 的网关 DNS 负载均衡也仅对 HTTP 请求生效;SDK 默认 https,此处需显式指定 http。config = CosConfig(Scheme='http',Region='ap-guangzhou',SecretId=os.environ['COS_SECRET_ID'],SecretKey=os.environ['COS_SECRET_KEY'],Token=os.environ.get('COS_SECURITY_TOKEN'),EnableRapidDomain=True)client = CosS3Client(config)bucket = 'examplebucket-x--1250000000'key = 'multipart-example.txt'# 初始化分块上传。init_resp = client.create_multipart_upload(Bucket=bucket, Key=key)upload_id = init_resp['UploadId']# 编号可以不连续;非最后一块至少 1MB。parts = []for part_number, data in ((1, b'a' * (1024 * 1024)), (3, b'last part')):resp = client.upload_part(Bucket=bucket, Key=key, Body=data,PartNumber=part_number, UploadId=upload_id)parts.append({'PartNumber': part_number, 'ETag': resp['ETag']})# 按 PartNumber 升序提交完成。result = client.complete_multipart_upload(Bucket=bucket,Key=key,UploadId=upload_id,MultipartUpload={'Part': parts},ForbidOverwrite='true')print('complete OK, ETag: %s' % result['ETag'])