ITPub博客

首页 > 数据库 > 数据库开发技术 > Flask + Ant Vue 实战(4)-脚手架配置文件读取解析

Flask + Ant Vue 实战(4)-脚手架配置文件读取解析

原创 数据库开发技术 作者:程序员小钟同学 时间:2021-02-24 17:07:12 0 删除 编辑

前言

每个服务都有自己的独立的配置文件,当然通常我们的一些关键的配置文件信息,一般不会直接写在本地,但是不管怎么样总汇有一个是需要些本地,即便你是通过类似Etcd或Nacos等服务配置中心等获取相关配置信息,所以本地还是还是需要保留一份关于配置信息读取。

配置文件读取解析


本节涉及知识点:

  • 通过加载类对象形式加载配置信息
  • 通过文件形式加载配置文件
  • 通过环境变量形式加载配置信息

规划backend中的App对象创建工厂模式创建App

编写配置我们的backend中的app.py,创建工厂模式创建App,规划初步的加载相关信息的形式:

#!/usr/bin/evn python
# coding=utf-8
import os
from flask import Flask, jsonify
from backend.config import config


def __init_config(app):
    # 读取的该插件的下自定义的配置信息对象
    import os
    run_mode = os.getenv('FASTAPI_MODE', 'test')
    app.config.from_object(config[run_mode])


def __init_ext(app):
    '''
    第三方模块单例模式的初始化
    :param app:
    :return:
    '
''
    pass


def __init_db(app):
    '''
    数据库对象初始化
    :return:
    '
''
    pass


def __init_route(app):
    # 初始化该插件的下的蓝图路由
    pass


def __init_error_handlers(app):
    pass

    # 自定义404错误码的返回信息异常的处理
    # app.register_error_handler(APIError, error_handler)

    @app.errorhandler(Exception)
    def custom_error_handler(e):
        pass


def __init_hooks(app):
    pass

    # app.before_request(before_request_handler)
    # app.after_request(after_request_handler)
    # 在第一次请求之前运行
    @app.before_first_request
    def before_first_request():
        pass

    @app.before_request
    def before_request():
        '''
        收到请求前的钩子
        :return:
        '
''
        # 请求记录初始化
        pass

    @app.after_request
    def after_request(response):
        '''
               收到请求后的钩子
               :param response:http返回结构体
               :return:
        '
''
        return response

    # 无论视图函数是否出现异常,每一次请求之后都会调用,会接受一个参数,参数是服务器出现的错误信息(Debug模式下不会执行)
    @app.teardown_request
    def teardown_request(error):
        pass


def __init_all_plugins(app):
    '''
     # 全局初始化第三方的插件
    :return:
    '
''
    pass


def __init_celery_plugins():
    '''
     # 全局初始化第三方的插件
    :return:
    '
''
    pass


def __register_customize_log_loguru():
    '''
    配置日志路径和配置信息--定义到当前项目目录内进行创建log文件
    :return:
    '
''
    pass


def __health_chcek_route(app):
    pass

    @app.route('/backend_health')
    def backend_health():
        return 'ok'

    @app.route('/')
    def route_map():
        """
        主视图,返回所有视图网址
        "
""
        rules_iterator = app.url_map.iter_rules()
        return jsonify(
            {rule.endpoint: rule.rule for rule in rules_iterator if rule.endpoint not in ('route_map', 'static')})


def create_app():
    app = Flask(__name__)
    # 初始化默认有的路由
    __health_chcek_route(app)
    # 初始化配置信息----初始化优先级1
    __init_config(app)
    # # 初始化数据库的链接
    __init_db(app)
    __register_customize_log_loguru()
    # 全局错误处理初始化
    __init_error_handlers(app)
    # 初始化钩子异常
    __init_hooks(app)
    # 初始化相关的第三方的插件库
    __init_all_plugins(app)
    # WSGI代理支持
    # app.wsgi_app = ProxyFix(app.wsgi_app, num_proxies=1)
    return app


def create_celery_app():
    # 初始化配置信息----仅用于配置文件信息的读取
    __init_celery_plugins()
    # print(app.url_map)
    return app


# from apicore.ext.celery_flask import make_celery

if __name__ == '__main__':
    app = create_app()
    print(app.env)
    print(app.url_map)
    app.run(host='127.0.0.1', port='5000', debug=True)


上面的代码运行后输出的结果为:

production
Map([<Rule '/backend_health' (OPTIONS, HEAD, GET) -> backend_health>,
 <Rule '/' (OPTIONS, HEAD, GET) -> route_map>,
 <Rule '/static/<filename>' (OPTIONS, HEAD, GET) -> static>])
 * Debugger is active!
 * Debugger PIN: 104-589-570
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

初步的我们的app模块对象的启动已经规划完成。那杰西莱我们的主要是如何启动的时候,开始读取的配置信息。

读取配置信息

第1种 通过app.config.from_object类型对象形式加载配置文件

  1. 定义配置类信息,分开具体环境
  2. 通过app.config.from_object进行加载配置类

1)新建default.py基础通用配置信息

#!/usr/bin/evn python
# coding=utf-8

class Config:
    # **********************************************************************************************
    # **********************************************************************************************
    # 系统自带的原生的日志信息的配置
    # ==============================================================================================
    # ==============================================================================================
    LOG_PATH = 'logs/'
    LOG_FILENAME = 'info.log'
    LOG_LEVEL = 'info'
    # 日志信息的配置
    ERROR_LOG_FILENAME = 'error.log'
    ERROR_LOG_LEVEL = 'error'

    # **********************************************************************************************
    # **********************************************************************************************
    # 第三方的LOGURU日志信息的配置
    # ==============================================================================================
    # ==============================================================================================
    LOGURU_LOG_PATH = 'logs\\'
    #
    # """默认配置"""
    # # mysql配置
    # SQLALCHEMY_DATABASE_URI = 'mysql://root:mysql@192.168.174.129:3306/hm_top_news'
    # # 主从数据库的URI
    # SQLALCHEMY_BINDS = {
    #     "master": 'mysql://root:mysql@192.168.174.129:3306/hm_top_news',
    #     "slave1": 'mysql://root:mysql@192.168.174.129:3306/hm_top_news',
    #     "slave2": 'mysql://root:mysql@192.168.174.129:8306/hm_top_news'
    # }
    # SQLALCHEMY_TRACK_MODIFICATIONS = False
    # SQLALCHEMY_ECHO = False
    #
    # # redis配置
    # # REDIS_HOST = '192.168.174.129'
    # # REDIS_PORT = 6381
    #
    # # redis集群配置
    # CLUSTER_NODES = [  # 集群中主数据库的ip和端口号
    #     {'host': '192.168.174.129', 'port': 7000},
    #     {'host': '192.168.174.129', 'port': 7001},
    #     {'host': '192.168.174.129', 'port': 7002},
    # ]
    #
    # # 设置哨兵的ip和端口
    # SENTINEL_LIST = [
    #     ('192.168.174.129', 26380),
    #     ('192.168.174.129', 26381),
    #     ('192.168.174.129', 26382),
    # ]
    #
    # SERVICE_NAME = 'mymaster'  # 哨兵配置的主数据库别名

    # **********************************************************************************************
    # **********************************************************************************************
    # 数据链接的配置信息
    # ==============================================================================================
    # ==============================================================================================
    SQLALCHEMY_TRACK_MODIFICATIONS = True
    SQLALCHEMY_COMMIT_ON_TEARDOWN = True
    SQLALCHEMY_DATABASE_URI = 'postgresql://postgres:123456@localhost:5432/youbao_system_v2'
    # 链接的数据库信息
    # SQLALCHEMY_DATABASE_URI = 'sqlite:///user.db'

    # 如果设置为Ture, SQLAlchemy 会记录所有 发给 stderr 的语句,这对调试有用。(打印sql语句)
    SQLALCHEMY_ECHO = True
    # 如果为True,则连接池将记录信息输出,例如连接失效时以及连接被回收到默认日志处理程序时,默认sys.stdout为输出。如果设置为字符串 "debug",则日志记录将包括池检出和签入。使用标准Python logging模块也可以直接控制日志记录 。
    # SQLALCHEMY_ECHO_POOL = True
    # 数据库连接池的大小。默认是引擎默认值
    # SQLALCHEMY_POOL_SIZE = 20
    # 设定连接池的连接超时时间。默认是 10 。
    # SQLALCHEMY_POOL_TIMEOUT = 10

    ENABLE_SENTRY = False
    SENTRY_DSN = ''

    # **********************************************************************************************
    # **********************************************************************************************
    # PEEWEE数据库链接的配置
    # self._db_host = self.app.config.get('PEEWEE_CONFIG_DB_HOST', "localhost")
    # self._db_name = self.app.config.get('PEEWEE_CONFIG_DB_NAME', "postgres")
    # self._db_user = self.app.config.get('PEEWEE_CONFIG_DB_USER', "postgres")
    # self._db_pass = self.app.config.get('PEEWEE_CONFIG_DB_PASSWORD', "123456")
    # self._db_port = self.app.config.get('PEEWEE_CONFIG_DB_PORT', "5432")
    # self._max_connections = self.app.config.get('PEEWEE_CONFIG_DB_MAX_CONNECTIONS', 60)
    # self._stale_timeout = self.app.config.get('PEEWEE_CONFIG_DB_STALE_TIMEOUT', 300)
    # self._timeout = self.app.config.get('PEEWEE_CONFIG_DB_TIMEOUT', 20)
    # ==============================================================================================
    # ==============================================================================================
    PEEWEE_CONFIG_DB_HOST = '数据库的HOTP'  # token密钥
    PEEWEE_CONFIG_DB_NAME = '数据库名称'
    PEEWEE_CONFIG_DB_USER = '数据库用户名称'
    PEEWEE_CONFIG_DB_PASSWORD = '数据库密码'
    PEEWEE_CONFIG_DB_PORT = 5432
    PEEWEE_CONFIG_DB_MAX_CONNECTIONS = 60
    PEEWEE_CONFIG_DB_STALE_TIMEOUT = 300
    PEEWEE_CONFIG_DB_TIMEOUT = 20

    # **********************************************************************************************
    # **********************************************************************************************
    # 服务启动的相关的信息
    # ==============================================================================================
    # ==============================================================================================
    REDIS_HOST = 'localhost'
    REDIS_PORT = 6379
    REDIS_DB = 0
    REDIS_PASSWORD = '123456'

    REQUEST_STATS_WINDOW = 60

    # **********************************************************************************************
    # **********************************************************************************************
    # 消息队列的redis缓存的信息
    # ==============================================================================================
    # ==============================================================================================
    CELERY_BROKER_URL = 'redis://localhost:6379/0'
    CELERY_RESULT_BACKEND = 'redis://localhost:6379/1'
    CELERY_TASK_SERIALIZER = 'msgpack'
    CELERY_RESULT_SERIALIZER = 'json'
    CELERY_TASK_RESULT_EXPIRES = 60 * 60
    CELERY_ACCEPT_CONTENT = ['json', 'msgpack']

    RATELIMIT_HEADERS_ENABLED = True

    # **********************************************************************************************
    # **********************************************************************************************
    # Flask-Caching---缓存的插件的前缀的配置及相关的链接的配置
    # ==============================================================================================
    # ==============================================================================================
    CACHE_TYPE = 'redis'
    CACHE_KEY_PREFIX = 'rx::'
    CACHE_REDIS_HOST = 'localhost'
    CACHE_REDIS_PASSWORD = ''
    CACHE_REDIS_PORT = 6379
    CACHE_REDIS_DB = 2
    CACHE_DEFAULT_TIMEOUT = 60 * 60

    # **********************************************************************************************
    # **********************************************************************************************
    # flask_limiter--插件的的配置
    # ==============================================================================================
    # ==============================================================================================
    # RATELIMIT_APPLICATION 应用策略,用于将限制应用于整个应用程序(即,由所有路由共享)。
    RATELIMIT_APPLICATION = False
    # RATELIMIT_STORAGE_URL 存储位置:
    RATELIMIT_STORAGE_URL = 'redis://127.0.0.1:6379/2'

    # **********************************************************************************************
    # **********************************************************************************************
    # flask-session
    # 作用:可以让session持久化存储
    # 使用redis数据库,先要开启redis数据库
    # ==============================================================================================
    # ==============================================================================================
    SESSION_TYPE = 'redis'  # 必选
    SESSION_COOKIE_NAME = 'rf'  # 设置session的别名rf,可选项
    SESSION_COOKIE_LIFETIME = 60  # 设置session的过期时间60s,可选项

    # **********************************************************************************************
    # **********************************************************************************************
    # Flask-Bcrypt
    # 作用:Flask-Bcrypt是一个Flask扩展,它为你的应用提供了bcrypt散列功能
    # BCRYPT_LOG_ROUNDS选项可以在flask应用中进行配置,这个值会决定encryption的复杂程度,默认值为12。(详情见bcrypt。)
    # ==============================================================================================
    # ==============================================================================================
    BCRYPT_LOG_ROUNDS = 12

    # **********************************************************************************************
    # **********************************************************************************************
    # flask_jwt_extended
    # 作用:用户的认证处理
    # ==============================================================================================
    # ==============================================================================================
    JWT_SECRET_KEY = 'zyxyuanxiaos'  # token密钥
    JWT_BLACKLIST_ENABLED = True  # 黑名单管理
    JWT_BLACKLIST_TOKEN_CHECKS = ['access', 'refresh']  # 允许将access and refresh tokens加入黑名单

    # **********************************************************************************************
    # **********************************************************************************************
    # 系统后台登入的免验证的检查的白名单接口
    # 作用:用户的认证处理
    # ==============================================================================================
    # ==============================================================================================
    ADMIN_WHILE_ROUTE = [
        # '/sys/user/logout',
        '/sys/user/login',
        '/',
        '/websocket/1'
    ]
    # **********************************************************************************************
    # **********************************************************************************************
    # 系统后台登入的日志记录记录日志信息的接口白名单关键词信息
    # 作用:这些地址不记录到日志表里面
    # ==============================================================================================
    # ==============================================================================================
    NOT_LOG_WIRTE_ULR_KEYWORED = [
        '/',
        '/sys/dict/getDictItems/activiti_sync',
        '/sys/dict/getDictItems/global_perms_type',
        '/sys/dict/getDictItems/valid_status',
        '/sys/dict/getDictItems/position_rank',
        '/sys/visitInfo',
        '/sys/loginfo',
        '/sys/duplicate/check',
        '/sys/annountCement/listByUser',
        '/sys/dict/getDictItems/operate_type',
        '/sys/log/list',
        '/favicon.ico'
    ]

2)新建dev.py开发环境配置信息

#!/usr/bin/evn python
# coding=utf-8

from .default import Config

class DevConfig(Config):
    LOG_LEVEL = 'debug'

3)新建prod.py线上生产环境配置信息

#!/usr/bin/evn python
# coding=utf-8


from .default import Config

class ProdConfig(Config):
    LOG_LEVEL = 'error'

4)test.py测试环境配置信息

#!/usr/bin/evn python
# coding=utf-8


from .default import Config

class ProdConfig(Config):
    LOG_LEVEL = 'error'

5) config包下的__init__里导入我们的初始化我们的配置环境的对象

#!/usr/bin/evn python
# coding=utf-8

from .dev import DevConfig
from .test import TestConfig
from .prod import ProdConfig


config = {
    'dev': DevConfig,
    'test': TestConfig,
    'prod': ProdConfig
}

修改我们的app.py初始化__init_config的访问,使用app.config.from_object进行加载

def __init_config(app):
    # 读取的该插件的下自定义的配置信息对象
    import os
    run_mode = os.getenv('FASTAPI_MODE', 'test')
    app.config.from_object(config[run_mode])

查看我们的这种方式读取的配置结果: 修改我们的app.py,启动的时候输出相关的测试信息数据

if __name__ == '__main__':
    app = create_app()
    print(app.env)
    print(app.url_map)
    print('ADMIN_WHILE_ROUTE',app.config.get('ADMIN_WHILE_ROUTE', ""))
    print('NOT_LOG_WIRTE_ULR_KEYWORED',app.config.get('NOT_LOG_WIRTE_ULR_KEYWORED', ""))
    app.run(host='127.0.0.1', port='5000', debug=True)

把服务跑起来之后查看结果显示为:

Map([<Rule '/backend_health' (OPTIONS, HEAD, GET) -> backend_health>,
 <Rule '/' (OPTIONS, HEAD, GET) -> route_map>,
 <Rule '/static/<filename>' (OPTIONS, HEAD, GET) -> static>])
ADMIN_WHILE_ROUTE ['/sys/user/login', '/', '/websocket/1']
NOT_LOG_WIRTE_ULR_KEYWORED ['/', '/sys/dict/getDictItems/activiti_sync', '/sys/dict/getDictItems/global_perms_type', '/sys/dict/getDictItems/valid_status', '/sys/dict/getDictItems/position_rank', '/sys/visitInfo', '/sys/loginfo', '/sys/duplicate/check', '/sys/annountCement/listByUser', '/sys/dict/getDictItems/operate_type', '/sys/log/list', '/favicon.ico']
 * Debugger is active!
 * Debugger PIN: 104-589-570
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

上述结果说明了我们已经成功读取了我们类里面配置信息了。

第2种 通过app.config.from_object类型对象形式加载配置文件

  1. 定义配置文件
  2. 通过app.config.from_pyfile("config.cfg")进行加载配置文件

定义我们的配置文件对象config.cfg:

LOG_LEVEL = 'debug'
DEBUG_TEXT= '测试读取'

修改我们的app.py初始化__init_config的访问,使用app.config.from_object进行加载

def __init_config(app):
    # 读取的该插件的下自定义的配置信息对象
    import os
    run_mode = os.getenv('FASTAPI_MODE', 'test')
    app.config.from_object(config[run_mode])
    # 新增这个从文件读取的方式--注意路径
    app.config.from_pyfile("D:/code/python/local_python/AntFlask/backend/config/config.cfg")

查看我们的这种方式读取的配置结果: 修改我们的app.py,启动的时候输出相关的测试信息数据

if __name__ == '__main__':
    app = create_app()
    print(app.env)
    print(app.url_map)
    print('ADMIN_WHILE_ROUTE',app.config.get('ADMIN_WHILE_ROUTE', ""))
    print('NOT_LOG_WIRTE_ULR_KEYWORED',app.config.get('NOT_LOG_WIRTE_ULR_KEYWORED', ""))
    
    # 读取文件里面的配置信息
    print('DEBUG_TEXT', app.config.get('DEBUG_TEXT', ""))
    app.run(host='127.0.0.1', port='5000', debug=True)



把服务跑起来之后查看结果显示为:

production
Map([<Rule '/backend_health' (OPTIONS, HEAD, GET) -> backend_health>,
 <Rule '/' (OPTIONS, HEAD, GET) -> route_map>,
 <Rule '/static/<filename>' (OPTIONS, HEAD, GET) -> static>])
ADMIN_WHILE_ROUTE ['/sys/user/login', '/', '/websocket/1']
NOT_LOG_WIRTE_ULR_KEYWORED ['/', '/sys/dict/getDictItems/activiti_sync', '/sys/dict/getDictItems/global_perms_type', '/sys/dict/getDictItems/valid_status', '/sys/dict/getDictItems/position_rank', '/sys/visitInfo', '/sys/loginfo', '/sys/duplicate/check', '/sys/annountCement/listByUser', '/sys/dict/getDictItems/operate_type', '/sys/log/list', '/favicon.ico']
DEBUG_TEXT 测试读取
 * Debugger is active!
 * Debugger PIN: 104-589-570
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

第3种 通过环境变量

  1. 编辑配置文件

  2. 写自己的环境变量信息

修改我们的app.py,启动的时候输出相关的测试信息数据

if __name__ == '__main__':
    app = create_app()
    print(app.env)
    print(app.url_map)
    print('ADMIN_WHILE_ROUTE',app.config.get('ADMIN_WHILE_ROUTE', ""))
    print('NOT_LOG_WIRTE_ULR_KEYWORED',app.config.get('NOT_LOG_WIRTE_ULR_KEYWORED', ""))
    print('DEBUG_TEXT', app.config.get('DEBUG_TEXT', ""))
    # 通过环境变量读取
    # print(app.config.from_envvar('GUAN'))
    print(os.getenv('XIAOZHONGCESHI', '默认值'))
    app.run(host='127.0.0.1', port='5000', debug=True)

把服务跑起来之后查看结果显示为:输出了=====》测试环境变量

Map([<Rule '/backend_health' (GET, HEAD, OPTIONS) -> backend_health>,
 <Rule '/' (GET, HEAD, OPTIONS) -> route_map>,
 <Rule '/static/<filename>' (GET, HEAD, OPTIONS) -> static>])
ADMIN_WHILE_ROUTE ['/sys/user/login', '/', '/websocket/1']
NOT_LOG_WIRTE_ULR_KEYWORED ['/', '/sys/dict/getDictItems/activiti_sync', '/sys/dict/getDictItems/global_perms_type', '/sys/dict/getDictItems/valid_status', '/sys/dict/getDictItems/position_rank', '/sys/visitInfo', '/sys/loginfo', '/sys/duplicate/check', '/sys/annountCement/listByUser', '/sys/dict/getDictItems/operate_type', '/sys/log/list', '/favicon.ico']
DEBUG_TEXT 测试读取
测试环境变量
 * Debugger is active!
 * Debugger PIN: 104-589-570
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

以上就是三种模式的配置信息读取,后续的我们的脚手架采取是第一种方式,从对象中获取。

END

小钟同学 | 文  【原创】【转载请联系本人】| QQ:308711822


原文作者:程序员小钟同学;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2021-02-20

  • 博文量
    224
  • 访问量
    111698