Files
ai_api_web/backend/app.py
2026-01-22 18:26:47 +08:00

95 lines
3.7 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from flask import Flask, jsonify, request
from flask_cors import CORS
from flask_jwt_extended import JWTManager, get_jwt_identity, verify_jwt_in_request
from flask_jwt_extended.exceptions import JWTDecodeError, NoAuthorizationError, InvalidHeaderError
from config import Config
from models import db
from routes.auth import auth_bp
from routes.tokens import tokens_bp
from routes.dashboard import dashboard_bp
from routes.logs import logs_bp
from routes.recharge import recharge_bp
from routes.user import user_bp
from routes.models import models_bp
import logging
# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def create_app():
app = Flask(__name__)
app.config.from_object(Config)
# 请求前钩子:记录请求信息(用于调试)
@app.before_request
def log_request():
if request.path.startswith('/api/') and request.path != '/api/auth/login' and request.path != '/api/auth/register':
auth_header = request.headers.get('Authorization', 'None')
logger.info(f"[{request.method}] {request.path}")
logger.info(f"Authorization Header: {auth_header[:80] if auth_header != 'None' else 'Missing'}")
# 初始化扩展
db.init_app(app)
# CORS配置允许所有来源并支持credentials
CORS(app,
resources={r"/api/*": {
"origins": "*",
"methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
"allow_headers": ["Content-Type", "Authorization"],
"supports_credentials": True
}},
supports_credentials=True)
jwt = JWTManager(app)
# JWT错误处理器
@jwt.expired_token_loader
def expired_token_callback(jwt_header, jwt_payload):
logger.warning(f"Token expired: {jwt_payload}")
return jsonify({'error': 'Token已过期请重新登录'}), 401
@jwt.invalid_token_loader
def invalid_token_callback(error):
auth_header = request.headers.get('Authorization', 'None')
logger.error(f"Invalid token error: {str(error)}")
logger.error(f"Authorization header: {auth_header[:100] if auth_header != 'None' else 'Missing'}")
return jsonify({
'error': '无效的Token',
'detail': str(error),
'hint': '请检查Authorization头格式是否正确应为: Bearer <token>'
}), 422
@jwt.unauthorized_loader
def missing_token_callback(error):
logger.warning(f"Missing token: {str(error)}")
auth_header = request.headers.get('Authorization', 'None')
logger.warning(f"Authorization header: {auth_header[:100] if auth_header != 'None' else 'Missing'}")
return jsonify({
'error': '缺少认证Token请先登录',
'detail': str(error)
}), 401
@jwt.needs_fresh_token_loader
def token_not_fresh_callback(jwt_header, jwt_payload):
logger.warning(f"Token not fresh: {jwt_payload}")
return jsonify({'error': 'Token需要刷新'}), 401
# 注册蓝图
app.register_blueprint(auth_bp, url_prefix='/api/auth')
app.register_blueprint(tokens_bp, url_prefix='/api/tokens')
app.register_blueprint(dashboard_bp, url_prefix='/api/dashboard')
app.register_blueprint(logs_bp, url_prefix='/api/logs')
app.register_blueprint(recharge_bp, url_prefix='/api/recharge')
app.register_blueprint(user_bp, url_prefix='/api/user')
app.register_blueprint(models_bp, url_prefix='/api/models')
# 创建数据库表
with app.app_context():
db.create_all()
return app
if __name__ == '__main__':
app = create_app()
app.run(debug=True, host='0.0.0.0', port=5000)