Python Web

Flask中优雅使用config

2017-07-31  本文已影响1548人  jiaxiaolei

flask原生提供current_app, application 一旦启动,就可以通过current_app.config 获取当前application的所有配置。

公司有一个使用flask做web framework的项目,其中的使用方式如下:

# filename: config.py 
APP_ENV = "testing"

class BaseConfig:
    DEBUG = False

class DevelopmentConfig(BaseConfig):
    CRP_URL = 'xxxx'
    ... 

class TestingConfig(BaseConfig):
    CRP_URL = 'xxxx'
    ... 
 
configs = {
    'development': DevelopmentConfig,
    'testing': TestingConfig,
}

项目中的应用举例1:

# filename: uop/pool/handler.py
from config import APP_ENV, configs
...
pool_api = Api(pool_blueprint, errors=pool_errors)

CRP_URL = configs[APP_ENV].CRP_URL


class PoolListAPI(Resource):
    pass

项目中的应用举例2:

# filename: crp/res_set/handler.py
from config import TestingConfig, DevelopmentConfig

nginx_ip = DevelopmentConfig.nginx_ip
MONGODB_SCRIPT_PATH = DevelopmentConfig.MONGODB_SCRIPT_PATH

改进策略:

flask中提供current_app来标示当前application。相关的config信息在调用create_app()的时候已经对application进行了初始化,在业务代码中不应该再次使用从配置文件中去加载,也不应该和不需要关心当前的配置环境(dev,test,prod) 。而是直接使用已经初始化的create_app.

改写如下:

from flask import current_app

CRP_URL = current_app.config['CRP_URL']
nginx_ip = current_app.config['nginx_ip']
MONGODB_SCRIPT_PATH = current_app.config['MONGODB_SCRIPT_PATH']

如果改用current_app, 相关变量都可以使用了,都没有必要提前去获取了。

扩展阅读:

flask 源码中的一个例子:
https://github.com/pallets/flask/blob/master/flask/json/init.py

def _dump_arg_defaults(kwargs):
    """Inject default arguments for dump functions."""
    if current_app:
        bp = current_app.blueprints.get(request.blueprint) if request else None
        kwargs.setdefault(
            'cls',
            bp.json_encoder if bp and bp.json_encoder
                else current_app.json_encoder
        )

        if not current_app.config['JSON_AS_ASCII']:
            kwargs.setdefault('ensure_ascii', False)

        kwargs.setdefault('sort_keys', current_app.config['JSON_SORT_KEYS'])
    else:
        kwargs.setdefault('sort_keys', True)
        kwargs.setdefault('cls', JSONEncoder)

flask example 中的一个例子:
https://github.com/pallets/flask/blob/master/examples/flaskr/flaskr/blueprints/flaskr.py

from sqlite3 import dbapi2 as sqlite3
from flask import Blueprint, request, session, g, redirect, url_for, abort, \
     render_template, flash, current_app


# create our blueprint :)
bp = Blueprint('flaskr', __name__)


def connect_db():
    """Connects to the specific database."""
    rv = sqlite3.connect(current_app.config['DATABASE'])
    rv.row_factory = sqlite3.Row
    return rv


def init_db():
    """Initializes the database."""
    db = get_db()
    with current_app.open_resource('schema.sql', mode='r') as f:
        db.cursor().executescript(f.read())
    db.commit()
上一篇下一篇

猜你喜欢

热点阅读