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

时间:2016-10-23 13:46:30

标签: python amazon-s3 aiohttp botocore

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

  • 我不想将整个文件内容存储在内存中,
  • 我希望能够在从S3下载文件时处理其他请求(aiobotocore,aiohttp),
  • 我希望能够对我下载的文件进行修改,因此我希望逐行处理并将响应流式传输到客户端

现在,我在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()返回一个带有Body(ClientResponseContentProxy对象)的dict。使用read()方法,我如何获得预期响应的一大块并将其流式传输到客户端?

当我这样做时:

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

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

但是当我这样做时:

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

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

由于

1 个答案:

答案 0 :(得分:2)

它是因为onProgressUpdate() api与aiobotocore不同,此处botocore返回read()生成器,您需要从中生成< / p>

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

FlowControlStreamReader.read

实际上,在您的情况下,您甚至可以使用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()

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