如何使用 Boto3 使用 AWS 资源从 S3 下载对象?
问题陈述-使用Python中的boto3库在给定的本地路径/默认路径下从S3下载对象,并将现有文件覆盖为true。例如test.zip从S3的Bucket_1/testfolder下载。
解决这个问题的方法/算法
步骤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资源。
Step7-拆分S3路径并执行操作以分离根存储桶名称和要下载的对象路径。
步骤8-检查overwrite_existing_file是否设置为False并且文件是否已存在于给定的本地路径中;在这种情况下不要做任何操作。
步骤9-否则(如果这些条件中的任何一个不成立),下载对象。如果给出了本地路径,则在那里下载;否则下载到默认路径。
步骤10-根据响应代码处理异常以验证文件是否已下载。
步骤11-如果在下载文件时出现问题,请处理通用异常。
示例
使用以下代码从AWSS3下载文件-
import boto3 frombotocore.exceptionsimport 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 + " 文件未找到: ") raise Exception(s3path + " 文件未找到: ") 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 文件未找到: 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