How to send a response only after all background tasks are completed in FastAPI

Using python 3x on a Mac. I have a FastAPI server with one endpoint. In this endpoint, I want to be able to run some background tasks. After they are completed, make some computation and only then sends an HTTP response.

What I have is the following:

import asyncio

import uvicorn
from fastapi import BackgroundTasks, FastAPI

app = FastAPI()


async def log(message: str):
    print(f"start to process message: {message}")
    if message == "aaaaa":
        await asyncio.sleep(10)
    else:
        await asyncio.sleep(3)
    print(f"processed {message}")


async def process():
    tasks = [log('aaaaa'),
             log('bbbbb')]
    print("start processing the tasks")
    await asyncio.gather(*tasks)
    print(" we are done with all the tasks")


@app.post("/upload-to-process")
async def upload(background_tasks: BackgroundTasks):
    background_tasks.add_task(process)

    return {"result": "all tasks are completed successfully successfully"}


if __name__ == "__main__":
    uvicorn.run(app, host="localhost", port=8001)

what the above does is send the result immediately and not wait for the tasks to be complete.

How do I change the above code to wait till all of the backgrounds are completed and only then send the response back?


It doesn't really make sense to wait for background tasks, as they are ran by definition on the background.

If what you want is to run the function that run those tasks synchronously, i.e. not in the background, you can do this:

@app.post("/upload-to-process")
async def upload(background_tasks: BackgroundTasks):
    await process()
    return {"result": "all tasks are completed successfully successfully"}

Note, however, that if those tasks take too long (this depends on your server configuration request time limits, which usually vary between 30 seconds and 15 min), the request will time out.