Asyncio running multiple asynconrous functions at once with uvicorn and fastapi

Question:

I’m having some problems with running my own async functions with uvicorn (fastapi)

My goal is to be able to run the queue manager function, as well as the uvicorn webapp. However, it seems that my start function blocks the uvicorn.run code from running.


async def queue_manager(self):
        while True:
            job = await self.queue.get()
            print(job)
            await asyncio.sleep(2)

async def start():
    task1 = asyncio.create_task(queue_manager())
    await asyncio.gather(task1)

app = FastAPI()
app.include_router(server.router)

if __name__ == "__main__":
    asyncio.run(start())
    uvicorn.run("main:app", host="0.0.0.0", port=5959)

In order to fix this I attempted to run uvicorn.run inside of my start function, however this results in the following error:

line 35, in <module>
    asyncio.run(start())
line 17, in start
    await uvicorn.run("main:app", host="0.0.0.0", port=5959)
RuntimeError: asyncio.run() cannot be called from a running event loop
async def start():
    task1 = asyncio.create_task(custom_instance_manager.queue_manager())
    task2 = asyncio.create_task(uvicorn.run(
        "main:app", host="0.0.0.0", port=5959))
    await asyncio.gather(task1, task2)

if __name__ == "__main__":
    asyncio.run(start())
Asked By: jaal kamza

||

Answers:

You could use startup event.

async def queue_manager(self):
        while True:
            job = await self.queue.get()
            print(job)
            await asyncio.sleep(2)


app = FastAPI()
app.include_router(server.router)

@app.on_event('startup')
async def start():
    asyncio.create_task(queue_manager())

if __name__ == "__main__":
    uvicorn.run("main:app", host="0.0.0.0", port=5959)
Answered By: kosciej16

Instead of using uvicorn.run you can use uvicorn server async func with fast api config

async def run_server():
    api = configure_fastapi()
    config = uvicorn.Config(api, port=8021, host='0.0.0.0')
    server = uvicorn.Server(config)
    await server.serve()
Answered By: Raza Ashfaq Mirza