You need to enable JavaScript to run this app.
导航

断点续传(Python SDK)

最近更新时间2024.02.04 18:30:58

首次发布时间2022.09.13 20:46:25

通过断点续传上传的方式将文件上传到 TOS 前,您可以设置分片大小、上传分片的线程数、上传时客户端限速、事件回调函数等。同时也能在断点续传上传任务执行过程中,取消该任务。若出现网络异常等情况导致文件上传失败时,可从断点续传上传未完成的部分。

注意事项

  • 上传对象前,您必须具有 tos:PutObject 权限,具体操作,请参见权限配置指南
  • 上传对象时,对象名必须满足一定规范,详细信息,请参见对象命名规范
  • TOS 是面向海量存储设计的分布式对象存储产品,内部分区存储了对象索引数据。为横向扩展您上传对象和下载对象时的最大吞吐量和减小热点分区的概率,请您避免使用字典序递增的对象命名方式,详细信息,请参见性能优化
  • 如果桶中已经存在同名对象,则新对象会覆盖已有的对象。如果您的桶开启了版本控制,则会保留原有对象,并生成一个新版本号用于标识新上传的对象。

示例代码

失败后重入上传

以下代码用于断点续传上传,将本地文件上传到目标桶 bucket-testobject-test对象 ,若上传过程中抛出 TosClientError 并且错误原因为网络超时情况,则用户以相同参数调用 upload_file 后可实现断点重入上传。

import os
import tos

# 从环境变量获取 AK 和 SK 信息。
ak = os.getenv('TOS_ACCESS_KEY')
sk = os.getenv('TOS_SECRET_KEY')
# your endpoint 和 your region 填写Bucket 所在区域对应的Endpoint。# 以华北2(北京)为例,your endpoint 填写 tos-cn-beijing.volces.com,your region 填写 cn-beijing。
endpoint = "your endpoint"
region = "your region"
bucket_name = "bucket-test"
object_key = "object-test"
# 本地文件完整路径,例如usr/local/testfile.txt
filename = "/usr/local/testfile.txt"
try:
    # 创建 TosClientV2 对象,对桶和对象的操作都通过 TosClientV2 实现
    client = tos.TosClientV2(ak, sk, endpoint, region)
    # 可通过part_size可选参数指定分片大小
    # 通过enable_checkpoint参数开启和关闭断点续传特性
    # 通过task_num设置线程数
    client.upload_file(bucket_name, object_key, filename,
                       # 设置断点续传执行线程数,默认为1
                       task_num=3,
                       # 设置断点续传分片大小,默认20mb
                       part_size=1024 * 1024 * 5)
                  
except tos.exceptions.TosClientError as e:
    # 操作失败,捕获客户端异常,一般情况为非法请求参数或网络异常
    print('fail with client error, message:{}, cause: {}'.format(e.message, e.cause))
except tos.exceptions.TosServerError as e:
    # 操作失败,捕获服务端异常,可从返回信息中获取详细错误信息
    print('fail with server error, code: {}'.format(e.code))
    # request id 可定位具体问题,强烈建议日志中保存
    print('error with request id: {}'.format(e.request_id))
    print('error with message: {}'.format(e.message))
    print('error with http code: {}'.format(e.status_code))
    print('error with ec: {}'.format(e.ec))
    print('error with request url: {}'.format(e.request_url))
except Exception as e:
    print('fail with unknown error: {}'.format(e))

处理进度条

以下代码用于配置断点续传上传进度条功能。

import os
import tos

from tos import DataTransferType

# 从环境变量获取 AK 和 SK 信息。
ak = os.getenv('TOS_ACCESS_KEY')
sk = os.getenv('TOS_SECRET_KEY')
# your endpoint 和 your region 填写Bucket 所在区域对应的Endpoint。# 以华北2(北京)为例,your endpoint 填写 tos-cn-beijing.volces.com,your region 填写 cn-beijing。
endpoint = "your endpoint"
region = "your region"
bucket_name = "bucket-test"
object_key = "object-test"
# 本地文件完整路径,例如usr/local/testfile.txt
filename = "/usr/local/testfile.txt"
try:
    # 创建 TosClientV2 对象,对桶和对象的操作都通过 TosClientV2 实现
    client = tos.TosClientV2(ak, sk, endpoint, region)
    def percentage(consumed_bytes: int, total_bytes: int, rw_once_bytes: int, type: DataTransferType):
        if total_bytes:
            rate = int(100 * float(consumed_bytes) / float(total_bytes))
            print("rate:{}, consumed_bytes:{},total_bytes{}, rw_once_bytes:{}, type:{}".format(rate, consumed_bytes,
                                                                                               total_bytes,
                                                                                               rw_once_bytes, type))


    # 可通过part_size可选参数指定分片大小
    # 通过enable_checkpoint参数开启和关闭断点续传特性
    # 通过task_num设置线程数
    client.upload_file(bucket_name, object_key, filename,
                       # 设置断点续传执行线程数,默认为1
                       task_num=3,
                       # 设置断点续传分片大小,默认20mb
                       part_size=1024 * 1024 * 5,
                       # 设置断点续传进度条回调函数
                       data_transfer_listener=percentage)
except tos.exceptions.TosClientError as e:
    # 操作失败,捕获客户端异常,一般情况为非法请求参数或网络异常
    print('fail with client error, message:{}, cause: {}'.format(e.message, e.cause))
except tos.exceptions.TosServerError as e:
    # 操作失败,捕获服务端异常,可从返回信息中获取详细错误信息
    print('fail with server error, code: {}'.format(e.code))
    # request id 可定位具体问题,强烈建议日志中保存
    print('error with request id: {}'.format(e.request_id))
    print('error with message: {}'.format(e.message))
    print('error with http code: {}'.format(e.status_code))
    print('error with ec: {}'.format(e.ec))
    print('error with request url: {}'.format(e.request_url))
except Exception as e:
    print('fail with unknown error: {}'.format(e))

处理事件回调

以下代码用于自定义断点续传上传回调函数。

import os
import tos

from tos import UploadEventType
from tos.models2 import PartInfo

# 从环境变量获取 AK 和 SK 信息。
ak = os.getenv('TOS_ACCESS_KEY')
sk = os.getenv('TOS_SECRET_KEY')
# your endpoint 和 your region 填写Bucket 所在区域对应的Endpoint。# 以华北2(北京)为例,your endpoint 填写 tos-cn-beijing.volces.com,your region 填写 cn-beijing。
endpoint = "your endpoint"
region = "your region"
bucket_name = "bucket-test"
object_key = "object-test"
# 本地文件完整路径,例如usr/local/testfile.txt
filename = "/usr/local/testfile.txt"
try:
    client = tos.TosClientV2(ak, sk, endpoint, region)
    # 自定事件回调处理函数
    def upload_event(type: UploadEventType, err: Exception, bucket: str, key: str, upload_id: str, file_path: str,
                     checkpoint_file: str, part: PartInfo):
        print(type, err, bucket, key, upload_id, file_path, checkpoint_file, part)

    # 可通过part_size可选参数指定分片大小
    # 通过enable_checkpoint参数开启和关闭断点续传特性
    # 通过task_num设置线程数
    client.upload_file(bucket_name, object_key, filename,
                       # 设置断点续传执行线程数,默认为1
                       task_num=3,
                       # 设置断点续传分片大小,默认5mb
                       part_size=1024 * 1024 * 5,
                       # 设置是否开启断点续传,默认开启
                       enable_checkpoint=True,
                       # 配置自定义事件回调
                       upload_event_listener=upload_event)
except tos.exceptions.TosClientError as e:
    # 操作失败,捕获客户端异常,一般情况为非法请求参数或网络异常
    print('fail with client error, message:{}, cause: {}'.format(e.message, e.cause))
except tos.exceptions.TosServerError as e:
    # 操作失败,捕获服务端异常,可从返回信息中获取详细错误信息
    print('fail with server error, code: {}'.format(e.code))
    # request id 可定位具体问题,强烈建议日志中保存
    print('error with request id: {}'.format(e.request_id))
    print('error with message: {}'.format(e.message))
    print('error with http code: {}'.format(e.status_code))
    print('error with ec: {}'.format(e.ec))
    print('error with request url: {}'.format(e.request_url))
except Exception as e:
    print('fail with unknown error: {}'.format(e))

处理客户端限速

以下代码用于设置断点续传上传客户端限速。

import os
import tos


from tos import UploadEventType
from tos.models2 import PartInfo
# 从环境变量获取 AK 和 SK 信息。
ak = os.getenv('TOS_ACCESS_KEY')
sk = os.getenv('TOS_SECRET_KEY')
# your endpoint 和 your region 填写Bucket 所在区域对应的Endpoint。# 以华北2(北京)为例,your endpoint 填写 tos-cn-beijing.volces.com,your region 填写 cn-beijing。
endpoint = "your endpoint"
region = "your region"
bucket_name = "bucket-test"
object_key = "object-test"
# 本地文件完整路径,例如usr/local/testfile.txt
filename = "/usr/local/testfile.txt"
try:
    # 创建 TosClientV2 对象,对桶和对象的操作都通过 TosClientV2 实现
    client = tos.TosClientV2(ak, sk, endpoint, region)

    # TOS Python SDK 通过最基本的令牌桶算法实现了客户端限速,其中rate为发送令牌的速率,capacity为总容量
    # 以下配置的意义为5mb/s的平均上传速率,最大支持 10 + 5 mb/s的上传速率
    rate_limiter = tos.RateLimiter(5 * 1024 * 1024, 10 * 1024 * 1024)
    client.upload_file(bucket_name, object_key, filename,
                       # 设置断点续传执行线程数,默认为1
                       task_num=3,
                       # 设置断点续传分片大小,默认5mb
                       part_size=1024 * 1024 * 5,
                       # 设置是否开启断点续传,默认开启
                       enable_checkpoint=True,
                       # rate_limiter 为可选参数, 用于实现客户端限速。
                       rate_limiter=rate_limiter)
except tos.exceptions.TosClientError as e:
    # 操作失败,捕获客户端异常,一般情况为非法请求参数或网络异常
    print('fail with client error, message:{}, cause: {}'.format(e.message, e.cause))
except tos.exceptions.TosServerError as e:
    # 操作失败,捕获服务端异常,可从返回信息中获取详细错误信息
    print('fail with server error, code: {}'.format(e.code))
    # request id 可定位具体问题,强烈建议日志中保存
    print('error with request id: {}'.format(e.request_id))
    print('error with message: {}'.format(e.message))
    print('error with http code: {}'.format(e.status_code))
    print('error with ec: {}'.format(e.ec))
    print('error with request url: {}'.format(e.request_url))
except Exception as e:
    print('fail with unknown error: {}'.format(e))

取消机制

以下代码用于在运行时取消正在执行的断点续传上传任务。

import time
from threading import Thread

import os
import tos
from tos.checkpoint import CancelHook
# 从环境变量获取 AK 和 SK 信息。
ak = os.getenv('TOS_ACCESS_KEY')
sk = os.getenv('TOS_SECRET_KEY')
# your endpoint 和 your region 填写Bucket 所在区域对应的Endpoint。# 以华北2(北京)为例,your endpoint 填写 tos-cn-beijing.volces.com,your region 填写 cn-beijing。
endpoint = "your endpoint"
region = "your region"
bucket_name = "bucket-test"
object_key = "object-test"
# 本地文件完整路径,例如usr/local/testfile.txt
filename = "/usr/local/testfile.txt"
try:
    # 创建 TosClientV2 对象,对桶和对象的操作都通过 TosClientV2 实现
    client = tos.TosClientV2(ak, sk, endpoint, region)
    # 继承 CancelHook 类实现断点续传上传任务取消功能
    class MyCancel(CancelHook):
        def cancel(self, is_abort: bool):
            # is_abort 为 true 时删除上下文信息并 abort 分段上传任务,为 false 时只是中断当前执行
            # 重写 cancel 方法时必须调用 父类的 cancel 方法
            # 模拟 10 秒后取消任务
            time.sleep(10)
            super(MyCancel, self).cancel(is_abort=is_abort)
            print('some user define')


    cancel = MyCancel()

    t1 = Thread(target=cancel.cancel, args=(False,))
    t1.start()

    upload_out = client.upload_file(bucket_name, object_key, file_path=filename,
                                    # 设置取消断点续传函数
                                    cancel_hook=cancel,
                                    # 设置上传文件的线程数, 默认为1
                                    task_num=3,
                                    # 设置文件分片大小,默认为 20MB,最小为 5MB
                                    part_size=1024 * 1024 * 5)
except tos.exceptions.TosClientError as e:
    # 操作失败,捕获客户端异常,一般情况为非法请求参数或网络异常
    print('fail with client error, message:{}, cause: {}'.format(e.message, e.cause))
except tos.exceptions.TosServerError as e:
    # 操作失败,捕获服务端异常,可从返回信息中获取详细错误信息
    print('fail with server error, code: {}'.format(e.code))
    # request id 可定位具体问题,强烈建议日志中保存
    print('error with request id: {}'.format(e.request_id))
    print('error with message: {}'.format(e.message))
    print('error with http code: {}'.format(e.status_code))
    print('error with ec: {}'.format(e.ec))
    print('error with request url: {}'.format(e.request_url))
except Exception as e:
    print('fail with unknown error: {}'.format(e))