每个服务都有自己的独立的配置文件,当然通常我们的一些关键的配置文件信息,一般不会直接写在本地,但是不管怎么样总汇有一个是需要些本地,即便你是通过类似Etcd或Nacos等服务配置中心等获取相关配置信息,所以本地还是还是需要保留一份关于配置信息读取。
本节涉及知识点:
编写配置我们的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模块对象的启动已经规划完成。那杰西莱我们的主要是如何启动的时候,开始读取的配置信息。
#!/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'
]
#!/usr/bin/evn python
# coding=utf-8
from .default import Config
class DevConfig(Config):
LOG_LEVEL = 'debug'
#!/usr/bin/evn python
# coding=utf-8
from .default import Config
class ProdConfig(Config):
LOG_LEVEL = 'error'
#!/usr/bin/evn python
# coding=utf-8
from .default import Config
class ProdConfig(Config):
LOG_LEVEL = 'error'
#!/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)
上述结果说明了我们已经成功读取了我们类里面配置信息了。
定义我们的配置文件对象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)
编辑配置文件
写自己的环境变量信息
修改我们的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)
以上就是三种模式的配置信息读取,后续的我们的脚手架采取是第一种方式,从对象中获取。
小钟同学 | 文 【原创】【转载请联系本人】| QQ:308711822
原文作者:程序员小钟同学;如有侵权,请联系管理员删除。