多个实例的Flask配置。最佳做法?

时间:2018-03-25 14:24:00

标签: flask configuration

在烧瓶中,配置模块非常简单,并且在互联网上有相同主题的最佳实践。

如果我必须开发支持多个实例的Application,例如假设应用程序支持的每个城市都有一个数据库,并且每个城市db都是托管在不同物理机器上的独立MongoDB实例。

支持我的示例的示例API代码:

from flask import Flask, request
from flask_restful import Resource, Api

app = Flask(__name__)
api = Api(app)

class CityPopulation(Resource):
    def get(self, city_name):
        '''
        CODE TO GET CITY BASED DB Config
        Currently in JSON format
        '''
        total_population = helper_city(city_name)
        return { population : total_population }


api.add_resource(CityPopulation, '/<string:city_name>/population')

if __name__ == '__main__':
    app.run(debug=True)

目前我所考虑的是一个json文件,其中包含DB的部分,如下所示

{
    db:[{
        'bengaluru' :{
            'host' : 'bengaluru.host.db'
            'port' : 27017,
            'user_name' : 'some_user',
            'password' : 'royalchallengers'
        },
        'hyderabad' :{
            'host' : 'hyderabad.host.db'
            'port' : 27017,
            'user_name' : 'some_user',
            'password' : 'sunrisers'
        }
    }]
}

和从JSON读取配置的类

class project_config:
    def __init__(self):
        with open(config_full_path, 'r') as myfile:
            configuration_raw = json.load(myfile)

在Flask中,配置模块的最佳实践建议如下

class BaseConfig(object):
    DEBUG = False
    TESTING = False

class DevelopmentConfig(BaseConfig):
    DEBUG = True
    TESTING = True

class TestingConfig(BaseConfig):
    DEBUG = False
    TESTING = True

我的方案是否可以包含烧瓶配置而不是维护单独的项目配置?就最佳实践而言。

1 个答案:

答案 0 :(得分:0)

The object based config in the flask docs is described an "an interesting pattern" but it's just one approach, not necessarily best practice.

You can update the contents of app.config in any way that makes sense for your use case. You could fetch values at run time from a service like etcd, zookeeper, or consul, or set them all via environment variables (a useful pattern with containerized apps), or load them from a config file like this.

import os
import json
from flask import Flask
from ConfigParser import ConfigParser

app = Flask(__name__)

def load_config():

    config = ConfigParser()
    config.read(os.environ.get('MY_APP_CONFIG_FILE'))

    for k, v in config.items('my_app'):
        app.config[k] = v

@app.route('/')
def get_config():
        return json.dumps(dict(app.config), default=str)    

load_config()

And then run it like:

$ cat test.ini 
[my_app]
thing = stuff
other_thing = junk

$ MY_APP_CONFIG_FILE=test.ini FLASK_APP=test.py flask run

$ curl -s localhost:5000 | jq '.'
{
  "JSON_AS_ASCII": true,
  "USE_X_SENDFILE": false,
  "SESSION_COOKIE_SECURE": false,
  "SESSION_COOKIE_PATH": null,
  "SESSION_COOKIE_DOMAIN": null,
  "SESSION_COOKIE_NAME": "session",
  "LOGGER_HANDLER_POLICY": "always",
  "LOGGER_NAME": "test",
  "DEBUG": false,
  "SECRET_KEY": null,
  "EXPLAIN_TEMPLATE_LOADING": false,
  "MAX_CONTENT_LENGTH": null,
  "APPLICATION_ROOT": null,
  "SERVER_NAME": null,
  "PREFERRED_URL_SCHEME": "http",
  "JSONIFY_PRETTYPRINT_REGULAR": true,
  "TESTING": false,
  "PERMANENT_SESSION_LIFETIME": "31 days, 0:00:00",
  "PROPAGATE_EXCEPTIONS": null,
  "TEMPLATES_AUTO_RELOAD": null,
  "TRAP_BAD_REQUEST_ERRORS": false,
  "thing": "stuff",                         <---
  "JSON_SORT_KEYS": true,
  "JSONIFY_MIMETYPE": "application/json",
  "SESSION_COOKIE_HTTPONLY": true,
  "SEND_FILE_MAX_AGE_DEFAULT": "12:00:00",
  "PRESERVE_CONTEXT_ON_EXCEPTION": null,
  "other_thing": "junk",                    <---
  "SESSION_REFRESH_EACH_REQUEST": true,
  "TRAP_HTTP_EXCEPTIONS": false
}