본문 바로가기

Software Engineering/Python

fastapi background task를 사용하여 지연 동작 수행하기

API 요청을 받고 일정 시간이 지난 뒤에 동작을 수행해야 하는 경우는 아래와 같이 구현 할 수 있다.

from fastapi import FastAPI, BackgroundTasks
import asyncio

app = FastAPI()

async def delay_print(sec: int):
    await asyncio.sleep(sec)
    print("Awaken")

@app.get("/")
async def delay_task(background_task: BackgroundTasks):
    background_task.add_task(delay_print, 5)
    return {"message": "recieved"}

 

위와 같이 작성하면, API는 호출 즉시 응답을 반환하고 실제 작업은 백그라운드에서 지정된 시간 이후에 동작하게 된다.

비동기가 적용되어 동시에 여러 요청이 처리가 되며, 백그라운드 태스크를 사용하여 서버 리소스를 효율적으로 사용할 수 있다.

 

router 내부에서 await asyncio.sleep을 수행하면 사용자는 API 호출에 대한 응답을 바로 받지 못하게 된다.

이를 해결하기 위해 background_task로 등록하여 백그라운드에서 시간을 대기한다.

 

그리고 실제 호출되는 함수 역시 async / await / asyncio 를 사용하여 비동기로 구현하였다. 

 

비동기 핸들러에서 주기적으로 조건을 확인해야하는 경우는 아래 처럼 구현할 수 있다.

from fastapi import FastAPI, BackgroundTasks
import asyncio

app = FastAPI()

async def delay_print(sec: int):
    total_time_sec = 60
    end_time = asyncio.get_event_loop().time() + total_time_sec
    count = 3
    while asyncio.get_event_loop().time() < end_time:
        if count > 0:
            count = count - 1
        else:
            break
        print("10초 대기")
        await asyncio.sleep(10)

    await asyncio.sleep(sec)
    print("Awaken")

@app.get("/")
async def delay_task(background_task: BackgroundTasks):
    background_task.add_task(delay_print, 5)
    return {"message": "recieved"}