0

I have the following code which streams a video file from disk. [Test the code with the python asyncio module in the terminal] python -m asyncio

from starlette.applications import Starlette
from starlette.responses import StreamingResponse
from starlette.routing import Route
import uvicorn
import random
import asyncio

video = open("C:\\Users\\USERNAME\\Downloads\\Big Buck Bunny\\Big Buck Bunny.mp4", 'rb')
async def stream_generator():
    while True:
        yield video.read(16384)

async def homepage(request):
    return StreamingResponse(stream_generator(), media_type='video/mp4')

app = Starlette(debug=True, routes=[
    Route('/', homepage),
])


if __name__ == "__main__":
    config = uvicorn.Config(app)
    server = uvicorn.Server(config)
    await server.serve()

The problem arises when I need to use asyncio.sleep() statements in the stream_generator function. Currently I use asyncio.sleep() as an async no_op function. However, for some reason, the asyncio.sleep statements get cancelled when running with uvicorn and starlette.

I am not sure what's causing this but I am positive that this is happening because of either uvicorn or starlette because my app works when I simply print the bytes yielded by stream_generator.

The following code uses asyncio.sleep() in the stream_generator. Notice how it fails to stream the video to the web browser while continuously catching asyncio.CancelledError:

video = open("C:\\Users\\USERNAME\\Downloads\\Big Buck Bunny\\Big Buck Bunny.mp4", 'rb')
async def stream_generator():
    while True:
        try:
            if random.random() * 100 > 99:
                await asyncio.sleep(4)
        except asyncio.CancelledError:
            print("Caught the Culpritttttttttttttttttttttttttttt")
        yield video.read(16384)

async def homepage(request):
    # return JSONResponse({'1': '1'}
    return StreamingResponse(stream_generator(), media_type='video/mp4')


app = Starlette(debug=True, routes=[
    Route('/', homepage),
])

Can someone explain why asyncio.sleep() gets cancelled when used with uvicorn and starlette?

Chris
  • 18,724
  • 6
  • 46
  • 80
Shakir
  • 270
  • 2
  • 11

0 Answers0