ML/AI/SW Developer

FastAPI - FastAPI 심화

0. 강의 소개

이번 강의에서는 백엔드 프로그래밍에 사용되는 Fast API에 대해 다룰 예정입니다.

1. FastAPI 익숙해지기

1.1 Event Handler

  • 이벤트가 발생했을 때, 처리!
  • FastAPI에선 App 실행 및 종료시 특정 함수 실행 가능

      @app.on_event("startup")
    
      @app.on_event("shutdown")
    

1.2 API Router

  • API Router는 더 큰 애플리케이션들에서 많이 사용되는 기능
  • API Endpoint를 정의
  • Python Subpackage
  • APIRouter는 Mini FastAPI로 여러 API를 연결해서 활용
  • 기존에 사용하던 @app.get, @app.post을 사용하지 않고, router 파일을 따로 설정하고 app에 import해서 사용

      from fastapi import FastAPI, APIRouter
      import uvicorn
    
      user_router = APIRouter(prefix="/users")
      order_router = APIRouter(prefix="/orders")
    
      @user_router.get("/", tags=["users"])
      def read_users():
          return [{"username": "Rick"}, {"username": "Morty"}]
    
      @user_router.get("/{username}", tags=["users"])
      def read_user(username: str):
          return {"username": username}
    
      @order_router.get("/", tags=["orders"])
      def read_orders():
          return [{"order": "Taco"}, {"order": "Burritto"}]
    
      @order_router.get("/me", tags=["orders"])
      def read_order_me():
          return {"my_order": "taco"}
    
      app = FastAPI()
    
      if __name__ == '__main__':
          app.include_router(user_router)
          app.include_router(order_router)
          uvicorn.run(app, host="0.0.0.0", port=8000)
    
    • 예제 프로젝트 구조

1.3 Error Handling

  • 웹 서버를 안정적으로 운영하기 위해 반드시 필요!!
  • 어떤 Error가 발생 했는지, 클라이언트에게 해당 정보를 전달해줄 수 있어야 함
    • 서버 개발자는 log로 error 수집!!
    • 예외처리를 잘 만들자!
    • 에러 핸들링을 더 잘 하려면 에러 메시지와 에러의 이유 등을 클라이언트에 전달하도록 코드를 작성해야 함
  • FastAPI의 HTTPException은 Error Response를 더 쉽게 보낼 수 있도록 하는 Class

      from fastapi import FastAPI, HTTPException
      import uvicorn
    
      app = FastAPI()
    
      items = {
          1: "Boostcamp",
          2: "AI",
          3: "Tech"
      }
    
      @app.get("/v1/{item_id}")
      async def find_by_id(item_id: int):
          return items[item_id]
    
      @app.get("/v2/{item_id}")
      async def find_by_id(item_id: int):
          try:
              item = items[item_id]
          # 더 자세한 오류를 피드백!
          except KeyError:
              raise HTTPException(status_code=404, detail=f"아이템을 찾을 수 없습니다 [id: {item_id}]")
          return item
    
      if __name__ == '__main__':
          uvicorn.run(app, host="0.0.0.0", port=8000)
    

1.4 Background Task

  • FastAPI는 Starlett이라는 비동기 프레임워크를 래핑해서 사용
  • Background Tasks 기능은 오래 걸리는 작업들을 background에서 실행
    • Online Serving에서 CPU 사용이 많은 작업들을 Background Task로 사용하면,
    • 클라이언트는 작업 완료를 기다리지 않고 즉시 Response를 받아볼 수 있음
    • 특정 작업 후, 이메일 전송하는 Task 등
    • 작업 결과물을 조회할 때는 Task를 어딘가에 저장해두고, GET 요청을 통해 Task가 완료됐는지 확인

2. FastAPI가 어렵다면

2.1 프로젝트 구조 - Cookiecutter

  • 처음 백엔드 프로그래밍을 할 때 어려웠음 - 왜 어려울까?
    • 1) 프로젝트 구조를 어떻게 잡아야 할지 모르겠다
    • 2) 객체 지향이 낯설다
    • 3) 백엔드 프로그래밍 자체가 처음
    • 4) 목표의 부재
  • 쿠키를 만들 때 사용하는 Cookiecutter
    • 많은 사람들이 프로젝트 구조에 대한 고민을 공유
    • CLI 형태로 프로젝트 생성 과정을 도와줌
    • 회사에서 공통의 프로젝트 구조가 필요하면 쿠키 커터로 설정
    • 개인용 쿠키 커터 템플릿을 만드는 것도 좋은 방법

2.2 객체 지향

  • 절차형 프로그래밍 vs 객체 지향 프로그래밍의 차이
    • 객체 지향 프로그래밍은 코드의 중복을 최소화해서 재사용성을 증가시킴
    • 복잡한 로직이 들어갈수록 점점 빛을 발휘함
    • To Do
      • 현재 가지고 있는 코드를 Class로 변경해보기
      • Pydantic Use Case 탐색하기

2.3 Try & Error

  • 백엔드 프로그래밍이 처음이면 낯선 것이 당연
  • 코드를 작성하고 => 실행하고 => 수정하는 Flow
  • 조급해하지 않고 작은 규모의 프로젝트부터 하나씩 만들기
    • 목표를 설정하고(무엇을 만들겠다) => 기능을 정의 => 하나씩 구현
    • 막연히 FastAPI를 학습해야지보다는 프로젝트를 FastAPI 백엔드로 구현! 등으로 목표 설정

Reference

  • AI boot camp 2기 서빙 강의