阅读341 返回首页    go 网易 go 网易蜂巢


对象存储 Python SDK

目录

安装

SDK

环境要求

此版本的 Python SDK 适用于 Python 2.7 版本。首先请根据 Python官网 的引导安装合适的 Python 版本。

安装

pip方式

如果你通过pip管理你的项目依赖,可以在你的控制台运行:

sudo pip install nos-python-sdk

源码方式

使用SDK源码安装,可以克隆github上SDK项目的master分支,或者到pypi上下载相应版本的源码包并解压,最后执行安装命令:

 sudo python setup.py install 

初始化

确定EndPoint

EndPoint 是NOS各个区域的地址,目前支持以下形式

EndPoint类型 备注
NOS区域域名地址 使用桶所在的区域的NOS域名地址

NOS区域域名地址

    进入NOS控制台,在桶的 属性 中可以查找到当前桶所在的区域及域名,桶的域名的后缀部分为 该桶的公网域名,例如:test-logging.nos-eastchina1.126.net中的nos-eastchina1.126.net 为该桶的公网EndPoint。

配置密钥

要接入NOS服务,你需要一对有效的AccessKey(包括AccessKeyId与AccessKeySecret)来进行 签名验证,开通服务与AccessKey请参考 访问控制 :

在获取到AccessKeyId与AccessKeySecret之后,可以按照以下的步骤进行初始化

新建Client

使用NOS地区域名创建Client

初始化代码如下所示:

import nos

access_key = "你的accessKeyId"
secret_key = "你的accessKeySecret"
end_point = "建桶时选择的的区域域名"
client = nos.Client(access_key, secret_key, end_point)

设置额外参数

如果你需要修改Client的默认配置,可以在实例化Client时添加其他可选参数:

import nos

access_key = "你的accessKeyId"
secret_key = "你的accessKeySecret"
end_point = "建桶时选择的的区域域名"
client = nos.Client(
    access_key,
    secret_key,
    end_point,
    num_pools=10,
    timeout=5,
    max_retries=4
)

具体参数见下表:

参数 描述 默认值
timeout 建立连接的超时时间(单位:秒) 默认:Socket的全局Timeout值
num_pools 允许打开的最大HTTP连接数 默认:16
max_retries 请求失败后最大的重试次数 默认:2

快速入门

请确认你已经熟悉NOS的基本概念,如Bucket、Object、EndPoint、AccessKeyId和AccessKeySecret等。 本节你将看到如何快速的使用NOS PYTHON SDK,完成常用的操作,上传文件、下载文件等。

常用类

常用类 备注
nos.Client NOS客户端类,用户通过Client调用服务
nos.exceptions.ServiceException NOS服务器返回的异常
nos.exceptions.ClientException NOS客户端抛出的异常


基本操作

上传文件

对象(Object)是NOS中最基本的数据单元,你可以把它简单的理解为文件,以下代码可以实现简单的对象上传:

import nos

access_key = "你的accessKeyId"
secret_key = "你的accessKeySecret"
end_point = "建桶时选择的的区域域名"
bucket = "使用的桶名,注意命名规则"
object = "使用的对象名,注意命名规则"
content = "Hello NOS!"

client = nos.Client(access_key, secret_key, end_point)

try:
    client.put_object(bucket, object, content)
except nos.exceptions.ServiceException as e:
    print (
        "ServiceException: %s\n"
        "status_code: %s\n"
        "error_type: %s\n"
        "error_code: %s\n"
        "request_id: %s\n"
        "message: %s\n"
    ) % (
        e,
        e.status_code,  # 错误http状态码
        e.error_type,   # NOS服务器定义错误类型
        e.error_code,   # NOS服务器定义错误码
        e.request_id,   # 请求ID,有利于nos开发人员跟踪异常请求的错误原因
        e.message       # 错误描述信息
    )
except nos.exceptions.ClientException as e:
    print (
        "ClientException: %s\n"
        "message: %s\n"
    ) % (
        e,
        e.message       # 客户端错误信息
    )

对象命名规则请参见 API 手册 对象

更多的上传文件信息,请参见 NOS-PYTHON-SDK上传文件

下载文件

上传对象成功之后,你可以读取它的内容,以下代码可以实现文件的下载:

import nos

access_key = "你的accessKeyId"
secret_key = "你的accessKeySecret"
end_point = "建桶时选择的的区域域名"
bucket = "使用的桶名,注意命名规则"
object = "使用的对象名,注意命名规则"

client = nos.Client(access_key, secret_key, end_point)

try:
    result = client.get_object(bucket, object)
    fp = result.get("body")
    object_str = fp.read()
    print "object content: ", object_str
except nos.exceptions.ServiceException as e:
    print (
        "ServiceException: %s\n"
        "status_code: %s\n"
        "error_type: %s\n"
        "error_code: %s\n"
        "request_id: %s\n"
        "message: %s\n"
    ) % (
        e,
        e.status_code,  # 错误http状态码
        e.error_type,   # NOS服务器定义错误类型
        e.error_code,   # NOS服务器定义错误码
        e.request_id,   # 请求ID,有利于nos开发人员跟踪异常请求的错误原因
        e.message       # 错误描述信息
    )
except nos.exceptions.ClientException as e:
    print (
        "ClientException: %s\n"
        "message: %s\n"
    ) % (
        e,
        e.message       # 客户端错误信息
    )

更多的下载文件信息,请参见 NOS-PYTHON-SDK下载文件

列举文件

当上传文件成功之后,可以查看桶中包含的文件列表,以下代码展示如何列举桶内的文件:

import nos

access_key = "你的accessKeyId"
secret_key = "你的accessKeySecret"
end_point = "建桶时选择的的区域域名"
bucket = "使用的桶名,注意命名规则"

client = nos.Client(access_key, secret_key, end_point)

try:
    object_lists = client.list_objects(bucket)
    for object_list in object_lists["response"].findall("Contents"):
        print object_list.find("Key"), object_list.find("Size"), object_list.find("LastModified")
except nos.exceptions.ServiceException as e:
    print (
        "ServiceException: %s\n"
        "status_code: %s\n"
        "error_type: %s\n"
        "error_code: %s\n"
        "request_id: %s\n"
        "message: %s\n"
    ) % (
        e,
        e.status_code,  # 错误http状态码
        e.error_type,   # NOS服务器定义错误类型
        e.error_code,   # NOS服务器定义错误码
        e.request_id,   # 请求ID,有利于nos开发人员跟踪异常请求的错误原因
        e.message       # 错误描述信息
    )
except nos.exceptions.ClientException as e:
    print (
        "ClientException: %s\n"
        "message: %s\n"
    ) % (
        e,
        e.message       # 客户端错误信息
    )

更多的管理文件信息,请参见 NOS-PYTHON-SDK 文件管理

删除文件

文件上传成功后,可以指定删除桶中的文件,以下代码实现桶中文件的删除:

import nos

access_key = "你的accessKeyId"
secret_key = "你的accessKeySecret"
end_point = "建桶时选择的的区域域名"
bucket = "使用的桶名,注意命名规则"
object = "使用的对象名,注意命名规则"

client = nos.Client(access_key, secret_key, end_point)

try:
    client.delete_object(bucket, object)
except nos.exceptions.ServiceException as e:
    print (
        "ServiceException: %s\n"
        "status_code: %s\n"
        "error_type: %s\n"
        "error_code: %s\n"
        "request_id: %s\n"
        "message: %s\n"
    ) % (
        e,
        e.status_code,  # 错误http状态码
        e.error_type,   # NOS服务器定义错误类型
        e.error_code,   # NOS服务器定义错误码
        e.request_id,   # 请求ID,有利于nos开发人员跟踪异常请求的错误原因
        e.message       # 错误描述信息
    )
except nos.exceptions.ClientException as e:
    print (
        "ClientException: %s\n"
        "message: %s\n"
    ) % (
        e,
        e.message       # 客户端错误信息
    )

文件上传

在NOS中用户的基本操作单元是对象,亦可以理解为文件,NOS PYTHON SDK提供了丰富的上传接口,可以通过以下的方式上传文件:

  • 字符串上传
  • 本地文件上传
  • 分片上传

字符串上传、本地文件上传最大为100M,分片上传对文件大小没有限制

字符串上传

你可以使用put_object上传字符串内容到文件中,具体实现如下:

bucket = "使用的桶名,注意命名规则"
object = "使用的对象名,注意命名规则"
content = "Hello NOS!"

client.put_object(bucket, object, content)

    *上传的字符串内容不超过100M

本地文件上传

你可以使用put_object上传文件内容,具体实现如下:

bucket = "使用的桶名,注意命名规则"
object = "使用的对象名,注意命名规则"
file_name = "待上传文件的名称"

client.put_object(bucket, object, open(file_name, "rb"))

    *1.上传的文件内容不超过100M

    *2.必须以二进制的方式打开文件

分片上传

除了通过put_object接口上传文件到NOS之外,NOS还提供了另外一种上传模式-分片上传,用户可以在如下应用场景内(但不限于此),使用分片上传模式,如:

  • 需支持断点上传
  • 上传超过100M的文件
  • 网络条件较差,经常和NOS服务器断开连接
  • 上传文件之前无法确定文件的大小

原始接口分片上传

  • 初始化一个分片上传任务(create_multipart_upload)
  • 逐个或并行上传分片(upload_part)
  • 完成分片上传(complete_multipart_upload)或者取消分片上传

(abort_multipart_upload)

下面通过一个完整的示例说明了如何通过原始的api接口一步一步的进行分片上传操作,如果用户需要做断点续传等高级操作,可以参考下面代码:

bucket = "使用的桶名,注意命名规则"
object = "使用的对象名,注意命名规则"

# step 1. 初始化一个分块上传,获取分块上传ID,桶名 + 对像名 + 分块上传ID 唯一确定一个分块上传
result=client.create_multipart_upload(bucket, object)
# 分块上传ID用于后续分块上传操作
upload_id=result["response"].find("UploadId").text

# step 2. 上传分块
index = 0
slice_size = 100 * 1024 * 1024
file_name = "待上传文件的名称"
with open(file_name, "rb") as fp:
    while True:
        index += 1
        part = fp.read(slice_size)
        if not part:
            break
        client.upload_part(bucket, object, index, upload_id, part)

# step 3. 列出所有分块,完成分块上传
rParts = client.list_parts(bucket, object, upload_id)
Parts=rParts["response"]
partETags=[]
for k in Parts.findall("Part"):
    partETags.append({"part_num":k.find("PartNumber").text,"etag":k.find("ETag").text})

client.complete_multipart_upload(bucket, object, upload_id, partETags)

    *1.上面程序一共分为三个步骤:a. create_multipart_upload b. upload_part c. complete_multipart_upload

    *2.upload_part 方法要求除最后一个Part以外,其他的Part大小都要大于或等于16K。但是upload_part接口并不会立即校验上传Part的大小(因为不知道是否为最后一块),只有当complete_multipart_upload的时候才会校验。

    *3.Part号码的范围是1~10000。如果超出这个范围,NOS将返回InvalidArgument的错误码。

    *4.Part的大小为16K到100M

    *5.分片上传任务初始化或上传部分分片后,可以使用abort_multipart_upload接口中止分片上传事件。当分片上传事件被中止后,就不能再使用这个upload_id做任何操作,已经上传的分片数据也会被删除。

    *6.在完成上传时,需要在参数中提供上传块的ETag与块编号(PartNumber)的组合信息,具体操作参考上面代码。

查看已经上传的分片

查看已经上传的分片可以罗列出指定upload_id(create_multipart_upload时获取)所属的所有已经上传成功的分片,你可以通过list_parts接口获取已经上传的分片,可以参考以下代码:

rParts = client.list_parts(bucket, object, upload_id)
for k in rParts.get("response").findall("Part"):
    print k.find("PartNumber").text, k.find("ETag").text

文件下载

用户可以通过以下方式从NOS获取文件:

  • 下载文件

下载文件

以下源代码实现下载文件到内存中:

import nos

access_key = "你的accessKeyId"
secret_key = "你的accessKeySecret"
end_point = "建桶时选择的的区域域名"
bucket = "使用的桶名,注意命名规则"
object = "使用的对象名,注意命名规则"

client = nos.Client(access_key, secret_key, end_point)

try:
    result = client.get_object(bucket, object)
    fp = result.get("body")
    object_str = fp.read()
    print "object content: ", object_str
except nos.exceptions.ServiceException as e:
    print (
        "ServiceException: %s\n"
        "status_code: %s\n"
        "error_type: %s\n"
        "error_code: %s\n"
        "request_id: %s\n"
        "message: %s\n"
    ) % (
        e,
        e.status_code,  # 错误http状态码
        e.error_type,   # NOS服务器定义错误类型
        e.error_code,   # NOS服务器定义错误码
        e.request_id,   # 请求ID,有利于nos开发人员跟踪异常请求的错误原因
        e.message       # 错误描述信息
    )
except nos.exceptions.ClientException as e:
    print (
        "ClientException: %s\n"
        "message: %s\n"
    ) % (
        e,
        e.message       # 客户端错误信息
    )

    *下载内容也可以存储到文件中

文件管理

在NOS中,用户可以通过一系列的接口管理桶(Bucket)中的文件(Object),比如list_objects,delete_object,copy_object等。

列出桶中的文件

你可以使用list_objects列出桶中的文件:

import nos

access_key = "你的accessKeyId"
secret_key = "你的accessKeySecret"
end_point = "建桶时选择的的区域域名"
bucket = "使用的桶名,注意命名规则"

client = nos.Client(access_key, secret_key, end_point)

try:
    object_lists = client.list_objects(bucket)
    for object_list in object_lists["response"].findall("Contents"):
        print object_list.find("Key")
except nos.exceptions.ServiceException as e:
    print (
        "ServiceException: %s\n"
        "status_code: %s\n"
        "error_type: %s\n"
        "error_code: %s\n"
        "request_id: %s\n"
        "message: %s\n"
    ) % (
        e,
        e.status_code,  # 错误http状态码
        e.error_type,   # NOS服务器定义错误类型
        e.error_code,   # NOS服务器定义错误码
        e.request_id,   # 请求ID,有利于nos开发人员跟踪异常请求的错误原因
        e.message       # 错误描述信息
    )
except nos.exceptions.ClientException as e:
    print (
        "ClientException: %s\n"
        "message: %s\n"
    ) % (
        e,
        e.message       # 客户端错误信息
    )

list_objects可以指定的可选参数如下所示:

参数 说明
delimiter 用于对Object名字进行分组的字符。所有名字包含指定的前缀且第一次出现delimiter字符之间的object作为一组元素
prefix 限定返回的object key必须以prefix作为前缀。注意使用prefix查询时,返回的key中仍会包含prefix
limit 限定此次返回object的最大数,如果不设定,默认为100
marker 设定结果从marker之后按字母排序的第一个开始返回


删除单个文件

你可以使用delete_object删除单个需要删除的文件:

import nos

access_key = "你的accessKeyId"
secret_key = "你的accessKeySecret"
end_point = "建桶时选择的的区域域名"
bucket = "使用的桶名,注意命名规则"
object = "使用的对象名,注意命名规则"

client = nos.Client(access_key, secret_key, end_point)

try:
    client.delete_object(bucket, object)
except nos.exceptions.ServiceException as e:
    print (
        "ServiceException: %s\n"
        "status_code: %s\n"
        "error_type: %s\n"
        "error_code: %s\n"
        "request_id: %s\n"
        "message: %s\n"
    ) % (
        e,
        e.status_code,  # 错误http状态码
        e.error_type,   # NOS服务器定义错误类型
        e.error_code,   # NOS服务器定义错误码
        e.request_id,   # 请求ID,有利于nos开发人员跟踪异常请求的错误原因
        e.message       # 错误描述信息
    )
except nos.exceptions.ClientException as e:
    print (
        "ClientException: %s\n"
        "message: %s\n"
    ) % (
        e,
        e.message       # 客户端错误信息
    )

删除多个文件

你可以使用delete_objects批量删除文件:

import nos

access_key = "你的accessKeyId"
secret_key = "你的accessKeySecret"
end_point = "建桶时选择的的区域域名"
bucket = "使用的桶名,注意命名规则"
keys=["your-objectname1", "your-objectname2", "your-objectname3"]

client = nos.Client(access_key, secret_key, end_point)

try:
    client.delete_objects(bucket, keys)
except nos.exceptions.ServiceException as e:
    print (
        "ServiceException: %s\n"
        "status_code: %s\n"
        "error_type: %s\n"
        "error_code: %s\n"
        "request_id: %s\n"
        "message: %s\n"
    ) % (
        e,
        e.status_code,  # 错误http状态码
        e.error_type,   # NOS服务器定义错误类型
        e.error_code,   # NOS服务器定义错误码
        e.request_id,   # 请求ID,有利于nos开发人员跟踪异常请求的错误原因
        e.message       # 错误描述信息
    )
except nos.exceptions.ClientException as e:
    print (
        "ClientException: %s\n"
        "message: %s\n"
    ) % (
        e,
        e.message       # 客户端错误信息
    )

拷贝文件

你可以使用copy_object拷贝文件:

import nos

access_key = "你的accessKeyId"
secret_key = "你的accessKeySecret"
end_point = "建桶时选择的的区域域名"
bucket = "使用的桶名,注意命名规则"
src_object = "拷贝来源的对象名,注意命名规则"
dst_object = "拷贝目的的对象名,注意命名规则"

client = nos.Client(access_key, secret_key, end_point)

try:
    client.copy_object(bucket, src_object, bucket, dst_object)
except nos.exceptions.ServiceException as e:
    print (
        "ServiceException: %s\n"
        "status_code: %s\n"
        "error_type: %s\n"
        "error_code: %s\n"
        "request_id: %s\n"
        "message: %s\n"
    ) % (
        e,
        e.status_code,  # 错误http状态码
        e.error_type,   # NOS服务器定义错误类型
        e.error_code,   # NOS服务器定义错误码
        e.request_id,   # 请求ID,有利于nos开发人员跟踪异常请求的错误原因
        e.message       # 错误描述信息
    )
except nos.exceptions.ClientException as e:
    print (
        "ClientException: %s\n"
        "message: %s\n"
    ) % (
        e,
        e.message       # 客户端错误信息
    )

    *支持跨桶的文件copy

移动文件

你可以使用move_object移动文件:

import nos

access_key = "你的accessKeyId"
secret_key = "你的accessKeySecret"
end_point = "建桶时选择的的区域域名"
bucket = "使用的桶名,注意命名规则"
src_object = "移动来源的对象名,注意命名规则"
dst_object = "移动目的的对象名,注意命名规则"

client = nos.Client(access_key, secret_key, end_point)

try:
    client.move_object(bucket, src_object, bucket, dst_object)
except nos.exceptions.ServiceException as e:
    print (
        "ServiceException: %s\n"
        "status_code: %s\n"
        "error_type: %s\n"
        "error_code: %s\n"
        "request_id: %s\n"
        "message: %s\n"
    ) % (
        e,
        e.status_code,  # 错误http状态码
        e.error_type,   # NOS服务器定义错误类型
        e.error_code,   # NOS服务器定义错误码
        e.request_id,   # 请求ID,有利于nos开发人员跟踪异常请求的错误原因
        e.message       # 错误描述信息
    )
except nos.exceptions.ClientException as e:
    print (
        "ClientException: %s\n"
        "message: %s\n"
    ) % (
        e,
        e.message       # 客户端错误信息
    )

    *暂时不支持跨桶的文件move

错误处理

异常处理

调用Client类的相关接口时,如果抛出异常,则表明操作失败,否则操作成功。抛出异常时,方法返回的数据无效。SDK中所有异常均属于NOSException类,其下分为两个子类:ClientException、ServiceException。在调用PYTHON SDK接口的时候,捕捉这些异常并打印必要的信息有利于定位问题。

异常处理实例

错误处理代码如下所示:

try:
    resp = client.XXX(bucket=bucket, key=key)
except nos.exceptions.ServiceException as e:
    print (
        "ServiceException: %s\n"
        "status_code: %s\n"
        "error_type: %s\n"
        "error_code: %s\n"
        "request_id: %s\n"
        "message: %s\n"
    ) % (
        e,
        e.status_code,  # 错误http状态码
        e.error_type,   # NOS服务器定义错误类型
        e.error_code,   # NOS服务器定义错误码
        e.request_id,   # 请求ID,有利于nos开发人员跟踪异常请求的错误原因
        e.message       # 错误描述信息
    )
except nos.exceptions.ClientException as e:
    print (
        "ClientException: %s\n"
        "message: %s\n"
    ) % (
        e,
        e.message       # 客户端错误信息
    )

NOSException

ClientException

ClientException包含SDK客户端的异常。比如,上传对象时对象名为空,就会抛出该异常。 ClientException类下有如下子类,用于细分客户端异常:

类名 抛出异常的原因
InvalidBucketName 传入的桶名为空
InvalidObjectName 传入的对象名为空
FileOpenModeError 出入的对象为文件且没有使用二进制文件方式打开
XmlParseError 解析服务端响应的XML内容失败
SerializationError 上传对象序列化失败
ConnectionError 连接服务端异常
ConnectionTimeout 连接服务端超时

ServiceException

ServiceException包含NOS服务器返回的异常。当NOS服务器返回4xx或5xx的HTTP错误码时,PYTHON SDK会将NOS Server的响应转换为ServiceException。 ServiceException类下有如下子类,用于细分NOS服务器返回的异常:

类名 抛出异常的原因
MultiObjectDeleteException 批量删除对象时,存在部分对象无法删除
BadRequestError 服务端返回 HTTP 400 响应
ForbiddenError 服务端返回 HTTP 403 响应
NotFoundError 服务端返回 HTTP 404 响应
MethodNotAllowedError 服务端返回 HTTP 405 响应
ConflictError 服务端返回 HTTP 409 响应
LengthRequiredError 服务端返回 HTTP 411 响应
RequestedRangeNotSatisfiableError 服务端返回 HTTP 416 响应
InternalServerErrorError 服务端返回 HTTP 500 响应
NotImplementedError 服务端返回 HTTP 501 响应
ServiceUnavailableError 服务端返回 HTTP 503 响应

最后更新:2017-01-03 10:48:53

  上一篇:go 宁夏地区管局规则
  下一篇:go GO-SDK