對象存儲 Python SDK
安裝
SDK
- github地址: https://github.com/NetEase-Object-Storage/nos-python-sdk
- pypi地址: https://pypi.python.org/pypi/nos-python-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