메뉴 여닫기
개인 메뉴 토글
로그인하지 않음
만약 지금 편집한다면 당신의 IP 주소가 공개될 수 있습니다.

파이썬 설정 저장

데브카페

파이썬에서 설정값 관리하기

https://mingrammer.com/ways-to-manage-the-configuration-in-python/


config.py를 사용한 설정

  • config.py
  • 가장 쉽고 직관적인 방법
# config.py
DATABASE_CONFIG = {
    'host': 'localhost',
    'dbname': 'company',
    'user': 'user',
    'password': 'password',
    'port': 3306
}

# main.py
import pymysql
import config

def connect_db(dbname):
    if dbname != config.DATABASE_CONFIG['dbname']:
        raise ValueError("Could not find DB with given name")
    conn = pymysql.connect(host=config.DATABASE_CONFIG['host'],
                           user=config.DATABASE_CONFIG['user'],
                           password=config.DATABASE_CONFIG['password'],
                           db=config.DATABASE_CONFIG['dbname'])
    return conn

connect_db('company')

예시2

# config.py
class Config:
    APP_NAME = 'myapp'
    SECRET_KEY = 'secret-key-of-myapp'
    ADMIN_NAME = 'administrator'

    AWS_DEFAULT_REGION = 'ap-northeast-2'
    
    STATIC_PREFIX_PATH = 'static'
    ALLOWED_IMAGE_FORMATS = ['jpg', 'jpeg', 'png', 'gif']
    MAX_IMAGE_SIZE = 5242880 # 5MB

    
class DevelopmentConfig(Config):
    DEBUG = True
    
    AWS_ACCESS_KEY_ID = 'aws-access-key-for-dev'
    AWS_SECERT_ACCESS_KEY = 'aws-secret-access-key-for-dev'
    AWS_S3_BUCKET_NAME = 'aws-s3-bucket-name-for-dev'

    DATABASE_URI = 'database-uri-for-dev'


class TestConfig(Config):
    DEBUG = True
    TESTING = True
    
    AWS_ACCESS_KEY_ID = 'aws-access-key-for-test'
    AWS_SECERT_ACCESS_KEY = 'aws-secret-access-key-for-test'
    AWS_S3_BUCKET_NAME = 'aws-s3-bucket-name-for-test'
    
    DATABASE_URI = 'database-uri-for-test'
  

class ProductionConfig(Config):
    DEBUG = False

    AWS_ACCESS_KEY_ID = 'aws-access-key-for-prod'
    AWS_SECERT_ACCESS_KEY = 'aws-secret-access-key-for-prod'
    AWS_S3_BUCKET_NAME = 'aws-s3-bucket-name-for-prod'

    DATABASE_URI = 'database-uri-for-prod'


class CIConfig:
    SERVICE = 'travis-ci'
    HOOK_URL = 'web-hooking-url-from-ci-service'
   
# main.py
import sys
import config

...

if __name__ == '__main__':
    env = sys.argv[1] if len(sys.argv) > 2 else 'dev'
    
    if env == 'dev':
        app.config = config.DevelopmentConfig
    elif env == 'test':
        app.config = config.TestConfig
    elif env == 'prod':
        app.config = config.ProductionConfig
    else:
        raise ValueError('Invalid environment name')
   
    app.ci = config.CIConfig
  1. 같은 프로젝트 내에서 바로 임포트가 가능하며, 빌트인 데이터 구조를 그대로 활용할 수 있기 때문에 사용 편리.
  2. 설정값이 시크릿값이라면 보안상 이슈가 생길 수가 있다. 설정값에 시크릿값이 없는 경우에 사용하는걸 추천한다.

외부 파일을 통한 설정

  1. 외부 파일에 정의된 설정값들을 로드하여 사용하는 방법
  2. ini와 json 포맷의 설정파일을 다루는 방법

INI파일 사용 방법

# main_with_ini.py
import configparser

config = configparser.ConfigParser()
config.read('config.ini')

secret_key = config['DEFAULT']['SECRET_KEY'] # 'secret-key-of-myapp'
ci_hook_url = config['CI']['HOOK_URL'] # 'web-hooking-url-from-ci-service'
; config.ini
[DEFAULT]
SECRET_KEY = secret-key-of-myapp
ADMIN_NAME = administrator
AWS_DEFAULT_REGION = ap-northeast-2
MAX_IMAGE_SIZE = 5242880

[TEST]
TEST_TMP_DIR = tests
TEST_TIMEOUT = 20

[CI]
SERVICE = travis-ci
HOOK_URL = web-hooking-url-from-ci-service

JSON 사용방법

# main_with_json.py
import json

with open('config.json', 'r') as f:
    config = json.load(f)

secret_key = config['DEFAULT']['SECRET_KEY'] # 'secret-key-of-myapp'
ci_hook_url = config['CI']['HOOK_URL'] # 'web-hooking-url-from-ci-service'
// config.json
{
  "DEFAULT": {
    "SECRET_KEY": "secret-key-of-myapp",
    "ADMIN_NAME": "administrator",
    "AWS_DEFAULT_REGION": "ap-northeast-2",
    "MAX_IMAGE_SIZE": 5242880
  },
  "TEST": {
    "TEST_TMP_DIR": "tests",
    "TEST_TIMEOUT": 20
  },
  "CI": {
    "SERVICE": "travis-ci",
    "HOOK_URL": "web-hooking-url-from-ci-service"
  }
}


// config.json.example
{
  "DEFAULT": {
    "SECRET_KEY": "...",
    "ADMIN_NAME": "...",
    "AWS_DEFAULT_REGION": "...",
    "MAX_IMAGE_SIZE": 5242880
  },
  "TEST": {
    "TEST_TMP_DIR": "tests",
    "TEST_TIMEOUT": 20
  },
  "CI": {
    "SERVICE": "travis-ci",
    "HOOK_URL": "..."
  }
}

os 환경 변수를 사용한 설정

  1. 파이썬 소스 파일이나 설정 파일과 같은 파일이 아닌 시스템의 환경 변수를 사용해 설정값들을 관리하는 방법
import os
from myapp import app

secret_key = os.environ.get('SECRET_KEY', None)

if not secret_key:
    raise ValueError('You must have "SECRET_KEY" variable')

app.config['SECRET_KEY'] = secert_key
  • 별도의 파일로 관리되지 않으므로 시크릿값 등이 노출될 위험이 적으며, 환경 변수만 받아오면 되기 때문에 사용하기가 매우 편리

동적 로딩을 통한 설정

# /opt/settings/config.py
DATABASE_CONFIG = {
    'host': 'localhost',
    'dbname': 'company',
    'user': 'user',
    'password': 'password',
    'port': 3306
}

# main.py
import sys
import pymysql

sys.path.append('/opt/settings')
import config

def connect_db(dbname):
    if dbname != config.DATABASE_CONFIG['dbname']:
        raise ValueError("Couldn't not find DB with given name")
    conn = pymysql.connect(host=config.DATABASE_CONFIG['host'],
                           user=config.DATABASE_CONFIG['user'],
                           password=config.DATABASE_CONFIG['password'],
                           db=config.DATABASE_CONFIG['dbname'])
    return conn

connect_db('company')
  • 이 방법의 장점은 파이썬 소스 파일 자체를 파이썬 프로젝트와 분리할 수 있다는 것이다.
  • 파이썬 소스 파일을 프로젝트 코드베이스와 분리하여 관리하고 싶을때 적합하다.


# 프로비저닝 스크립트
...
cd /opt/settings
git clone git@github.com/company/config.git

cd /opt/app
git clone git@github.com/company/api-server.git
...

Comments