Skip to content

Close request after consuming all content #643

@rowillia

Description

@rowillia

I'm just getting started with aiohttp, but I'm finding myself frequently wanting to write a function that returns a response generator where I can iterate over it's lines and then it closes itself when all of the data has been read. This way consumers can just deal with async generators without having to leak the response object.

This is what I rolled on my own

import aiohttp
import asyncio

class AutoclosingResponse:
    def __init__(self, response: aiohttp.ClientResponse):
        self.response = response
        self.resolved_response = None
    async def __aiter__(self):
        return self
    @asyncio.coroutine
    def __anext__(self):
        if not self.resolved_response:
            self.resolved_response = yield from self.response
        data = yield from self.resolved_response.content.readline()
        if data:
            return data
        else:
            self.resolved_response.close()
            raise StopAsyncIteration

# Usage
async def print_all_lines(line_cooroutine_generator):
    async for line in line_cooroutine_generator:
        print(line)

def get_python_lines():
    resp = aiohttp.get('http://python.org')
    return AutoclosingResponse(resp)

loop = asyncio.get_event_loop()
loop.run_until_complete(print_all_lines(get_python_lines()))

Is there a better way to do this? If not, would it make sense to the response object?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions