python-3.x - Boto3:需要 Future 或协程
问题描述
我正在尝试使用 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
,求指教。
解决方案
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和滚动您自己的 AWS 身份验证,而不是使用 boto3 和线程(完全披露:关于滚动您自己的 AWS 身份验证的帖子是我写的)
推荐阅读
- r - R STUDIO:我无法读取 .csv 中的 Ü 等特殊字符
- mysql - 用 if else 语句更新 mysqli 中的一行
- python - 将装饰器应用于 Python 类
- html - 我的描述文字没有响应,但输入的文字效果很好
- python - 从包含 self 的不同 Python 文件导入变量
- express - 将nginx与expressJS结合使用时,我应该在express还是nginx中使用压缩?
- c++ - 尝试通过 memcpy 复制大尺寸浮点向量时出现分段错误
- javascript - 如何根据不同变量的属性值对 JSON 数据进行分组?
- laravel - 在 Laravel 中获得雄辩的链接以从 mysql 复制连接
- javascript - 如果从 IBM Domino lotusscript 代理收到的响应文本有一个“€”符号,那么它显示的是€