qgyd2021's picture
[first commit]
00aa292
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import json
import os
from dotenv import load_dotenv
from dotenv.main import DotEnv
from toolbox.json.misc import traverse
class EnvironmentManager(object):
def __init__(self, path, env, override=False):
filename = os.path.join(path, '{}.env'.format(env))
self.filename = filename
load_dotenv(
dotenv_path=filename,
override=override
)
self._environ = dict()
def open_dotenv(self, filename: str = None):
filename = filename or self.filename
dotenv = DotEnv(
dotenv_path=filename,
stream=None,
verbose=False,
interpolate=False,
override=False,
encoding="utf-8",
)
result = dotenv.dict()
return result
def get(self, key, default=None, dtype=str):
result = os.environ.get(key)
if result is None:
if default is None:
result = None
else:
result = default
else:
result = dtype(result)
self._environ[key] = result
return result
_DEFAULT_DTYPE_MAP = {
'int': int,
'float': float,
'str': str,
'json.loads': json.loads
}
class JsonConfig(object):
"""
将 json 中, 形如 `$float:threshold` 的值, 处理为:
从环境变量中查到 threshold, 再将其转换为 float 类型.
"""
def __init__(self, dtype_map: dict = None, environment: EnvironmentManager = None):
self.dtype_map = dtype_map or _DEFAULT_DTYPE_MAP
self.environment = environment or os.environ
def sanitize_by_filename(self, filename: str):
with open(filename, 'r', encoding='utf-8') as f:
js = json.load(f)
return self.sanitize_by_json(js)
def sanitize_by_json(self, js):
js = traverse(
js,
callback=self.sanitize,
environment=self.environment
)
return js
def sanitize(self, string, environment):
"""支持 $ 符开始的, 环境变量配置"""
if isinstance(string, str) and string.startswith('$'):
dtype, key = string[1:].split(':')
dtype = self.dtype_map[dtype]
value = environment.get(key)
if value is None:
raise AssertionError('environment not exist. key: {}'.format(key))
value = dtype(value)
result = value
else:
result = string
return result
def demo1():
import json
from project_settings import project_path
environment = EnvironmentManager(
path=os.path.join(project_path, 'server/callbot_server/dotenv'),
env='dev',
)
init_scenes = environment.get(key='init_scenes', dtype=json.loads)
print(init_scenes)
print(environment._environ)
return
if __name__ == '__main__':
demo1()