Read Configuration - minnie0531/fastapi-template GitHub Wiki
python์์๋ ๋ค์ํ ๋ฐฉ๋ฒ์ผ๋ก configuration์ ์ฝ์ ์ ์๋๋ฐ ์ด๋ ํ์ผ์ ํํ๋ ์ฌ์ฉ์์ ์๋์ ๋ฐ๋ผ ๊ฒฐ์ ๋๋ค. ํฌ๊ฒ ํ๊ฒฝ๋ณ์๋ฅผ ์ฝ๋ ๋ฐฉ๋ฒ๊ณผ ํ์ผ๋ก ์ฝ๋ ๋ฐฉ๋ฒ์ด ์๊ณ , ํ๊ฒฝ ๋ณ์๋ก configuration๋ค์ด ์ค์ ๋ ๊ฒฝ์ฐ os.getenv("VARIABLE_NAME") ์ผ๋ก ๊ฐ์ ๊ฐ์ ธ ์ค๋ฉด ๋๋ค.
ํ์ผ๋ก ์ฝ๋ ๋ฐฉ๋ฒ์ json์ด๋ yaml ํํ๋ json์ด๋ pyyaml์ ํตํด ์ฝ๋ ๋ฐฉ๋ฒ๊ณผ ๋์ผ ํ๋ฉฐ, ์ฌ๊ธฐ์์๋ pydantic์ settings๋ฅผ ์ด์ฉํ .env ํ์ผ ์ฝ๋ ๋ฐฉ๋ฒ๊ณผ configparser์ jpproperties๋ฅผ ์ด์ฉํ python config ํ์ผ์ฝ๊ธฐ๋ฅผ ๋ค๋ฃฐ ์์ ์ด๋ค.
Use Pydantic settings
FastAPI๋ฅผ ์ฌ์ฉ๊ฒ ๋๋ฉด ์์ฐ์ค๋ฝ๊ฒ pydantic์ model์ business๋ชจ๋ธ๋ก ๊ตฌํํ ๋ ์ฌ์ฉํ๊ฒ ๋๋ค. ๊ทธ๋ฌ๋ฉด ๊ธฐ์กด์ ์ฌ์ฉํ๊ณ ์๋ ๋ชจ๋์ ์ฌ์ฉํด์ configuration์ ๊ตฌํ ํ๋ค๋ฉด ์ผ์ข ์ ํต์ผ๊ฐ์ ์ฃผ๋ ๋ง์์ ์์ (?)์ ๊ฐ์ง ์ ์๊ธฐ ๋๋ฌธ์ ํ๋ฒ ์๋ ํด๋ณด๊ธฐ๋ก ํ๋ค.
pydatic์ ๊ฒฝ์ฐ python ๋ชจ๋ ์ค python-dotenv๋ฅผ ์ด์ฉํ์ฌ .env๋ฅผ ์ฝ์ด์ฌ ์ ์๊ฒ ํด์ค๋ค.
- db_confg.env ์ค๋น
HOST="localhost"
PORT=1521
SID="ORACLE"
USER_ID="aaa"
USER_PW="1234"
- Create Settings class
from pydantic import BaseSettings
class Settings(BaseSettings):
host: str
port: int
sid: str
user_id: str
user_pw: str
class Config:
env_file = 'db_config.env'
env_file_encodeing = 'utf-8'
- Create Settings instance and get values
settings = Settings(_env_file='./app/config/db_config.env')
dsn = cx_Oracle.makedsn(host=**settings.host**, port=**settings.port**, sid=**settings.sid**)
engine = create_engine("oracle+cx_oracle://%s:%s@%s" % (**settings.user_id**, **settings.user_pw**, str(dsn)))
์ฌ์ฉ๋ฐฉ๋ฒ์ด ์ด๋ ต์ง ์์ง๋ง setting์ ๋ํ ๋ชจ๋ธ์ ๋ค์ํ๋ฒ ์ ์ ํ๊ณ ๋ค์ด๊ฐ๋ค. ์ด๋ฌํ ๋ฐฉ๋ฒ์ ์ด๋ค ์์๋ค์ด ์๋์ง์ ๋ํด ๋ช ์์ ์ด์ง๋ง, ํํธ์ผ๋ก๋ ์ฝ๋๋ฅผ ๋ถ์ํ ๋ ํ์ผ์ ํ๋ ๋ ๋ณด๊ฒ ํ๋ ๋ฒ๊ฑฐ๋ก์์ด ์๋ค. configuration๋ค์ ๋๊ฒ ๋ฐ๋ก ์์ ๋ณผ ์ ์๋ ๋ณ์๋ค์ ์ ํํ๊ณ ์๊ธฐ๋ ํ๊ณ ์ด๋ฏธ ์๊ณ ์ ์๋ ๊ฐ์ผ๋ก ์ ๋ฌํ๊ธฐ ๋๋ฌธ์ ๊ฐ์ธ์ ์ผ๋ก๋ ์ฝ๋๋ฅผ ์ฝ๊ธฐ ํธํ๊ฒ ํ๊ธฐ ์ํด์ ์ด๋ฌํ ๋ฐฉ๋ฒ๋ณด๋ค๋ ๋ค์ด๋ ํธ๋ก ๊ฐ์ ๊ฐ์ ธ์ค๋ ๊ฒ์ ์ ํธ ํ๋ค. (๊ฐ์ธ์ ์ธ ์ฐจ์ด๋ค)
Use configParser
- Use db_config.env but add section on the config and remove quotation marks " '
Quotation mark๋ ๊ฐ์ด ์ฝ์ด๊ฐ๊ธฐ ๋๋ฌธ์ ์ง์์ฃผ๋ ๊ฒ ์ข์
**[db]**
HOST=localhost
PORT=1521
SID=ORCLCDB
USER_ID=aaa
USER_PW=1234
- Declare configParser and read file and attributes
๊ธฐ๋ณธ์ ์ผ๋ก string์ผ๋ก ๋ณํํ์ฌ ์ฃผ๊ธฐ๋๋ฌธ์ int๋ก ์ฝ์ด๊ฐ์ผ ํ๋ ๋ถ๋ถ์์ ํ๋ณํ์ด ํ์๋กํจ.
parser = ConfigParser()
parser.read(r'./app/config/db_config.env')
dsn = cx_Oracle.makedsn(host=parser.get('db', 'host'), port=int(parser.get('db', 'port')), sid=parser.get('db', 'sid'))
engine = create_engine("oracle+cx_oracle://%s:%d@%s" % (parser.get('db','user_id'), int(parser.get('db','user_pw')), str(dsn)))
Kubernetes์์ configMap ์ ๊ฒฝ์ฐ ๋๋ถ๋ถ propertiesํ์ผ๋ก ์ ๋ฌํ๊ฒ ๋๋๋ฐ, ์ด๋ ์ฒ์ ์ฌ์ฉํ db_cofnig.env์ ๊ฐ๊น๋ค. sectionํํธ๊ฐ ์๊ธฐ ๋๋ฌธ์ configParser๋ฅผ ์ด์ฉํ๋ฉด ์๋์ ๊ฐ์ ์๋ฌ๊ฐ ๋์ฌ ๊ฒ์ด๋ค. configparser.MissingSectionHeaderError: File contains no section headers
๊ทธ๋์ section์ด ์์ ๊ฒฝ์ฐ string ํํ๋ก ๋ณ๊ฒฝํ๊ณ section์ถ๊ฐํ configParser๋ฅผ ์ด์ฉํ๋ ๋ฐฉ๋ฒ๋ ์๋ค.(์์์ง ์๋ค..)
User jproperties
confgMap์ผ๋ก ์ ์ฅ๋ properties ํ์ผ์ ์ฝ์ด ๊ฐ๊ณ ์ค๊ธฐ์ ๊ฐ์ฅ ํธํ ๋ฐฉ๋ฒ์ด ์๋๊น ์๊ฐ๋๋ค. ๋ฐ๋ก ๋ชจ๋ธ์ ๋ํ ๊ตฌํ ์์ด ๊ฐ์ getํ์ฌ ๊ฐ์ ธ ์ฌ ์ ์๊ณ ์ถ๊ฐ์ ์ผ๋ก section์ ๋ฃ์ด์ฃผ๋ ๊ฒ๋ ์๋ค.
- pip install jproperties
- user original db_config.env
HOST=localhost
PORT=1521
SID=ORCLCDB
USER_ID=aaa
USER_PW=1234
- Declare properties and get the values
from jproperties import Properties
configs = Properties()
with open('./app/config/db_config.env', 'rb') as config_file:
configs.load(config_file)
dsn = cx_Oracle.makedsn(host=configs.get('HOST').data, port=int(configs.get('PORT').data), sid=configs.get('SID').data)
engine = create_engine("oracle+cx_oracle://%s:%d@%s" % (configs.get('USER_ID').data, int(configs.get('USER_PW').data), str(dsn)))
๊ตฌํ์ด๋ ๊ฐ๋ ์ฑ์ ์์ด์ ์ฅ์ ์ด ์์ง๋ง, ์์ ๋จผ์ ๋ณด์ฌ์ค ์์ ์ ๋ฌ๋ฆฌ, ๋ชจ๋์ ์ถ๊ฐ๋ก ์ค์นํด์ผ ํ๋ค.
ํ์ผ์ ์ฝ์ด์ configuration์ ์ค์ ํ๋ ๋ฐฉ๋ฒ์ ์ฌ๋ฌ๊ฐ์ง๊ฐ ์๊ธฐ ๋๋ฌธ์ ์ํฉ์ ๋ฐ๋ผ ์ ์ ํ๊ฒ ์ ์ฉํด๋ณด์!