Victoree's Blog

[6] Middleware, Background Tasks, Sub Application in Fast API 본문

Python/Fast API

[6] Middleware, Background Tasks, Sub Application in Fast API

victoree 2021. 7. 30. 15:43
728x90

1. Middleware란

1) 미들웨어란?

미들웨어란 특정 path에 따른 모든 요청/응답을 처리하기 전에 수행할 함수이다.

  • 앱에 오는 요청을 받고, 작업을 수행하거나 필요한 코드를 수행함
  • 어플리케이션에는 나머지 부분에서 처리할 요청을 전달함
  • 어플리케이션에서 생성한 응답을 가져와, 작업을 수행하거나 필요한 코드를 실행하고 응답을 반환함

미들웨어 예시

import time

from fastapi import FastAPI, Request

app = FastAPI()

@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    start_time = time.time()
    response = await call_next(request)
    process_time = time.time() - start_time
    response.headers["X-Process-Time"] = str(process_time)
    return response

2) Middleware 추가하기

Fast API 내에선 아래와 같이 add_middleware라는 함수를 통해 미들웨어를 쉽게 추가할 수 있다.

from fastapi import FastAPI
from unicorn import UnicornMiddleware

app = FastAPI()

app.add_middleware(UnicornMiddleware, some_config="rainbow")

3) 기타 Middleware

  1. HTTPSRedirectMiddleware
    1. 모든 요청이 https 또는 wss임을 강제하기 위한 미들웨어
    2. from fastapi import FastAPI from fastapi.middleware.httpsredirect import **HTTPSRedirectMiddleware** app = FastAPI() app.add_middleware(**HTTPSRedirectMiddleware**)
  2. TrustedHostMiddleware
    1. 모든 요청이 Host 헤더가 적절하게 세팅되었는지 강제하기 위한 미들웨어
    2. HTTP Host Header 공격으로부터 지키기 위함
    3. 요청이 적절하지 않으면, 400 Bad Request 응답을 리턴함
    4. from fastapi import FastAPI from fastapi.middleware.trustedhost import TrustedHostMiddleware app = FastAPI() app.add_middleware( TrustedHostMiddleware, allowed_hosts=["example.com", "*.example.com"] )

2. Background Tasks

클라이언트가 특정 요청에 대해서 작업의 완료를 기다리고 응답을 받는 것이 아니라 요청을 한 이후에 accepted 로 응답을 받고, 나머지 작업을 완료하고 싶을 때 Fast apiBackgroundTasks를 이용하면 된다.

BackgroundTasksstarlette.background를 직접 상속받은 클래스이다.

  • 특정 작업 수행 후 이메일 노티피케이션
  • 데이터 처리
  • 로그를 파일에 남기는 작업
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"}

Caveat

  • 무거운 백그라운드 연산을 돌려야하고, 이를 같은 프로세스에서 수행하지 않아도 된다고 하면, 더 큰 third-party 라이브러리인 celery를 사용하는 것이 좋다.
  • RabbitMQ나 Redis 같은 메세지/잡 큐 매니저나 상세 설정도 지원한다
  • 정리 : 간단한 작은 테스크는 Fast API의 BackgroundsTasks를 사용하고, 무거운 연산의 테스크는 Celery를 사용할 것!

Sub Application

  • 완전히 독립적인 어플리케이션을 특정 경로에 마운트하여 서브 어플리케이션을 등록할 수 있음
from fastapi import FastAPI

app = FastAPI()

@app.get("/app")
def read_main():
    return {"message": "Hello World from main app"}

subapi = FastAPI()

@subapi.get("/sub")
def read_sub():
    return {"message": "Hello World from sub API"}

app.mount("/subapi", subapi)
  • app이라는 루트에 탑 레벨 어플리케이션을 정의
  • /sub 라는 루트에 하위 어플리케이션을 정의
  • 스웨거 상에서 localhost:8000/docs 를 들어가면, 탑 레벨 어플리케이션의 독스를 볼 수 있고, **localhost:8000/sub/docs** 에 들어가면 서브 어플리케이션의 독스를 볼 수 있음
  • API의 버전관리 할때 용이할까?
728x90

'Python > Fast API' 카테고리의 다른 글

[5] Dependency Injection이란? in Fast API  (0) 2021.07.22
[4] Pydantic Model  (0) 2021.07.22
[3] Fast API Basic - Response 편  (0) 2021.07.20
[2] Fast API Basic - Request 편  (2) 2021.07.20
[1] Fast API로 한걸음!  (0) 2021.07.19
Comments