📜 제목으로 보기

환경변수를 사용을 위한 settings.py와 python-dotenv 사용

01 settings.py에 환경변수 상수필드로 저장할 class들 정의하기

  1. pip3 install python-dotenv

  2. root에 .env 생성 및 .gitignore 생성하여 넣어주기

    image-20221015003050610

  3. src > config > settings.py를 생성한다

    • 장고의 파일명 차용

    image-20221015002736471

  4. setting.py내부에서는 각 카테고리별 환경변수를 상수필드에 저장할 class를 개별로 생성하고, 카테고리별 환경변수class의 객체를 맨 아래 생성한다

    • FastApi 방식 차용: 참고 github

    • class Project

    • class DB

    • class Auth

      • project = Project()
      • db = DB()
      • auth = Auth()
    • 정의

      1. 사용할 상수필드명 = os.getenv(“KEY”)으로 미리 정의해 둔다.

        image-20221023232319004

      2. 환경변수를 꺼내기 전에, load_dotenv()가 수행되어야한다.

        image-20221023232331767

      3. **DB의 종류에 따라 DB_CONNECTION에 소문자로 dialect+driver형식으로 정의해주고, **

        • sqlite라면, root폴더의 DB_NAME.db만 사용하도록 정의해주었다.
          • sqlite의 memory db만 쓰는 경우, DB_NAME을 memory라고 주면, 정해진 양식만 사용하도록 설정했다.
      4. fastapi의 config가 아닌 경우, type변환을 직접해줘야한다.

        • None에 int()가 씌여서 에러가 날 수 도 있으니 숫자형으로 변환할 환경변수는, 숫자문자열 기본값을 os.getenv()에 지정해준다
    import os
    from pathlib import Path
    from dotenv import load_dotenv
       
    dotenv_path = Path("./.env")
    load_dotenv(dotenv_path=dotenv_path)
       
       
    class Project:
        # project
        PROJECT_NAME: str = os.getenv("PROJECT_NAME")
        PROJECT_VERSION: str = os.getenv("PROJECT_VERSION")
       
       
    class DB:
        # DB_CONNECTION은 dialect+driver를 문자열로 지정한다
        # -> driver를 지정안해주면 기본 driver가 들어간다.
        DB_CONNECTION = os.getenv("DB_CONNECTION").lower()
       
        DB_USER: str = os.getenv("DB_USER")
        DB_PASSWORD = os.getenv("DB_PASSWORD")
        DB_SERVER = os.getenv("DB_SERVER", "localhost")
        DB_PORT: str = os.getenv("DB_PORT", "3306")
        DB_NAME: str = os.getenv("DB_NAME", "test")
       
        ## DB_CONNECTION은 dialect+driver를 문자열로 하지만, sqlite인 경우 양식이 다르다.
        ## => sqlite은 dialect만 지정해주되
        ## => DB_NAME이 memory명 다른 양식으로 입력되도록 짠다.
        if DB_CONNECTION == "sqlite":
            #1) sqlite를 메모리로 쓰는 경우 for fake data + CRUD 연습
            if DB_NAME == 'memory':
                DATABASE_URL = f"sqlite:///:memory:"
            #2) sqlite를 file로 쓰는 경우
            else:
                DATABASE_URL = f"sqlite:///{DB_NAME}.db"
        else:
            DATABASE_URL = f"{DB_CONNECTION}://{DB_USER}:{DB_PASSWORD}@{DB_SERVER}:{DB_PORT}/{DB_NAME}"
        print("*" * 15 + f"DATABASE_URL: {DATABASE_URL}" + "*" * 15)
       
       
    class Auth:
        # jwt. Watch out -> int( None )
        TOKEN_KEY = os.getenv("TOKEN_KEY")
        EXP_TIME_MIN = int(os.getenv("EXP_TIME_MIN", "30"))
        REFRESH_TIME_MIN = int(os.getenv("REFRESH_TIME_MIN", "15"))
       
           
    project = Project()
    db = DB()
    auth = Auth()
    
  5. src>config> init.py에 생성해놓은 환경변수객체들을 import해놓는다.

    image-20221023232852851

    from .settings import db, auth, project
    
  6. 환경변수가 필요한 곳으로 가서 from src.config에서 import 필요한 환경변수객체를 import하여 상수필드를 꺼내 쓴다.

    image-20221023232958438

02 settings.py를 보고 .env 채우기

  1. src> config> settings.py로 가서, 사용할 환경변수 목록을 확인한다.

    image-20221023233126925

  2. .env파일에서 그대로 보고 작성한다

    image-20221023233207086

예시

src>config>settings.py

import os
from pathlib import Path
from dotenv import load_dotenv

dotenv_path = Path("./.env")
load_dotenv(dotenv_path=dotenv_path)


# fastapi 세팅 참고
# https://github.com/heumsi/python-rest-api-server-101/blob/main/project/src/config.py
class Project:
    # project
    PROJECT_NAME: str = os.getenv("PROJECT_NAME")
    PROJECT_VERSION: str = os.getenv("PROJECT_VERSION")


class DB:
    # database
    DB_CONNECTION = os.getenv("DB_CONNECTION").lower()

    DB_USER: str = os.getenv("DB_USER")
    DB_PASSWORD = os.getenv("DB_PASSWORD")
    DB_SERVER = os.getenv("DB_SERVER", "localhost")
    DB_PORT: str = os.getenv("DB_PORT", "3306")
    DB_NAME: str = os.getenv("DB_NAME", "test")

    ## sqlite인 경우 양식이 다르다.
    if DB_CONNECTION == "sqlite":
        ## sqlite를 메모리로 쓰는 경우 for fake data + CRUD 연습
        if DB_NAME == 'memory':
            DATABASE_URL = f"sqlite:///:memory:"
        ## sqlite를 file로 쓰는 경우
        else:
            DATABASE_URL = f"sqlite:///{DB_NAME}.db"
    else:
        DATABASE_URL = f"{DB_CONNECTION}://{DB_USER}:{DB_PASSWORD}@{DB_SERVER}:{DB_PORT}/{DB_NAME}"
    print("*" * 15 + f"DATABASE_URL: {DATABASE_URL}" + "*" * 15)


class Auth:
    # jwt. Watch out -> int( None )
    TOKEN_KEY = os.getenv("TOKEN_KEY")
    EXP_TIME_MIN = int(os.getenv("EXP_TIME_MIN", "30"))
    REFRESH_TIME_MIN = int(os.getenv("REFRESH_TIME_MIN", "15"))


project = Project()
db = DB()
auth = Auth()

.env 예시

# 비워둘거면 아예 주석처리해야 default값이 적용된다.

# project===
# PROJECT_NAME
# PROJECT_VERSION

# database-sqlite===
DB_CONNECTION=sqlite
# DB_NAME=xxxx.db
DB_NAME=memory

# database===
# DB_CONNECTION=mysql+pymysql
# DB_NAME=cinema
# DB_USER=root
# DB_PASSWORD=564123
# DB_SERVER= 
# DB_PORT=

# jwt
# TOKEN_KEY=
# EXP_TIME_MIN=
# REFRESH_TIME_MIN