class AsyncFileASGIHandler[source]

AsyncFileASGIHandler() :: ASGIHandler

Same as default ASGIHandler from Django if there's no is_async_fileresponse attribute. If set to true, AsyncFileASGIHandler delegates the streaming of the actual response to the response to allow for statements like:

async with aiofiles.open(path):
        ...

or

async with minio_response["Body"] as stream:
        ...

Tests

class Response:
    cookies = {}
    streaming = True
    status_code = 200
    stream_called = False

    def __init__(self, content, is_async_fileresponse=None):
        self.index = -1
        self.contents = [content]
        if is_async_fileresponse is not None:
            self.is_async_fileresponse = is_async_fileresponse

    async def stream(self, send):
        self.stream_called = True
        for content in self.contents:
            await send(content)

    def __iter__(self):
        return self

    def __next__(self):
        self.index += 1
        try:
            return self.contents[self.index]
        except IndexError:
            raise StopIteration

    def items(self):
        return []

    def close(self):
        pass


def get_send(received):
    async def send(data):
        received.append(data)

    return send

Happy Path

app = AsyncFileASGIHandler()
content = "<h1>Content!</h1>"
response = Response(content, is_async_fileresponse=True)
received = []
send = get_send(received)
await app.send_response(response, send)
returned_content = received[0]
assert response.stream_called
assert content == returned_content

Response Without is_async_fileresponse attribute

app = AsyncFileASGIHandler()
content = "<h1>Content!</h1>"
response = Response(content)
received = []
send = get_send(received)
await app.send_response(response, send)
returned_content = received[1]["body"]
assert not response.stream_called
assert content == returned_content