0

I'm trying to add background tasks to my middleware, but haven't found any official way to do it in their docs, this is what I have tried so far:

async def task1():
    logging.info("Waiting ...")
    time.sleep(5)
    logging.info("Waited.")

@app.middleware("http")
async def add_process_time_header(request, call_next, bt=Depends(BackgroundTasks)):
    a = bt.dependency()
    a.add_task(task1)
    a()

    return await call_next(request)

This is blocking my requests, also shouldn't I be able to call async functions without await? I want to completely ignore the results of the background tasks, I dont need results from bg tasks

redigaffi
  • 349
  • 3
  • 17

2 Answers2

1

I found some way to solve your problem, i think you can find better way,but for now you can use like this:

import logging
import time
import asyncio
from fastapi import FastAPI, Request

app = FastAPI()
@app.get("/")
async def call_api():
    await asyncio.sleep(5)
    return True

async def task1():
    logging.info("Waiting ...")
    await asyncio.sleep(5)
    logging.info("Waited.")

@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    start_time = time.time()

    response , res__task1 = await asyncio.gather(*[call_next(request),task1()])
    process_time = time.time() - start_time
    response.headers["X-Process-Time"] = str(process_time)
    print(process_time)

    return response

A total of 5 seconds are spent on all tasks

milad_vayani
  • 254
  • 3
  • 12
  • 1
    The github link you sent previously did the job: github.com/tiangolo/fastapi/issues/2215#issuecomment-931411005 – redigaffi May 25 '22 at 08:59
0

You are using a blocking function for your background task.

time.sleep(5)

Eventhough you are using an async fuction, it doesn't contain any non-blocking i/o. So in effect, it cannot be executed asynchronously.

You should use the following sleep function for a non-blocking timeout.

import asyncio
   await asyncio.sleep(5)

In this way, your sleepwill not block requests being processed. Read more here:Python 3.7 - asyncio.sleep() and time.sleep()

John S John
  • 202
  • 2
  • 8
  • According to this video, my code should work fine https://www.youtube.com/watch?v=_yXOJvr5vOM only difference is he is using a controller instead of a middleware. The problem here is injecting the BackgroundTask service to my middleware afaik – redigaffi May 25 '22 at 06:45
  • did you try asyncio sleep? Also what is the the uvicorn command that you use to run the server? If you are running single threaded uvicorn server, I don't see how your code can work with blocking operation. – John S John May 25 '22 at 09:26
  • I managed to get it to work with github.com/tiangolo/fastapi/issues/2215#issuecomment-931411005 also uvicorn running with 1 worker – redigaffi May 25 '22 at 09:51
  • I see that you still have use asyncio.sleep() as I suggested. Good that it's working. – John S John May 25 '22 at 11:14
  • I dont need to use async.sleep, I can use a normal sleep and it works as expected, but thanks for the help – redigaffi May 25 '22 at 11:25