[FastAPI] 5. pyyaml을 이용한 FastAPI 환경 나누기

반응형

FastAPI로 기본적인 API와 문서를 만드는 작업 그리고 데이터베이스를 연동하는 것까지 해봤다면 이제는 본격적인 애플리케이션 배포를 위해 환경을 나누어야 합니다.

 

여기서 환경이라는 것은 무엇일까요? 개발 환경? 개발 환경이라면 우리는 PyCharm을 사용하고 Python을 설치했고 이미 다 작업한 것이 아닌가요?

 

2021/01/16 - [Programming/Python] - [FastAPI] 4. SQLAlchemy + Alembic 조합을 이용한 Database Migration 가이드

 

[FastAPI] 4. SQLAlchemy + Alembic 조합을 이용한 Database Migration 가이드

웹 서비스를 개발하고 배포한 뒤에 반드시 한 번 쯤 따르는 업데이트 사항이 바로 데이터베이스 마이그레이션입니다. 데이터베이스를 마이그레이션하는 경우는 보통 아래의 3가지가 대표적입

blog.neonkid.xyz

우리는 지난 포스트에서 데이터베이스 마이그레이션을 다루었고, 환경이 나누어진 상태에서 데이터베이스의 마이그레이션을 어떻게 효율적으로 할 수 있는지에 대해 알아봤습니다.

 

이런 환경을 나눠야하는 이유는 서비스가 운영되어 있는 곳에서 새로운 기능을 테스트하거나 버그 패치 등의 작업을 할 수 없기 때문입니다. 이미 운영 중인 서비스에서 코드를 고치고 배포하면 실제 서비스하는 곳에 영향을 받으면서 사용자들의 불편함이 가중되거나 또 다른 장애로 이뤄질 수도 있기 때문에 환경을 나누는 것이죠.

 

 

 

 

YAML

스프링을 다룬 저의 입장에서 YAML은 아주 익숙하다고 할 수 있습니다. Spring boot를 사용하는 경우 기본적으로 환경 설정을 properties로 작업하게 되지만 그와 비슷하게 YAML 파일로도 쉽게 변경할 수 있기 때문이죠.

 

FastAPI 또한 마찬가지로 파이썬 코드를 이용해서 서로의 환경 코드를 분리할 수 있지만 pyyaml 패키지를 이용하면 YAML 파일을 이용하여 환경 설정을 나눌 수 있습니다. 다만 공교롭게도 모든 환경 설정은 Spring boot처럼 라이브러리나 프레임워크에서 제공해주는 것은 거의 없고 대부분 만들어 써야한다는 것입니다.

 

YAML은 이렇게 KEY-VALUE 형태로 제공하는 파일의 구조를 가지고 있으면서 동시에 배열, 문자열, 숫자형 등의 자료형을 사용하여 파일을 구성하는 포맷입니다.

 

 

 

 

 

PyYAML

Python에서는 YAML 파일을 읽을 수 있는 파싱 라이브러리인 pyyaml을 제공합니다. 내가 직접 YAML 파일을 작성해서 설정 파일을 구성하고 이를 Python에서 변수로 부를 수 있습니다.

 

간단한 사용법에 대해 알아보도록 하죠.

$ poetry add pyyaml

디펜던시 매니저를 통해 pyyaml을 추가/설치합니다.

 

그러고 나면 import yaml 코드를 사용할 수 있게 됩니다. pyyaml을 설치한 뒤 yaml을 import하여 사용할 수 있습니다.

 

yaml에서 load 함수를 사용하여 파일을 읽어들일 수 있지만 safe_load 함수를 사용한 이유는 만약 파일이 존재하지 않는 등의 문제가 발생하면 Exception이 발생하지 않고, None을 반환시키도록 하기 위함입니다. 물론 애플리케이션 개발을 어떻게 하냐에 따라서 어떤 함수를 사용할지는 여러분들이 결정하시면 됩니다.

 

또한 모든 Config는 파일 외에서 정적으로 수정하는 것 외에 파이썬 코드에서 변수를 임의로 고치지 않도록 open 함수의 두 번째 인자에 read only 옵션인 'r'을 넣어주도록 합시다.

 

불러진 파일은 dict 형태로 불러들이게 되며 'conf['${key_name}']' 으로 받을 수 있습니다.

 

 

 

 

Dev, Prod, Test 환경 나누기

우리가 위에서 작성한 pyyaml 코드를 토대로 OS 환경 변수를 겸하여 애플리케이션의 환경을 나누어보도록 하겠습니다. 먼저 위에서 작성한 코드를 일부 수정해보도록 하죠.

 

Python에서 제공하는 os 코드를 사용하여 환경 변수에 접근하는 함수를 이용해보도록 하겠습니다. OS 환경 변수에서 APP_ENV에 prod, dev, test를 붙여주는 것으로 하여금 환경을 다르게 실행하는 것으로 구현해줍니다.

 

이를 토대로 YAML 파일 역시 메인 KEY에 각 환경에 해당하는 이름을 붙여주고 설정합니다. 이렇게 하면 OS 환경 변수의 변동에 따라 DB 접속 주소 등의 변수가 바뀌게 됩니다.

 

 

 

 

Test

그러면 위 코드가 잘 동작되고 있는지를 확인해보도록 하겠습니다.

 

main.py에 간단하게 print 문을 사용하여 어떻게 불러오고 있는지를 확인해보도록 하겠습니다.

 

기본적으로 환경 변수가 설정되어 있지 않은 경우 'dev'로 불러오도록 설정되었기 때문에 dev 환경의 설정 값이 출력되고 있음을 확인할 수 있습니다.

$ export APP_ENV=prod

보통 export 명령어를 이용하여 환경 변수를 설정할 수 있지만...

 

PyCharm을 이용하고 있다면 Run Edit Configurations에서 환경 변수를 설정해야합니다. 위와 같이 환경 변수를 prod로 변경하게 되면...

 

위와 같이 다른 변수명이 불러지는 것을 볼 수 있습니다. 

 

이와 같은 방법으로 각 코드에서 역할에 맞는 변수를 설정하고, 이를 파라미터에 설정하면 환경 변수에 따라 다르게 설정할 수 있습니다. 이런 방법은 CI/CD 통합 작업에 여러모로 유용하게 사용할 수 있겠군요.

 

 

 

 

 

마치며...

Pure Python 코드만을 이용해서도 Config 파일을 작성할 수 있지만 Spring에서 사용했던 application.yml 파일의 설정 방법이 워낙 익숙하다보니 FastAPI에서도 이러한 방법을 채택하게 되었습니다.

 

하지만 이 방법에도 단점이 존재합니다. 실 서비스로 운영하고 있는 애플리케이션이라면 DB와 같은 미들웨어의 정보 누출에 굉장히 민감하게 작용될 수 있습니다. 물론 Git과 같은 형상 관리 시스템을 Private 모드로 사용한다면 큰 문제가 되지 않겠지만 외부에 반출되는 소스 코드의 경우 이러한 방법은 권장하지 않습니다. 패스워드 등을 평문 그대로 설정해서 들어가기 때문에 소프트웨어의 소스 코드를 반출하는 목적과 더불어 인프라의 정보를 유출하는 사고를 일으킬 수 있기 때문입니다.

 

별도의 미들웨어 설정을 개별적으로 운영자에게 위임하고자 한다면 YAML 파일이 아닌 Python 코드에서 직접 os 함수를 이용해 환경 변수로 설정할 수 있도록 유도하는 것을 권장합니다. 이렇게 하면 컨테이너 기반의 운영 시스템에서도 직접 환경 변수를 셋팅하여 그에 맞게 설정할 수 있습니다.

 

 

반응형
comments powered by Disqus

Tistory Comments 0