如何使用 Boto3 和 AWS 資源從 S3 下載物件


問題陳述 − 使用 Python 中的 boto3 庫從 S3 的給定本地路徑/預設路徑下載物件,並將覆蓋現有檔案設定為 true。例如,從 S3 的 Bucket_1/testfolder 下載 test.zip。

解決此問題的方法/演算法

步驟 1 − 匯入 boto3 和 botocore 異常以處理異常。

步驟 2 − 從 **pathlib** 匯入 Path 以檢查檔名

步驟 3 − **s3_path**、**localpath** 和 **overwrite_existing_file** 是函式 **download_object_from_s3** 的三個引數。

步驟 4 − 驗證 **s3_path** 是否以 AWS 格式 **s3://bucket_name/key** 傳遞。預設情況下,**localpath = None** 和 **overwrite_existing_file = True**。使用者也可以傳遞這些值以便在給定的本地路徑下載。

步驟 5 − 使用 boto3 庫建立 AWS 會話。

步驟 6 − 為 S3 建立 AWS 資源。

步驟 7 − 分割 S3 路徑並執行操作以分離根儲存桶名稱和要下載的物件路徑。

步驟 8 − 檢查 **overwrite_existing_file** 是否設定為 False 以及檔案是否已存在於給定的本地路徑中;如果是,則不執行任何操作。

步驟 9 − 否則(如果這些條件中的任何一個不為真),則下載物件。如果提供了 localpath,則下載到該路徑;否則下載到預設路徑。

步驟 10 − 根據響應程式碼處理異常以驗證檔案是否已下載。

步驟 11 − 如果下載檔案時出現錯誤,則處理通用異常。

示例

使用以下程式碼從 AWS S3 下載檔案:

import boto3
from botocore.exceptions import ClientError
from pathlib import Path

def download_object_from_s3(s3path, localPath=None,
overwrite_existing_file=True):

   if 's3://' not in s3path:
      print('Given path is not a valid s3 path.')
      raise Exception('Given path is not a valid s3 path.')

   session = boto3.session.Session()
   s3_resource = session.resource('s3')

   s3_tokens = s3path.split('/')
   bucket_name = s3_tokens[2]
   object_path = ""
   filename = s3_tokens[len(s3_tokens) - 1]
   print('Filename: ' + filename)

   if len(s3_tokens) > 4:
      for tokn in range(3, len(s3_tokens) - 1):
         object_path += s3_tokens[tokn] + "/"
      object_path += filename
   else:
      object_path += filename
   print('object: ' + object_path)
   try:
      if not overwrite_existing_file and Path.is_file(filename):
         pass
      else:
         if localPath is None:
            s3_resource.meta.client.download_file(bucket_name, object_path, filename)
         else:
            s3_resource.meta.client.download_file(bucket_name, object_path, localPath + '/' + filename)
      print('Filename: ' + filename)
      return filename
   except ClientError as error:
      if error.response['Error']['Code'] == '404':
         print(s3path + " File not found: ")
         raise Exception(s3path + " File not found: ")
   except Exception as error:
      print("Unexpected error in download_object function of s3 helper: " + error.__str__())
      raise Exception("Unexpected error in download_object function of s3 helper: " + error.__str__())

#Download into default localpath
print(download_object_from_s3("s3://Bucket_1/testfolder/test.zip"))
#Download into given path
print(download_object_from_s3("s3://Bucket_1/testfolder/test.zip","C://AWS"))
#File doesn’t exist in S3
print(download_object_from_s3("s3://Bucket_1/testfolder/abc.zip"))

輸出

#Download into default localpath
Filename: test.zip
object: testfolder/test.zip
Filename: test.zip

#Download into given path
Filename: test.zip
object: testfolder/test.zip
Filename: test.zip

#File doesn’t exist in S3
Filename: abc.zip
object: testfolder/abc.zip
s3://Bucket_1/testfolder/abc.zip File not found:
botocore.exceptions.ClientError: An error occurred (404) when calling
the HeadObject operation: Not Found

注意: 預設下載路徑是編寫此函式的目錄。如果未提供本地路徑,則檔案將下載到同一目錄中。

例如,如果此函式寫入 S3_class,並且此類位於 C://AWS/src/S3_class,則檔案 test.zip 將下載到 C://AWS/src/test.zip。

更新於:2021年3月22日

2K+ 次檢視

啟動您的 職業生涯

透過完成課程獲得認證

開始
廣告
© . All rights reserved.