Lessweb 配置系统
Lessweb 框架提供了一个强大而灵活的配置系统,支持 TOML 格式的配置文件、多环境配置、环境变量覆盖以及模块化配置管理。
配置系统概述
Lessweb 的配置系统具有以下特性:
- TOML 格式:使用易读易写的 TOML 格式
- 多环境支持:支持基于环境的配置文件自动加载
- 环境变量覆盖:支持通过环境变量覆盖配置文件中的值
- 模块化配置:支持为不同模块定义独立的配置结构
- Pydantic 验证:使用 Pydantic 进行配置验证和类型检查
配置文件组织
基本用法
在创建 Bridge 实例时,可以指定配置文件或配置目录:
from lessweb import Bridge
# 使用配置目录
bridge = Bridge('config')
# 使用单个配置文件
bridge = Bridge('config.toml')
配置目录结构
当使用配置目录时,Lessweb 会自动加载目录中的所有 .toml
文件:
config/
├── lessweb.toml # 框架核心配置
├── mysql.toml # MySQL 配置
├── redis.toml # Redis 基础配置
├── redis.production.toml # Redis 生产环境配置
└── other.toml # 其他模块配置
多环境配置
Lessweb 支持基于 ENV
环境变量的多环境配置:
- 设置环境变量:
export ENV=production
- 创建对应环境的配置文件:
redis.production.toml
- 框架会优先加载环境特定的配置文件
环境变量覆盖
配置系统支持通过环境变量覆盖配置文件中的任何值。环境变量名规则:
- 使用配置路径的大写形式
- 用下划线连接层级
示例:
# config.toml
[lessweb]
port = 8080
[lessweb.logger]
level = 'INFO'
[mysql]
host = 'localhost'
port = 3306
对应的环境变量:
export LESSWEB_PORT=9000
export LESSWEB_LOGGER_LEVEL=DEBUG
export MYSQL_HOST=production-db.example.com
export MYSQL_PORT=3307
Lessweb 框架配置
核心配置项
在配置文件中,使用 [lessweb]
节定义框架核心配置:
[lessweb]
port = 80 # 服务器端口(默认为8080)
enable_global_error_handling = false # 是否启用全局错误处理(默认为true)
orjson_option = 'SORT_KEYS,STRICT_INTEGER,UTC_Z,...' # orjson 序列化选项
配置项说明
配置项 | 类型 | 默认值 | 说明 |
---|---|---|---|
port |
int | 8080 | HTTP 服务器监听端口 |
enable_global_error_handling |
bool | true | 是否启用全局错误处理中间件 |
orjson_option |
str | '' | orjson 库的序列化选项配置 |
日志配置
在 [lessweb.logger]
节中配置日志系统:
[lessweb.logger]
format = '%(asctime)s %(name)s %(filename)s:%(lineno)d %(levelname)s - %(message)s'
level = 'INFO' # 日志级别:DEBUG, INFO, WARNING, ERROR
stream = 'stdout' # 输出目标:stdout, stderr, file
name = 'my-app' # 指定日志器名称
file = 'logs/myapp.log' # 日志文件路径(stream=file时使用)
# 日志轮转配置(可选)
[lessweb.logger.rotating]
when = 'd' # 轮转时机:d(天), h(小时), m(分钟)
interval = 1 # 轮转间隔
backup_count = 30 # 保留备份数量
suffix = "%Y%m%d" # 备份文件名后缀格式
日志配置项说明
配置项 | 类型 | 默认值 | 说明 |
---|---|---|---|
format |
str | '%(asctime)s %(name)s %(filename)s:%(lineno)d %(levelname)s - %(message)s' |
日志格式字符串 |
level |
str | 'INFO' | 日志级别,可选:DEBUG, INFO, WARNING, ERROR |
stream |
str | 'stdout' | 输出目标,可选:stdout, stderr, file |
name |
str | None | 指定的日志器名称(可选) |
file |
str | None | 日志文件路径,当 stream='file' 时必需 |
日志轮转配置:
配置项 | 类型 | 默认值 | 说明 |
---|---|---|---|
when |
str | 'd' | 轮转时机:'d'(天), 'h'(小时), 'm'(分钟) |
interval |
int | 1 | 轮转间隔数 |
backup_count |
int | 30 | 保留的备份文件数量 |
suffix |
str | "%Y%m%d" | 备份文件名的时间戳后缀格式 |
示例配置
# lessweb.toml
[lessweb]
port = 8080
enable_global_error_handling = true
[lessweb.logger]
format = '%(asctime)s %(name)s %(filename)s:%(lineno)d %(levelname)s - %(message)s'
level = 'INFO'
stream = 'file'
name = 'my-web-app'
file = 'logs/myapp.log'
[lessweb.logger.rotating]
when = 'd'
interval = 1
backup_count = 30
suffix = "%Y%m%d"
模块配置系统
定义配置模型
使用 Pydantic 定义配置模型:
from pydantic import BaseModel
class RedisConfig(BaseModel):
host: str
port: int
password: str | None = None
db: int = 0
class MysqlConfig(BaseModel):
host: str
port: int = 3306
user: str
password: str
db: str
maxsize: int = 20
autocommit: bool = True
在模块中使用配置
在 Module 子类中实现 load_config
方法:
from typing import Annotated
from lessweb import Module, load_module_config
class RedisModule(Module):
def load_config(self, app: Application) -> Annotated[RedisConfig, 'redis']:
return load_module_config(app, 'redis', RedisConfig)
async def on_startup(self, app: Application) -> None:
config = self.load_config(app)
# 使用配置初始化 Redis 连接
self.redis_client = redis.Redis(
host=config.host,
port=config.port,
password=config.password,
db=config.db,
decode_responses=True,
)
load_module_config 函数
def load_module_config(app: Application, module_config_key: str, module_config_cls: Type[T]) -> T:
"""
加载指定模块的配置
参数:
app: aiohttp Application 实例
module_config_key: 配置键名,对应 TOML 文件中的节名
module_config_cls: Pydantic 配置模型类
返回:
配置模型实例
"""
完整使用示例
1. 配置文件
# config/lessweb.toml
[lessweb]
port = 8080
[lessweb.logger]
level = 'INFO'
stream = 'file'
file = 'logs/myapp.log'
# config/mysql.toml
[mysql]
host = '127.0.0.1'
port = 3306
user = 'username'
password = 'password'
db = 'database'
maxsize = 20
2. 配置模型定义
# models/config.py
from pydantic import BaseModel
class RedisConfig(BaseModel):
host: str
port: int
password: str | None = None
db: int
class MysqlConfig(BaseModel):
host: str
port: int = 3306
user: str
password: str
db: str
maxsize: int = 20
3. 模块实现
# modules/redis_module.py
from typing import Annotated
import redis.asyncio as redis
from aiohttp.web import Application
from lessweb import Module, load_module_config
from models.config import RedisConfig
class RedisModule(Module):
def load_config(self, app: Application) -> Annotated[RedisConfig, 'redis']:
return load_module_config(app, 'redis', RedisConfig)
async def on_startup(self, app: Application) -> None:
config = self.load_config(app)
self.redis_client = redis.Redis(
host=config.host,
port=config.port,
password=config.password,
db=config.db,
decode_responses=True,
)
async def on_cleanup(self, app: Application) -> None:
await self.redis_client.aclose()
def redis_bean(redis_module: RedisModule) -> redis.Redis:
return redis_module.redis_client
4. 应用启动
# main.py
from lessweb import Bridge
from modules.redis_module import redis_bean
def main():
# 使用配置目录初始化
bridge = Bridge('config')
# 注册 bean
bridge.beans(redis_bean)
# 扫描并注册路由
bridge.scan('src')
# 启动应用
bridge.run_app()
if __name__ == '__main__':
main()
5. 使用环境变量覆盖
# 设置环境和覆盖配置
export ENV=production
export REDIS_HOST=redis.production.example.com
export MYSQL_HOST=db.production.example.com
export LESSWEB_PORT=9000
python main.py
最佳实践
1. 配置文件组织
- 将不同模块的配置分离到独立的 TOML 文件
- 使用环境特定的配置文件管理多环境差异
- 敏感信息(密码、密钥)通过环境变量覆盖
2. 配置模型设计
- 使用 Pydantic 模型定义配置结构
- 为配置项提供合理的默认值
- 使用类型注解增强代码可读性
3. 模块配置
- 在 Module 的
load_config
方法中加载配置 - 在
on_startup
中使用配置初始化资源 - 在
on_cleanup
中正确清理资源
4. 安全考虑
- 不要将敏感信息提交到版本控制
- 使用环境变量或外部密钥管理系统
- 在生产环境中限制配置文件访问权限
通过这套配置系统,你可以轻松管理复杂应用的配置需求,同时保持代码的清晰和可维护性。