aiobotocore-aiohttp - 获取 S3 文件内容并将其流式传输到响应中

aiobotocore-aiohttp - Get S3 file content and stream it in the response

我想使用 botocore 和 aiohttp 服务获取 S3 上上传文件的内容。由于文件可能很大:

现在,我的 aiohttp 处理程序中有以下代码:

import asyncio                                  
import aiobotocore                              

from aiohttp import web                         

@asyncio.coroutine                              
def handle_get_file(loop):                      

    session = aiobotocore.get_session(loop=loop)

    client = session.create_client(             
        service_name="s3",                      
        region_name="",                         
        aws_secret_access_key="",               
        aws_access_key_id="",                   
        endpoint_url="http://s3:5000"           
    )                                           

    response = yield from client.get_object(    
        Bucket="mybucket",                      
        Key="key",                              
    )                                           

每次我从给定文件中读取一行时,我都想发送响应。实际上,get_object() returns 一个内部有 Body(ClientResponseContentProxy 对象)的字典。使用 read() 方法,如何获取预期响应的块并将其流式传输到客户端?

当我这样做时:

for content in response['Body'].read(10):
    print("----")                        
    print(content)          

循环内的代码永远不会执行。

但是当我这样做的时候:

result = yield from response['Body'].read(10)

我在结果中得到了文件的内容。我对如何在这里使用 read() 有点困惑。

谢谢

这是因为 aiobotocore api 与 botocore 不同,这里 read() returns 一个 FlowControlStreamReader.read 生成器你需要 yield from

看起来像那样(取自https://github.com/aio-libs/aiobotocore/pull/19

resp = yield from s3.get_object(Bucket='mybucket', Key='k')
stream = resp['Body']
try:
    chunk = yield from stream.read(10)
    while len(chunk) > 0:
      ...
      chunk = yield from stream.read(10)
finally:
  stream.close()

实际上在你的情况下你甚至可以使用 readline()

https://github.com/KeepSafe/aiohttp/blob/c39355bef6c08ded5c80e4b1887e9b922bdda6ef/aiohttp/streams.py#L587