Skip to content

Commit

Permalink
update config
Browse files Browse the repository at this point in the history
  • Loading branch information
jadbin committed Sep 28, 2018
1 parent e246eab commit 4bdf8b9
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 48 deletions.
4 changes: 2 additions & 2 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ Change log
- ``guniflask init`` 会将用户的选择保存在 .guniflask-init.json 中,再次使用该命令会直接使用保存的选择重新生成项目,如需重新进行选择可使用 ``guniflask init -f``
- bin/manage.py 添加了默认环境变量的设置
- 添加gunicorn默认配置 ``preload_app=True`` ,debug模式下自动设置 ``preload_app=False``
- 在 ``manage debug/start`` 命令中通过 ``-p`` 选项设置 ``active_profiles``
- ``active_profiles`` 改为只能通过环境变量进行设置
- 在 ``manage debug/start`` 命令中可以通过 ``-p`` 选项设置 ``active_profiles`` 对应的环境变量
- ``manage initdb`` 会自动加载foo模块及子模块中所有声明的 ``db.Model``
- Flask app的name更正为项目的名称
- 在app启动之前使用 ``config.settings`` 不再raise RuntimeError,但在app初始化之前 ``config.settings`` 尚未加载项目的配置项
- 项目配置相关文件统一命名为app,包括 conf/app.py , conf/app-env.sh , bin/app-config.sh

0.2.5 (2018-09-18)
Expand Down
18 changes: 17 additions & 1 deletion docs/settings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ Getting Settings
Built-in Settings
-----------------

home
^^^^

项目根目录。

在配置文件中设置无效。

.. _active_profiles:

active_profiles
Expand All @@ -35,10 +42,19 @@ active_profiles

激活哪些profile。

也可以通过环境变量 ``GUNIFLASK_ACTIVE_PROFILES`` 进行设置,或通过 ``manage debug/start`` 命令的 ``-p`` 选项进行设置。
在配置文件中设置无效。可以通过环境变量 ``GUNIFLASK_ACTIVE_PROFILES`` 进行设置,或通过 ``manage debug/start`` 命令的 ``-p`` 选项进行设置。

有关使用profile区别运行环境并加载不同配置的详细信息请参考 :ref:`profile` 。

debug
^^^^^

- Default: ``None``

是否为debug模式。

在配置文件中设置无效。可以通过环境变量 ``GUNIFLASK_DEBUG`` 进行设置,在执行 ``manage debug`` 命令会自动设置。

cors
^^^^

Expand Down
14 changes: 10 additions & 4 deletions guniflask/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,27 @@
import copy
from collections import MutableMapping

from flask import _app_ctx_stack

from guniflask.utils.config import load_app_config


class ConfigProxy:
def __init__(self, app=None):
self._settings = Settings()
if app is not None:
if app:
self.init_app(app)

def init_app(self, app):
self._settings.update(load_app_config())
settings = Settings(load_app_config(app))
app.app_settings = settings
return settings

@property
def settings(self):
return self._settings
ctx = _app_ctx_stack.top
if ctx is None:
raise RuntimeError('There is no app context')
return ctx.app.app_settings


class Settings(MutableMapping):
Expand Down
33 changes: 17 additions & 16 deletions guniflask/templates/project/bin/manage.py.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import time
from sqlalchemy.engine import create_engine
from sqlalchemy.schema import MetaData

from guniflask.utils.config import load_config, walk_modules, load_app_config
from guniflask.utils.config import load_config, walk_modules
from guniflask.modelgen import SqlToModelGenerator
from guniflask.errors import UsageError

Expand Down Expand Up @@ -80,14 +80,13 @@ class InitDb(Command):
help='force creating all tables')

def run(self, args):
from {{project_name}} import create_app, db
from {{project_name}} import create_app, db, config

settings = load_app_config()
if 'SQLALCHEMY_DATABASE_URI' not in settings:
raise UsageError("Please set 'SQLALCHEMY_DATABASE_URI' in configuration.")
walk_modules('{{project_name}}')
app = create_app()
with app.app_context():
if config.settings['SQLALCHEMY_DATABASE_URI'] is None:
raise UsageError("Please set 'SQLALCHEMY_DATABASE_URI' in configuration.")
if args.force:
db.drop_all()
else:
Expand Down Expand Up @@ -118,17 +117,19 @@ class TableToModel(Command):
args.tables = args.tables.split(',')

def run(self, args):
home_dir = os.environ['GUNIFLASK_HOME']
settings = load_app_config()
database_uri = settings.get('SQLALCHEMY_DATABASE_URI')
if not database_uri:
raise UsageError("Please set 'SQLALCHEMY_DATABASE_URI' in configuration.")
engine = create_engine(database_uri)
metadata = MetaData(engine)
metadata.reflect(only=args.tables)
gen = SqlToModelGenerator('{{project_name}}', metadata)
dest = settings.get('table2model_dest', join('{{project_name}}', 'models'))
gen.render(join(home_dir, dest))
from {{project_name}} import create_app, config

app = create_app()
with app.app_context():
database_uri = config.settings['SQLALCHEMY_DATABASE_URI']
if database_uri is None:
raise UsageError("Please set 'SQLALCHEMY_DATABASE_URI' in configuration.")
engine = create_engine(database_uri)
metadata = MetaData(engine)
metadata.reflect(only=args.tables)
gen = SqlToModelGenerator('{{project_name}}', metadata)
dest = config.settings.get('table2model_dest', join('{{project_name}}', 'models'))
gen.render(join(app.config['GUNIFLASK_HOME'], dest))


class Debug(Command):
Expand Down
7 changes: 3 additions & 4 deletions guniflask/templates/project/conf/wsgi.py.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ from gunicorn.config import KNOWN_SETTINGS
from gunicorn.app.base import Application
from gunicorn.util import import_app

from guniflask.utils.config import load_config, load_profile_config, walk_files, load_app_config
from guniflask.utils.config import load_config, load_profile_config, walk_files

conf_dir = os.environ['GUNIFLASK_CONF_DIR']
pid_dir = os.environ['GUNIFLASK_PID_DIR']
Expand Down Expand Up @@ -76,10 +76,9 @@ options = {
'errorlog': join(log_dir, '{{project__name}}-' + id_string + '.error.log')
}

settings = load_app_config()
options.update(make_profile_options(settings['active_profiles']))
options.update(make_profile_options(os.environ.get('GUNIFLASK_ACTIVE_PROFILES')))
# if debug
if settings['debug']:
if os.environ.get('GUNIFLASK_DEBUG'):
options.update(make_debug_options())
makedirs(options)

Expand Down
32 changes: 16 additions & 16 deletions guniflask/templates/project/{{project_name}}/app.py.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -7,40 +7,40 @@ from flask_cors import CORS
from flask_sqlalchemy import SQLAlchemy

from guniflask.config import ConfigProxy
from guniflask.utils.config import walk_modules
from guniflask.utils.config import walk_modules, set_app_config_from_environ
from guniflask.utils.logging import redirect_app_logger, redirect_logger
from guniflask.utils.model import model_to_dict, dict_to_model, update_model_by_dict
from guniflask.utils.model import inject_sqlalchemy_model

log = logging.getLogger(__name__)

config = ConfigProxy()

db = SQLAlchemy()
db.Model.to_dict = lambda self, **kwargs: model_to_dict(self, **kwargs)
db.Model.from_dict = classmethod(lambda cls, dict_obj, **kwargs: dict_to_model(dict_obj, model_cls=cls, **kwargs))
db.Model.update_by_dict = lambda self, dict_obj, **kwargs: update_model_by_dict(self, dict_obj, **kwargs)
inject_sqlalchemy_model(db.Model)


def set_app_config(app):
config.init_app(app)
for k, v in config.settings.items():
set_app_config_from_environ(app)
settings = config.init_app(app)
for k, v in settings.items():
if k.isupper():
app.config[k] = v

from {{project_name}} import hooks

_make_settings = getattr(hooks, 'make_settings', None)
if _make_settings:
_make_settings(app, config.settings)
_make_settings(app, settings)

log.info('{{project_name}} active profiles: %s', config.settings['active_profiles'])
log.info('{{project_name}} active profiles: %s', settings['active_profiles'])
return settings


def init_app(app):
def init_app(app, settings):
# CORS
if config.settings['cors']:
if isinstance(config.settings['cors'], dict):
CORS(app, **config.settings['cors'])
if settings['cors']:
if isinstance(settings['cors'], dict):
CORS(app, **settings['cors'])
else:
CORS(app)

Expand All @@ -52,7 +52,7 @@ def init_app(app):

_init_app = getattr(hooks, 'init_app', None)
if _init_app:
_init_app(app, config.settings)
_init_app(app, settings)


def register_blueprints(app):
Expand All @@ -72,6 +72,6 @@ def create_app():
redirect_app_logger(app, gunicorn_logger)
redirect_logger('{{project_name}}', gunicorn_logger)
register_blueprints(app)
set_app_config(app)
init_app(app)
settings = set_app_config(app)
init_app(app, settings)
return app
22 changes: 17 additions & 5 deletions guniflask/utils/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@ def load_profile_config(conf_dir, name, profiles=None):
return pc


environ_config_attrs = ['GUNIFLASK_HOME',
'GUNIFLASK_CONF_DIR',
'GUNIFLASK_ACTIVE_PROFILES',
'GUNIFLASK_DEBUG']


def set_app_config_from_environ(app):
for c in environ_config_attrs:
app.config[c] = os.environ.get(c)


app_default_settings = {
'active_profiles': None,
'debug': False,
Expand All @@ -47,20 +58,21 @@ def load_profile_config(conf_dir, name, profiles=None):
}


def load_app_config():
c = app_default_settings
conf_dir = os.environ.get('GUNIFLASK_CONF_DIR')
def load_app_config(app):
c = dict(app_default_settings)
conf_dir = app.config.get('GUNIFLASK_CONF_DIR')
if conf_dir:
c.update(load_config(join(conf_dir, 'app.py')))
active_profiles = os.environ.get('GUNIFLASK_ACTIVE_PROFILES', c.get('active_profiles'))
active_profiles = app.config.get('GUNIFLASK_ACTIVE_PROFILES')
c.update(load_profile_config(conf_dir, 'app', profiles=active_profiles))
c['active_profiles'] = active_profiles
settings = {}
for name in c:
if not name.startswith('_') and not inspect.ismodule(c[name]) and not inspect.isfunction(c[name]):
settings[name] = c[name]
if os.environ.get('GUNIFLASK_DEBUG'):
if app.config.get('GUNIFLASK_DEBUG'):
settings['debug'] = True
settings['home'] = app.config.get('GUNIFLASK_HOME')
return settings


Expand Down
6 changes: 6 additions & 0 deletions guniflask/utils/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,9 @@ def _get_ignore_set(ignore):
if isinstance(ignore, str):
ignore = [i.strip() for i in ignore.split(',')]
return set(ignore if ignore else [])


def inject_sqlalchemy_model(model_cls):
model_cls.to_dict = lambda self, **kwargs: model_to_dict(self, **kwargs)
model_cls.from_dict = classmethod(lambda cls, dict_obj, **kwargs: dict_to_model(dict_obj, model_cls=cls, **kwargs))
model_cls.update_by_dict = lambda self, dict_obj, **kwargs: update_model_by_dict(self, dict_obj, **kwargs)

0 comments on commit 4bdf8b9

Please sign in to comment.