在Python AWS Lambda中异步调用AWS服务报错:await wasn't used with future
问题分析与修复
错误原因
报错await wasn't used with future的核心问题出在asyncio.gather(*loop.run_in_executor(...))的写法上:
loop.run_in_executor返回单个Future对象,而*会尝试将这个Future的执行结果(即s3_client.list_objects_v2返回的字典)拆分为多个参数传给gather,但这些字典的键值对并非可等待对象,导致await无法正确处理。- 另外,你当前仅需异步执行单个S3调用,完全不需要使用
asyncio.gather(该方法用于并发执行多个可等待对象)。
修复后的代码
方案一:移除不必要的asyncio.gather(推荐)
这是最简洁的修复方式,适配你当前单任务异步的场景:
import asyncio import functools import boto3 s3_client = boto3.client('s3') async def main(): bucketName = 'data-store-test' folder = 'Contacts-Aggre' lastModifiedFolderPath = await getLastModifiedBucketPath(bucketName, folder) print('Received lastModifiedFolderPath:', lastModifiedFolderPath) async def getLastModifiedBucketPath(bucketName, prefix): loop = asyncio.get_running_loop() # 直接await run_in_executor返回的Future对象,无需gather bucket_objects = await loop.run_in_executor( None, functools.partial(s3_client.list_objects_v2, Bucket=bucketName, Prefix=prefix) ) all_objects = bucket_objects['Contents'] latest = max(all_objects, key=lambda x: x['LastModified']) folderPaths = latest['Key'].split('/') lastModifiedFolder = folderPaths[1] if len(folderPaths) >=2 else folderPaths[0] return lastModifiedFolder def lambda_handler(event, context): loop = asyncio.get_event_loop() loop.run_until_complete(main())
方案二:保留gather但去掉解包(仅作多任务场景演示)
如果后续需要并发多个S3调用,可以参考此写法(当前场景无必要):
async def getLastModifiedBucketPath(bucketName, prefix): loop = asyncio.get_running_loop() # 不对Future对象解包,直接传入gather bucket_objects_list = await asyncio.gather( loop.run_in_executor( None, functools.partial(s3_client.list_objects_v2, Bucket=bucketName, Prefix=prefix) ) ) # gather返回结果列表,取第一个元素即为当前任务的结果 bucket_objects = bucket_objects_list[0] all_objects = bucket_objects['Contents'] latest = max(all_objects, key=lambda x: x['LastModified']) folderPaths = latest['Key'].split('/') lastModifiedFolder = folderPaths[1] if len(folderPaths) >=2 else folderPaths[0] return lastModifiedFolder
额外注意事项
- 确保Lambda环境中正确初始化
s3_client(修复代码已补充boto3.client('s3')的初始化逻辑)。 - 建议添加空值判断:如果
s3_client.list_objects_v2返回的Contents为空,max函数会报错,可提前处理这种边界情况。
内容的提问来源于stack exchange,提问作者DevAra
相关产品推荐
相关产品推荐

