first commit

This commit is contained in:
rjb
2025-12-21 00:20:27 +08:00
commit 6fb3c6c23d
42 changed files with 2265 additions and 0 deletions

43
config/__init__.py Normal file
View File

@@ -0,0 +1,43 @@
"""
配置管理模块
根据环境变量自动选择对应的配置类
"""
import os
from .base import Config
from .development import DevelopmentConfig
from .production import ProductionConfig
from .testing import TestingConfig
from .local import LocalConfig
# 配置映射字典
config_map = {
'development': DevelopmentConfig,
'production': ProductionConfig,
'testing': TestingConfig,
'local': LocalConfig,
'default': DevelopmentConfig
}
def get_config():
"""
根据环境变量获取对应的配置类
环境变量: FLASK_ENV
可选值: development, production, testing, local
Returns:
Config类: 对应环境的配置类
"""
env = os.environ.get('FLASK_ENV', 'development')
return config_map.get(env, config_map['default'])
# 导出配置类
__all__ = [
'Config',
'DevelopmentConfig',
'ProductionConfig',
'TestingConfig',
'LocalConfig',
'get_config'
]

82
config/base.py Normal file
View File

@@ -0,0 +1,82 @@
"""
基础配置类
包含所有环境通用的配置项
"""
import os
from datetime import timedelta
class Config:
"""
基础配置类
所有环境配置都继承此类
"""
# Flask基础配置
SECRET_KEY = os.environ.get('SECRET_KEY')
if not SECRET_KEY:
raise ValueError("SECRET_KEY 环境变量未设置,请在.env文件中配置")
# 数据库配置
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or 'sqlite:///app.db'
SQLALCHEMY_TRACK_MODIFICATIONS = False
SQLALCHEMY_ENGINE_OPTIONS = {
'pool_pre_ping': True, # 连接前检查连接是否有效
'pool_recycle': 300, # 连接回收时间(秒)
}
# 跨域配置
CORS_ORIGINS = os.environ.get('CORS_ORIGINS', '*').split(',')
# 日志配置
LOG_LEVEL = os.environ.get('LOG_LEVEL', 'INFO')
LOG_FILE = os.environ.get('LOG_FILE', 'logs/app.log')
# 缓存配置
CACHE_TYPE = os.environ.get('CACHE_TYPE', 'simple')
CACHE_DEFAULT_TIMEOUT = int(os.environ.get('CACHE_DEFAULT_TIMEOUT', 300))
# Redis缓存配置当CACHE_TYPE=redis时使用
REDIS_URL = os.environ.get('REDIS_URL', 'redis://localhost:6379/0')
# 会话配置
PERMANENT_SESSION_LIFETIME = timedelta(
hours=int(os.environ.get('SESSION_LIFETIME_HOURS', 24))
)
# 文件上传配置
MAX_CONTENT_LENGTH = int(os.environ.get('MAX_CONTENT_LENGTH', 16 * 1024 * 1024)) # 16MB
UPLOAD_FOLDER = os.environ.get('UPLOAD_FOLDER', 'uploads')
# 安全配置
WTF_CSRF_ENABLED = os.environ.get('WTF_CSRF_ENABLED', 'True').lower() == 'true'
WTF_CSRF_TIME_LIMIT = int(os.environ.get('WTF_CSRF_TIME_LIMIT', 3600))
@staticmethod
def init_app(app):
"""
初始化应用配置
创建必要的目录和配置日志
"""
# 创建必要的目录
os.makedirs('logs', exist_ok=True)
os.makedirs('uploads', exist_ok=True)
# 配置日志
import logging
from logging.handlers import RotatingFileHandler
if not app.debug and not app.testing:
file_handler = RotatingFileHandler(
Config.LOG_FILE,
maxBytes=10240000, # 10MB
backupCount=10
)
file_handler.setFormatter(logging.Formatter(
'%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]'
))
file_handler.setLevel(getattr(logging, Config.LOG_LEVEL))
app.logger.addHandler(file_handler)
app.logger.setLevel(getattr(logging, Config.LOG_LEVEL))
app.logger.info('应用启动')

22
config/development.py Normal file
View File

@@ -0,0 +1,22 @@
"""
开发环境配置
"""
from .base import Config
class DevelopmentConfig(Config):
"""
开发环境配置
启用调试模式,使用开发数据库
"""
DEBUG = True
TESTING = False
# 开发环境可以使用SQLite
SQLALCHEMY_DATABASE_URI = Config.SQLALCHEMY_DATABASE_URI or 'sqlite:///dev.db'
# 开发环境日志级别
LOG_LEVEL = 'DEBUG'
# 开发环境允许所有跨域请求
CORS_ORIGINS = ['*']

15
config/local.py Normal file
View File

@@ -0,0 +1,15 @@
"""
本地环境配置
用于本地开发,可以覆盖默认配置
"""
from .development import DevelopmentConfig
class LocalConfig(DevelopmentConfig):
"""
本地环境配置
继承开发环境配置,可以添加本地特定配置
"""
# 本地环境可以使用本地数据库
# 可以在这里覆盖开发环境的配置
pass

35
config/production.py Normal file
View File

@@ -0,0 +1,35 @@
"""
生产环境配置
"""
from .base import Config
class ProductionConfig(Config):
"""
生产环境配置
关闭调试模式,使用生产数据库
"""
DEBUG = False
TESTING = False
# 生产环境必须使用生产数据库
# 从环境变量获取,如果没有设置会抛出错误
SQLALCHEMY_DATABASE_URI = Config.SQLALCHEMY_DATABASE_URI
if not SQLALCHEMY_DATABASE_URI or SQLALCHEMY_DATABASE_URI.startswith('sqlite'):
raise ValueError("生产环境必须配置非SQLite数据库")
# 生产环境日志级别
LOG_LEVEL = 'INFO'
# 生产环境限制跨域来源
# 应该从环境变量获取,格式: https://yourdomain.com,https://www.yourdomain.com
CORS_ORIGINS = Config.CORS_ORIGINS
if CORS_ORIGINS == ['*']:
import warnings
warnings.warn("生产环境CORS_ORIGINS设置为'*'存在安全风险,请配置具体域名")
# 生产环境安全配置
WTF_CSRF_ENABLED = True
SESSION_COOKIE_SECURE = True # 仅HTTPS传输
SESSION_COOKIE_HTTPONLY = True # 防止XSS
SESSION_COOKIE_SAMESITE = 'Lax' # CSRF保护

25
config/testing.py Normal file
View File

@@ -0,0 +1,25 @@
"""
测试环境配置
"""
from .base import Config
class TestingConfig(Config):
"""
测试环境配置
使用内存数据库关闭CSRF保护
"""
DEBUG = True
TESTING = True
# 测试环境使用内存数据库
SQLALCHEMY_DATABASE_URI = 'sqlite:///:memory:'
# 测试环境关闭CSRF保护
WTF_CSRF_ENABLED = False
# 测试环境日志级别
LOG_LEVEL = 'DEBUG'
# 测试环境允许所有跨域请求
CORS_ORIGINS = ['*']