我正在尝试使用boto3从S3下载2个文件,等到下载2个文件后,将继续处理2个文件
我做了什么
async def download_files():
await client.download_file(const.bucket_name, 'file/name.txt', '/tmp/name.txt')
print('file 1 downloaded')
await client.download_file(const.bucket_name, 'file/class.txt', '/tmp/class.txt')
print('file 2 downloaded')
return True
def main():
...
loop = asyncio.get_event_loop()
loop.run_until_complete(download_files())
loop.close()
...
main()
我收到一个错误
A Future or coroutine is required
这是我第一次使用asyncio
,请告诉我。
答案 0 :(得分:1)
boto3不支持异步...它的功能正在阻塞,而不是可以等待。因此,这里要做的绝对最低限度就是从对await
的调用中删除download_file
,它应该可以工作。
client.download_file(const.bucket_name, 'file/name.txt', '/tmp/name.txt')
print('file 1 downloaded')
client.download_file(const.bucket_name, 'file/class.txt', '/tmp/class.txt')
print('file 2 downloaded')
return True
但是,如果线程的事件循环中有任何其他并发任务,则这将具有较差的并发属性:它们将被阻塞并且在下载期间不会继续进行[这将使asyncio的使用变得不必要。 ..并发任务的进行有点异步...]
要获得更好的并发属性,您应该能够通过run_in_executor
调用这些函数,默认情况下,它们将在另一个线程中运行传递的函数。
async def download_files(loop):
await loop.run_in_executor(None, client.download_file, const.bucket_name, 'file/name.txt', '/tmp/name.txt')
print('file 1 downloaded')
await loop.run_in_executor(None, client.download_file, const.bucket_name, 'file/class.txt', '/tmp/class.txt')
print('file 2 downloaded')
return True
或者,您可以使用aiohttp和roll-you-own AWS authentication(而不是使用boto3和线程)(完整披露:我编写滚动式AWS认证的帖子)
答案 1 :(得分:0)
查看aioboto3。另外,对于更底层的内容,请查看aiobotocore。两者都可以通过pip获得