更新时间:2024-11-26 GMT+08:00

分段上传简介(Python SDK)

对于较大文件上传,可以切分成段上传。用户可以在如下的应用场景内(但不仅限于此),使用分段上传的模式:

  • 上传超过100MB大小的文件。
  • 网络条件较差,和OBS服务端之间的链接经常断开。
  • 上传前无法确定将要上传文件的大小。

分段上传分为如下3个步骤:

  1. 初始化分段上传任务(ObsClient.initiateMultipartUpload)。
  2. 逐个或并行上传段(ObsClient.uploadPart)。
  3. 合并段(ObsClient.completeMultipartUpload)或取消分段上传任务(ObsClient.abortMultipartUpload)。

本示例用于展示完整的多段上传,具体为初始化上传段任务、上传每个段、合并段。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# -*- coding:utf-8 -*-
from obs import ObsClient,CompleteMultipartUploadRequest, CompletePart
import os
import traceback
# 推荐通过环境变量获取AKSK,这里也可以使用其他外部引入方式传入。如果使用硬编码可能会存在泄露风险
# 您可以登录访问管理控制台获取访问密钥AK/SK,获取方式请参见https://support.huaweicloud.com/intl/zh-cn/usermanual-ca/ca_01_0003.html
ak = os.getenv("AccessKeyID")
sk = os.getenv("SecretAccessKey")
# 【可选】如果使用临时AKSK和SecurityToken访问OBS,则同样推荐通过环境变量获取
# security_token = os.getenv("SecurityToken")
# server填写Bucket对应的Endpoint, 这里以中国-香港为例,其他地区请按实际情况填写
server = "https://obs.ap-southeast-1.myhuaweicloud.com" 
# 创建obsClient实例
# 如果使用临时AKSK和SecurityToken访问OBS,需要在创建实例时通过security_token参数指定securityToken值
obsClient = ObsClient(access_key_id=ak, secret_access_key=sk, server=server)
try:
    #桶名
    bucketName = "examplebucket"
    #对象名
    objectKey = "objectname"
    # 对象的MIME类型
    contentType = 'text/plain'
    # 初始化分段上传任务
    resp = obsClient.initiateMultipartUpload(bucketName, objectKey,
                                             contentType=contentType)
    #获取初始化上传任务的uploadId
    uploadId = resp.body["uploadId"]
    #上传段大小
    partSize = 512 * 1024 * 1024
    #段号
    partNum = 1
    # 指明object字段是否代表文件路径,默认为False、此处为True
    isFile = True
    #本地要上传的对象文件
    filepath = r"D:\tmp\file.txt"
    contentLength = os.path.getsize(filepath)
    #源文件中某一分段的起始偏移大小。
    offset = 0
    etags = {}

    while offset < contentLength:
        partSize = min(partSize, (contentLength - offset));
        # 用于上传段
        resp1 = obsClient.uploadPart(bucketName, objectKey, partNum, uploadId, filepath, isFile, partSize, offset)
        etags[partNum] = resp1.body.etag
        offset = offset + partSize
        partNum = partNum + 1

    completes = []
    for i in range(1, partNum):
        completes.append(CompletePart(i, etags[i]))
    # 用于合并段
    completeMultipartUploadRequest = CompleteMultipartUploadRequest(parts = completes)
    resp = obsClient.completeMultipartUpload(bucketName, objectKey, uploadId, completeMultipartUploadRequest)
    # 返回码为2xx时,接口调用成功,否则接口调用失败
    if resp.status < 300:
        print('Upload Part Succeeded')
        print('requestId:', resp.requestId)
        print('etag:', resp.body.etag)
    else:
        print('Upload Part Failed')
        print('requestId:', resp.requestId)
        print('errorCode:', resp.errorCode)
        print('errorMessage:', resp.errorMessage)
except:
    print('multPartsUpload Failed')
    print(traceback.format_exc())

其他分段操作请参考: