Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Python

Cách tải xuống đối tượng từ S3 bằng Boto3 và AWS Resource


Đề bài – Sử dụng thư viện boto3 trong Python để tải xuống một đối tượng từ S3 vào đường dẫn cục bộ cho trước/đường dẫn mặc định với tùy chọn ghi đè file hiện có là true. Ví dụ: tải xuống test.zip từ Bucket_1/testfolder của S3.

Phương pháp/Thuật toán giải quyết

Bước 1 – Import boto3 và các ngoại lệ từ botocore để xử lý lỗi.

Bước 2 – Từ pathlib, import Path để kiểm tra tên file.

Bước 3 – s3_path, localpath và overwrite_existing_file là ba tham số trong hàm download_object_from_s3.

Bước 4 – Kiểm tra s3_path có đúng định dạng AWS s3://bucket_name/key không. Mặc định localpath = None và overwrite_existing_file = True. Người dùng có thể truyền các giá trị này để tải xuống vào đường dẫn cục bộ cho trước.

Bước 5 – Tạo phiên AWS (session) bằng thư viện boto3.

Bước 6 – Tạo resource AWS cho S3.

Bước 7 – Tách đường dẫn S3 và thực hiện các thao tác để tách tên bucket gốc và đường dẫn đối tượng cần tải xuống.

Bước 8 – Kiểm tra xem overwrite_existing_file có được đặt là False và file đã tồn tại ở đường dẫn cục bộ cho trước không; trong trường hợp đó thì không thực hiện thao tác nào.

Bước 9 – Ngược lại (nếu một trong các điều kiện không đúng), tải xuống đối tượng. Nếu localpath được cung cấp, tải xuống đó; ngược lại tải xuống vào đường dẫn mặc định.

Bước 10 – Xử lý ngoại lệ dựa trên mã phản hồi để xác thực xem file đã được tải xuống hay chưa.

Bước 11 – Xử lý ngoại lệ chung nếu có lỗi xảy ra khi tải xuống file.

Ví dụ

Sử dụng mã sau để tải file từ 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('Đường dẫn không phải là đường dẫn S3 hợp lệ.')
        raise Exception('Đường dẫn không phải là đường dẫn S3 hợp lệ.')
    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("Lỗi không mong đợi trong download_object function của s3 helper: " + error.__str__())
        raise Exception("Lỗi không mong đợi trong download_object function của s3 helper: " + error.__str__())

# Tải xuống vào localpath mặc định
print(download_object_from_s3("s3://Bucket_1/testfolder/test.zip"))
# Tải xuống vào đường dẫn cho trước
print(download_object_from_s3("s3://Bucket_1/testfolder/test.zip", "C://AWS"))
# File không tồn tại trong S3
print(download_object_from_s3("s3://Bucket_1/testfolder/abc.zip"))

Kết quả

# Tải xuống vào localpath mặc định
Filename: test.zip
object: testfolder/test.zip
Filename: test.zip
# Tải xuống vào đường dẫn cho trước
Filename: test.zip
object: testfolder/test.zip
Filename: test.zip
# File không tồn tại trong 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

Lưu ý: Đường dẫn mặc định để tải xuống là thư mục chứa hàm này. Nếu không cung cấp local path, file sẽ được tải xuống vào cùng thư mục.

Ví dụ, nếu hàm này được viết trong S3_class và class này nằm ở C://AWS/src/S3_class, thì file test.zip sẽ được tải xuống vào C://AWS/src/test.zip.