基于Boto3重构Tornado API以获取指定路径的AWS S3桶内容
用Boto3实现原Boto S3内容列表功能的解决方案
我懂你现在的困扰——原Boto代码能精准返回你想要的结构,但换成Boto3后总是拿到带全路径的对象列表,没法直接复用原有逻辑。别担心,我帮你把原代码的核心逻辑1:1转换成Boto3版本,还会拆解关键差异点。
先梳理下你原Boto代码的核心逻辑:
- 基于传入的
path和bucket_name,用/作为分隔符模拟目录结构,列出指定路径下的“文件夹”和文件 - 跳过与当前
path完全一致的条目 - 区分文件夹(以
/结尾)和文件,分别提取截掉path前缀后的文件名、类型、格式化后的大小 - 组装成指定结构的响应返回
在Boto3里,对应的API是list_objects_v2,关键是要正确设置Prefix和Delimiter参数,这样才能得到和原Botobucket.list(path, "/")一样的“目录视图”,而不是返回所有前缀匹配的对象。下面是转换后的完整代码:
import boto3 from botocore.exceptions import ClientError import json def post(self): try: resp = [] path = self.get_argument('path') bucket_name = self.get_argument('bucket_name') path_len = len(path) # 初始化Boto3 S3客户端(需指定区域可添加region_name参数,比如region_name='us-west-2') s3_client = boto3.client('s3') # 用分页器处理大量对象场景,自动处理分页逻辑 paginator = s3_client.get_paginator('list_objects_v2') response_iterator = paginator.paginate( Bucket=bucket_name, Prefix=path, Delimiter='/' ) for page in response_iterator: # 处理模拟的"文件夹"(Boto3中用CommonPrefixes返回) if 'CommonPrefixes' in page: for prefix in page['CommonPrefixes']: folder_name = prefix['Prefix'] if folder_name == path: continue # 截取path之后的文件夹名,去掉末尾的/ file_name = folder_name[path_len:-1] resp.append({ "bucket": bucket_name, "path": path, "name": file_name, "type": 'd', "size": "" }) # 处理实际文件对象(Boto3中用Contents返回) if 'Contents' in page: for obj in page['Contents']: obj_name = obj['Key'] if obj_name == path: continue # 截取path之后的文件名 file_name = obj_name[path_len:] _file_size = self.filesize(obj['Size']) resp.append({ "bucket": bucket_name, "path": path, "name": file_name, "type": 'f', "size": _file_size }) self.write(json.dumps(resp)) except ClientError as e: # 可根据需求添加错误处理逻辑,比如返回500状态码 self.set_status(500) self.write(json.dumps({"error": str(e)})) except Exception as e: self.set_status(500) self.write(json.dumps({"error": str(e)}))
关键细节说明:
- 分页处理:Boto3的
list_objects_v2默认最多返回1000个对象,用paginator自动处理分页,避免遗漏内容(原Boto的bucket.list()其实也自动分页,只是隐藏了细节)。 - 文件夹与文件区分:Boto3通过
CommonPrefixes返回模拟的文件夹(以/结尾的前缀),通过Contents返回实际文件对象,完全对应原代码的区分逻辑。 - 区域兼容:Boto3客户端会通过AWS配置链自动识别桶的区域,若需强制指定,可在初始化时添加
region_name参数,解决原代码在部分区域桶失效的问题。 - 文件名截取:和原代码逻辑完全一致,文件夹去掉末尾的
/,文件直接截取path后的部分,保证返回结构和原代码完全相同。
这样转换后,返回的resp结构和原Boto代码完全一致,应该能解决你之前遇到的全路径问题,同时兼容不同区域的桶。
内容的提问来源于stack exchange,提问作者Aditya
相关产品推荐
相关产品推荐

