配置文件python
# settings.py class Config(object): DEBUG = False TESTING = False DATABASE_URI = 'sqlite://:memory:' class ProductionConfig(Config): DATABASE_URI = 'mysql://user@localhost/foo' class DevelopmentConfig(Config): DEBUG = True class TestingConfig(Config): TESTING = True
读取mysql
import importlib path = 'settings.Foo' p,c = path.rsplit('.',maxsplit=1) m = importlib.import_module(p) # m = __import__(p) cls = getattr(m,c) for key in dir(cls): if key.isupper(): print(key,getattr(cls,key))
这种方法很是简单,直接把配置的内容写到了代码中,在应用中直接进行引用。另外也能够把这个py配置文件放到其余python应用中,修改具体的配置内容便可。可是,它存在严重的安全问题,咱们都知道不该该把配置写到代码中,若是有人把咱们的源代码上传到了github中,那么数据库的配置就至关于向全世界公开了。固然,当配置文件不包含敏感信息时,也能够采用这种简单的方法。git
更常见的配置管理方法就是利用外部的配置文件,让配置文件仅仅包含配置信息,和代码独立开来,不直接引用也就不须要写成python代码。一般使用json、yaml或者ini的文件格式来存储配置。github
利用configparseredis
写入文件 import configparser config = configparser.ConfigParser() config["DEFAULT"] = {'ServerAliveInterval': '45', 'Compression': 'yes', 'CompressionLevel': '9', 'ForwardX11':'yes' } config['bitbucket.org'] = {'User':'hg'} config['topsecret.server.com'] = {'Host Port':'50022','ForwardX11':'no'} with open('example.ini', 'w') as file: config.write(file)
配置文件sql
# example.ini [DEFAULT] serveraliveinterval = 45 compression = yes compressionlevel = 9 forwardx11 = yes [bitbucket.org] user = hg [topsecret.server.com] host port = 50022 forwardx11 = no
除此以外,咱们还能够用json文件来存储数据库
# config.json { "DATABASE": { "host": "localhost", "dbname": "test", "user": "user", "password": "password", "port": 3306 } }
结合环境变量和python库configparser读取外部文件,首先在开发一般不会接触到生产环境,所以生产环境的配置文件由运维来写,运维将应用所须要的配置写好后,放到生产服务器的指定位置,代码从指定位置读取配置。为了方便程序的统一调试,能够提早约定好一个系统环境变量(CONFIG_PATH)来指定配置文件的存放路径。json
export CONFIG_PATH = /home/test/configs/config.ini
读取的代码以下:安全
import os import configparser try: CONFIG_PATH = os.environ['CONFIG_PATH'] except Exception: raise ValueError config = configparser.ConfigParser() config.read(CONFIG_PATH) host = config["DATABASE"]["HOST"]
此方法不使用文件来存储配置信息,将全部的配置信息存储到环境变量中,在实践中也比较常见,运维经过ansible部署脚本,在程序运行前将须要配置信息导入到环境变量中。服务器
import os 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
不利用文件存储,在必定程度上增强了对密码等配置信息的保护,但也增长了运维的工做量,尤为当须要修改配置的时候。
上面介绍了三种常见的项目配置方法,最有介绍一个好用的python动态项目配置库:Dynaconf。dyanconf是OSM(Object Settings Mapper), 可以从不一样的配置数据存储方式中读取配置,例如python配置文件、系统环境变量、redis、ini文件、json文件等等。
安装:pip install dynaconf
使用方式:
from dynaconf import settings print(settings.SOME_VARIABLE) or print(settings.get('SOME_VARIABLE'))
若是不但愿配置跟随项目,能够经过系统环境变量来指定配置文件的位置
# using module name export DYNACONF_SETTINGS=myproject.production_settings # or using location path export DYNACONF_SETTINGS=/etc/myprogram/settings.py
当咱们部署的程序须要读取一个MYSQL_HOST的配置用于测试,不须要去重写配置文件,仅须要再系统环境变量中加入:
export DYNACONF_MYSQL_HOST=myserver.com
而后,程序即可以获取到该配置:
>>> from dynaconf import settings >>> print(settings.MYSQL_HOST) myserver.com
若是须要指定配置值的数值类型,则经过如下方式增长对应的系统环境变量:
export DYNACONF_NUMBER='@int 123' export DYNACONF_FLOAT='@float 12.2' export DYNACONF_FLAG='@bool yes' export DYNACONF_FLAG2='@bool disabled' export DYNACONF_LIST='@json [1, 2, 3, 4]' export DYNACONF_DICT='@json {"name": "Bruno"}'
读取到的配置以下所示:
from dynaconf import settings type(settings.NUMBER) int type(settings.FLOAT) float type(settings.FLAG) bool print(settings.FLAG2 == False) True print(settings.LIST[1]) 2 print(settings.DICT['name']) Bruno
咱们也能够讲配置文件存储到redis中,达到在对不一样的机器共享环境变量的效果,仅须要在settings.py文件中增长一下代码:
# connection REDIS_FOR_DYNACONF = { 'host': 'localhost', 'port': 6379, 'db': 0 } # and loader LOADERS_FOR_DYNACONF = [ 'dynaconf.loaders.env_loader', 'dynaconf.loaders.redis_loader' # 增长了redis的加载 ]
如今能够讲配置存储到redis中,hash默认为DYNACONF_DYNACONF。dyanconf还提供了方法去将配置写入到redis:
from dynaconf.utils import redis_writer from dynaconf import settings redis_writer.write(settings,name='test',mysql_host='localhost', MYSQL_PORT=3306)
查看Redis,存储的结果以下:
DYNACONF_DYNACONF: NAME='test' MYSQL_HOST='localhost' PORT='@int 3306'
至此,python项目常见的配置方法总结完毕,不过在一些微服务架构中,会专门开发配置中心,程序直接从线上读取配置,配置的管理也会开发一套GUI,方便开发和运维。