오늘은 백그라운드 작업에 대해서 끄적여 보겠습니다 !
API에서 단순히 DB에 대한 CRUD 뿐만아니라 메일을 작성한다 던가, 로그를 작성한 다던가 크롤링을 하거나 머신 러닝과 딥러닝등 다양한 작업을 수행 할 때가 있습니다.
이런 경우, 시간이 오래 걸리기 때문에 빠르게 응답을 할 수 가 없습니다. 이때, 사용가능한 가장 쉬운 작업이 백그라운드 작업입니다.
백그라운드 작업을 하기 위해서 멀티프로세싱을 하거나 python에서는 서브 프레세스 모듈을 사용하게 됩니다. 다만, FastAPI에서는 백그라운드 작업을 하기 위해서 BackgroundTasks라는 것을 사용해서 간단하게 구현할 수 있습니다.
백그라운드에 대한 작업을 수행하기 위한 매우 간단 main.py 코드입니다.
import uvicorn
import time
from typing import Optional
from fastapi import BackgroundTasks, FastAPI, status
app = FastAPI()
def write_log(message: str):
time.sleep(2.0)
with open("log.txt", mode="a") as log:
log.write(message)
@app.post("/send-notification/{email}", status_code=status.HTTP_202_ACCEPTED)
async def send_notification(email: str, background_tasks: BackgroundTasks):
message = f"message to {email}\n"
background_tasks.add_task(write_log, message)
return {"message": "Message sent"}
if __name__ == '__main__':
uvicorn.run("main:app", reload = True)
위의 코드를 작성 후 실행해 봅시다.
python main.py
실행 후에 fastapi 문서로 접속해 봅시다.(http://127.0.0.1:8000/docs)
send-notification을 클릭한 후에
try it out을 누른 후에 다음과 email을 입력해 봅시다.
입력후 위에 보이는 Execute를 클릭해서 결과를 보면 다음과 같이 202라는 code가 타다 난 것을 알 수 있습니다.
202라는 코드는 accepted라는 http의 상태를 나태는 코드입니다. 202 코드의 의미는 용청을 받았지만 아직 처리를 하지 않았다는 의미를 가지고 있습니다.
위의 코드를 조금씩 살펴 보겠습니다.
@app.post("/send-notification/{email}", status_code=status.HTTP_202_ACCEPTED)
위의 코드중에 "/send-notification/{email}" 라는 부분은 path parameter에 해당하고, status_code는 202에 해당하는 accepted를 사용한 것을 알 수 있습니다.
async def send_notification(email: str, background_tasks: BackgroundTasks):
message = f"message to {email}\n"
background_tasks.add_task(write_log, message)
return {"message": "Message sent"}
이 함수를 살펴보면, Fastapi에서 백그라운드 작업을 하기해서 BackgroundTasks라는 것을 입력으로 받고 있다는 것을 알 수 있습니다.
BackgroundTasks는 Fastapi를 사용해서 import를 할 수 있습니다. BackgroundTasks에는 add_task라는 것이 있는데 add_task에다가 write_log라는 정의한 함수를 사용하게 해주는 역할을 합니다.
message는 f"message to {email}\n"으로 정의 했고, BackgroundTasks를 처리할 함수로 add_task를 사용해서 write_log라는 함수를 사용했고, write_log를 수행하기 위한 인자의 값으로 message를 주었다고 생각하면 됩니다.
write_log로 정의 된 함수는 다음과 같습니다.
def write_log(message: str):
time.sleep(2.0)
with open("log.txt", mode = "a") as log:
log.write(message)
write_log 함수의 목적은 log를 작성하는 것입니다.
time.sleep을 통해서 2초정도 정지를 하고, log를 작성하도록 만든 함수입니다.
우리가 docs에서 입력과 결과는 2초의 시간이 없이 바로 결과가 나왔는데요 !!
하지만 그것과는 우리가 입력한 내용을 별개로 2초후에 log.txt로 작성이 된다고 생가하시면 됩니다.
fastapi에서 보낸 log가 기록된 txt 파일을 보면 다음과 같습니다.
HTTPie로도 실험을 해볼 수 있는데 다음과 같이 입력을 하면됩니다.
http POST :8000/send-notification/example%40example.com
서버에 요청이 오고 이걸 수행을 할 때, BackgroundTask를 사용해서 간단하게 처리를 할 수 있습니다.
'FastAPI' 카테고리의 다른 글
미들웨어 - 1 (0) | 2024.03.19 |
---|---|
백그라운드 작업 - 2 (0) | 2024.03.13 |
인증 (1) | 2024.02.27 |
의존성 주입 - 2 (0) | 2024.02.18 |
의존성 주입 - 1 (1) | 2024.02.15 |