在streamresponse中使用aiohttp的MultipartWriter

2024-10-05 11:44:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试创建一个数据端点,它可以流式传输整个文件,也可以适当地响应范围请求。流式传输整个文件似乎可以理解,但我不清楚如何处理范围请求。特别是,我看不到aiohttp.MultipartWriter如何写入StreamResponse。在

到目前为止,以下是我代码的抽象形式:

from aiohttp.web import Request, StreamResponse
from aiohttp.multipart import MultipartWriter

async def data_handler(req:Request) -> StreamResponse:
    is_range_request = "Range" in req.headers

    with open("my_big_file", "rb") as f:
        if is_range_request:
            status_code = 202
            content_type = "multipart/bytes"
        else:
            status_code = 200
            content_type = "application/octet-stream"

        resp = SteamResponse(status=status_code, headers={"Content-Type": content_type})
        resp.enable_chunked_encoding()
        resp.enable_compression()

        await resp.prepare(req)

        if is_range_request:
            # _parse_range_header :: str -> List[ByteRange]
            # ByteRange = Tuple[int, int]  i.e., "from" and "to", inclusive
            ranges = _parse_range_header(req.headers["Range"])

            mpwriter = MultipartWriter("bytes")

            for r in ranges:
                range_from, range_to = r
                range_size = (range_to - range_from) + 1
                range_header = {"Content-Type": "application/octet-stream"}

                # FIXME Won't this block?
                f.seek(range_from)
                mpwriter.append(f.read(range_size), range_header)

            # TODO Write to response. How?...

        else:
            while True:
                data = f.read(8192)
                if not data:
                    await resp.drain()
                    break

                 resp.write(data)

    return resp

这也不会返回响应,直到它到达最后。在我看来,这似乎不正确:在返回响应之前,上游调用如何知道发生了什么;或者asyncio的东西是自动为我做这件事的?在


Tags: tofromdataifaiohttpisrequeststatus

热门问题