CI/CD Pipeline / test-admin (push) Waiting to run
CI/CD Pipeline / test-bigscreen (push) Waiting to run
CI/CD Pipeline / build-push (ljwx-admin) (push) Blocked by required conditions
CI/CD Pipeline / build-push (ljwx-bigscreen) (push) Blocked by required conditions
CI/CD Pipeline / build-push (ljwx-boot) (push) Blocked by required conditions
CI/CD Pipeline / update-deploy (push) Blocked by required conditions
CI/CD Pipeline / build-pr (ljwx-admin) (push) Blocked by required conditions
CI/CD Pipeline / build-pr (ljwx-bigscreen) (push) Blocked by required conditions
CI/CD Pipeline / build-pr (ljwx-boot) (push) Blocked by required conditions
CI/CD Pipeline / security-scan (push) Has been cancelled
CI/CD Pipeline / test-build-boot (push) Has been cancelled
新增核心功能: - 健康画像生成系统(用户/部门/组织基线) - 风险评估框架(心血管/运动/呼吸/睡眠) - 行为画像分析(饮食/运动/睡眠/健康关注度) - 数据质量评分和告警 数据库迁移: - V1.3.0~V1.7.0 健康监测表结构 前端增强: - ljwx-admin: BigScreen集成、健康搜索优化 - ljwx-bigscreen: SSO认证、登录界面 文档体系: - 强制文档管理规范(kebab-case、分类、Git hooks) - 架构文档、开发指南、运维手册 - 工程蓝图 v2.1 CI/CD: - 文档验证工作流 - 生产就绪性检查脚本 - 完整测试覆盖 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
135 lines
3.9 KiB
Python
135 lines
3.9 KiB
Python
"""
|
||
Flask应用工厂模块
|
||
"""
|
||
from flask import Flask
|
||
from flask_cors import CORS
|
||
from flask_compress import Compress
|
||
from flask_session import Session
|
||
|
||
def create_app(config_name='default'):
|
||
"""
|
||
创建Flask应用实例
|
||
|
||
Args:
|
||
config_name: 配置名称 ('development', 'production', 'testing')
|
||
|
||
Returns:
|
||
Flask应用实例
|
||
"""
|
||
app = Flask(__name__)
|
||
|
||
# 加载配置
|
||
if config_name == 'development':
|
||
from config import DevelopmentConfig
|
||
app.config.from_object(DevelopmentConfig)
|
||
elif config_name == 'production':
|
||
from config import ProductionConfig
|
||
app.config.from_object(ProductionConfig)
|
||
else:
|
||
from config import Config
|
||
app.config.from_object(Config)
|
||
|
||
# 初始化Flask扩展
|
||
from app.extensions import db, init_redis, socketio, redis_client
|
||
db.init_app(app)
|
||
init_redis(app)
|
||
socketio.init_app(app, cors_allowed_origins="*")
|
||
|
||
# 初始化 Flask-Session(使用 Redis)
|
||
app.config['SESSION_REDIS'] = redis_client
|
||
Session(app)
|
||
|
||
# CORS和压缩
|
||
CORS(app)
|
||
Compress(app)
|
||
|
||
# 初始化可观测性(日志、链路追踪、指标)
|
||
try:
|
||
from observability import init_tracing, init_metrics, setup_logging
|
||
from config import setup_logging as config_setup_logging
|
||
|
||
# 设置结构化日志
|
||
config_setup_logging(app)
|
||
|
||
# 初始化 OpenTelemetry 链路追踪
|
||
init_tracing(app)
|
||
|
||
# 初始化 Prometheus 指标
|
||
init_metrics(app)
|
||
|
||
app.logger.info("Observability initialized successfully")
|
||
except Exception as e:
|
||
app.logger.warning(f"Failed to initialize observability: {e}")
|
||
|
||
# 注册蓝图
|
||
register_blueprints(app)
|
||
|
||
# 注册全局钩子
|
||
register_hooks(app)
|
||
|
||
# 注册错误处理器
|
||
register_error_handlers(app)
|
||
|
||
return app
|
||
|
||
|
||
def register_blueprints(app):
|
||
"""注册所有蓝图"""
|
||
from app.blueprints.auth import auth_bp
|
||
from app.blueprints.health import health_bp
|
||
from app.blueprints.device import device_bp
|
||
from app.blueprints.alert import alert_bp
|
||
from app.blueprints.user import user_bp
|
||
from app.blueprints.statistics import statistics_bp
|
||
from app.blueprints.message import message_bp
|
||
from app.blueprints.config_mgmt import config_mgmt_bp
|
||
from app.blueprints.recommendation import recommendation_bp
|
||
from app.blueprints.monitoring import monitoring_bp
|
||
from app.blueprints.views import views_bp
|
||
|
||
app.register_blueprint(auth_bp) # 认证蓝图(SSO)
|
||
app.register_blueprint(health_bp)
|
||
app.register_blueprint(device_bp)
|
||
app.register_blueprint(alert_bp)
|
||
app.register_blueprint(user_bp)
|
||
app.register_blueprint(statistics_bp)
|
||
app.register_blueprint(message_bp)
|
||
app.register_blueprint(config_mgmt_bp)
|
||
app.register_blueprint(recommendation_bp)
|
||
app.register_blueprint(monitoring_bp)
|
||
app.register_blueprint(views_bp)
|
||
|
||
|
||
def register_hooks(app):
|
||
"""注册全局请求钩子"""
|
||
import time
|
||
from flask import g, request
|
||
|
||
@app.before_request
|
||
def before_request():
|
||
"""请求前钩子 - 记录请求开始时间"""
|
||
g.start_time = time.time()
|
||
|
||
@app.after_request
|
||
def after_request(response):
|
||
"""请求后钩子 - 记录请求时间"""
|
||
if hasattr(g, 'start_time'):
|
||
elapsed = time.time() - g.start_time
|
||
if elapsed > 1.0: # 慢请求告警
|
||
app.logger.warning(f'Slow request: {request.path} took {elapsed:.2f}s')
|
||
return response
|
||
|
||
|
||
def register_error_handlers(app):
|
||
"""注册错误处理器"""
|
||
from flask import jsonify
|
||
|
||
@app.errorhandler(404)
|
||
def not_found(error):
|
||
return jsonify({'success': False, 'message': 'Resource not found'}), 404
|
||
|
||
@app.errorhandler(500)
|
||
def internal_error(error):
|
||
app.logger.error(f'Internal error: {str(error)}')
|
||
return jsonify({'success': False, 'message': 'Internal server error'}), 500
|