Boto3:需要Future或协程

时间:2019-01-24 14:18:47

标签: python-3.x boto3 python-asyncio

我正在尝试使用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,请告诉我。

2 个答案:

答案 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

或者,您可以使用aiohttproll-you-own AWS authentication(而不是使用boto3和线程)(完整披露:我编写滚动式AWS认证的帖子)

答案 1 :(得分:0)

查看aioboto3。另外,对于更底层的内容,请查看aiobotocore。两者都可以通过pip获得