File size: 2,423 Bytes
a66365f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
"""Stream authenticated storage video ranges without downloading the full file first."""

import httpx
from fastapi import HTTPException, Request
from huggingface_hub import hf_hub_url
from starlette.background import BackgroundTask
from starlette.responses import Response, StreamingResponse


async def video_response(request: Request, repo_id: str, path: str, token: str):
    # Browser cookies and user headers never go to the storage service.
    headers = {"Authorization": f"Bearer {token}", "Accept-Encoding": "identity"}
    for name in ("range", "if-range"):
        if request.headers.get(name):
            headers[name] = request.headers[name]
    client = httpx.AsyncClient(follow_redirects=True, timeout=httpx.Timeout(60, connect=15))
    try:
        upstream = await client.send(client.build_request(
            request.method, hf_hub_url(repo_id, path, repo_type="dataset"), headers=headers), stream=True)
    except httpx.HTTPError:
        await client.aclose()
        raise HTTPException(502, "Video storage is temporarily unavailable") from None

    async def close():
        try:
            await upstream.aclose()
        finally:
            await client.aclose()

    if upstream.status_code not in (200, 206, 416):
        await close()
        raise HTTPException(404 if upstream.status_code == 404 else 502,
                            "Video not found" if upstream.status_code == 404 else "Video storage is temporarily unavailable")
    response_headers = {name: upstream.headers[name] for name in (
        "content-type", "content-length", "content-range", "accept-ranges", "etag", "last-modified"
    ) if name in upstream.headers}
    response_headers["Cache-Control"] = "private, no-store"
    if request.method == "HEAD" or upstream.status_code == 416:
        await close()
        # A 416 may have a storage error body: don't forward its body length with an empty response.
        if upstream.status_code == 416:
            response_headers.pop("content-length", None)
        return Response(status_code=upstream.status_code, headers=response_headers)

    async def chunks():
        try:
            async for chunk in upstream.aiter_raw():
                yield chunk
        finally:
            await close()

    return StreamingResponse(chunks(), status_code=upstream.status_code, headers=response_headers,
                             background=BackgroundTask(close))