FastAPI를 이용한 TDD 개발 - 1

2024. 3. 10. 21:23·프로그래밍 언어/파이썬

프로젝트 구조를 만들어 보겠습니다.

셋업


$ mkdir demo_fastapi_tdd_docker && cd demo_fastapi_tdd_docker

$ mkdir project

$ mkdir app

$ python -m venv venv; source venv/bin/activate; python -m pip install --upgrade pip;



(venv)$ pip install fastapi

(venv)$ pip install uvicorn

main.py, _init_.py 파일을 app 디렉토리에 만들어 줍니다. main 모듈에서 FastAPI의 인스턴스를 생성하고 동기식으로

테스트용 엔드포인트 API를 만들어 보겠습니다.

# project/app/main.py



from fastapi import FastAPI



app = FastAPI()



@app.get("/ping")

def pong():

    return {"ping": "pong!"}

라우트 설정과 서버 가동을 위한 설정은 되었습니다.

그리고 requirements.txt 파일을 만들어 주겠습니다.

$ pip freeze > requirements.txt
❯ tree -L 3 -I "venv"
.
├── app
│   ├── __init__.py
│   └── main.py
└── requirements.txt

2 directories, 3 files

서버 기동을 하겠습니다. project/app 디렉토리에서 아래 명령어를 실행합니다.

❯ uvicorn app.main:app --reload
INFO:     Will watch for changes in these directories: ['/Users/main/Project/testdriven/demo_fastapi_tdd_docker/project']
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [7860] using StatReload
INFO:     Started server process [7900]
INFO:     Waiting for application startup.
INFO:     Application startup complete.

FastAPI 애플리케이션을 찾을 수 있는 위치를 Uvicorn에 알려줍니다.

브라우저에서 http://localhost:8000/ping으로 이동합니다.

 

{"ping": "pong!"

 

Auto-reload

코드 변경 시, 수동으로 서버를 끄고 다시 켜지 않도록 할 수 있습니다. 

(env)$ uvicorn app.main:app --reload

INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [84187]
INFO:     Started server process [84189]
INFO:     Waiting for application startup.
INFO:     Application startup complete.

 

설정

app 패키지에 config.py 모듈을 생성합니다. 각 환경별(개발, 테스트, 운영)로 변수의 값 정의를 다르게 하겠습니다. 

# project/app/config.py


import logging

from pydantic_settings import BaseSettings


log = logging.getLogger("uvicorn")


class Settings(BaseSettings):
    environment: str = "dev"
    testing: bool = bool(0)


def get_settings() -> BaseSettings:
    log.info("Loading config settings from the environment...")
    return Settings()

 

pydantic-settings를 설치 합니다. 

(env)$ pip install pydantic-settings==2.1.0

 

main.py 를 업데이트 합니다. 

# project/app/main.py


from fastapi import FastAPI, Depends

from app.config import get_settings, Settings


app = FastAPI()


@app.get("/ping")
def pong(settings: Settings = Depends(get_settings)):
    return {
        "ping": "pong!",
        "environment": settings.environment,
        "testing": settings.testing
    }

 

이후 다시 ping 엔드포인트로 접근하면 아래와 같은 결과가 나타납니다. 

{
  "ping": "pong!",
  "environment": "dev",
  "testing": false
}

 

이번에는 결과가 다르게 나타나도록 하겠습니다. 

리눅스의 export 명령어로 환경변수의 키와 값을 설정합니다. 

(env)$ export ENVIRONMENT=prod
(env)$ export TESTING=1

다시 서버를 기동하고 해당 엔드포인트로 접근합니다. 

{
  "ping": "pong!",
  "environment": "prod",
  "testing": true
}

 

해당 엔드 포인트로 접근을 여러 차례 시도하면 로그가 여러 차례 출력 되는 걸 볼 수 있습니다. 

Loading config settings from the environment...

 

get_settings 가 여러 차례 보입니다. 해당 모듈을 여러차례 호출한다는 의미입니다. lru_cache를 사용하면 딱! 한번만 호출 할 수 있습니다. 

 

# project/app/config.py


import logging
from functools import lru_cache

from pydantic_settings import BaseSettings


log = logging.getLogger("uvicorn")


class Settings(BaseSettings):
    environment: str = "dev"
    testing: bool = 0


@lru_cache()
def get_settings() -> BaseSettings:
    log.info("Loading config settings from the environment...")
    return Settings()

 

auto-reload 이후 브러우저 새로고침을 여러 차례 해봅니다. 그럼 아래 로그가 딱! 한번 출력 되는 것을 알 수 있습니다.

Loading config settings from the environment...

 

Async Handlers

동기 핸들러를 비동기로 전환해보겠습니다. 

 

쓰레드를 사용하거나 Celery 또는 RabbitMQ의 task queue를 사용하는 번거로움 없이도 FastAPI에서는 이를 가능하게 만들 수 있습니다. async 키워드를 추가하면 Blocking I/O 없이 핸들러를 처리 할 수 있습니다. 

@app.get("/ping")
async def pong(settings: Settings = Depends(get_settings)):
    return {
        "ping": "pong!",
        "environment": settings.environment,
        "testing": settings.testing
    }

 

저작자표시 (새창열림)

'프로그래밍 언어 > 파이썬' 카테고리의 다른 글

FastAPI를 이용한 TDD 개발 - 4  (0) 2024.03.14
FastAPI를 이용한 TDD 개발 - 3  (0) 2024.03.12
FastAPI를 이용한 TDD 개발 - 2  (0) 2024.03.11
FastAPI를 이용한 TDD 개발  (0) 2024.03.10
re 모듈의 sub 메소드 사용법  (0) 2021.11.28
'프로그래밍 언어/파이썬' 카테고리의 다른 글
  • FastAPI를 이용한 TDD 개발 - 3
  • FastAPI를 이용한 TDD 개발 - 2
  • FastAPI를 이용한 TDD 개발
  • re 모듈의 sub 메소드 사용법
hyeseong-dev
hyeseong-dev
안녕하세요. 백엔드 개발자 이혜성입니다.
  • hyeseong-dev
    어제 오늘 그리고 내일
    hyeseong-dev
  • 전체
    오늘
    어제
    • 분류 전체보기 (283)
      • 여러가지 (108)
        • 알고리즘 & 자료구조 (73)
        • 오류 (4)
        • 이것저것 (29)
        • 일기 (1)
      • 프레임워크 (39)
        • 자바 스프링 (39)
        • React Native (0)
      • 프로그래밍 언어 (39)
        • 파이썬 (31)
        • 자바 (3)
        • 스프링부트 (5)
      • 컴퓨터 구조와 운영체제 (3)
      • DB (17)
        • SQL (0)
        • Redis (17)
      • 클라우드 컴퓨팅 (2)
        • 도커 (2)
        • AWS (0)
      • 스케쥴 (65)
        • 세미나 (0)
        • 수료 (0)
        • 스터디 (24)
        • 시험 (41)
      • 트러블슈팅 (1)
      • 자격증 (0)
        • 정보처리기사 (0)
      • 재태크 (0)
        • 암호화폐 (0)
        • 기타 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    OOP
    Spring Boot
    파이썬
    항해99
    AWS
    reactor
    프로그래머스
    EC2
    그리디
    시험
    완전탐색
    mybatis
    docker
    Spring WebFlux
    FastAPI
    자바
    java
    spring
    SAA
    ecs
    Python
    celery
    Redis
    Docker-compose
    WebFlux
    DP
    #개발자포트폴리오 #개발자이력서 #개발자취업 #개발자취준 #코딩테스트 #항해99 #취리코 #취업리부트코스
    RDS
    취업리부트
    백준
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
hyeseong-dev
FastAPI를 이용한 TDD 개발 - 1
상단으로

티스토리툴바