""" PIT Router Flask 应用工厂 """ from flask import Flask from flask_socketio import SocketIO import logging from app.config import config from app.extensions import ( db, migrate, jwt, login_manager, cors, limiter, init_redis ) # Socket.IO 实例 - 避免与 app/socketio 目录冲突 socketio_app = SocketIO(cors_allowed_origins="*", async_mode='threading') def create_app(config_name='default'): """创建 Flask 应用实例""" app = Flask(__name__) app.config.from_object(config[config_name]) # 初始化扩展 _init_extensions(app) # 注册蓝图 _register_blueprints(app) # 注册 Socket.IO 事件 _register_socketio_events() # 配置日志 _configure_logging(app) # 注册错误处理 _register_error_handlers(app) # 根路由 @app.route('/') def index(): return { 'service': '智队中枢', 'version': '0.6.1', 'status': 'running', 'endpoints': { 'health': '/health', 'auth': '/api/auth', 'sessions': '/api/sessions', 'agents': '/api/agents', 'gateways': '/api/gateways', 'messages': '/api/messages', 'stats': '/api/stats', 'websocket': 'ws://host:9000' } } # 健康检查端点 @app.route('/health') def health_check(): return {'status': 'ok', 'service': 'pit-router'} return app def _init_extensions(app): """初始化 Flask 扩展""" db.init_app(app) migrate.init_app(app, db) jwt.init_app(app) login_manager.init_app(app) cors.init_app(app) limiter.init_app(app) socketio_app.init_app(app) # 配置 Flask-Login user_loader from app.models import User @login_manager.user_loader def load_user(user_id): return User.query.get(user_id) # 初始化 Redis init_redis(app) # 创建数据库表 with app.app_context(): db.create_all() def _register_blueprints(app): """注册蓝图""" from app.routes.auth import auth_bp from app.routes.sessions import sessions_bp from app.routes.agents import agents_bp from app.routes.gateways import gateways_bp from app.routes.messages import messages_bp from app.routes.stats import stats_bp from app.web.routes import web_bp from app.web.api import web_api_bp app.register_blueprint(auth_bp, url_prefix='/api/auth') app.register_blueprint(sessions_bp, url_prefix='/api/sessions') app.register_blueprint(agents_bp, url_prefix='/api/agents') app.register_blueprint(gateways_bp, url_prefix='/api/gateways') app.register_blueprint(messages_bp, url_prefix='/api/messages') app.register_blueprint(stats_bp, url_prefix='/api/stats') app.register_blueprint(web_bp, url_prefix='/web') app.register_blueprint(web_api_bp) def _register_socketio_events(): """注册 Socket.IO 事件处理器""" from app.socketio import handlers as socketio_handlers socketio_handlers.register_handlers(socketio_app) def _configure_logging(app): """配置日志""" log_level = app.config.get('LOG_LEVEL', 'INFO') logging.basicConfig( level=getattr(logging, log_level), format='%(asctime)s [%(levelname)s] %(name)s: %(message)s' ) def _register_error_handlers(app): """注册错误处理器""" from flask import jsonify, render_template, request, render_template @app.errorhandler(400) def bad_request(error): if request.accepts('text/html'): return render_template('errors/400.html', error=str(error)), 400 return jsonify({'error': 'Bad Request', 'message': str(error)}), 400 @app.errorhandler(401) def unauthorized(error): if request.accepts('text/html'): return render_template('errors/401.html', error=str(error)), 401 return jsonify({'error': 'Unauthorized', 'message': str(error)}), 401 @app.errorhandler(403) def forbidden(error): if request.accepts('text/html'): return render_template('errors/403.html', error=str(error)), 403 return jsonify({'error': 'Forbidden', 'message': str(error)}), 403 @app.errorhandler(404) def not_found(error): if request.accepts('text/html'): return render_template('errors/404.html', error=str(error)), 404 return jsonify({'error': 'Not Found', 'message': str(error)}), 404 @app.errorhandler(500) def internal_error(error): if request.accepts('text/html'): return render_template('errors/500.html', error=str(error)), 500 return jsonify({'error': 'Internal Server Error', 'message': str(error)}), 500