FastApi(自用脚手架)+Snowy搭建后台管理系统(7)脚手架--APP应用配置
前言
通常我们的应用程序需要进行一些常量等信息的配置。比如:APP 项目名称,文档版本信息,服务器监听端口,数据库相关配置项信息,日志配置项信息等等。甚至于一些敏感数据配置项信息我们不可能是硬编码在源代码中,所以我们需要有相关机制进行各种配置项信息的读取以及相关校验处理。因此,本小节,将介绍如何对我们APP应用的配置处理。如下如所示:
配置项配置
首先我们Fastapi提供的基于pydantic的BaseSettings天然支持上述一些读取环境变量信息和配置项校验等处理机制。但是我们需要根据我们运行环境配置不同的配置信息,所以我们的如上图所示中,分为了
- base 是具体环境配置通用的配置
- development 开发环境下的配置(基于base覆盖配置)
- production 正式环境下的配置(基于base覆盖配置)
- setting 是配置实例入口
应该的配置项中也是其他插件中需要配置项重要来源。
1.base配置
下面的配置项是项目不管任何环境都是一样的配置项,如下代码所示:
from typing import Optional, MutableMapping, Any, Union
from pydantic import BaseSettings
from afast_core.core_libs.starsessions import CookieStore, AsyncRedisStore, InMemoryStore
from afast_core.core_plugins.loguru.enums import RecordModel
class ISettings(BaseSettings):
''' 应用基础的配置项信息'''
project_name: str = 'Snowy-FastApi个人脚手架后台api示例'
project_version: str = '1.0.0'
environment: str = 'production'
debug: bool = False
# ===========日志插件参数配置==============
# 日志插件参数配置
LOG_MODEL = RecordModel.SCATTERED
# 配置日志相关信息
LOG_PROJECT_SLUG: str = "info"
# 日志文件的目录,当前插件初始化位置所在的目录
LOG_FILE_PATH: str = "./snowy_logs"
# 日志文件切割的日期- rotation='00:00', # 每天 0 点创建一个新日志文件
LOG_FILE_ROTATION: str = "00:00"
# 日志文件的保留的天数 # retention="7 days", # 定时自动清理文件
LOG_FILE_RETENTION: Union[int, str] = 8
# 日志压缩的搁置
LOG_FILE_COMPRESSION: str = "gz"
# 日志记录的等等级
LOG_FILE_LEVEL: str = "INFO"
# 日志需要过滤的不做记录的URL请求
FLITER_REQUEST_URL = ['/favicon.ico', '/docs', '/', '/openapi.json', '/health_checks',
'/static/swagger-ui.css',
'/static/swagger-ui-bundle.js',
]
# ===========SwaggeruiPluginClient插件参数配置==============
swaggerui_proxy: bool = False
# ===========SessionPluginClient插件参数配置==============
session_store: Union[CookieStore, AsyncRedisStore, InMemoryStore] = CookieStore(secret_key='kTd5NsCsaj52TzHb')
# 只是只允许https读取
session_cookie_https_only: bool = False
# 会话生存时间
session_lifetime: int = 3600 * 24 * 14
# 是否自动加载
session_is_auto_load: bool = True
# 是否滚地会话时效续期
session_is_rolling: bool = False
# ===========SqlalchemyPluginForClassV2Client插件参数配置==============
# MYSQL_SERVER_HOST: str
# MYSQL_USER_NAME: str
# MYSQL_PASSWORD: str
# MYSQL_DB_NAME: str
# # 数据库连接池
# SQLALCHEMY_DATABASE_ECHO: bool
# SQLALCHEMY_POOL_RECYCLE: int
# SQLALCHEMY_POOL_PRE_PING: bool
# SQLALCHEMY_POOL_SIZE: int
# SQLALCHEMY_MAX_OVERFLOW: int
2.开发和生产环境配置项
开发和生产环境配置项都是基于base配置而来,如下代码所示:
#!/usr/bin/evn python
# -*- coding: utf-8 -*-
from snowy_src.snowy_system.snowy_settings.base import ISettings
class DevSettings(ISettings):
''' 应用基础的配置项信息'''
environment: str = 'development'
debug: bool = True
# ===========SqlalchemyPluginForClassV2Client插件参数配置==============
MYSQL_SERVER_HOST: str = "47.99.189.42:31166"
MYSQL_USER_NAME: str = "root"
MYSQL_PASSWORD: str = "xiaozhong123456"
MYSQL_DB_NAME: str = "snowypy2"
# 数据库连接池
SQLALCHEMY_DATABASE_ECHO: bool = False
SQLALCHEMY_POOL_RECYCLE: int = 7200
SQLALCHEMY_POOL_PRE_PING: bool = True
SQLALCHEMY_POOL_SIZE: int = 20
SQLALCHEMY_MAX_OVERFLOW: int = 64
class ProSettings(ISettings):
''' 应用基础的配置项信息'''
environment: str = 'production'
debug: bool = False
# ===========SqlalchemyPluginForClassV2Client插件参数配置==============
MYSQL_SERVER_HOST: str = "47.99.189.42:31166"
MYSQL_USER_NAME: str = "root"
MYSQL_PASSWORD: str = "xiaozhong123456"
MYSQL_DB_NAME: str = "snowypy2"
# 数据库连接池
SQLALCHEMY_DATABASE_ECHO: bool = False
SQLALCHEMY_POOL_RECYCLE: int = 7200
SQLALCHEMY_POOL_PRE_PING: bool = True
SQLALCHEMY_POOL_SIZE: int = 20
SQLALCHEMY_MAX_OVERFLOW: int = 64
3.配置项入口实例化
实例化入口包含创建DevSettingsBuilder和ProSettingsBuilder类的定义,它们分别负责返回对应的DevSettings和ProSettings的对象。如下代码所示:
#!/usr/bin/evn python
# -*- coding: utf-8 -*-
from typing import MutableMapping, Any, Union
import os
from snowy_src.snowy_system.snowy_settings.base import ISettings
from snowy_src.snowy_system.snowy_settings.development import DevSettings
from snowy_src.snowy_system.snowy_settings.production import ProSettings
class DevSettingsBuilder():
''' 开发环境的配置 '''
@classmethod
def build(cls) -> ISettings:
return DevSettings()
class ProSettingsBuilder():
''' 开发环境的配置 '''
@classmethod
def build(cls) -> ISettings:
return ProSettings(environment='production')
然后定义完成DevSettingsBuilder和ProSettingsBuilder类的定义后,再定义一个Environment类,其中它负责根据不同的环境返回不同的势力对对象。如下代码所示:
class Environment():
'''
该静态方法实现了从环境变量中读取设置,并将其转换为Settings类型,以便使用。
'''
@staticmethod
def select() -> Union[DevSettings, ProSettings, ISettings]:
'''
定义静态方法select,它返回一个Settings类型的值;
:return:
'''
# 根据环境变量的来选择使用的配置
env_vars: MutableMapping[Any, Any] = os.environ
print("环境变量信息", env_vars)
# 根据不同环境变量返回不同的环境配置实例对象
if env_vars.get('environment') == 'development':
settings_class = DevSettingsBuilder
# 如果是正式环境则使用正式环境的配置
elif env_vars.get('environment') == 'production':
settings_class = DevSettingsBuilder
else:
# 默认的是要开发环境的配置信息
settings_class = DevSettingsBuilder
# 创建配置实例对象
settings = settings_class().build()
print(settings)
return settings
4:应用启动创建时候开始初始化
完成相关的配置信息处理后,接下来进行环境配置项的初始化,如下代码所示:
app = FastApplicationBuilder \
.with_environment_settings() \
.build()
其中最关键的是with_environment_settings()方法的调用,其中细节代码如下:
class FastApplicationBuilder(IApplicationBuilder):
def __init__(self, *, settings: Union[DevSettings, ProSettings]):
''' 创建APP实例对象 '''
if settings is None:
# 检测是否存在配置实例对象
raise RuntimeError('Must provide a valid Settings object')
self.settings = settings
@classmethod
def with_environment_settings(cls) -> 'FastApplicationBuilder':
''' 根据当前环境变量选择指定的环境配置实例 '''
return cls(settings=Environment.select())
至此,关于APP应用配置相关介绍分享已完成!以上内容分享纯属个人经验,仅供参考!
文笔有限,如有笔误或错误!欢迎批评指正!感谢各位大佬!有什么问题也可以随时交流!
结尾
转载自:https://juejin.cn/post/7196274316512854053