FastAPI 보일러플레이트 소개

Key Kim
Neuralworks
Published in
6 min readMar 6, 2021

뉴럴웍스에선 MLOps 를 위한 API 서비스들을 FastAPI 로 개발하고 있습니다.

이번 포스팅에서는 pytest, github actions 등을 포함한 FastAPI 보일러 플레이트에 대해 소개합니다.

환경 소개

python3.9 를 사용하고, flake8, black formatter를 지원합니다.

pipenv를 이용해 python package를 관리합니다.

포스팅에서 다루는 소스코드는 아래에 올라와있습니다.

폴더별 설명은 아래와 같습니다.

  1. src : 소스파일의 최상위 디렉토리
  2. src/app.py : 각 서비스들을 최초 실행하는 main 함수
  3. decorator : 데코레이터 함수들을 모아둔 폴더
  4. database : redis, mongo 에 접속할 수 있는 클래스
  5. dtos : 입력/출력을 위한 데이터 클래스
  6. models : 데이터베이스에 접근하기 위한 데이터 모델들
  7. repo : 데이터베이스 접근을 위한 wrapper 함수들의 모음 (repository)
  8. router : api 엔드포인트를 정의해둔 폴더 (controller)
  9. services : 기능별 서비스들을 모아둔 폴더 (service)
  10. test : 유닛테스트들을 모아둔 폴더

설치 & 실행

python 3.9 가상환경 생성

pipenv --python 3.9

가상환경 실행

pipenv shell

패키지 설치

pipenv sync

실행

DOT_ENV=development pipenv run start

DOT_ENV 는 env 파일의 이름입니다.

만약 .test.env 파일에 설정 정보들이 있다면

DOT_ENV=test pipenv run start

를 입력하여 실행합니다.

지원 기능

1. Lint & formatter

flake8과 black을 사용합니다.

.pre-commit-config, .flake8 파일을 참조하여 commit 이전에 문법 오류 및 flake8 규칙에 맞지 않는 코드를 탐지할 수 있습니다.

2. Redis & mongodb

aioredis, motor 라이브러리를 통해 redis, mongo 에 접속할 수 있습니다.

로컬 개발환경에선

 docker-compose up 

명령어를 통해 redis, mongo 서비스를 실행시켜 테스트할 수 있습니다.

3. OpenAPI

FastAPI 에서 기본적으로 제공해주는 기능입니다.

엔드포인트의 출력 데이터 양식을 지정하려면 아래와 같이 코드를 작성합니다.

먼저 리턴될 데이터 양식을 가지는 Dto 클래스를 생성합니다.

작성한 클래스는

id, createdAt, ip, alive, service_name, optional_field 를 최종 필드로 가지게 됩니다.

이제 방금 만든 클래스를 라우터 model에 넣어줍니다.

그러면 아래와 같이 swagger가 생성됩니다.

만약 카멜케이스로 데이터를 리턴해야한다면 BaseDtoMixin에

config 클래스를 추가해줍니다.

4. 테스트

pytest를 사용하고, monkeypatch를 이용해 mocking 합니다.

monkeypatch 에서 지원하는 함수 리스트

health_check 함수를 테스트한다고 생각 해봅시다.

health_check 함수는 몽고디비에 접근하는 find_one, insert_one 함수를 사용합니다.

유닛테스트를 작성할 때는 외부 컴포넌트와의 의존성을 제거하여 순수한 로직만이 테스트 되도록 해야합니다.

insert_one의 예상 기능을 mock_insert_one 함수에 작성하고,

monkeypatch.setattr 를 사용해 health_check 함수 실행과정에서 insert_onemock_insert_one으로 바꿔치기하여 의존성을 제거합니다.

5. Github actions

코드가 변경될 때 마다 수동으로 테스트, 배포하는건 귀찮은 일입니다.

반복되고 귀찮은 작업을 github actions 으로 해결해봅시다.

아래 스크립트를 통해서 프로젝트 빌드 및 테스트를 해봅시다.

git push origin main 을 입력하여 메인 브랜치로 커밋을 올립니다.

CI 가 정상적으로 동작하는걸 확인할 수 있습니다 :)

--

--