新增页面:
- session_detail.html - 会话详情独立页面
- channel_edit.html - 频道配置编辑独立页面
- 错误页面 (401/403/404/500)
功能优化:
- 添加错误处理器支持 HTML 响应
- 更新编辑按钮跳转独立页面
- 完善暗黑主题支持
作者: 小黑 🐶
157 lines
4.7 KiB
Python
157 lines
4.7 KiB
Python
"""
|
|
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
|