Running function in FastAPI view while returning an HTTP response without waiting for the function to finish

Question:

I have the following code:

from fastapi import FastAPI, Request, Form
import uvicorn
from testphoto.utils.logger import get_log
import datetime
import time
import asyncio

log = get_log()

app = FastAPI()

def process():
    log.info("Sleeping at "+str(datetime.datetime.now()))
    time.sleep(5)
    log.info("Woke up at "+str(datetime.datetime.now()))
    return "Sucess"

@app.post("/api/photos")
async def root(request: Request, photo: str = Form()):
    process()
    return {"message": "Hello World"}

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8008)

What I want to do is to run the function process and return the response while keeping the function process running. I’ve read some documentation about asyncio and FastAPI but I’m still unable to figure this out. Where would you point me to in order make the code do exactly as I want?

Asked By: Samir Ahmane

||

Answers:

What you’re looking for, if not CPU intensive, is called a background task.

You can read more in the docs:

https://fastapi.tiangolo.com/tutorial/background-tasks/

An example from the reference guide on how to use background tasks:

from fastapi import BackgroundTasks, FastAPI

app = FastAPI()


def write_notification(email: str, message=""):
    with open("log.txt", mode="w") as email_file:
        content = f"notification for {email}: {message}"
        email_file.write(content)


@app.post("/send-notification/{email}")
async def send_notification(email: str, background_tasks: BackgroundTasks):
    background_tasks.add_task(write_notification, email, message="some notification")
    return {"message": "Notification sent in the background"}
Answered By: lsabi